#include "asterisk.h"
#include "asterisk/_private.h"
#include <sys/time.h>
#include <signal.h>
#include <math.h>
#include "asterisk/paths.h"
#include "asterisk/pbx.h"
#include "asterisk/frame.h"
#include "asterisk/mod_format.h"
#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include "asterisk/musiconhold.h"
#include "asterisk/say.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/manager.h"
#include "asterisk/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/threadstorage.h"
#include "asterisk/slinfactory.h"
#include "asterisk/audiohook.h"
#include "asterisk/framehook.h"
#include "asterisk/timing.h"
#include "asterisk/autochan.h"
#include "asterisk/stringfields.h"
#include "asterisk/global_datastores.h"
#include "asterisk/data.h"

Go to the source code of this file.
Data Structures | |
| struct | ast_channel_iterator |
| struct | ast_epoll_data |
| struct | ast_party_id_ies |
| struct | ast_party_name_ies |
| struct | ast_party_number_ies |
| struct | ast_party_subaddress_ies |
| struct | ast_silence_generator |
| struct | backends |
| the list of registered channel types More... | |
| struct | chanlist |
| List of channel drivers. More... | |
| struct | plc_ds |
| struct | tonepair_def |
| struct | tonepair_state |
| struct | xfer_masquerade_ds |
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_PLAN, AST_CONNECTED_LINE_ID_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, AST_CONNECTED_LINE_TAG, AST_CONNECTED_LINE_VERSION, AST_CONNECTED_LINE_NAME_VALID, AST_CONNECTED_LINE_NAME_CHAR_SET, AST_CONNECTED_LINE_NAME_PRESENTATION, AST_CONNECTED_LINE_NUMBER_VALID, AST_CONNECTED_LINE_NUMBER_PRESENTATION } |
| Element identifiers for connected line indication frame data. More... | |
| enum | { AST_REDIRECTING_FROM_NUMBER, AST_REDIRECTING_FROM_NAME, AST_REDIRECTING_FROM_NUMBER_PLAN, AST_REDIRECTING_FROM_ID_PRESENTATION, AST_REDIRECTING_TO_NUMBER, AST_REDIRECTING_TO_NAME, AST_REDIRECTING_TO_NUMBER_PLAN, AST_REDIRECTING_TO_ID_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, AST_REDIRECTING_FROM_TAG, AST_REDIRECTING_TO_TAG, AST_REDIRECTING_VERSION, AST_REDIRECTING_FROM_NAME_VALID, AST_REDIRECTING_FROM_NAME_CHAR_SET, AST_REDIRECTING_FROM_NAME_PRESENTATION, AST_REDIRECTING_FROM_NUMBER_VALID, AST_REDIRECTING_FROM_NUMBER_PRESENTATION, AST_REDIRECTING_TO_NAME_VALID, AST_REDIRECTING_TO_NAME_CHAR_SET, AST_REDIRECTING_TO_NAME_PRESENTATION, AST_REDIRECTING_TO_NUMBER_VALID, AST_REDIRECTING_TO_NUMBER_PRESENTATION } |
| 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 ap) |
| Create a new channel structure. | |
| static int | __ast_channel_masquerade (struct ast_channel *original, struct ast_channel *clonechan, struct ast_datastore *xfer_ds) |
| 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, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *addr, 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) |
| static void | adjust_frame_for_plc (struct ast_channel *chan, struct ast_frame *frame, struct ast_datastore *datastore) |
| static void | apply_plc (struct ast_channel *chan, struct ast_frame *frame) |
| 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) |
| struct ast_format * | ast_best_codec (struct ast_format_cap *cap, struct ast_format *result) |
| 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, const char *addr, int timeout) |
| Make a call. | |
| struct ast_channel * | ast_call_forward (struct ast_channel *caller, struct ast_channel *orig, int *timeout, struct ast_format_cap *cap, 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. | |
| static int | ast_channel_by_exten_cb (void *obj, void *arg, void *data, int flags) |
| static int | ast_channel_by_name_cb (void *obj, void *arg, void *data, int flags) |
| static int | ast_channel_by_uniqueid_cb (void *obj, void *arg, void *data, int flags) |
| 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. | |
| int | ast_channel_cc_params_init (struct ast_channel *chan, const struct ast_cc_config_params *base_params) |
| Set up datastore with CCSS parameters for a channel. | |
| static void | ast_channel_change_linkedid (struct ast_channel *chan, const char *linkedid) |
| void | ast_channel_clear_softhangup (struct ast_channel *chan, int flag) |
| Clear a set of softhangup flags from a channel. | |
| 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 is_caller, int is_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. | |
| int | ast_channel_get_cc_agent_type (struct ast_channel *chan, char *agent_type, size_t size) |
| Find the appropriate CC agent type to use given a channel. | |
| struct ast_cc_config_params * | ast_channel_get_cc_config_params (struct ast_channel *chan) |
| Get the CCSS parameters from a channel. | |
| int | ast_channel_get_device_name (struct ast_channel *chan, char *device_name, size_t name_buffer_length) |
| Get a device name given its channel structure. | |
| 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 *clone) |
| 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, const struct ast_set_party_connected_line *update) |
| 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, const struct ast_set_party_redirecting *update) |
| 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_redirecting_macro (struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *redirecting_info, int is_caller, int is_frame) |
| Run a redirecting interception macro and update a channel's redirecting information. | |
| 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_caller (struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update) |
| Set the caller id information in the Asterisk channel. | |
| void | ast_channel_set_caller_event (struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update) |
| Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name or number changed. | |
| void | ast_channel_set_connected_line (struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update) |
| 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, const struct ast_set_party_redirecting *update) |
| 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. | |
| int | ast_channel_transfer_masquerade (struct ast_channel *target_chan, const struct ast_party_connected_line *target_id, int target_held, struct ast_channel *transferee_chan, const struct ast_party_connected_line *transferee_id, int transferee_held) |
| Setup a masquerade to transfer a call. | |
| void | ast_channel_undefer_dtmf (struct ast_channel *chan) |
| Unset defer DTMF flag on channel. | |
| void | ast_channel_unlink (struct ast_channel *chan) |
| Remove a channel from the global channels container. | |
| 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, const struct ast_set_party_connected_line *update) |
| Indicate that the connected line information has changed. | |
| void | ast_channel_update_redirecting (struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update) |
| 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, const struct ast_set_party_connected_line *update) |
| Build the connected line information data frame. | |
| void | ast_connected_line_copy_from_caller (struct ast_party_connected_line *dest, const struct ast_party_caller *src) |
| Copy the caller information to the connected line information. | |
| void | ast_connected_line_copy_to_caller (struct ast_party_caller *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. | |
| int | ast_is_deferrable_frame (const struct ast_frame *frame) |
| Should we keep this frame for later? | |
| 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_party_caller *dest, const struct ast_party_caller *src) |
| Copy the source caller information to the destination caller. | |
| void | ast_party_caller_free (struct ast_party_caller *doomed) |
| Destroy the caller party contents. | |
| void | ast_party_caller_init (struct ast_party_caller *init) |
| Initialize the given caller structure. | |
| void | ast_party_caller_set (struct ast_party_caller *dest, const struct ast_party_caller *src, const struct ast_set_party_caller *update) |
| Set the caller information based on another caller source. | |
| void | ast_party_caller_set_init (struct ast_party_caller *init, const struct ast_party_caller *guide) |
| Initialize the given caller structure using the given guide for a set update operation. | |
| void | ast_party_connected_line_collect_caller (struct ast_party_connected_line *connected, struct ast_party_caller *caller) |
| 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, const struct ast_set_party_connected_line *update) |
| 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. | |
| void | ast_party_dialed_copy (struct ast_party_dialed *dest, const struct ast_party_dialed *src) |
| Copy the source dialed party information to the destination dialed party. | |
| void | ast_party_dialed_free (struct ast_party_dialed *doomed) |
| Destroy the dialed party contents. | |
| void | ast_party_dialed_init (struct ast_party_dialed *init) |
| Initialize the given dialed structure. | |
| void | ast_party_dialed_set (struct ast_party_dialed *dest, const struct ast_party_dialed *src) |
| Set the dialed information based on another dialed source. | |
| void | ast_party_dialed_set_init (struct ast_party_dialed *init, const struct ast_party_dialed *guide) |
| Initialize the given dialed structure using the given guide for a set update operation. | |
| void | ast_party_id_copy (struct ast_party_id *dest, const struct ast_party_id *src) |
| Copy the source party id information to the destination party id. | |
| void | ast_party_id_free (struct ast_party_id *doomed) |
| Destroy the party id contents. | |
| void | ast_party_id_init (struct ast_party_id *init) |
| Initialize the given party id structure. | |
| int | ast_party_id_presentation (const struct ast_party_id *id) |
| Determine the overall presentation value for the given party. | |
| void | ast_party_id_set (struct ast_party_id *dest, const struct ast_party_id *src, const struct ast_set_party_id *update) |
| Set the source party id information into the destination party id. | |
| void | ast_party_id_set_init (struct ast_party_id *init, const struct ast_party_id *guide) |
| Initialize the given party id structure using the given guide for a set update operation. | |
| void | ast_party_name_copy (struct ast_party_name *dest, const struct ast_party_name *src) |
| Copy the source party name information to the destination party name. | |
| void | ast_party_name_free (struct ast_party_name *doomed) |
| Destroy the party name contents. | |
| void | ast_party_name_init (struct ast_party_name *init) |
| Initialize the given name structure. | |
| void | ast_party_name_set (struct ast_party_name *dest, const struct ast_party_name *src) |
| Set the source party name information into the destination party name. | |
| void | ast_party_name_set_init (struct ast_party_name *init, const struct ast_party_name *guide) |
| Initialize the given party name structure using the given guide for a set update operation. | |
| void | ast_party_number_copy (struct ast_party_number *dest, const struct ast_party_number *src) |
| Copy the source party number information to the destination party number. | |
| void | ast_party_number_free (struct ast_party_number *doomed) |
| Destroy the party number contents. | |
| void | ast_party_number_init (struct ast_party_number *init) |
| Initialize the given number structure. | |
| void | ast_party_number_set (struct ast_party_number *dest, const struct ast_party_number *src) |
| Set the source party number information into the destination party number. | |
| void | ast_party_number_set_init (struct ast_party_number *init, const struct ast_party_number *guide) |
| Initialize the given party number structure using the given guide for a set update operation. | |
| 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_init (struct ast_party_redirecting *init) |
| Initialize the given redirecting structure. | |
| void | ast_party_redirecting_set (struct ast_party_redirecting *dest, const struct ast_party_redirecting *src, const struct ast_set_party_redirecting *update) |
| Set the redirecting information based on another redirecting source. | |
| 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 subaddress structure using the given guide for a set update operation. | |
| int | ast_plc_reload (void) |
| Reload genericplc configuration value from codecs.conf. | |
| 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, const struct ast_set_party_redirecting *update) |
| 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, struct ast_format_cap *request_cap, const struct ast_channel *requestor, const char *addr, int *cause) |
| Requests a channel. | |
| struct ast_channel * | ast_request_and_dial (const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *addr, 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) |
| function to pronounce character and phonetic strings | |
| 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) |
| Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable. | |
| 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 and generate AMI event. | |
| 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, struct ast_format *format) |
| Sets read format on channel chan. | |
| int | ast_set_read_format_by_id (struct ast_channel *chan, enum ast_format_id id) |
| Sets read format on channel chan by id. | |
| int | ast_set_read_format_from_cap (struct ast_channel *chan, struct ast_format_cap *cap) |
| Sets read format on channel chan from capabilities 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, struct ast_format *format) |
| Sets write format on channel chan. | |
| int | ast_set_write_format_by_id (struct ast_channel *chan, enum ast_format_id id) |
| Sets write format on channel chan. | |
| int | ast_set_write_format_from_cap (struct ast_channel *chan, struct ast_format_cap *cap) |
| 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 int | calc_monitor_jump (int samples, int sample_rate, int seek_rate) |
| calculates the number of samples to jump forward with in a monitor stream. | |
| static void | call_forward_inherit (struct ast_channel *new_chan, struct ast_channel *parent, struct ast_channel *orig) |
| static void * | channel_cc_params_copy (void *data) |
| static void | channel_cc_params_destroy (void *data) |
| 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 int | data_channels_provider_handler (const struct ast_data_search *search, struct ast_data *root) |
| static int | data_channeltypes_provider_handler (const struct ast_data_search *search, struct ast_data *data_root) |
| static void | destroy_hooks (struct ast_channel *chan) |
| static void | free_translation (struct ast_channel *clonechan) |
| static int | generator_force (const void *data) |
| static void | generator_write_format_change (struct ast_channel *chan) |
| 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 struct ast_frame * | kill_exception (struct ast_channel *chan) |
| static int | kill_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
| static int | kill_hangup (struct ast_channel *chan) |
| static struct ast_frame * | kill_read (struct ast_channel *chan) |
| static int | kill_write (struct ast_channel *chan, struct ast_frame *frame) |
| static void | manager_bridge_event (int onoff, int type, struct ast_channel *c0, struct ast_channel *c1) |
| Send manager event for bridge link and unlink events. | |
| static void | masquerade_colp_transfer (struct ast_channel *transferee, struct xfer_masquerade_ds *colp) |
| static const char * | oldest_linkedid (const char *a, const char *b) |
| static void | party_connected_line_copy_transfer (struct ast_party_connected_line *dest, const struct ast_party_connected_line *src) |
| static int | party_id_build_data (unsigned char *data, size_t datalen, const struct ast_party_id *id, const char *label, const struct ast_party_id_ies *ies, const struct ast_set_party_id *update) |
| static int | party_name_build_data (unsigned char *data, size_t datalen, const struct ast_party_name *name, const char *label, const struct ast_party_name_ies *ies) |
| static int | party_number_build_data (unsigned char *data, size_t datalen, const struct ast_party_number *number, const char *label, const struct ast_party_number_ies *ies) |
| static int | party_subaddress_build_data (unsigned char *data, size_t datalen, const struct ast_party_subaddress *subaddress, const char *label, const struct ast_party_subaddress_ies *ies) |
| static void | plc_ds_destroy (void *data) |
| static void | queue_dtmf_readq (struct ast_channel *chan, struct ast_frame *f) |
| static void | report_new_callerid (struct ast_channel *chan) |
| static void | send_dtmf_event (struct ast_channel *chan, const char *direction, const char digit, const char *begin, const char *end) |
| static int | set_format (struct ast_channel *chan, struct ast_format_cap *cap_set, struct ast_format *rawformat, struct ast_format *format, struct ast_trans_pvt **trans, const int direction) |
| static int | set_security_requirements (const struct ast_channel *requestor, struct ast_channel *out) |
| 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) |
| static void | xfer_ds_destroy (void *data) |
Variables | |
| struct ast_channel_tech | ast_kill_tech |
| Kill the channel channel driver technology descriptor. | |
| 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 ast_datastore_info | cc_channel_datastore_info |
| static struct ast_data_entry | channel_providers [] |
| static struct ao2_container * | channels |
| All active channels on the system. | |
| static struct ast_data_handler | channels_provider |
| static struct ast_data_handler | channeltypes_provider |
| static struct ast_cli_entry | cli_channel [] |
| unsigned long | global_fin |
| unsigned long | global_fout |
| static struct ast_channel_tech | null_tech |
| static struct ast_datastore_info | plc_ds_info |
| 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 |
| static struct ast_datastore_info | xfer_ds_info |
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 104 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 107 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 111 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 8526 of file channel.c.
08526 { 08527 AST_CONNECTED_LINE_NUMBER, 08528 AST_CONNECTED_LINE_NAME, 08529 AST_CONNECTED_LINE_NUMBER_PLAN, 08530 AST_CONNECTED_LINE_ID_PRESENTATION,/* Combined number and name presentation. */ 08531 AST_CONNECTED_LINE_SOURCE, 08532 AST_CONNECTED_LINE_SUBADDRESS, 08533 AST_CONNECTED_LINE_SUBADDRESS_TYPE, 08534 AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, 08535 AST_CONNECTED_LINE_SUBADDRESS_VALID, 08536 AST_CONNECTED_LINE_TAG, 08537 AST_CONNECTED_LINE_VERSION, 08538 AST_CONNECTED_LINE_NAME_VALID, 08539 AST_CONNECTED_LINE_NAME_CHAR_SET, 08540 AST_CONNECTED_LINE_NAME_PRESENTATION, 08541 AST_CONNECTED_LINE_NUMBER_VALID, 08542 AST_CONNECTED_LINE_NUMBER_PRESENTATION, 08543 };
| anonymous enum |
Element identifiers for redirecting indication frame data.
Definition at line 8847 of file channel.c.
08847 { 08848 AST_REDIRECTING_FROM_NUMBER, 08849 AST_REDIRECTING_FROM_NAME, 08850 AST_REDIRECTING_FROM_NUMBER_PLAN, 08851 AST_REDIRECTING_FROM_ID_PRESENTATION, 08852 AST_REDIRECTING_TO_NUMBER, 08853 AST_REDIRECTING_TO_NAME, 08854 AST_REDIRECTING_TO_NUMBER_PLAN, 08855 AST_REDIRECTING_TO_ID_PRESENTATION, 08856 AST_REDIRECTING_REASON, 08857 AST_REDIRECTING_COUNT, 08858 AST_REDIRECTING_FROM_SUBADDRESS, 08859 AST_REDIRECTING_FROM_SUBADDRESS_TYPE, 08860 AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, 08861 AST_REDIRECTING_FROM_SUBADDRESS_VALID, 08862 AST_REDIRECTING_TO_SUBADDRESS, 08863 AST_REDIRECTING_TO_SUBADDRESS_TYPE, 08864 AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, 08865 AST_REDIRECTING_TO_SUBADDRESS_VALID, 08866 AST_REDIRECTING_FROM_TAG, 08867 AST_REDIRECTING_TO_TAG, 08868 AST_REDIRECTING_VERSION, 08869 AST_REDIRECTING_FROM_NAME_VALID, 08870 AST_REDIRECTING_FROM_NAME_CHAR_SET, 08871 AST_REDIRECTING_FROM_NAME_PRESENTATION, 08872 AST_REDIRECTING_FROM_NUMBER_VALID, 08873 AST_REDIRECTING_FROM_NUMBER_PRESENTATION, 08874 AST_REDIRECTING_TO_NAME_VALID, 08875 AST_REDIRECTING_TO_NAME_CHAR_SET, 08876 AST_REDIRECTING_TO_NAME_PRESENTATION, 08877 AST_REDIRECTING_TO_NUMBER_VALID, 08878 AST_REDIRECTING_TO_NUMBER_PRESENTATION, 08879 };
| 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 2767 of file channel.c.
References ast_channel::_state, ast_channel_lock, ast_channel_name(), ast_channel_unlock, AST_CONTROL_HANGUP, ast_debug, AST_FRAME_CNG, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_frisolate(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_log(), ast_queue_frame_head(), ast_raw_answer(), ast_read(), AST_STATE_RING, AST_STATE_RINGING, ast_waitfor(), errno, frames, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, MAX, and ast_frame::subclass.
Referenced by ast_answer(), pbx_builtin_answer(), and pbx_builtin_incomplete().
02768 { 02769 int res = 0; 02770 enum ast_channel_state old_state; 02771 02772 old_state = chan->_state; 02773 if ((res = ast_raw_answer(chan, cdr_answer))) { 02774 return res; 02775 } 02776 02777 switch (old_state) { 02778 case AST_STATE_RINGING: 02779 case AST_STATE_RING: 02780 /* wait for media to start flowing, but don't wait any longer 02781 * than 'delay' or 500 milliseconds, whichever is longer 02782 */ 02783 do { 02784 AST_LIST_HEAD_NOLOCK(, ast_frame) frames; 02785 struct ast_frame *cur, *new; 02786 int ms = MAX(delay, 500); 02787 unsigned int done = 0; 02788 02789 AST_LIST_HEAD_INIT_NOLOCK(&frames); 02790 02791 for (;;) { 02792 ms = ast_waitfor(chan, ms); 02793 if (ms < 0) { 02794 ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", ast_channel_name(chan), strerror(errno)); 02795 res = -1; 02796 break; 02797 } 02798 if (ms == 0) { 02799 ast_debug(2, "Didn't receive a media frame from %s within %d ms of answering. Continuing anyway\n", ast_channel_name(chan), MAX(delay, 500)); 02800 break; 02801 } 02802 cur = ast_read(chan); 02803 if (!cur || ((cur->frametype == AST_FRAME_CONTROL) && 02804 (cur->subclass.integer == AST_CONTROL_HANGUP))) { 02805 if (cur) { 02806 ast_frfree(cur); 02807 } 02808 res = -1; 02809 ast_debug(2, "Hangup of channel %s detected in answer routine\n", ast_channel_name(chan)); 02810 break; 02811 } 02812 02813 if ((new = ast_frisolate(cur)) != cur) { 02814 ast_frfree(cur); 02815 } 02816 02817 AST_LIST_INSERT_HEAD(&frames, new, frame_list); 02818 02819 /* if a specific delay period was requested, continue 02820 * until that delay has passed. don't stop just because 02821 * incoming media has arrived. 02822 */ 02823 if (delay) { 02824 continue; 02825 } 02826 02827 switch (new->frametype) { 02828 /* all of these frametypes qualify as 'media' */ 02829 case AST_FRAME_VOICE: 02830 case AST_FRAME_VIDEO: 02831 case AST_FRAME_TEXT: 02832 case AST_FRAME_DTMF_BEGIN: 02833 case AST_FRAME_DTMF_END: 02834 case AST_FRAME_IMAGE: 02835 case AST_FRAME_HTML: 02836 case AST_FRAME_MODEM: 02837 done = 1; 02838 break; 02839 case AST_FRAME_CONTROL: 02840 case AST_FRAME_IAX: 02841 case AST_FRAME_NULL: 02842 case AST_FRAME_CNG: 02843 break; 02844 } 02845 02846 if (done) { 02847 break; 02848 } 02849 } 02850 02851 if (res == 0) { 02852 ast_channel_lock(chan); 02853 while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list))) { 02854 ast_queue_frame_head(chan, cur); 02855 ast_frfree(cur); 02856 } 02857 ast_channel_unlock(chan); 02858 } 02859 } while (0); 02860 break; 02861 default: 02862 break; 02863 } 02864 02865 return res; 02866 }
| 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 6080 of file channel.c.
References ast_channel_name(), ast_channel_name_set(), ast_channel_uniqueid(), ast_manager_event, and EVENT_FLAG_CALL.
Referenced by ast_change_name(), and ast_do_masquerade().
06081 { 06082 ast_manager_event(chan, EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", ast_channel_name(chan), newname, ast_channel_uniqueid(chan)); 06083 ast_channel_name_set(chan, newname); 06084 }
| 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 |
By default, new channels are set to the "s" extension and "default" context.
Definition at line 1153 of file channel.c.
References __ast_channel_alloc_ap().
01159 { 01160 va_list ap; 01161 struct ast_channel *result; 01162 01163 va_start(ap, name_fmt); 01164 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context, 01165 linkedid, amaflag, file, line, function, name_fmt, ap); 01166 va_end(ap); 01167 01168 return result; 01169 }
| 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 | ap | |||
| ) | [static, read] |
Create a new channel structure.
Definition at line 913 of file channel.c.
References __ao2_alloc_debug(), ast_channel::_state, ast_channel::alertpipe, ast_channel::amaflags, ao2_alloc, ao2_link, ao2_ref, ARRAY_LEN, 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_accountcode(), ast_channel_destructor(), ast_channel_name(), ast_channel_name_set(), ast_channel_set_fd(), ast_channel_uniqueid(), ast_channel_unref, ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_default_accountcode, ast_default_amaflags, ast_format_cap_alloc(), ast_get_channel_tech(), AST_LIST_HEAD_INIT_NOLOCK, ast_log(), ast_manager_event, ast_party_caller_init(), ast_party_connected_line_init(), ast_party_dialed_init(), ast_party_redirecting_init(), ast_sched_context_create(), ast_state2str(), ast_strdup, ast_strdupa, ast_string_field_init, ast_strlen_zero(), ast_timer_fd(), ast_timer_get_name(), ast_timer_open(), AST_TIMING_FD, ast_channel::autochans, ast_channel::caller, ast_channel::cdr, channels, ast_channel::connected, ast_channel::context, ast_channel::datastores, defaultlanguage, ast_channel::dialed, errno, EVENT_FLAG_CALL, ast_channel::exten, ast_channel::fds, ast_channel::fin, chanlist::flags, ast_channel::fout, ast_party_caller::id, LOG_WARNING, ast_party_id::name, ast_channel::nativeformats, null_tech, ast_party_id::number, ast_channel::priority, ast_channel::redirecting, S_OR, ast_channel::sched, ast_party_number::str, ast_party_name::str, ast_channel::streamid, ast_channel::tech, chanlist::tech, ast_channel::timer, ast_channel::timingfd, ast_party_number::valid, ast_party_name::valid, and ast_channel::varshead.
Referenced by __ast_channel_alloc(), and ast_channel_alloc().
00917 { 00918 struct ast_channel *tmp; 00919 int x; 00920 int flags; 00921 struct varshead *headp; 00922 char *tech = "", *tech2 = NULL; 00923 00924 /* If shutting down, don't allocate any new channels */ 00925 if (shutting_down) { 00926 ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n"); 00927 return NULL; 00928 } 00929 00930 #if defined(REF_DEBUG) 00931 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_channel_destructor, "", file, line, 00932 function, 1); 00933 #elif defined(__AST_DEBUG_MALLOC) 00934 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_channel_destructor, "", file, line, 00935 function, 0); 00936 #else 00937 tmp = ao2_alloc(sizeof(*tmp), ast_channel_destructor); 00938 #endif 00939 if (!tmp) { 00940 /* Channel structure allocation failure. */ 00941 return NULL; 00942 } 00943 if (!(tmp->nativeformats = ast_format_cap_alloc())) { 00944 ao2_ref(tmp, -1); 00945 /* format capabilities structure allocation failure */ 00946 return NULL; 00947 } 00948 00949 /* 00950 * Init file descriptors to unopened state so 00951 * the destructor can know not to close them. 00952 */ 00953 tmp->timingfd = -1; 00954 for (x = 0; x < ARRAY_LEN(tmp->alertpipe); ++x) { 00955 tmp->alertpipe[x] = -1; 00956 } 00957 for (x = 0; x < ARRAY_LEN(tmp->fds); ++x) { 00958 tmp->fds[x] = -1; 00959 } 00960 #ifdef HAVE_EPOLL 00961 tmp->epfd = epoll_create(25); 00962 #endif 00963 00964 if (!(tmp->sched = ast_sched_context_create())) { 00965 ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n"); 00966 return ast_channel_unref(tmp); 00967 } 00968 00969 ast_party_dialed_init(&tmp->dialed); 00970 ast_party_caller_init(&tmp->caller); 00971 ast_party_connected_line_init(&tmp->connected); 00972 ast_party_redirecting_init(&tmp->redirecting); 00973 00974 if (cid_name) { 00975 tmp->caller.id.name.valid = 1; 00976 tmp->caller.id.name.str = ast_strdup(cid_name); 00977 if (!tmp->caller.id.name.str) { 00978 return ast_channel_unref(tmp); 00979 } 00980 } 00981 if (cid_num) { 00982 tmp->caller.id.number.valid = 1; 00983 tmp->caller.id.number.str = ast_strdup(cid_num); 00984 if (!tmp->caller.id.number.str) { 00985 return ast_channel_unref(tmp); 00986 } 00987 } 00988 00989 if ((tmp->timer = ast_timer_open())) { 00990 if (strcmp(ast_timer_get_name(tmp->timer), "timerfd")) { 00991 needqueue = 0; 00992 } 00993 tmp->timingfd = ast_timer_fd(tmp->timer); 00994 } 00995 00996 if (needqueue) { 00997 if (pipe(tmp->alertpipe)) { 00998 ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe! Try increasing max file descriptors with ulimit -n\n"); 00999 return ast_channel_unref(tmp); 01000 } else { 01001 flags = fcntl(tmp->alertpipe[0], F_GETFL); 01002 if (fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) { 01003 ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno)); 01004 return ast_channel_unref(tmp); 01005 } 01006 flags = fcntl(tmp->alertpipe[1], F_GETFL); 01007 if (fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK) < 0) { 01008 ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno)); 01009 return ast_channel_unref(tmp); 01010 } 01011 } 01012 } 01013 01014 /* 01015 * This is the last place the channel constructor can fail. 01016 * 01017 * The destructor takes advantage of this fact to ensure that the 01018 * AST_CEL_CHANNEL_END is not posted if we have not posted the 01019 * AST_CEL_CHANNEL_START yet. 01020 */ 01021 if ((ast_string_field_init(tmp, 128))) { 01022 return ast_channel_unref(tmp); 01023 } 01024 01025 /* Always watch the alertpipe */ 01026 ast_channel_set_fd(tmp, AST_ALERT_FD, tmp->alertpipe[0]); 01027 /* And timing pipe */ 01028 ast_channel_set_fd(tmp, AST_TIMING_FD, tmp->timingfd); 01029 01030 /* Initial state */ 01031 tmp->_state = state; 01032 01033 tmp->streamid = -1; 01034 01035 tmp->fin = global_fin; 01036 tmp->fout = global_fout; 01037 01038 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) { 01039 ast_channel_uniqueid_build(tmp, "%li.%d", (long) time(NULL), 01040 ast_atomic_fetchadd_int(&uniqueint, 1)); 01041 } else { 01042 ast_channel_uniqueid_build(tmp, "%s-%li.%d", ast_config_AST_SYSTEM_NAME, 01043 (long) time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1)); 01044 } 01045 01046 if (!ast_strlen_zero(linkedid)) { 01047 ast_channel_linkedid_set(tmp, linkedid); 01048 } else { 01049 ast_channel_linkedid_set(tmp, ast_channel_uniqueid(tmp)); 01050 } 01051 01052 if (!ast_strlen_zero(name_fmt)) { 01053 char *slash, *slash2; 01054 /* Almost every channel is calling this function, and setting the name via the ast_string_field_build() call. 01055 * And they all use slightly different formats for their name string. 01056 * This means, to set the name here, we have to accept variable args, and call the string_field_build from here. 01057 * This means, that the stringfields must have a routine that takes the va_lists directly, and 01058 * uses them to build the string, instead of forming the va_lists internally from the vararg ... list. 01059 * This new function was written so this can be accomplished. 01060 */ 01061 ast_channel_name_build_va(tmp, name_fmt, ap); 01062 tech = ast_strdupa(ast_channel_name(tmp)); 01063 if ((slash = strchr(tech, '/'))) { 01064 if ((slash2 = strchr(slash + 1, '/'))) { 01065 tech2 = slash + 1; 01066 *slash2 = '\0'; 01067 } 01068 *slash = '\0'; 01069 } 01070 } else { 01071 /* 01072 * Start the string with '-' so it becomes an empty string 01073 * in the destructor. 01074 */ 01075 ast_channel_name_set(tmp, "-**Unknown**"); 01076 } 01077 01078 /* Reminder for the future: under what conditions do we NOT want to track cdrs on channels? */ 01079 01080 /* These 4 variables need to be set up for the cdr_init() to work right */ 01081 if (amaflag) 01082 tmp->amaflags = amaflag; 01083 else 01084 tmp->amaflags = ast_default_amaflags; 01085 01086 if (!ast_strlen_zero(acctcode)) 01087 ast_channel_accountcode_set(tmp, acctcode); 01088 else 01089 ast_channel_accountcode_set(tmp, ast_default_accountcode); 01090 01091 if (!ast_strlen_zero(context)) 01092 ast_copy_string(tmp->context, context, sizeof(tmp->context)); 01093 else 01094 strcpy(tmp->context, "default"); 01095 01096 if (!ast_strlen_zero(exten)) 01097 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); 01098 else 01099 strcpy(tmp->exten, "s"); 01100 01101 tmp->priority = 1; 01102 01103 tmp->cdr = ast_cdr_alloc(); 01104 ast_cdr_init(tmp->cdr, tmp); 01105 ast_cdr_start(tmp->cdr); 01106 01107 ast_cel_report_event(tmp, AST_CEL_CHANNEL_START, NULL, NULL, NULL); 01108 01109 headp = &tmp->varshead; 01110 AST_LIST_HEAD_INIT_NOLOCK(headp); 01111 01112 AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores); 01113 01114 AST_LIST_HEAD_INIT_NOLOCK(&tmp->autochans); 01115 01116 ast_channel_language_set(tmp, defaultlanguage); 01117 01118 tmp->tech = &null_tech; 01119 01120 ao2_link(channels, tmp); 01121 01122 /* 01123 * And now, since the channel structure is built, and has its name, let's 01124 * call the manager event generator with this Newchannel event. This is the 01125 * proper and correct place to make this call, but you sure do have to pass 01126 * a lot of data into this func to do it here! 01127 */ 01128 if (ast_get_channel_tech(tech) || (tech2 && ast_get_channel_tech(tech2))) { 01129 ast_manager_event(tmp, EVENT_FLAG_CALL, "Newchannel", 01130 "Channel: %s\r\n" 01131 "ChannelState: %d\r\n" 01132 "ChannelStateDesc: %s\r\n" 01133 "CallerIDNum: %s\r\n" 01134 "CallerIDName: %s\r\n" 01135 "AccountCode: %s\r\n" 01136 "Exten: %s\r\n" 01137 "Context: %s\r\n" 01138 "Uniqueid: %s\r\n", 01139 ast_channel_name(tmp), 01140 state, 01141 ast_state2str(state), 01142 S_OR(cid_num, ""), 01143 S_OR(cid_name, ""), 01144 ast_channel_accountcode(tmp), 01145 S_OR(exten, ""), 01146 S_OR(context, ""), 01147 ast_channel_uniqueid(tmp)); 01148 } 01149 01150 return tmp; 01151 }
| static int __ast_channel_masquerade | ( | struct ast_channel * | original, | |
| struct ast_channel * | clonechan, | |||
| struct ast_datastore * | xfer_ds | |||
| ) | [static] |
Definition at line 5844 of file channel.c.
References ast_channel::_bridge, ast_bridged_channel(), ast_channel_datastore_add(), ast_channel_lock_both, ast_channel_name(), ast_channel_trylock, ast_channel_unlock, ast_debug, AST_FLAG_ZOMBIE, ast_log(), ast_null_frame, ast_queue_frame(), ast_test_flag, ast_channel_tech::get_base_channel, LOG_WARNING, ast_channel::masq, ast_channel::masqr, and ast_channel::tech.
Referenced by ast_channel_masquerade(), and ast_channel_transfer_masquerade().
05845 { 05846 int res = -1; 05847 struct ast_channel *final_orig, *final_clone, *base; 05848 05849 for (;;) { 05850 final_orig = original; 05851 final_clone = clonechan; 05852 05853 ast_channel_lock_both(original, clonechan); 05854 05855 if (ast_test_flag(original, AST_FLAG_ZOMBIE) 05856 || ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) { 05857 /* Zombies! Run! */ 05858 ast_log(LOG_WARNING, 05859 "Can't setup masquerade. One or both channels is dead. (%s <-- %s)\n", 05860 ast_channel_name(original), ast_channel_name(clonechan)); 05861 ast_channel_unlock(clonechan); 05862 ast_channel_unlock(original); 05863 return -1; 05864 } 05865 05866 /* 05867 * Each of these channels may be sitting behind a channel proxy 05868 * (i.e. chan_agent) and if so, we don't really want to 05869 * masquerade it, but its proxy 05870 */ 05871 if (original->_bridge 05872 && (original->_bridge != ast_bridged_channel(original)) 05873 && (original->_bridge->_bridge != original)) { 05874 final_orig = original->_bridge; 05875 } 05876 if (clonechan->_bridge 05877 && (clonechan->_bridge != ast_bridged_channel(clonechan)) 05878 && (clonechan->_bridge->_bridge != clonechan)) { 05879 final_clone = clonechan->_bridge; 05880 } 05881 if (final_clone->tech->get_base_channel 05882 && (base = final_clone->tech->get_base_channel(final_clone))) { 05883 final_clone = base; 05884 } 05885 05886 if ((final_orig != original) || (final_clone != clonechan)) { 05887 /* 05888 * Lots and lots of deadlock avoidance. The main one we're 05889 * competing with is ast_write(), which locks channels 05890 * recursively, when working with a proxy channel. 05891 */ 05892 if (ast_channel_trylock(final_orig)) { 05893 ast_channel_unlock(clonechan); 05894 ast_channel_unlock(original); 05895 05896 /* Try again */ 05897 continue; 05898 } 05899 if (ast_channel_trylock(final_clone)) { 05900 ast_channel_unlock(final_orig); 05901 ast_channel_unlock(clonechan); 05902 ast_channel_unlock(original); 05903 05904 /* Try again */ 05905 continue; 05906 } 05907 ast_channel_unlock(clonechan); 05908 ast_channel_unlock(original); 05909 original = final_orig; 05910 clonechan = final_clone; 05911 05912 if (ast_test_flag(original, AST_FLAG_ZOMBIE) 05913 || ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) { 05914 /* Zombies! Run! */ 05915 ast_log(LOG_WARNING, 05916 "Can't setup masquerade. One or both channels is dead. (%s <-- %s)\n", 05917 ast_channel_name(original), ast_channel_name(clonechan)); 05918 ast_channel_unlock(clonechan); 05919 ast_channel_unlock(original); 05920 return -1; 05921 } 05922 } 05923 break; 05924 } 05925 05926 if (original == clonechan) { 05927 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", ast_channel_name(original)); 05928 ast_channel_unlock(clonechan); 05929 ast_channel_unlock(original); 05930 return -1; 05931 } 05932 05933 ast_debug(1, "Planning to masquerade channel %s into the structure of %s\n", 05934 ast_channel_name(clonechan), ast_channel_name(original)); 05935 05936 if (!original->masqr && !original->masq && !clonechan->masq && !clonechan->masqr) { 05937 original->masq = clonechan; 05938 clonechan->masqr = original; 05939 if (xfer_ds) { 05940 ast_channel_datastore_add(original, xfer_ds); 05941 } 05942 ast_queue_frame(original, &ast_null_frame); 05943 ast_queue_frame(clonechan, &ast_null_frame); 05944 ast_debug(1, "Done planning to masquerade channel %s into the structure of %s\n", ast_channel_name(clonechan), ast_channel_name(original)); 05945 res = 0; 05946 } else if (original->masq) { 05947 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 05948 ast_channel_name(original->masq), ast_channel_name(original)); 05949 } else if (original->masqr) { 05950 /* not yet as a previously planned masq hasn't yet happened */ 05951 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 05952 ast_channel_name(original), ast_channel_name(original->masqr)); 05953 } else if (clonechan->masq) { 05954 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 05955 ast_channel_name(clonechan->masq), ast_channel_name(clonechan)); 05956 } else { /* (clonechan->masqr) */ 05957 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 05958 ast_channel_name(clonechan), ast_channel_name(clonechan->masqr)); 05959 } 05960 05961 ast_channel_unlock(clonechan); 05962 ast_channel_unlock(original); 05963 05964 return res; 05965 }
| static int __ast_queue_frame | ( | struct ast_channel * | chan, | |
| struct ast_frame * | fin, | |||
| int | head, | |||
| struct ast_frame * | after | |||
| ) | [static] |
Definition at line 1206 of file channel.c.
References ast_channel::alertpipe, ast_channel_lock, ast_channel_name(), ast_channel_unlock, AST_CONTROL_END_OF_Q, AST_CONTROL_HANGUP, AST_FLAG_BLOCKING, AST_FRAME_CONTROL, AST_FRAME_NULL, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frdup(), ast_frfree, AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_LIST_AFTER, AST_LIST_INSERT_TAIL, AST_LIST_LAST, AST_LIST_NEXT, AST_LIST_REMOVE, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_test_flag, ast_timer_enable_continuous(), ast_channel::blocker, errno, f, frames, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, 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().
01207 { 01208 struct ast_frame *f; 01209 struct ast_frame *cur; 01210 unsigned int new_frames = 0; 01211 unsigned int new_voice_frames = 0; 01212 unsigned int queued_frames = 0; 01213 unsigned int queued_voice_frames = 0; 01214 AST_LIST_HEAD_NOLOCK(, ast_frame) frames; 01215 01216 ast_channel_lock(chan); 01217 01218 /* 01219 * Check the last frame on the queue if we are queuing the new 01220 * frames after it. 01221 */ 01222 cur = AST_LIST_LAST(&chan->readq); 01223 if (cur && cur->frametype == AST_FRAME_CONTROL && !head && (!after || after == cur)) { 01224 switch (cur->subclass.integer) { 01225 case AST_CONTROL_END_OF_Q: 01226 if (fin->frametype == AST_FRAME_CONTROL 01227 && fin->subclass.integer == AST_CONTROL_HANGUP) { 01228 /* 01229 * Destroy the end-of-Q marker frame so we can queue the hangup 01230 * frame in its place. 01231 */ 01232 AST_LIST_REMOVE(&chan->readq, cur, frame_list); 01233 ast_frfree(cur); 01234 01235 /* 01236 * This has degenerated to a normal queue append anyway. Since 01237 * we just destroyed the last frame in the queue we must make 01238 * sure that "after" is NULL or bad things will happen. 01239 */ 01240 after = NULL; 01241 break; 01242 } 01243 /* Fall through */ 01244 case AST_CONTROL_HANGUP: 01245 /* Don't queue anything. */ 01246 ast_channel_unlock(chan); 01247 return 0; 01248 default: 01249 break; 01250 } 01251 } 01252 01253 /* Build copies of all the new frames and count them */ 01254 AST_LIST_HEAD_INIT_NOLOCK(&frames); 01255 for (cur = fin; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 01256 if (!(f = ast_frdup(cur))) { 01257 if (AST_LIST_FIRST(&frames)) { 01258 ast_frfree(AST_LIST_FIRST(&frames)); 01259 } 01260 ast_channel_unlock(chan); 01261 return -1; 01262 } 01263 01264 AST_LIST_INSERT_TAIL(&frames, f, frame_list); 01265 new_frames++; 01266 if (f->frametype == AST_FRAME_VOICE) { 01267 new_voice_frames++; 01268 } 01269 } 01270 01271 /* Count how many frames exist on the queue */ 01272 AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) { 01273 queued_frames++; 01274 if (cur->frametype == AST_FRAME_VOICE) { 01275 queued_voice_frames++; 01276 } 01277 } 01278 01279 if ((queued_frames + new_frames > 128 || queued_voice_frames + new_voice_frames > 96)) { 01280 int count = 0; 01281 ast_log(LOG_WARNING, "Exceptionally long %squeue length queuing to %s\n", queued_frames + new_frames > 128 ? "" : "voice ", ast_channel_name(chan)); 01282 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, cur, frame_list) { 01283 /* Save the most recent frame */ 01284 if (!AST_LIST_NEXT(cur, frame_list)) { 01285 break; 01286 } else if (cur->frametype == AST_FRAME_VOICE || cur->frametype == AST_FRAME_VIDEO || cur->frametype == AST_FRAME_NULL) { 01287 if (++count > 64) { 01288 break; 01289 } 01290 AST_LIST_REMOVE_CURRENT(frame_list); 01291 ast_frfree(cur); 01292 } 01293 } 01294 AST_LIST_TRAVERSE_SAFE_END; 01295 } 01296 01297 if (after) { 01298 AST_LIST_INSERT_LIST_AFTER(&chan->readq, &frames, after, frame_list); 01299 } else { 01300 if (head) { 01301 AST_LIST_APPEND_LIST(&frames, &chan->readq, frame_list); 01302 AST_LIST_HEAD_INIT_NOLOCK(&chan->readq); 01303 } 01304 AST_LIST_APPEND_LIST(&chan->readq, &frames, frame_list); 01305 } 01306 01307 if (chan->alertpipe[1] > -1) { 01308 int blah[new_frames]; 01309 01310 memset(blah, 1, sizeof(blah)); 01311 if (write(chan->alertpipe[1], &blah, sizeof(blah)) != (sizeof(blah))) { 01312 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s (qlen = %d): %s!\n", 01313 ast_channel_name(chan), queued_frames, strerror(errno)); 01314 } 01315 } else if (chan->timingfd > -1) { 01316 ast_timer_enable_continuous(chan->timer); 01317 } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 01318 pthread_kill(chan->blocker, SIGURG); 01319 } 01320 01321 ast_channel_unlock(chan); 01322 01323 return 0; 01324 }
| static struct ast_frame* __ast_read | ( | struct ast_channel * | chan, | |
| int | dropaudio | |||
| ) | [static, read] |
Definition at line 3568 of file channel.c.
References __ast_queue_frame(), ast_channel::_softhangup, ast_channel::_state, ast_control_read_action_payload::action, ast_channel::alertpipe, ast_audiohook_detach_list(), AST_AUDIOHOOK_DIRECTION_READ, ast_audiohook_write_list(), ast_audiohook_write_list_empty(), ast_bridged_channel(), AST_CEL_ANSWER, ast_cel_report_event(), ast_channel_connected_line_macro(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_check_hangup(), ast_clear_flag, ast_connected_line_parse_data(), AST_CONTROL_ANSWER, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_END_OF_Q, AST_CONTROL_HANGUP, AST_CONTROL_READ_ACTION, ast_deactivate_generator(), ast_debug, AST_DEFAULT_EMULATE_DTMF_DURATION, ast_do_masquerade(), AST_FLAG_DEFER_DTMF, AST_FLAG_EMULATE_DTMF, AST_FLAG_END_DTMF_ONLY, AST_FLAG_EXCEPTION, AST_FLAG_IN_DTMF, AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_format_cap_iscompatible(), ast_format_rate(), AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_frame_dump(), AST_FRAME_NULL, AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO, AST_FRAME_VOICE, ast_framehook_list_read_event(), ast_frfree, AST_GENERATOR_FD, ast_getformatname(), ast_getformatname_multiple(), ast_indicate_data(), AST_JITTERBUFFER_FD, 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_party_connected_line_copy(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_queue_control(), ast_queue_frame(), ast_queue_frame_head(), ast_read_generator_actions(), ast_seekstream(), ast_set_flag, ast_setstate(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_test_flag, ast_timer_ack(), ast_timer_disable_continuous(), ast_timer_get_event(), ast_timer_set_rate(), AST_TIMING_EVENT_CONTINUOUS, AST_TIMING_EVENT_EXPIRED, AST_TIMING_FD, ast_translate(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_writestream(), ast_channel::audiohooks, ast_channel::blocker, calc_monitor_jump(), cause, ast_channel::connected, 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, ast_channel::fdno, ast_channel::fds, ast_channel::fin, chanlist::flags, ast_filestream::fmt, ast_format_def::format, ast_frame_subclass::format, FRAMECOUNT_INC, ast_channel::framehooks, ast_frame::frametype, ast_generator::generate, ast_channel::generator, ast_channel::generatordata, ast_channel::hangupcause, ast_channel::insmpl, ast_frame_subclass::integer, ast_frame::len, LOG_DTMF, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_channel::masq, ast_channel::monitor, ast_channel::music_state, ast_channel::nativeformats, ast_channel::outsmpl, ast_control_read_action_payload::payload, ast_control_read_action_payload::payload_size, ast_frame::ptr, 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().
03569 { 03570 struct ast_frame *f = NULL; /* the return value */ 03571 int blah; 03572 int prestate; 03573 int cause = 0; 03574 03575 /* this function is very long so make sure there is only one return 03576 * point at the end (there are only two exceptions to this). 03577 */ 03578 03579 if (chan->masq) { 03580 if (ast_do_masquerade(chan)) 03581 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 03582 else 03583 f = &ast_null_frame; 03584 return f; 03585 } 03586 03587 /* if here, no masq has happened, lock the channel and proceed */ 03588 ast_channel_lock(chan); 03589 03590 /* Stop if we're a zombie or need a soft hangup */ 03591 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 03592 if (chan->generator) 03593 ast_deactivate_generator(chan); 03594 03595 /* 03596 * It is possible for chan->_softhangup to be set and there 03597 * still be control frames that need to be read. Instead of 03598 * just going to 'done' in the case of ast_check_hangup(), we 03599 * need to queue the end-of-Q frame so that it can mark the end 03600 * of the read queue. If there are frames to be read, 03601 * ast_queue_control() will be called repeatedly, but will only 03602 * queue the first end-of-Q frame. 03603 */ 03604 if (chan->_softhangup) { 03605 ast_queue_control(chan, AST_CONTROL_END_OF_Q); 03606 } else { 03607 goto done; 03608 } 03609 } else { 03610 #ifdef AST_DEVMODE 03611 /* 03612 * The ast_waitfor() code records which of the channel's file 03613 * descriptors reported that data is available. In theory, 03614 * ast_read() should only be called after ast_waitfor() reports 03615 * that a channel has data available for reading. However, 03616 * there still may be some edge cases throughout the code where 03617 * ast_read() is called improperly. This can potentially cause 03618 * problems, so if this is a developer build, make a lot of 03619 * noise if this happens so that it can be addressed. 03620 * 03621 * One of the potential problems is blocking on a dead channel. 03622 */ 03623 if (chan->fdno == -1) { 03624 ast_log(LOG_ERROR, 03625 "ast_read() on chan '%s' called with no recorded file descriptor.\n", 03626 ast_channel_name(chan)); 03627 } 03628 #endif 03629 } 03630 03631 prestate = chan->_state; 03632 03633 /* Read and ignore anything on the alertpipe, but read only 03634 one sizeof(blah) per frame that we send from it */ 03635 if (chan->alertpipe[0] > -1) { 03636 int flags = fcntl(chan->alertpipe[0], F_GETFL); 03637 /* For some odd reason, the alertpipe occasionally loses nonblocking status, 03638 * which immediately causes a deadlock scenario. Detect and prevent this. */ 03639 if ((flags & O_NONBLOCK) == 0) { 03640 ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", ast_channel_name(chan)); 03641 if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) { 03642 ast_log(LOG_WARNING, "Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno)); 03643 f = &ast_null_frame; 03644 goto done; 03645 } 03646 } 03647 if (read(chan->alertpipe[0], &blah, sizeof(blah)) < 0) { 03648 if (errno != EINTR && errno != EAGAIN) 03649 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 03650 } 03651 } 03652 03653 if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD) { 03654 enum ast_timer_event res; 03655 03656 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 03657 03658 res = ast_timer_get_event(chan->timer); 03659 03660 switch (res) { 03661 case AST_TIMING_EVENT_EXPIRED: 03662 ast_timer_ack(chan->timer, 1); 03663 03664 if (chan->timingfunc) { 03665 /* save a copy of func/data before unlocking the channel */ 03666 int (*func)(const void *) = chan->timingfunc; 03667 void *data = chan->timingdata; 03668 chan->fdno = -1; 03669 ast_channel_unlock(chan); 03670 func(data); 03671 } else { 03672 ast_timer_set_rate(chan->timer, 0); 03673 chan->fdno = -1; 03674 ast_channel_unlock(chan); 03675 } 03676 03677 /* cannot 'goto done' because the channel is already unlocked */ 03678 return &ast_null_frame; 03679 03680 case AST_TIMING_EVENT_CONTINUOUS: 03681 if (AST_LIST_EMPTY(&chan->readq) || 03682 !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) { 03683 ast_timer_disable_continuous(chan->timer); 03684 } 03685 break; 03686 } 03687 03688 } else if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) { 03689 /* if the AST_GENERATOR_FD is set, call the generator with args 03690 * set to -1 so it can do whatever it needs to. 03691 */ 03692 void *tmp = chan->generatordata; 03693 chan->generatordata = NULL; /* reset to let ast_write get through */ 03694 chan->generator->generate(chan, tmp, -1, -1); 03695 chan->generatordata = tmp; 03696 f = &ast_null_frame; 03697 chan->fdno = -1; 03698 goto done; 03699 } else if (chan->fds[AST_JITTERBUFFER_FD] > -1 && chan->fdno == AST_JITTERBUFFER_FD) { 03700 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 03701 } 03702 03703 /* Check for pending read queue */ 03704 if (!AST_LIST_EMPTY(&chan->readq)) { 03705 int skip_dtmf = should_skip_dtmf(chan); 03706 03707 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, f, frame_list) { 03708 /* We have to be picky about which frame we pull off of the readq because 03709 * there are cases where we want to leave DTMF frames on the queue until 03710 * some later time. */ 03711 03712 if ( (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && skip_dtmf) { 03713 continue; 03714 } 03715 03716 AST_LIST_REMOVE_CURRENT(frame_list); 03717 break; 03718 } 03719 AST_LIST_TRAVERSE_SAFE_END; 03720 03721 if (!f) { 03722 /* There were no acceptable frames on the readq. */ 03723 f = &ast_null_frame; 03724 if (chan->alertpipe[0] > -1) { 03725 int poke = 0; 03726 /* Restore the state of the alertpipe since we aren't ready for any 03727 * of the frames in the readq. */ 03728 if (write(chan->alertpipe[1], &poke, sizeof(poke)) != sizeof(poke)) { 03729 ast_log(LOG_ERROR, "Failed to write to alertpipe: %s\n", strerror(errno)); 03730 } 03731 } 03732 } 03733 03734 /* Interpret hangup and end-of-Q frames to return NULL */ 03735 /* XXX why not the same for frames from the channel ? */ 03736 if (f->frametype == AST_FRAME_CONTROL) { 03737 switch (f->subclass.integer) { 03738 case AST_CONTROL_HANGUP: 03739 chan->_softhangup |= AST_SOFTHANGUP_DEV; 03740 cause = f->data.uint32; 03741 /* Fall through */ 03742 case AST_CONTROL_END_OF_Q: 03743 ast_frfree(f); 03744 f = NULL; 03745 break; 03746 default: 03747 break; 03748 } 03749 } 03750 } else { 03751 chan->blocker = pthread_self(); 03752 if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) { 03753 if (chan->tech->exception) 03754 f = chan->tech->exception(chan); 03755 else { 03756 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", ast_channel_name(chan)); 03757 f = &ast_null_frame; 03758 } 03759 /* Clear the exception flag */ 03760 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 03761 } else if (chan->tech && chan->tech->read) 03762 f = chan->tech->read(chan); 03763 else 03764 ast_log(LOG_WARNING, "No read routine on channel %s\n", ast_channel_name(chan)); 03765 } 03766 03767 /* Perform the framehook read event here. After the frame enters the framehook list 03768 * there is no telling what will happen, <insert mad scientist laugh here>!!! */ 03769 f = ast_framehook_list_read_event(chan->framehooks, f); 03770 03771 /* 03772 * Reset the recorded file descriptor that triggered this read so that we can 03773 * easily detect when ast_read() is called without properly using ast_waitfor(). 03774 */ 03775 chan->fdno = -1; 03776 03777 if (f) { 03778 struct ast_frame *readq_tail = AST_LIST_LAST(&chan->readq); 03779 struct ast_control_read_action_payload *read_action_payload; 03780 struct ast_party_connected_line connected; 03781 03782 /* if the channel driver returned more than one frame, stuff the excess 03783 into the readq for the next ast_read call 03784 */ 03785 if (AST_LIST_NEXT(f, frame_list)) { 03786 ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list)); 03787 ast_frfree(AST_LIST_NEXT(f, frame_list)); 03788 AST_LIST_NEXT(f, frame_list) = NULL; 03789 } 03790 03791 switch (f->frametype) { 03792 case AST_FRAME_CONTROL: 03793 if (f->subclass.integer == AST_CONTROL_ANSWER) { 03794 if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) { 03795 ast_debug(1, "Ignoring answer on an inbound call!\n"); 03796 ast_frfree(f); 03797 f = &ast_null_frame; 03798 } else if (prestate == AST_STATE_UP && ast_bridged_channel(chan)) { 03799 ast_debug(1, "Dropping duplicate answer!\n"); 03800 ast_frfree(f); 03801 f = &ast_null_frame; 03802 } else { 03803 /* Answer the CDR */ 03804 ast_setstate(chan, AST_STATE_UP); 03805 /* removed a call to ast_cdr_answer(chan->cdr) from here. */ 03806 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 03807 } 03808 } else if (f->subclass.integer == AST_CONTROL_READ_ACTION) { 03809 read_action_payload = f->data.ptr; 03810 switch (read_action_payload->action) { 03811 case AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO: 03812 ast_party_connected_line_init(&connected); 03813 ast_party_connected_line_copy(&connected, &chan->connected); 03814 if (ast_connected_line_parse_data(read_action_payload->payload, 03815 read_action_payload->payload_size, &connected)) { 03816 ast_party_connected_line_free(&connected); 03817 break; 03818 } 03819 if (ast_channel_connected_line_macro(NULL, chan, &connected, 1, 0)) { 03820 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, 03821 read_action_payload->payload, 03822 read_action_payload->payload_size); 03823 } 03824 ast_party_connected_line_free(&connected); 03825 break; 03826 } 03827 ast_frfree(f); 03828 f = &ast_null_frame; 03829 } 03830 break; 03831 case AST_FRAME_DTMF_END: 03832 send_dtmf_event(chan, "Received", f->subclass.integer, "No", "Yes"); 03833 ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass.integer, ast_channel_name(chan), f->len); 03834 /* Queue it up if DTMF is deferred, or if DTMF emulation is forced. */ 03835 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) || ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) { 03836 queue_dtmf_readq(chan, f); 03837 ast_frfree(f); 03838 f = &ast_null_frame; 03839 } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) { 03840 if (!ast_tvzero(chan->dtmf_tv) && 03841 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) { 03842 /* If it hasn't been long enough, defer this digit */ 03843 queue_dtmf_readq(chan, f); 03844 ast_frfree(f); 03845 f = &ast_null_frame; 03846 } else { 03847 /* There was no begin, turn this into a begin and send the end later */ 03848 f->frametype = AST_FRAME_DTMF_BEGIN; 03849 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF); 03850 chan->emulate_dtmf_digit = f->subclass.integer; 03851 chan->dtmf_tv = ast_tvnow(); 03852 if (f->len) { 03853 if (f->len > AST_MIN_DTMF_DURATION) 03854 chan->emulate_dtmf_duration = f->len; 03855 else 03856 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION; 03857 } else 03858 chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION; 03859 ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass.integer, chan->emulate_dtmf_duration, ast_channel_name(chan)); 03860 } 03861 if (chan->audiohooks) { 03862 struct ast_frame *old_frame = f; 03863 /*! 03864 * \todo XXX It is possible to write a digit to the audiohook twice 03865 * if the digit was originally read while the channel was in autoservice. */ 03866 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 03867 if (old_frame != f) 03868 ast_frfree(old_frame); 03869 } 03870 } else { 03871 struct timeval now = ast_tvnow(); 03872 if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) { 03873 ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass.integer, ast_channel_name(chan)); 03874 ast_clear_flag(chan, AST_FLAG_IN_DTMF); 03875 if (!f->len) 03876 f->len = ast_tvdiff_ms(now, chan->dtmf_tv); 03877 03878 /* detect tones that were received on 03879 * the wire with durations shorter than 03880 * AST_MIN_DTMF_DURATION and set f->len 03881 * to the actual duration of the DTMF 03882 * frames on the wire. This will cause 03883 * dtmf emulation to be triggered later 03884 * on. 03885 */ 03886 if (ast_tvdiff_ms(now, chan->dtmf_tv) < AST_MIN_DTMF_DURATION) { 03887 f->len = ast_tvdiff_ms(now, chan->dtmf_tv); 03888 ast_log(LOG_DTMF, "DTMF end '%c' detected to have actual duration %ld on the wire, emulation will be triggered on %s\n", f->subclass.integer, f->len, ast_channel_name(chan)); 03889 } 03890 } else if (!f->len) { 03891 ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass.integer, ast_channel_name(chan)); 03892 f->len = AST_MIN_DTMF_DURATION; 03893 } 03894 if (f->len < AST_MIN_DTMF_DURATION && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) { 03895 ast_log(LOG_DTMF, "DTMF end '%c' has duration %ld but want minimum %d, emulating on %s\n", f->subclass.integer, f->len, AST_MIN_DTMF_DURATION, ast_channel_name(chan)); 03896 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF); 03897 chan->emulate_dtmf_digit = f->subclass.integer; 03898 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len; 03899 ast_frfree(f); 03900 f = &ast_null_frame; 03901 } else { 03902 ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass.integer, ast_channel_name(chan)); 03903 if (f->len < AST_MIN_DTMF_DURATION) { 03904 f->len = AST_MIN_DTMF_DURATION; 03905 } 03906 chan->dtmf_tv = now; 03907 } 03908 if (chan->audiohooks) { 03909 struct ast_frame *old_frame = f; 03910 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 03911 if (old_frame != f) 03912 ast_frfree(old_frame); 03913 } 03914 } 03915 break; 03916 case AST_FRAME_DTMF_BEGIN: 03917 send_dtmf_event(chan, "Received", f->subclass.integer, "Yes", "No"); 03918 ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass.integer, ast_channel_name(chan)); 03919 if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) || 03920 (!ast_tvzero(chan->dtmf_tv) && 03921 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) { 03922 ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass.integer, ast_channel_name(chan)); 03923 ast_frfree(f); 03924 f = &ast_null_frame; 03925 } else { 03926 ast_set_flag(chan, AST_FLAG_IN_DTMF); 03927 chan->dtmf_tv = ast_tvnow(); 03928 ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass.integer, ast_channel_name(chan)); 03929 } 03930 break; 03931 case AST_FRAME_NULL: 03932 /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration 03933 * is reached , because we want to make sure we pass at least one 03934 * voice frame through before starting the next digit, to ensure a gap 03935 * between DTMF digits. */ 03936 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) { 03937 struct timeval now = ast_tvnow(); 03938 if (!chan->emulate_dtmf_duration) { 03939 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF); 03940 chan->emulate_dtmf_digit = 0; 03941 } else if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) { 03942 chan->emulate_dtmf_duration = 0; 03943 ast_frfree(f); 03944 f = &chan->dtmff; 03945 f->frametype = AST_FRAME_DTMF_END; 03946 f->subclass.integer = chan->emulate_dtmf_digit; 03947 f->len = ast_tvdiff_ms(now, chan->dtmf_tv); 03948 chan->dtmf_tv = now; 03949 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF); 03950 chan->emulate_dtmf_digit = 0; 03951 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, ast_channel_name(chan)); 03952 if (chan->audiohooks) { 03953 struct ast_frame *old_frame = f; 03954 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 03955 if (old_frame != f) { 03956 ast_frfree(old_frame); 03957 } 03958 } 03959 } 03960 } 03961 break; 03962 case AST_FRAME_VOICE: 03963 /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration 03964 * is reached , because we want to make sure we pass at least one 03965 * voice frame through before starting the next digit, to ensure a gap 03966 * between DTMF digits. */ 03967 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) { 03968 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF); 03969 chan->emulate_dtmf_digit = 0; 03970 } 03971 03972 if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) { 03973 if (dropaudio) 03974 ast_read_generator_actions(chan, f); 03975 ast_frfree(f); 03976 f = &ast_null_frame; 03977 } 03978 03979 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_IN_DTMF)) { 03980 struct timeval now = ast_tvnow(); 03981 if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) { 03982 chan->emulate_dtmf_duration = 0; 03983 ast_frfree(f); 03984 f = &chan->dtmff; 03985 f->frametype = AST_FRAME_DTMF_END; 03986 f->subclass.integer = chan->emulate_dtmf_digit; 03987 f->len = ast_tvdiff_ms(now, chan->dtmf_tv); 03988 chan->dtmf_tv = now; 03989 if (chan->audiohooks) { 03990 struct ast_frame *old_frame = f; 03991 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 03992 if (old_frame != f) 03993 ast_frfree(old_frame); 03994 } 03995 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, ast_channel_name(chan)); 03996 } else { 03997 /* Drop voice frames while we're still in the middle of the digit */ 03998 ast_frfree(f); 03999 f = &ast_null_frame; 04000 } 04001 } else if ((f->frametype == AST_FRAME_VOICE) && !ast_format_cap_iscompatible(chan->nativeformats, &f->subclass.format)) { 04002 /* This frame is not one of the current native formats -- drop it on the floor */ 04003 char to[200]; 04004 ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n", 04005 ast_channel_name(chan), ast_getformatname(&f->subclass.format), ast_getformatname_multiple(to, sizeof(to), chan->nativeformats)); 04006 ast_frfree(f); 04007 f = &ast_null_frame; 04008 } else if ((f->frametype == AST_FRAME_VOICE)) { 04009 /* Send frame to audiohooks if present */ 04010 if (chan->audiohooks) { 04011 struct ast_frame *old_frame = f; 04012 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 04013 if (old_frame != f) 04014 ast_frfree(old_frame); 04015 } 04016 if (chan->monitor && chan->monitor->read_stream ) { 04017 /* XXX what does this do ? */ 04018 #ifndef MONITOR_CONSTANT_DELAY 04019 int jump = chan->outsmpl - chan->insmpl - 4 * f->samples; 04020 if (jump >= 0) { 04021 jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(&f->subclass.format), ast_format_rate(&chan->monitor->read_stream->fmt->format)); 04022 if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1) 04023 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 04024 chan->insmpl += (chan->outsmpl - chan->insmpl) + f->samples; 04025 } else 04026 chan->insmpl+= f->samples; 04027 #else 04028 int jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 04029 if (jump - MONITOR_DELAY >= 0) { 04030 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1) 04031 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 04032 chan->insmpl += chan->outsmpl - chan->insmpl; 04033 } else 04034 chan->insmpl += f->samples; 04035 #endif 04036 if (chan->monitor->state == AST_MONITOR_RUNNING) { 04037 if (ast_writestream(chan->monitor->read_stream, f) < 0) 04038 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n"); 04039 } 04040 } 04041 04042 if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL) { 04043 f = &ast_null_frame; 04044 } 04045 04046 /* it is possible for the translation process on chan->readtrans to have 04047 produced multiple frames from the single input frame we passed it; if 04048 this happens, queue the additional frames *before* the frames we may 04049 have queued earlier. if the readq was empty, put them at the head of 04050 the queue, and if it was not, put them just after the frame that was 04051 at the end of the queue. 04052 */ 04053 if (AST_LIST_NEXT(f, frame_list)) { 04054 if (!readq_tail) { 04055 ast_queue_frame_head(chan, AST_LIST_NEXT(f, frame_list)); 04056 } else { 04057 __ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list), 0, readq_tail); 04058 } 04059 ast_frfree(AST_LIST_NEXT(f, frame_list)); 04060 AST_LIST_NEXT(f, frame_list) = NULL; 04061 } 04062 04063 /* Run generator sitting on the line if timing device not available 04064 * and synchronous generation of outgoing frames is necessary */ 04065 ast_read_generator_actions(chan, f); 04066 } 04067 break; 04068 default: 04069 /* Just pass it on! */ 04070 break; 04071 } 04072 } else { 04073 /* Make sure we always return NULL in the future */ 04074 if (!chan->_softhangup) { 04075 chan->_softhangup |= AST_SOFTHANGUP_DEV; 04076 } 04077 if (cause) 04078 chan->hangupcause = cause; 04079 if (chan->generator) 04080 ast_deactivate_generator(chan); 04081 /* We no longer End the CDR here */ 04082 } 04083 04084 /* High bit prints debugging */ 04085 if (chan->fin & DEBUGCHAN_FLAG) 04086 ast_frame_dump(ast_channel_name(chan), f, "<<"); 04087 chan->fin = FRAMECOUNT_INC(chan->fin); 04088 04089 done: 04090 if (chan->music_state && chan->generator && chan->generator->digit && f && f->frametype == AST_FRAME_DTMF_END) 04091 chan->generator->digit(chan, f->subclass.integer); 04092 04093 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) { 04094 /* The list gets recreated if audiohooks are added again later */ 04095 ast_audiohook_detach_list(chan->audiohooks); 04096 chan->audiohooks = NULL; 04097 } 04098 ast_channel_unlock(chan); 04099 return f; 04100 }
| struct ast_channel* __ast_request_and_dial | ( | const char * | type, | |
| struct ast_format_cap * | cap, | |||
| const struct ast_channel * | requestor, | |||
| const char * | addr, | |||
| 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 | capabilities for requested channel | |
| requestor | channel requesting data | |
| addr | destination of the call | |
| 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 5301 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_answer(), ast_cdr_busy(), 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_call_forward(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_lock_both, ast_channel_set_connected_line(), ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, 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_flag, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_waitfor(), 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, ast_frame::frametype, handle_cause(), ast_channel::hangupcause, ast_party_connected_line::id, ast_frame_subclass::integer, LOG_NOTICE, ast_party_id::name, ast_party_id::number, outgoing_helper::parent_channel, ast_party_name::presentation, ast_party_number::presentation, ast_channel::priority, outgoing_helper::priority, ast_party_name::str, ast_party_number::str, ast_frame::subclass, ast_party_name::valid, ast_party_number::valid, and outgoing_helper::vars.
Referenced by ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_request_and_dial(), and parkandannounce_exec().
05302 { 05303 int dummy_outstate; 05304 int cause = 0; 05305 struct ast_channel *chan; 05306 int res = 0; 05307 int last_subclass = 0; 05308 struct ast_party_connected_line connected; 05309 05310 if (outstate) 05311 *outstate = 0; 05312 else 05313 outstate = &dummy_outstate; /* make outstate always a valid pointer */ 05314 05315 chan = ast_request(type, cap, requestor, addr, &cause); 05316 if (!chan) { 05317 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, addr); 05318 handle_cause(cause, outstate); 05319 return NULL; 05320 } 05321 05322 if (oh) { 05323 if (oh->vars) { 05324 ast_set_variables(chan, oh->vars); 05325 } 05326 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) { 05327 /* 05328 * Use the oh values instead of the function parameters for the 05329 * outgoing CallerID. 05330 */ 05331 cid_num = oh->cid_num; 05332 cid_name = oh->cid_name; 05333 } 05334 if (oh->parent_channel) { 05335 /* Safely inherit variables and datastores from the parent channel. */ 05336 ast_channel_lock_both(oh->parent_channel, chan); 05337 ast_channel_inherit_variables(oh->parent_channel, chan); 05338 ast_channel_datastore_inherit(oh->parent_channel, chan); 05339 ast_channel_unlock(oh->parent_channel); 05340 ast_channel_unlock(chan); 05341 } 05342 if (oh->account) { 05343 ast_channel_lock(chan); 05344 ast_cdr_setaccount(chan, oh->account); 05345 ast_channel_unlock(chan); 05346 } 05347 } 05348 05349 ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED); 05350 ast_party_connected_line_set_init(&connected, &chan->connected); 05351 if (cid_num) { 05352 connected.id.number.valid = 1; 05353 connected.id.number.str = (char *) cid_num; 05354 connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 05355 } 05356 if (cid_name) { 05357 connected.id.name.valid = 1; 05358 connected.id.name.str = (char *) cid_name; 05359 connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 05360 } 05361 ast_channel_set_connected_line(chan, &connected, NULL); 05362 05363 if (ast_call(chan, addr, 0)) { /* ast_call failed... */ 05364 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, addr); 05365 } else { 05366 res = 1; /* mark success in case chan->_state is already AST_STATE_UP */ 05367 while (timeout && chan->_state != AST_STATE_UP) { 05368 struct ast_frame *f; 05369 res = ast_waitfor(chan, timeout); 05370 if (res == 0) { /* timeout, treat it like ringing */ 05371 *outstate = AST_CONTROL_RINGING; 05372 break; 05373 } 05374 if (res < 0) /* error or done */ 05375 break; 05376 if (timeout > -1) 05377 timeout = res; 05378 if (!ast_strlen_zero(ast_channel_call_forward(chan))) { 05379 if (!(chan = ast_call_forward(NULL, chan, NULL, cap, oh, outstate))) { 05380 return NULL; 05381 } 05382 continue; 05383 } 05384 05385 f = ast_read(chan); 05386 if (!f) { 05387 *outstate = AST_CONTROL_HANGUP; 05388 res = 0; 05389 break; 05390 } 05391 if (f->frametype == AST_FRAME_CONTROL) { 05392 switch (f->subclass.integer) { 05393 case AST_CONTROL_RINGING: /* record but keep going */ 05394 *outstate = f->subclass.integer; 05395 break; 05396 05397 case AST_CONTROL_BUSY: 05398 ast_cdr_busy(chan->cdr); 05399 *outstate = f->subclass.integer; 05400 timeout = 0; 05401 break; 05402 05403 case AST_CONTROL_INCOMPLETE: 05404 ast_cdr_failed(chan->cdr); 05405 *outstate = AST_CONTROL_CONGESTION; 05406 timeout = 0; 05407 break; 05408 05409 case AST_CONTROL_CONGESTION: 05410 ast_cdr_failed(chan->cdr); 05411 *outstate = f->subclass.integer; 05412 timeout = 0; 05413 break; 05414 05415 case AST_CONTROL_ANSWER: 05416 ast_cdr_answer(chan->cdr); 05417 *outstate = f->subclass.integer; 05418 timeout = 0; /* trick to force exit from the while() */ 05419 break; 05420 05421 /* Ignore these */ 05422 case AST_CONTROL_PROGRESS: 05423 case AST_CONTROL_PROCEEDING: 05424 case AST_CONTROL_HOLD: 05425 case AST_CONTROL_UNHOLD: 05426 case AST_CONTROL_VIDUPDATE: 05427 case AST_CONTROL_SRCUPDATE: 05428 case AST_CONTROL_SRCCHANGE: 05429 case AST_CONTROL_CONNECTED_LINE: 05430 case AST_CONTROL_REDIRECTING: 05431 case AST_CONTROL_CC: 05432 case -1: /* Ignore -- just stopping indications */ 05433 break; 05434 05435 default: 05436 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass.integer); 05437 } 05438 last_subclass = f->subclass.integer; 05439 } 05440 ast_frfree(f); 05441 } 05442 } 05443 05444 /* Final fixups */ 05445 if (oh) { 05446 if (!ast_strlen_zero(oh->context)) 05447 ast_copy_string(chan->context, oh->context, sizeof(chan->context)); 05448 if (!ast_strlen_zero(oh->exten)) 05449 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten)); 05450 if (oh->priority) 05451 chan->priority = oh->priority; 05452 } 05453 if (chan->_state == AST_STATE_UP) 05454 *outstate = AST_CONTROL_ANSWER; 05455 05456 if (res <= 0) { 05457 ast_channel_lock(chan); 05458 if (AST_CONTROL_RINGING == last_subclass) { 05459 chan->hangupcause = AST_CAUSE_NO_ANSWER; 05460 } 05461 if (!chan->cdr && (chan->cdr = ast_cdr_alloc())) { 05462 ast_cdr_init(chan->cdr, chan); 05463 } 05464 if (chan->cdr) { 05465 char tmp[256]; 05466 05467 snprintf(tmp, sizeof(tmp), "%s/%s", type, addr); 05468 ast_cdr_setapp(chan->cdr, "Dial", tmp); 05469 ast_cdr_update(chan); 05470 ast_cdr_start(chan->cdr); 05471 ast_cdr_end(chan->cdr); 05472 /* If the cause wasn't handled properly */ 05473 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) { 05474 ast_cdr_failed(chan->cdr); 05475 } 05476 } 05477 ast_channel_unlock(chan); 05478 ast_hangup(chan); 05479 chan = NULL; 05480 } 05481 return chan; 05482 }
| static void __init_state2str_threadbuf | ( | void | ) | [static] |
| static void adjust_frame_for_plc | ( | struct ast_channel * | chan, | |
| struct ast_frame * | frame, | |||
| struct ast_datastore * | datastore | |||
| ) | [static] |
Definition at line 4565 of file channel.c.
References ast_calloc, ast_channel_datastore_remove(), ast_datastore_free(), ast_free, AST_FRIENDLY_OFFSET, ast_frame::data, ast_datastore::data, ast_frame::datalen, plc_ds::num_samples, ast_frame::offset, plc_fillin(), plc_rx(), plc_ds::plc_state, ast_frame::ptr, ast_frame::samples, and plc_ds::samples_buf.
Referenced by apply_plc().
04566 { 04567 int num_new_samples = frame->samples; 04568 struct plc_ds *plc = datastore->data; 04569 04570 /* As a general note, let me explain the somewhat odd calculations used when taking 04571 * the frame offset into account here. According to documentation in frame.h, the frame's 04572 * offset field indicates the number of bytes that the audio is offset. The plc->samples_buf 04573 * is not an array of bytes, but rather an array of 16-bit integers since it holds SLIN 04574 * samples. So I had two choices to make here with the offset. 04575 * 04576 * 1. Make the offset AST_FRIENDLY_OFFSET bytes. The main downside for this is that 04577 * I can't just add AST_FRIENDLY_OFFSET to the plc->samples_buf and have the pointer 04578 * arithmetic come out right. I would have to do some odd casting or division for this to 04579 * work as I wanted. 04580 * 2. Make the offset AST_FRIENDLY_OFFSET * 2 bytes. This allows the pointer arithmetic 04581 * to work out better with the plc->samples_buf. The downside here is that the buffer's 04582 * allocation contains an extra 64 bytes of unused space. 04583 * 04584 * I decided to go with option 2. This is why in the calloc statement and the statement that 04585 * sets the frame's offset, AST_FRIENDLY_OFFSET is multiplied by 2. 04586 */ 04587 04588 /* If this audio frame has no samples to fill in, ignore it */ 04589 if (!num_new_samples) { 04590 return; 04591 } 04592 04593 /* First, we need to be sure that our buffer is large enough to accomodate 04594 * the samples we need to fill in. This will likely only occur on the first 04595 * frame we write. 04596 */ 04597 if (plc->num_samples < num_new_samples) { 04598 ast_free(plc->samples_buf); 04599 plc->samples_buf = ast_calloc(1, (num_new_samples * sizeof(*plc->samples_buf)) + (AST_FRIENDLY_OFFSET * 2)); 04600 if (!plc->samples_buf) { 04601 ast_channel_datastore_remove(chan, datastore); 04602 ast_datastore_free(datastore); 04603 return; 04604 } 04605 plc->num_samples = num_new_samples; 04606 } 04607 04608 if (frame->datalen == 0) { 04609 plc_fillin(&plc->plc_state, plc->samples_buf + AST_FRIENDLY_OFFSET, frame->samples); 04610 frame->data.ptr = plc->samples_buf + AST_FRIENDLY_OFFSET; 04611 frame->datalen = num_new_samples * 2; 04612 frame->offset = AST_FRIENDLY_OFFSET * 2; 04613 } else { 04614 plc_rx(&plc->plc_state, frame->data.ptr, frame->samples); 04615 } 04616 }
| static void apply_plc | ( | struct ast_channel * | chan, | |
| struct ast_frame * | frame | |||
| ) | [static] |
Definition at line 4618 of file channel.c.
References adjust_frame_for_plc(), ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc, ast_datastore_free(), and ast_datastore::data.
Referenced by ast_write().
04619 { 04620 struct ast_datastore *datastore; 04621 struct plc_ds *plc; 04622 04623 datastore = ast_channel_datastore_find(chan, &plc_ds_info, NULL); 04624 if (datastore) { 04625 plc = datastore->data; 04626 adjust_frame_for_plc(chan, frame, datastore); 04627 return; 04628 } 04629 04630 datastore = ast_datastore_alloc(&plc_ds_info, NULL); 04631 if (!datastore) { 04632 return; 04633 } 04634 plc = ast_calloc(1, sizeof(*plc)); 04635 if (!plc) { 04636 ast_datastore_free(datastore); 04637 return; 04638 } 04639 datastore->data = plc; 04640 ast_channel_datastore_add(chan, datastore); 04641 adjust_frame_for_plc(chan, frame, datastore); 04642 }
| int ast_activate_generator | ( | struct ast_channel * | chan, | |
| struct ast_generator * | gen, | |||
| void * | params | |||
| ) |
Activate a given generator
Definition at line 2927 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(), spandsp_fax_gateway_start(), and transmit_audio().
02928 { 02929 int res = 0; 02930 02931 ast_channel_lock(chan); 02932 if (chan->generatordata) { 02933 if (chan->generator && chan->generator->release) 02934 chan->generator->release(chan, chan->generatordata); 02935 chan->generatordata = NULL; 02936 } 02937 if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) { 02938 res = -1; 02939 } 02940 if (!res) { 02941 ast_settimeout(chan, 50, generator_force, chan); 02942 chan->generator = gen; 02943 } 02944 ast_channel_unlock(chan); 02945 02946 ast_prod(chan); 02947 02948 return res; 02949 }
| int ast_active_channels | ( | void | ) |
returns number of active/allocated channels
Definition at line 625 of file channel.c.
References ao2_container_count(), and channels.
Referenced by action_corestatus(), ast_var_channels(), ast_var_channels_table(), can_safely_quit(), dahdi_restart(), handle_chanlist(), handle_show_settings(), and really_quit().
00626 { 00627 return channels ? ao2_container_count(channels) : 0; 00628 }
| 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 2868 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_do_pickup(), ast_pickup_call(), auth_exec(), background_detect_exec(), bridge_exec(), bridge_request(), builtin_parkcall(), common_exec(), conf_exec(), confbridge_exec(), count_exec(), dahdiras_exec(), dial_exec_full(), 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(), parked_call_exec(), pbx_builtin_background(), playback_exec(), privacy_exec(), read_exec(), readexten_exec(), receivefax_exec(), record_exec(), record_thread(), rpt_exec(), sayunixtime_exec(), send_waveform_to_channel(), sendfax_exec(), setup_privacy_args(), skel_exec(), sla_station_exec(), speech_background(), testclient_exec(), testserver_exec(), transmit(), vm_exec(), vm_execmain(), waitfor_exec(), and zapateller_exec().
02869 { 02870 return __ast_answer(chan, 0, 1); 02871 }
| 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 615 of file channel.c.
References ao2_callback, ast_channel_softhangup_cb(), channels, OBJ_MULTIPLE, and OBJ_NODATA.
Referenced by can_safely_quit().
00616 { 00617 shutting_down = 1; 00618 00619 if (hangup) { 00620 ao2_callback(channels, OBJ_NODATA | OBJ_MULTIPLE, ast_channel_softhangup_cb, NULL); 00621 } 00622 }
| struct ast_format* ast_best_codec | ( | struct ast_format_cap * | cap, | |
| struct ast_format * | result | |||
| ) | [read] |
Pick the best audio codec.
Pick the best codec.
Okay, ulaw is used by all telephony equipment, so start with it
Unless of course, you're a silly European, so then prefer ALAW
G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority
Okay, well, signed linear is easy to translate into other stuff
G.726 is standard ADPCM, in RFC3551 packing order
G.726 is standard ADPCM, in AAL2 packing order
ADPCM has great sound quality and is still pretty easy to translate
Okay, we're down to vocoders now, so pick GSM because it's small and easier to translate and sounds pretty good
iLBC is not too bad
Speex is free, but computationally more expensive than GSM
SILK is pretty awesome.
CELT supports crazy high sample rates
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 834 of file channel.c.
References ARRAY_LEN, AST_FORMAT_ADPCM, AST_FORMAT_ALAW, ast_format_cap_best_byid(), AST_FORMAT_CELT, ast_format_clear(), AST_FORMAT_G719, 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_SILK, AST_FORMAT_SIREN14, AST_FORMAT_SIREN7, AST_FORMAT_SLINEAR, AST_FORMAT_SLINEAR12, AST_FORMAT_SLINEAR16, AST_FORMAT_SLINEAR192, AST_FORMAT_SLINEAR24, AST_FORMAT_SLINEAR32, AST_FORMAT_SLINEAR44, AST_FORMAT_SLINEAR48, AST_FORMAT_SLINEAR96, AST_FORMAT_SPEEX, AST_FORMAT_SPEEX16, AST_FORMAT_SPEEX32, AST_FORMAT_TESTLAW, AST_FORMAT_ULAW, ast_getformatname_multiple(), ast_log(), LOG_WARNING, and prefs.
Referenced by __oh323_new(), ast_codec_choose(), ast_iax2_new(), ast_speech_new(), bridge_make_compatible(), echo_exec(), feature_request_and_dial(), free_translation(), gtalk_new(), handle_open_receive_channel_ack_message(), iax2_best_codec(), iax2_request(), jingle_new(), local_new(), mgcp_new(), misdn_new(), multicast_rtp_request(), phone_new(), set_format(), skinny_new(), skinny_set_rtp_peer(), start_rtp(), transmit_connect(), and unistim_new().
00835 { 00836 /* This just our opinion, expressed in code. We are asked to choose 00837 the best codec to use, given no information */ 00838 static const enum ast_format_id prefs[] = 00839 { 00840 /*! Okay, ulaw is used by all telephony equipment, so start with it */ 00841 AST_FORMAT_ULAW, 00842 /*! Unless of course, you're a silly European, so then prefer ALAW */ 00843 AST_FORMAT_ALAW, 00844 AST_FORMAT_G719, 00845 AST_FORMAT_SIREN14, 00846 AST_FORMAT_SIREN7, 00847 AST_FORMAT_TESTLAW, 00848 /*! G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority */ 00849 AST_FORMAT_G722, 00850 /*! Okay, well, signed linear is easy to translate into other stuff */ 00851 AST_FORMAT_SLINEAR192, 00852 AST_FORMAT_SLINEAR96, 00853 AST_FORMAT_SLINEAR48, 00854 AST_FORMAT_SLINEAR44, 00855 AST_FORMAT_SLINEAR32, 00856 AST_FORMAT_SLINEAR24, 00857 AST_FORMAT_SLINEAR16, 00858 AST_FORMAT_SLINEAR12, 00859 AST_FORMAT_SLINEAR, 00860 /*! G.726 is standard ADPCM, in RFC3551 packing order */ 00861 AST_FORMAT_G726, 00862 /*! G.726 is standard ADPCM, in AAL2 packing order */ 00863 AST_FORMAT_G726_AAL2, 00864 /*! ADPCM has great sound quality and is still pretty easy to translate */ 00865 AST_FORMAT_ADPCM, 00866 /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to 00867 translate and sounds pretty good */ 00868 AST_FORMAT_GSM, 00869 /*! iLBC is not too bad */ 00870 AST_FORMAT_ILBC, 00871 /*! Speex is free, but computationally more expensive than GSM */ 00872 AST_FORMAT_SPEEX32, 00873 AST_FORMAT_SPEEX16, 00874 AST_FORMAT_SPEEX, 00875 /*! SILK is pretty awesome. */ 00876 AST_FORMAT_SILK, 00877 /*! CELT supports crazy high sample rates */ 00878 AST_FORMAT_CELT, 00879 /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough 00880 to use it */ 00881 AST_FORMAT_LPC10, 00882 /*! G.729a is faster than 723 and slightly less expensive */ 00883 AST_FORMAT_G729A, 00884 /*! Down to G.723.1 which is proprietary but at least designed for voice */ 00885 AST_FORMAT_G723_1, 00886 }; 00887 char buf[512]; 00888 int x; 00889 00890 /* Find the first preferred codec in the format given */ 00891 for (x = 0; x < ARRAY_LEN(prefs); x++) { 00892 if (ast_format_cap_best_byid(cap, prefs[x], result)) { 00893 return result; 00894 } 00895 } 00896 00897 ast_format_clear(result); 00898 ast_log(LOG_WARNING, "Don't know any of %s formats\n", ast_getformatname_multiple(buf, sizeof(buf), cap)); 00899 00900 return NULL; 00901 }
| struct ast_channel* ast_bridged_channel | ( | struct ast_channel * | chan | ) | [read] |
Find bridged channel.
| chan | Current channel |
Definition at line 6932 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(), __ast_channel_masquerade(), __ast_read(), __dahdi_exception(), _skinny_show_lines(), action_agents(), action_coreshowchannels(), agents_data_provider_get(), agents_show(), agents_show_online(), analog_attempt_transfer(), analog_exception(), analog_hangup(), analog_ss_thread(), ast_bridge_call(), ast_cel_report_event(), ast_channel_data_add_structure(), ast_channel_set_linkgroup(), ast_do_masquerade(), 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(), fax_detect_framehook(), fax_gateway_framehook(), 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(), local_queryoption(), mgcp_hangup(), mgcp_ss(), misdn_attempt_transfer(), mixmonitor_thread(), my_get_sigpvt_bridged_channel(), park_call_full(), schedule_delivery(), serialize_showchan(), sip_hangup(), sip_set_rtp_peer(), skinny_transfer(), socket_process(), spandsp_fax_gateway_start(), start_spying(), startmon(), TransferCallStep1(), and unistim_hangup().
06933 { 06934 struct ast_channel *bridged; 06935 bridged = chan->_bridge; 06936 if (bridged && bridged->tech->bridged_channel) 06937 bridged = bridged->tech->bridged_channel(chan, bridged); 06938 return bridged; 06939 }
| int ast_call | ( | struct ast_channel * | chan, | |
| const 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 (Doesn't seem to be used.) |
| 0 | on success | |
| -1 | on failure |
Definition at line 5610 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(), alloc_playback_chan(), ast_call_forward(), attempt_reconnect(), begin_dial_channel(), connect_link(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), ring_entry(), rpt(), rpt_exec(), and wait_for_answer().
05611 { 05612 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 05613 If the remote end does not answer within the timeout, then do NOT hang up, but 05614 return anyway. */ 05615 int res = -1; 05616 /* Stop if we're a zombie or need a soft hangup */ 05617 ast_channel_lock(chan); 05618 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 05619 if (chan->cdr) { 05620 ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED); 05621 } 05622 if (chan->tech->call) 05623 res = chan->tech->call(chan, addr, timeout); 05624 ast_set_flag(chan, AST_FLAG_OUTGOING); 05625 } 05626 ast_channel_unlock(chan); 05627 return res; 05628 }
| struct ast_channel* ast_call_forward | ( | struct ast_channel * | caller, | |
| struct ast_channel * | orig, | |||
| int * | timeout, | |||
| struct ast_format_cap * | cap, | |||
| 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 | capabilities for requested channel | |
| oh | outgoing helper used with original channel | |
| outstate | reason why unsuccessful (if uncuccessful) |
Definition at line 5231 of file channel.c.
References outgoing_helper::account, ast_call(), AST_CDR_FLAG_ORIGINATED, ast_cdr_setaccount(), ast_channel_accountcode(), ast_channel_call_forward(), ast_channel_lock, ast_channel_lock_both, ast_channel_unlock, ast_copy_flags, ast_copy_string(), ast_hangup(), ast_log(), ast_party_connected_line_copy(), ast_party_redirecting_copy(), ast_request(), ast_set_variables(), call_forward_inherit(), cause, ast_channel::cdr, 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().
05232 { 05233 char tmpchan[256]; 05234 struct ast_channel *new_chan = NULL; 05235 char *data, *type; 05236 int cause = 0; 05237 int res; 05238 05239 /* gather data and request the new forward channel */ 05240 ast_copy_string(tmpchan, ast_channel_call_forward(orig), sizeof(tmpchan)); 05241 if ((data = strchr(tmpchan, '/'))) { 05242 *data++ = '\0'; 05243 type = tmpchan; 05244 } else { 05245 const char *forward_context; 05246 ast_channel_lock(orig); 05247 forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT"); 05248 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", ast_channel_call_forward(orig), S_OR(forward_context, orig->context)); 05249 ast_channel_unlock(orig); 05250 data = tmpchan; 05251 type = "Local"; 05252 } 05253 if (!(new_chan = ast_request(type, cap, orig, data, &cause))) { 05254 ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause); 05255 handle_cause(cause, outstate); 05256 ast_hangup(orig); 05257 return NULL; 05258 } 05259 05260 /* Copy/inherit important information into new channel */ 05261 if (oh) { 05262 if (oh->vars) { 05263 ast_set_variables(new_chan, oh->vars); 05264 } 05265 if (oh->parent_channel) { 05266 call_forward_inherit(new_chan, oh->parent_channel, orig); 05267 } 05268 if (oh->account) { 05269 ast_channel_lock(new_chan); 05270 ast_cdr_setaccount(new_chan, oh->account); 05271 ast_channel_unlock(new_chan); 05272 } 05273 } else if (caller) { /* no outgoing helper so use caller if avaliable */ 05274 call_forward_inherit(new_chan, caller, orig); 05275 } 05276 05277 ast_channel_lock_both(orig, new_chan); 05278 ast_copy_flags(new_chan->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED); 05279 ast_channel_accountcode_set(new_chan, ast_channel_accountcode(orig)); 05280 ast_party_connected_line_copy(&new_chan->connected, &orig->connected); 05281 ast_party_redirecting_copy(&new_chan->redirecting, &orig->redirecting); 05282 ast_channel_unlock(new_chan); 05283 ast_channel_unlock(orig); 05284 05285 /* call new channel */ 05286 res = ast_call(new_chan, data, 0); 05287 if (timeout) { 05288 *timeout = res; 05289 } 05290 if (res) { 05291 ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data); 05292 ast_hangup(orig); 05293 ast_hangup(new_chan); 05294 return NULL; 05295 } 05296 ast_hangup(orig); 05297 05298 return new_chan; 05299 }
| void ast_cancel_shutdown | ( | void | ) |
Cancel a shutdown in progress.
Cancels an existing shutdown and returns to normal operation
Definition at line 631 of file channel.c.
Referenced by handle_abort_shutdown().
00632 { 00633 shutting_down = 0; 00634 }
| 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 752 of file channel.c.
References ARRAY_LEN, and causes.
Referenced by __transmit_response(), ast_channel_data_add_structure(), ast_do_masquerade(), ast_hangup(), dial_exec_full(), findmeexec(), sip_hangup(), and transmit_request_with_auth().
00753 { 00754 int x; 00755 00756 for (x = 0; x < ARRAY_LEN(causes); x++) { 00757 if (causes[x].cause == cause) 00758 return causes[x].desc; 00759 } 00760 00761 return "Unknown"; 00762 }
| 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 6086 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().
06087 { 06088 /* We must re-link, as the hash value will change here. */ 06089 ao2_unlink(channels, chan); 06090 ast_channel_lock(chan); 06091 __ast_change_name_nolink(chan, newname); 06092 ast_channel_unlock(chan); 06093 ao2_link(channels, chan); 06094 }
| 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 9534 of file channel.c.
References __ast_channel_alloc_ap().
09539 { 09540 va_list ap; 09541 struct ast_channel *result; 09542 09543 09544 va_start(ap, name_fmt); 09545 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context, 09546 linkedid, amaflag, __FILE__, __LINE__, __FUNCTION__, name_fmt, ap); 09547 va_end(ap); 09548 09549 return result; 09550 }
| 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 7286 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_clear_softhangup(), ast_channel_make_compatible(), ast_channel_name(), 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_format_cap_copy(), ast_format_cap_destroy(), ast_format_cap_dup(), ast_format_cap_identical(), ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_framehook_list_is_empty(), 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_bridge_config::end_sound, 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::framehooks, ast_channel::generator, LOG_WARNING, manager_bridge_event(), ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::nativeformats, ast_bridge_config::nexteventts, ast_bridge_config::play_warning, ast_channel::readformat, ast_channel_tech::send_digit_begin, ast_bridge_config::start_sound, ast_bridge_config::start_time, ast_channel::tech, ast_bridge_config::timelimit, update_bridge_vars(), ast_bridge_config::warning_freq, ast_bridge_config::warning_sound, and ast_channel::writeformat.
Referenced by ast_bridge_call().
07288 { 07289 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 07290 struct ast_format_cap *o0nativeformats; 07291 struct ast_format_cap *o1nativeformats; 07292 long time_left_ms=0; 07293 char caller_warning = 0; 07294 char callee_warning = 0; 07295 07296 *fo = NULL; 07297 07298 if (c0->_bridge) { 07299 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 07300 ast_channel_name(c0), ast_channel_name(c0->_bridge)); 07301 return -1; 07302 } 07303 if (c1->_bridge) { 07304 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 07305 ast_channel_name(c1), ast_channel_name(c1->_bridge)); 07306 return -1; 07307 } 07308 07309 /* Stop if we're a zombie or need a soft hangup */ 07310 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 07311 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 07312 return -1; 07313 07314 o0nativeformats = ast_format_cap_dup(c0->nativeformats); 07315 o1nativeformats = ast_format_cap_dup(c1->nativeformats); 07316 if (!o0nativeformats || !o1nativeformats) { 07317 ast_format_cap_destroy(o0nativeformats); 07318 ast_format_cap_destroy(o1nativeformats); 07319 ast_log(LOG_WARNING, "failed to copy native formats\n"); 07320 return -1; 07321 } 07322 07323 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING); 07324 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING); 07325 07326 if (ast_tvzero(config->start_time)) { 07327 config->start_time = ast_tvnow(); 07328 if (config->start_sound) { 07329 if (caller_warning) { 07330 bridge_playfile(c0, c1, config->start_sound, config->timelimit / 1000); 07331 } 07332 if (callee_warning) { 07333 bridge_playfile(c1, c0, config->start_sound, config->timelimit / 1000); 07334 } 07335 } 07336 } 07337 07338 /* Keep track of bridge */ 07339 c0->_bridge = c1; 07340 c1->_bridge = c0; 07341 07342 ast_set_owners_and_peers(c0, c1); 07343 07344 if (config->feature_timer && !ast_tvzero(config->nexteventts)) { 07345 config->nexteventts = ast_tvadd(config->feature_start_time, ast_samp2tv(config->feature_timer, 1000)); 07346 } else if (config->timelimit) { 07347 time_left_ms = config->timelimit - ast_tvdiff_ms(ast_tvnow(), config->start_time); 07348 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 07349 if ((caller_warning || callee_warning) && config->play_warning) { 07350 long next_warn = config->play_warning; 07351 if (time_left_ms < config->play_warning && config->warning_freq > 0) { 07352 /* At least one warning was played, which means we are returning after feature */ 07353 long warns_passed = (config->play_warning - time_left_ms) / config->warning_freq; 07354 /* It is 'warns_passed * warning_freq' NOT '(warns_passed + 1) * warning_freq', 07355 because nexteventts will be updated once again in the 'if (!to)' block */ 07356 next_warn = config->play_warning - warns_passed * config->warning_freq; 07357 } 07358 config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(next_warn, 1000)); 07359 } 07360 } else { 07361 config->nexteventts.tv_sec = 0; 07362 config->nexteventts.tv_usec = 0; 07363 } 07364 07365 if (!c0->tech->send_digit_begin) 07366 ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY); 07367 if (!c1->tech->send_digit_begin) 07368 ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY); 07369 manager_bridge_event(1, 1, c0, c1); 07370 07371 /* Before we enter in and bridge these two together tell them both the source of audio has changed */ 07372 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 07373 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 07374 07375 for (/* ever */;;) { 07376 struct timeval now = { 0, }; 07377 int to; 07378 07379 to = -1; 07380 07381 if (!ast_tvzero(config->nexteventts)) { 07382 now = ast_tvnow(); 07383 to = ast_tvdiff_ms(config->nexteventts, now); 07384 if (to <= 0) { 07385 if (!config->timelimit) { 07386 res = AST_BRIDGE_COMPLETE; 07387 break; 07388 } 07389 to = 0; 07390 } 07391 } 07392 07393 if (config->timelimit) { 07394 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time); 07395 if (time_left_ms < to) 07396 to = time_left_ms; 07397 07398 if (time_left_ms <= 0) { 07399 if (caller_warning && config->end_sound) 07400 bridge_playfile(c0, c1, config->end_sound, 0); 07401 if (callee_warning && config->end_sound) 07402 bridge_playfile(c1, c0, config->end_sound, 0); 07403 *fo = NULL; 07404 res = 0; 07405 break; 07406 } 07407 07408 if (!to) { 07409 if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) { 07410 int t = (time_left_ms + 500) / 1000; /* round to nearest second */ 07411 if (caller_warning) 07412 bridge_playfile(c0, c1, config->warning_sound, t); 07413 if (callee_warning) 07414 bridge_playfile(c1, c0, config->warning_sound, t); 07415 } 07416 07417 if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) { 07418 config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000)); 07419 } else { 07420 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 07421 } 07422 } 07423 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE); 07424 } 07425 07426 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 07427 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07428 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE); 07429 } 07430 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07431 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE); 07432 } 07433 c0->_bridge = c1; 07434 c1->_bridge = c0; 07435 ast_debug(1, "Unbridge signal received. Ending native bridge.\n"); 07436 continue; 07437 } 07438 07439 /* Stop if we're a zombie or need a soft hangup */ 07440 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 07441 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) { 07442 *fo = NULL; 07443 res = 0; 07444 ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n", 07445 ast_channel_name(c0), ast_channel_name(c1), 07446 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No", 07447 ast_check_hangup(c0) ? "Yes" : "No", 07448 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No", 07449 ast_check_hangup(c1) ? "Yes" : "No"); 07450 break; 07451 } 07452 07453 update_bridge_vars(c0, c1); 07454 07455 bridge_play_sounds(c0, c1); 07456 07457 if (c0->tech->bridge && 07458 /* if < 1 ms remains use generic bridging for accurate timing */ 07459 (!config->timelimit || to > 1000 || to == 0) && 07460 (c0->tech->bridge == c1->tech->bridge) && 07461 !c0->monitor && !c1->monitor && 07462 !c0->audiohooks && !c1->audiohooks && 07463 ast_framehook_list_is_empty(c0->framehooks) && ast_framehook_list_is_empty(c1->framehooks) && 07464 !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) { 07465 int timeoutms = to - 1000 > 0 ? to - 1000 : to; 07466 /* Looks like they share a bridge method and nothing else is in the way */ 07467 ast_set_flag(c0, AST_FLAG_NBRIDGE); 07468 ast_set_flag(c1, AST_FLAG_NBRIDGE); 07469 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, timeoutms)) == AST_BRIDGE_COMPLETE) { 07470 manager_bridge_event(0, 1, c0, c1); 07471 ast_debug(1, "Returning from native bridge, channels: %s, %s\n", ast_channel_name(c0), ast_channel_name(c1)); 07472 07473 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 07474 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 07475 07476 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 07477 continue; 07478 } 07479 07480 c0->_bridge = NULL; 07481 c1->_bridge = NULL; 07482 ast_format_cap_destroy(o0nativeformats); 07483 ast_format_cap_destroy(o1nativeformats); 07484 return res; 07485 } else { 07486 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 07487 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 07488 } 07489 switch (res) { 07490 case AST_BRIDGE_RETRY: 07491 if (config->play_warning) { 07492 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE); 07493 } 07494 continue; 07495 default: 07496 ast_verb(3, "Native bridging %s and %s ended\n", ast_channel_name(c0), ast_channel_name(c1)); 07497 /* fallthrough */ 07498 case AST_BRIDGE_FAILED_NOWARN: 07499 break; 07500 } 07501 } 07502 07503 if (((ast_format_cmp(&c1->readformat, &c0->writeformat) == AST_FORMAT_CMP_NOT_EQUAL) || 07504 (ast_format_cmp(&c0->readformat, &c1->writeformat) == AST_FORMAT_CMP_NOT_EQUAL) || 07505 !ast_format_cap_identical(c0->nativeformats, o0nativeformats) || 07506 !ast_format_cap_identical(c1->nativeformats, o1nativeformats)) && 07507 !(c0->generator || c1->generator)) { 07508 if (ast_channel_make_compatible(c0, c1)) { 07509 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", ast_channel_name(c0), ast_channel_name(c1)); 07510 manager_bridge_event(0, 1, c0, c1); 07511 ast_format_cap_destroy(o0nativeformats); 07512 ast_format_cap_destroy(o1nativeformats); 07513 return AST_BRIDGE_FAILED; 07514 } 07515 07516 ast_format_cap_copy(o0nativeformats, c0->nativeformats); 07517 ast_format_cap_copy(o1nativeformats, c1->nativeformats); 07518 } 07519 07520 update_bridge_vars(c0, c1); 07521 07522 res = ast_generic_bridge(c0, c1, config, fo, rc); 07523 if (res != AST_BRIDGE_RETRY) { 07524 break; 07525 } else if (config->feature_timer) { 07526 /* feature timer expired but has not been updated, sending to ast_bridge_call to do so */ 07527 break; 07528 } 07529 } 07530 07531 ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY); 07532 ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY); 07533 07534 /* Now that we have broken the bridge the source will change yet again */ 07535 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 07536 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 07537 07538 c0->_bridge = NULL; 07539 c1->_bridge = NULL; 07540 07541 manager_bridge_event(0, 1, c0, c1); 07542 ast_debug(1, "Bridge stops bridging channels %s and %s\n", ast_channel_name(c0), ast_channel_name(c1)); 07543 07544 ast_format_cap_destroy(o0nativeformats); 07545 ast_format_cap_destroy(o1nativeformats); 07546 return res; 07547 }
| static int ast_channel_by_exten_cb | ( | void * | obj, | |
| void * | arg, | |||
| void * | data, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1442 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), ast_strlen_zero(), CMP_MATCH, CMP_STOP, ast_channel::context, context, ast_channel::exten, exten, LOG_ERROR, ast_channel::macrocontext, and ast_channel::macroexten.
Referenced by ast_channel_get_by_exten(), and ast_channel_iterator_by_exten_new().
01443 { 01444 struct ast_channel *chan = obj; 01445 char *context = arg; 01446 char *exten = data; 01447 int ret = CMP_MATCH; 01448 01449 if (ast_strlen_zero(exten) || ast_strlen_zero(context)) { 01450 ast_log(LOG_ERROR, "BUG! Must have a context and extension to match!\n"); 01451 return CMP_STOP; 01452 } 01453 01454 ast_channel_lock(chan); 01455 if (strcasecmp(chan->context, context) && strcasecmp(chan->macrocontext, context)) { 01456 ret = 0; /* Context match failed, continue */ 01457 } else if (strcasecmp(chan->exten, exten) && strcasecmp(chan->macroexten, exten)) { 01458 ret = 0; /* Extension match failed, continue */ 01459 } 01460 ast_channel_unlock(chan); 01461 01462 return ret; 01463 }
| static int ast_channel_by_name_cb | ( | void * | obj, | |
| void * | arg, | |||
| void * | data, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1420 of file channel.c.
References ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_log(), ast_strlen_zero(), CMP_MATCH, CMP_STOP, LOG_ERROR, and name.
Referenced by ast_channel_get_by_name_prefix(), and ast_channel_iterator_by_name_new().
01421 { 01422 struct ast_channel *chan = obj; 01423 const char *name = arg; 01424 size_t name_len = *(size_t *) data; 01425 int ret = CMP_MATCH; 01426 01427 if (ast_strlen_zero(name)) { 01428 ast_log(LOG_ERROR, "BUG! Must supply a channel name or partial name to match!\n"); 01429 return CMP_STOP; 01430 } 01431 01432 ast_channel_lock(chan); 01433 if ((!name_len && strcasecmp(ast_channel_name(chan), name)) 01434 || (name_len && strncasecmp(ast_channel_name(chan), name, name_len))) { 01435 ret = 0; /* name match failed, keep looking */ 01436 } 01437 ast_channel_unlock(chan); 01438 01439 return ret; 01440 }
| static int ast_channel_by_uniqueid_cb | ( | void * | obj, | |
| void * | arg, | |||
| void * | data, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1465 of file channel.c.
References ast_channel_lock, ast_channel_uniqueid(), ast_channel_unlock, ast_log(), ast_strlen_zero(), CMP_MATCH, CMP_STOP, and LOG_ERROR.
Referenced by ast_channel_get_by_name_prefix().
01466 { 01467 struct ast_channel *chan = obj; 01468 char *uniqueid = arg; 01469 size_t id_len = *(size_t *) data; 01470 int ret = CMP_MATCH; 01471 01472 if (ast_strlen_zero(uniqueid)) { 01473 ast_log(LOG_ERROR, "BUG! Must supply a uniqueid or partial uniqueid to match!\n"); 01474 return CMP_STOP; 01475 } 01476 01477 ast_channel_lock(chan); 01478 if ((!id_len && strcasecmp(ast_channel_uniqueid(chan), uniqueid)) 01479 || (id_len && strncasecmp(ast_channel_uniqueid(chan), uniqueid, id_len))) { 01480 ret = 0; /* uniqueid match failed, keep looking */ 01481 } 01482 ast_channel_unlock(chan); 01483 01484 return ret; 01485 }
| 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 1414 of file channel.c.
References ao2_callback_data, and channels.
Referenced by ast_cel_check_retire_linkedid(), ast_channel_get_by_exten(), ast_channel_get_by_name_prefix(), ast_channel_iterator_by_exten_new(), ast_channel_iterator_by_name_new(), ast_pickup_call(), handle_core_set_debug_channel(), my_ast_get_channel_by_name_locked(), pickup_by_group(), pickup_by_mark(), pickup_by_part(), and state_notify_build_xml().
01416 { 01417 return ao2_callback_data(channels, ao2_flags, cb_fn, arg, data); 01418 }
| int ast_channel_cc_params_init | ( | struct ast_channel * | chan, | |
| const struct ast_cc_config_params * | base_params | |||
| ) |
Set up datastore with CCSS parameters for a channel.
| chan | The channel to create the datastore on | |
| base_params | CCSS parameters we wish to copy into the channel |
| 0 | Success | |
| -1 | Failure |
Definition at line 9440 of file channel.c.
References ast_cc_config_params_destroy(), ast_cc_config_params_init, ast_cc_copy_config_params(), ast_channel_datastore_add(), ast_datastore_alloc, and ast_datastore::data.
Referenced by ast_channel_get_cc_config_params(), dahdi_new(), local_call(), local_request(), and sip_new().
09442 { 09443 struct ast_cc_config_params *cc_params; 09444 struct ast_datastore *cc_datastore; 09445 09446 if (!(cc_params = ast_cc_config_params_init())) { 09447 return -1; 09448 } 09449 09450 if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL))) { 09451 ast_cc_config_params_destroy(cc_params); 09452 return -1; 09453 } 09454 09455 if (base_params) { 09456 ast_cc_copy_config_params(cc_params, base_params); 09457 } 09458 cc_datastore->data = cc_params; 09459 ast_channel_datastore_add(chan, cc_datastore); 09460 return 0; 09461 }
| 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 6225 of file channel.c.
References ast_cel_check_retire_linkedid(), ast_channel_linkedid(), and ast_strlen_zero().
Referenced by ast_channel_set_linkgroup().
06226 { 06227 /* if the linkedid for this channel is being changed from something, check... */ 06228 if (!ast_strlen_zero(ast_channel_linkedid(chan)) && 0 != strcmp(ast_channel_linkedid(chan), linkedid)) { 06229 ast_cel_check_retire_linkedid(chan); 06230 } 06231 06232 ast_channel_linkedid_set(chan, linkedid); 06233 }
| void ast_channel_clear_softhangup | ( | struct ast_channel * | chan, | |
| int | flag | |||
| ) |
Clear a set of softhangup flags from a channel.
Never clear a softhangup flag from a channel directly. Instead, use this function. This ensures that all aspects of the softhangup process are aborted.
| chan | the channel to clear the flag on | |
| flag | the flag or flags to clear |
Definition at line 2479 of file channel.c.
References ast_channel::_softhangup, ast_channel_lock, ast_channel_unlock, AST_CONTROL_END_OF_Q, AST_FRAME_CONTROL, ast_frfree, AST_LIST_LAST, AST_LIST_REMOVE, ast_frame::frametype, ast_frame_subclass::integer, ast_channel::readq, and ast_frame::subclass.
Referenced by __ast_pbx_run(), ast_channel_bridge(), ast_generic_bridge(), check_goto_on_transfer(), and collect_digits().
02480 { 02481 ast_channel_lock(chan); 02482 02483 chan->_softhangup &= ~flag; 02484 02485 if (!chan->_softhangup) { 02486 struct ast_frame *fr; 02487 02488 /* If we have completely cleared the softhangup flag, 02489 * then we need to fully abort the hangup process. This requires 02490 * pulling the END_OF_Q frame out of the channel frame queue if it 02491 * still happens to be there. */ 02492 02493 fr = AST_LIST_LAST(&chan->readq); 02494 if (fr && fr->frametype == AST_FRAME_CONTROL && 02495 fr->subclass.integer == AST_CONTROL_END_OF_Q) { 02496 AST_LIST_REMOVE(&chan->readq, fr, frame_list); 02497 ast_frfree(fr); 02498 } 02499 } 02500 02501 ast_channel_unlock(chan); 02502 }
| static int ast_channel_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
| 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 672 of file channel.c.
References ast_channel_cmpwhentohangup_tv().
00673 { 00674 struct timeval when = { offset, }; 00675 return ast_channel_cmpwhentohangup_tv(chan, when); 00676 }
| 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 657 of file channel.c.
References ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), and ast_channel::whentohangup.
Referenced by ast_channel_cmpwhentohangup().
00658 { 00659 struct timeval whentohangup; 00660 00661 if (ast_tvzero(chan->whentohangup)) 00662 return ast_tvzero(offset) ? 0 : -1; 00663 00664 if (ast_tvzero(offset)) 00665 return 1; 00666 00667 whentohangup = ast_tvadd(offset, ast_tvnow()); 00668 00669 return ast_tvdiff_ms(whentohangup, chan->whentohangup); 00670 }
| 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 9338 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(), chanlist::connected, ast_channel::connected, ast_frame::data, ast_frame::datalen, pbx_builtin_getvar_helper(), ast_frame::ptr, and S_OR.
Referenced by __ast_read(), app_exec(), ast_bridge_call(), ast_do_pickup(), ast_generic_bridge(), atxfer_fail_cleanup(), builtin_atxfer(), feature_request_and_dial(), handle_frame(), local_bridge_loop(), parked_call_exec(), remote_bridge_loop(), and wait_for_answer().
09339 { 09340 const char *macro; 09341 const char *macro_args; 09342 int retval; 09343 09344 ast_channel_lock(macro_chan); 09345 macro = pbx_builtin_getvar_helper(macro_chan, is_caller 09346 ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO"); 09347 macro = ast_strdupa(S_OR(macro, "")); 09348 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller 09349 ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS"); 09350 macro_args = ast_strdupa(S_OR(macro_args, "")); 09351 09352 if (ast_strlen_zero(macro)) { 09353 ast_channel_unlock(macro_chan); 09354 return -1; 09355 } 09356 09357 if (is_frame) { 09358 const struct ast_frame *frame = connected_info; 09359 09360 ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->connected); 09361 } else { 09362 const struct ast_party_connected_line *connected = connected_info; 09363 09364 ast_party_connected_line_copy(¯o_chan->connected, connected); 09365 } 09366 ast_channel_unlock(macro_chan); 09367 09368 if (!(retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args))) { 09369 ast_channel_lock(macro_chan); 09370 ast_channel_update_connected_line(macro_chan, ¯o_chan->connected, NULL); 09371 ast_channel_unlock(macro_chan); 09372 } 09373 09374 return retval; 09375 }
| 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 2362 of file channel.c.
References AST_LIST_INSERT_HEAD, and ast_channel::datastores.
Referenced by __ast_channel_masquerade(), _macro_exec(), acf_curlopt_write(), acf_iaxvar_write(), acf_odbc_read(), add_features_datastores(), add_to_agi(), apply_plc(), ast_channel_cc_params_init(), ast_do_pickup(), ast_iax2_new(), ast_setup_cc_recall_datastore(), audiohook_volume_get(), authenticate_reply(), calendar_query_exec(), cc_interfaces_datastore_init(), chan_cleanup(), create_msg_q_chan(), dial_exec_full(), do_notify(), dundi_query_read(), enable_jack_hook(), enum_query_read(), find_or_create_details(), find_transaction(), frame_trace_helper(), func_channel_write_real(), get_lock(), gosub_exec(), jb_helper(), lua_get_state(), msg_datastore_find_or_create(), mute_add_audiohook(), pitchshift_helper(), raise_exception(), setup_inheritance_datastore(), setup_mixmonitor_ds(), setup_transfer_datastore(), shared_write(), smdi_msg_retrieve_read(), socket_process(), speech_create(), speex_write(), srv_datastore_setup(), try_calling(), and volume_write().
02363 { 02364 int res = 0; 02365 02366 AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry); 02367 02368 return res; 02369 }
| 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 2335 of file channel.c.
References ast_datastore_alloc.
02336 { 02337 return ast_datastore_alloc(info, uid); 02338 }
| 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 2376 of file channel.c.
References AST_LIST_TRAVERSE, 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(), apply_plc(), ast_can_pickup(), ast_cc_agent_set_interfaces_chanvar(), ast_cc_call_init(), ast_cc_completed(), ast_cc_extension_monitor_add_dialstring(), ast_cc_get_current_core_id(), ast_cc_is_recall(), ast_cc_offer(), ast_channel_get_cc_config_params(), ast_do_masquerade(), ast_handle_cc_control_frame(), ast_ignore_cc(), ast_odbc_retrieve_transaction_obj(), ast_set_cc_interfaces_chanvar(), attended_transfer_occurred(), audiohook_volume_callback(), audiohook_volume_get(), builtin_atxfer(), calendar_event_read(), calendar_query_exec(), calendar_query_result_exec(), cc_build_payload(), chan_cleanup(), clear_dialed_interfaces(), dial_exec_full(), disable_jack_hook(), dundi_result_read(), enable_jack_hook(), enum_result_read(), exec_odbcfinish(), find_details(), find_speech(), find_transaction(), frame_trace_helper(), func_channel_read(), func_channel_write_real(), func_inheritance_write(), func_mute_write(), get_agi_cmd(), get_lock(), gosub_exec(), handle_gosub(), iax2_call(), jack_hook_callback(), jb_helper(), local_read(), local_write(), lock_fixup(), lua_get_state(), manage_parked_call(), manager_mutestream(), mark_transaction_active(), msg_data_func_read(), msg_datastore_find_or_create(), msg_func_read(), msg_q_cb(), msg_send_exec(), mute_callback(), parked_call_exec(), pitchshift_cb(), pitchshift_helper(), pop_exec(), queue_transfer_fixup(), raise_exception(), release_transaction(), return_exec(), set_security_requirements(), shared_read(), shared_write(), smdi_msg_read(), speech_background(), speech_destroy(), speex_callback(), speex_read(), speex_write(), srv_query_read(), srv_result_read(), stop_mixmonitor_exec(), try_calling(), unlock_read(), volume_callback(), and volume_write().
02377 { 02378 struct ast_datastore *datastore = NULL; 02379 02380 if (info == NULL) 02381 return NULL; 02382 02383 AST_LIST_TRAVERSE(&chan->datastores, datastore, entry) { 02384 if (datastore->info != info) { 02385 continue; 02386 } 02387 02388 if (uid == NULL) { 02389 /* matched by type only */ 02390 break; 02391 } 02392 02393 if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) { 02394 /* Matched by type AND uid */ 02395 break; 02396 } 02397 } 02398 02399 return datastore; 02400 }
| int ast_channel_datastore_free | ( | struct ast_datastore * | datastore | ) |
Free a channel data store object.
Definition at line 2340 of file channel.c.
References ast_datastore_free().
02341 { 02342 return ast_datastore_free(datastore); 02343 }
| int ast_channel_datastore_inherit | ( | struct ast_channel * | from, | |
| struct ast_channel * | to | |||
| ) |
Inherit datastores from a parent to a child.
Definition at line 2345 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(), begin_dial_channel(), call_forward_inherit(), dial_exec_full(), dial_transfer(), do_forward(), findmeexec(), local_call(), ring_entry(), and wait_for_answer().
02346 { 02347 struct ast_datastore *datastore = NULL, *datastore2; 02348 02349 AST_LIST_TRAVERSE(&from->datastores, datastore, entry) { 02350 if (datastore->inheritance > 0) { 02351 datastore2 = ast_datastore_alloc(datastore->info, datastore->uid); 02352 if (datastore2) { 02353 datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL; 02354 datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1; 02355 AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry); 02356 } 02357 } 02358 } 02359 return 0; 02360 }
| 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 2371 of file channel.c.
References AST_LIST_REMOVE, and ast_channel::datastores.
Referenced by acf_fetch(), acf_odbc_read(), adjust_frame_for_plc(), ast_do_masquerade(), ast_do_pickup(), chan_cleanup(), clear_dialed_interfaces(), dial_exec_full(), disable_jack_hook(), exec_odbcfinish(), frame_trace_helper(), jb_helper(), lua_get_state(), queue_transfer_fixup(), speech_background(), speech_destroy(), speex_write(), srv_query_read(), stop_mixmonitor_exec(), and try_calling().
02372 { 02373 return AST_LIST_REMOVE(&chan->datastores, datastore, entry) ? 0 : -1; 02374 }
| 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 1396 of file channel.c.
References AST_FLAG_DEFER_DTMF, ast_set_flag, and ast_test_flag.
Referenced by __adsi_transmit_messages(), and find_cache().
01397 { 01398 int pre = 0; 01399 01400 if (chan) { 01401 pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF); 01402 ast_set_flag(chan, AST_FLAG_DEFER_DTMF); 01403 } 01404 return pre; 01405 }
| static void ast_channel_destructor | ( | void * | obj | ) | [static] |
Free a channel structure.
Definition at line 2181 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_NAME, ast_channel_unlock, ast_copy_string(), ast_datastore_free(), AST_DEVICE_UNKNOWN, ast_devstate_changed_literal(), ast_format_cap_destroy(), ast_free, ast_frfree, ast_jb_destroy(), AST_LIST_REMOVE_HEAD, ast_log(), AST_MAX_FDS, ast_moh_cleanup(), ast_party_caller_free(), ast_party_connected_line_free(), ast_party_dialed_free(), ast_party_redirecting_free(), ast_sched_context_destroy(), ast_string_field_free_memory, ast_timer_close(), ast_tone_zone_unref(), ast_translator_free_path(), ast_var_delete(), ast_channel::caller, ast_channel::cdr, ast_channel::connected, ast_channel::datastores, ast_channel::dialed, free, LOG_WARNING, ast_channel::monitor, ast_channel::music_state, ast_channel::nativeformats, ast_channel::pbx, ast_channel::readq, ast_channel::readtrans, ast_channel::redirecting, ast_channel::sched, 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().
02182 { 02183 struct ast_channel *chan = obj; 02184 int fd; 02185 #ifdef HAVE_EPOLL 02186 int i; 02187 #endif 02188 struct ast_var_t *vardata; 02189 struct ast_frame *f; 02190 struct varshead *headp; 02191 struct ast_datastore *datastore; 02192 char device_name[AST_CHANNEL_NAME]; 02193 02194 if (ast_channel_name(chan)) { 02195 /* The string fields were initialized. */ 02196 ast_cel_report_event(chan, AST_CEL_CHANNEL_END, NULL, NULL, NULL); 02197 ast_cel_check_retire_linkedid(chan); 02198 } 02199 02200 /* Get rid of each of the data stores on the channel */ 02201 ast_channel_lock(chan); 02202 while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry))) 02203 /* Free the data store */ 02204 ast_datastore_free(datastore); 02205 ast_channel_unlock(chan); 02206 02207 /* Lock and unlock the channel just to be sure nobody has it locked still 02208 due to a reference that was stored in a datastore. (i.e. app_chanspy) */ 02209 ast_channel_lock(chan); 02210 ast_channel_unlock(chan); 02211 02212 if (chan->tech_pvt) { 02213 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", ast_channel_name(chan)); 02214 ast_free(chan->tech_pvt); 02215 } 02216 02217 if (chan->sched) { 02218 ast_sched_context_destroy(chan->sched); 02219 } 02220 02221 if (ast_channel_name(chan)) { 02222 char *dashptr; 02223 02224 /* The string fields were initialized. */ 02225 ast_copy_string(device_name, ast_channel_name(chan), sizeof(device_name)); 02226 if ((dashptr = strrchr(device_name, '-'))) { 02227 *dashptr = '\0'; 02228 } 02229 } else { 02230 device_name[0] = '\0'; 02231 } 02232 02233 /* Stop monitoring */ 02234 if (chan->monitor) 02235 chan->monitor->stop( chan, 0 ); 02236 02237 /* If there is native format music-on-hold state, free it */ 02238 if (chan->music_state) 02239 ast_moh_cleanup(chan); 02240 02241 /* Free translators */ 02242 if (chan->readtrans) 02243 ast_translator_free_path(chan->readtrans); 02244 if (chan->writetrans) 02245 ast_translator_free_path(chan->writetrans); 02246 if (chan->pbx) 02247 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", ast_channel_name(chan)); 02248 02249 ast_party_dialed_free(&chan->dialed); 02250 ast_party_caller_free(&chan->caller); 02251 ast_party_connected_line_free(&chan->connected); 02252 ast_party_redirecting_free(&chan->redirecting); 02253 02254 /* Close pipes if appropriate */ 02255 if ((fd = chan->alertpipe[0]) > -1) 02256 close(fd); 02257 if ((fd = chan->alertpipe[1]) > -1) 02258 close(fd); 02259 if (chan->timer) { 02260 ast_timer_close(chan->timer); 02261 } 02262 #ifdef HAVE_EPOLL 02263 for (i = 0; i < AST_MAX_FDS; i++) { 02264 if (chan->epfd_data[i]) 02265 free(chan->epfd_data[i]); 02266 } 02267 close(chan->epfd); 02268 #endif 02269 while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list))) 02270 ast_frfree(f); 02271 02272 /* loop over the variables list, freeing all data and deleting list items */ 02273 /* no need to lock the list, as the channel is already locked */ 02274 headp = &chan->varshead; 02275 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) 02276 ast_var_delete(vardata); 02277 02278 ast_app_group_discard(chan); 02279 02280 /* Destroy the jitterbuffer */ 02281 ast_jb_destroy(chan); 02282 02283 if (chan->cdr) { 02284 ast_cdr_discard(chan->cdr); 02285 chan->cdr = NULL; 02286 } 02287 02288 if (chan->zone) { 02289 chan->zone = ast_tone_zone_unref(chan->zone); 02290 } 02291 02292 ast_string_field_free_memory(chan); 02293 02294 if (device_name[0]) { 02295 /* 02296 * We have a device name to notify of a new state. 02297 * 02298 * Queue an unknown state, because, while we know that this particular 02299 * instance is dead, we don't know the state of all other possible 02300 * instances. 02301 */ 02302 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name); 02303 } 02304 02305 chan->nativeformats = ast_format_cap_destroy(chan->nativeformats); 02306 }
| 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 7186 of file channel.c.
References ast_channel_tech::early_bridge, and ast_channel::tech.
Referenced by dial_exec_full(), and wait_for_answer().
07187 { 07188 /* Make sure we can early bridge, if not error out */ 07189 if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge))) 07190 return -1; 07191 07192 return c0->tech->early_bridge(c0, c1); 07193 }
| struct ast_channel* ast_channel_get_by_exten | ( | const char * | exten, | |
| const char * | context | |||
| ) | [read] |
Find a channel by extension and context.
| exten | the extension to search for | |
| context | the context to search for |
| a | channel that is at the specified extension and context | |
| NULL | if no channel was found |
Definition at line 1595 of file channel.c.
References ast_channel_by_exten_cb(), and ast_channel_callback().
01596 { 01597 char *l_exten = (char *) exten; 01598 char *l_context = (char *) context; 01599 01600 return ast_channel_callback(ast_channel_by_exten_cb, l_context, l_exten, 0); 01601 }
| struct ast_channel* ast_channel_get_by_name | ( | const char * | name | ) | [read] |
Find a channel by name.
Channel search functions
| name | the name or uniqueid of the channel to search for |
| a | channel with the name specified by the argument | |
| NULL | if no channel was found |
Definition at line 1590 of file channel.c.
References ast_channel_get_by_name_prefix().
Referenced by action_add_agi_cmd(), action_aocmessage(), 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_mixmonitor(), manager_mute_mixmonitor(), manager_mutestream(), manager_optimize_away(), manager_park(), manager_play_dtmf(), manager_stop_mixmonitor(), park_call_full(), pbx_builtin_importvar(), senddtmf_exec(), shared_read(), shared_write(), start_monitor_action(), and stop_monitor_action().
01591 { 01592 return ast_channel_get_by_name_prefix(name, 0); 01593 }
| struct ast_channel* ast_channel_get_by_name_prefix | ( | const char * | name, | |
| size_t | name_len | |||
| ) | [read] |
Find a channel by a name prefix.
| name | The channel name or uniqueid prefix to search for | |
| name_len | Only search for up to this many characters from the name |
| a | channel with the name prefix specified by the arguments | |
| NULL | if no channel was found |
Definition at line 1570 of file channel.c.
References ast_channel_by_name_cb(), ast_channel_by_uniqueid_cb(), ast_channel_callback(), ast_strlen_zero(), and OBJ_KEY.
Referenced by action_aocmessage(), action_bridge(), ast_channel_get_by_name(), ast_parse_device_state(), bridge_exec(), cc_generic_agent_stop_ringing(), common_exec(), handle_cli_mixmonitor(), shared_read(), and shared_write().
01571 { 01572 struct ast_channel *chan; 01573 char *l_name = (char *) name; 01574 01575 chan = ast_channel_callback(ast_channel_by_name_cb, l_name, &name_len, 01576 (name_len == 0) /* optimize if it is a complete name match */ ? OBJ_KEY : 0); 01577 if (chan) { 01578 return chan; 01579 } 01580 01581 if (ast_strlen_zero(l_name)) { 01582 /* We didn't have a name to search for so quit. */ 01583 return NULL; 01584 } 01585 01586 /* Now try a search for uniqueid. */ 01587 return ast_channel_callback(ast_channel_by_uniqueid_cb, l_name, &name_len, 0); 01588 }
| int ast_channel_get_cc_agent_type | ( | struct ast_channel * | chan, | |
| char * | agent_type, | |||
| size_t | size | |||
| ) |
Find the appropriate CC agent type to use given a channel.
Prior to adding this function, the call completion core attempted to figure this out for itself by stripping the technology off the channel's name. However, in the case of chan_dahdi, there are multiple agent types registered, and so simply searching for an agent type called "DAHDI" is not possible. In a case where multiple agent types are defined, the channel driver must have a queryoption callback defined in its channel_tech, and the queryoption callback must handle AST_OPTION_CC_AGENT_TYPE
If a channel driver does not have a queryoption callback or if the queryoption callback does not handle AST_OPTION_CC_AGENT_TYPE, then the old behavior of using the technology portion of the channel name is used instead. This is perfectly suitable for channel drivers whose channel technologies are a one-to-one match with the agent types defined within.
Note that this function is only called when the agent policy on a given channel is set to "native." Generic agents' type can be determined automatically by the core.
| chan | The channel for which we wish to retrieve the agent type | |
| [out] | agent_type | The type of agent the channel driver wants us to use |
| size | The size of the buffer to write to |
Definition at line 9502 of file channel.c.
References ast_channel_name(), ast_channel_queryoption(), ast_copy_string(), and AST_OPTION_CC_AGENT_TYPE.
Referenced by find_agent_callbacks().
09503 { 09504 int len = size; 09505 char *slash; 09506 09507 if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE, agent_type, &len, 0)) { 09508 return 0; 09509 } 09510 09511 ast_copy_string(agent_type, ast_channel_name(chan), size); 09512 if ((slash = strchr(agent_type, '/'))) { 09513 *slash = '\0'; 09514 } 09515 return 0; 09516 }
| struct ast_cc_config_params* ast_channel_get_cc_config_params | ( | struct ast_channel * | chan | ) | [read] |
Get the CCSS parameters from a channel.
| chan | Channel to retrieve parameters from |
| NULL | Failure | |
| non-NULL | The parameters desired |
Definition at line 9463 of file channel.c.
References ast_assert, ast_channel_cc_params_init(), ast_channel_datastore_find(), and ast_datastore::data.
Referenced by acf_cc_read(), acf_cc_write(), analog_call(), ast_cc_call_failed(), ast_cc_call_init(), ast_queue_cc_frame(), cc_agent_init(), cc_core_init_instance(), find_agent_callbacks(), local_call(), and local_request().
09464 { 09465 struct ast_datastore *cc_datastore; 09466 09467 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) { 09468 /* If we can't find the datastore, it almost definitely means that the channel type being 09469 * used has not had its driver modified to parse CC config parameters. The best action 09470 * to take here is to create the parameters on the spot with the defaults set. 09471 */ 09472 if (ast_channel_cc_params_init(chan, NULL)) { 09473 return NULL; 09474 } 09475 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) { 09476 /* Should be impossible */ 09477 return NULL; 09478 } 09479 } 09480 09481 ast_assert(cc_datastore->data != NULL); 09482 return cc_datastore->data; 09483 }
| int ast_channel_get_device_name | ( | struct ast_channel * | chan, | |
| char * | device_name, | |||
| size_t | name_buffer_length | |||
| ) |
Get a device name given its channel structure.
This function interfaces with a channel tech's queryoption callback to retrieve the name of the device being communicated with. If the channel does not implement this specific option, then the traditional method of using the channel name is used instead.
| chan | The channel to retrieve the information from | |
| [out] | device_name | The buffer to place the device's name into |
| name_buffer_length | The allocated space for the device_name |
Definition at line 9485 of file channel.c.
References ast_channel_name(), ast_channel_queryoption(), ast_copy_string(), and AST_OPTION_DEVICE_NAME.
Referenced by ast_cc_call_failed(), ast_cc_is_recall(), ast_queue_cc_frame(), cc_core_init_instance(), cccancel_exec(), ccreq_exec(), dial_exec_full(), sip_call(), and sip_handle_cc().
09486 { 09487 int len = name_buffer_length; 09488 char *dash; 09489 if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME, device_name, &len, 0)) { 09490 return 0; 09491 } 09492 09493 /* Dang. Do it the old-fashioned way */ 09494 ast_copy_string(device_name, ast_channel_name(chan), name_buffer_length); 09495 if ((dash = strrchr(device_name, '-'))) { 09496 *dash = '\0'; 09497 } 09498 09499 return 0; 09500 }
| static int ast_channel_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 7818 of file channel.c.
References ast_channel_name(), ast_str_case_hash(), ast_strlen_zero(), name, and OBJ_KEY.
07819 { 07820 const char *name = (flags & OBJ_KEY) ? obj : ast_channel_name((struct ast_channel *) obj); 07821 07822 /* If the name isn't set, return 0 so that the ao2_find() search will 07823 * start in the first bucket. */ 07824 if (ast_strlen_zero(name)) { 07825 return 0; 07826 } 07827 07828 return ast_str_case_hash(name); 07829 }
| 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 6096 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(), begin_dial_channel(), call_forward_inherit(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), ring_entry(), and wait_for_answer().
06097 { 06098 struct ast_var_t *current, *newvar; 06099 const char *varname; 06100 06101 AST_LIST_TRAVERSE(&parent->varshead, current, entries) { 06102 int vartype = 0; 06103 06104 varname = ast_var_full_name(current); 06105 if (!varname) 06106 continue; 06107 06108 if (varname[0] == '_') { 06109 vartype = 1; 06110 if (varname[1] == '_') 06111 vartype = 2; 06112 } 06113 06114 switch (vartype) { 06115 case 1: 06116 newvar = ast_var_assign(&varname[1], ast_var_value(current)); 06117 if (newvar) { 06118 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 06119 ast_debug(1, "Copying soft-transferable variable %s.\n", ast_var_name(newvar)); 06120 } 06121 break; 06122 case 2: 06123 newvar = ast_var_assign(varname, ast_var_value(current)); 06124 if (newvar) { 06125 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 06126 ast_debug(1, "Copying hard-transferable variable %s.\n", ast_var_name(newvar)); 06127 } 06128 break; 06129 default: 06130 ast_debug(1, "Not copying variable %s.\n", ast_var_name(current)); 06131 break; 06132 } 06133 } 06134 }
| 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 1544 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_complete_channels(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), common_exec(), data_channels_provider_handler(), func_channels_read(), handle_chanlist(), and handle_softhangup().
01545 { 01546 struct ast_channel_iterator *i; 01547 01548 if (!(i = ast_calloc(1, sizeof(*i)))) { 01549 return NULL; 01550 } 01551 01552 i->simple_iterator = ao2_iterator_init(channels, 0); 01553 i->active_iterator = &i->simple_iterator; 01554 01555 return i; 01556 }
| struct ast_channel_iterator* ast_channel_iterator_by_exten_new | ( | const char * | exten, | |
| const char * | context | |||
| ) | [read] |
Create a new channel iterator based on extension.
| exten | The extension that channels must be in | |
| context | The context that channels must be in |
| NULL | on failure | |
| a | new channel iterator based on the specified parameters |
Definition at line 1504 of file channel.c.
References ast_channel_iterator::active_iterator, ast_calloc, ast_channel_by_exten_cb(), ast_channel_callback(), ast_free, and OBJ_MULTIPLE.
Referenced by common_exec(), and pickup_by_exten().
01505 { 01506 struct ast_channel_iterator *i; 01507 char *l_exten = (char *) exten; 01508 char *l_context = (char *) context; 01509 01510 if (!(i = ast_calloc(1, sizeof(*i)))) { 01511 return NULL; 01512 } 01513 01514 i->active_iterator = (void *) ast_channel_callback(ast_channel_by_exten_cb, 01515 l_context, l_exten, OBJ_MULTIPLE); 01516 if (!i->active_iterator) { 01517 ast_free(i); 01518 return NULL; 01519 } 01520 01521 return i; 01522 }
| struct ast_channel_iterator* ast_channel_iterator_by_name_new | ( | const char * | name, | |
| size_t | name_len | |||
| ) | [read] |
Create a new channel iterator based on name.
| name | channel name or channel uniqueid to match | |
| name_len | number of characters in the channel name to match on. This would be used to match based on name prefix. If matching on the full channel name is desired, then this parameter should be 0. |
| NULL | on failure | |
| a | new channel iterator based on the specified parameters |
Definition at line 1524 of file channel.c.
References ast_channel_iterator::active_iterator, ast_calloc, ast_channel_by_name_cb(), ast_channel_callback(), ast_free, OBJ_KEY, and OBJ_MULTIPLE.
Referenced by ast_complete_channels(), common_exec(), and softhangup_exec().
01525 { 01526 struct ast_channel_iterator *i; 01527 char *l_name = (char *) name; 01528 01529 if (!(i = ast_calloc(1, sizeof(*i)))) { 01530 return NULL; 01531 } 01532 01533 i->active_iterator = (void *) ast_channel_callback(ast_channel_by_name_cb, 01534 l_name, &name_len, 01535 OBJ_MULTIPLE | (name_len == 0 /* match the whole word, so optimize */ ? OBJ_KEY : 0)); 01536 if (!i->active_iterator) { 01537 ast_free(i); 01538 return NULL; 01539 } 01540 01541 return i; 01542 }
| struct ast_channel_iterator* ast_channel_iterator_destroy | ( | struct ast_channel_iterator * | i | ) | [read] |
Destroy a channel iterator.
| i | the itereator to destroy |
Definition at line 1496 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(), data_channels_provider_handler(), func_channels_read(), handle_chanlist(), handle_softhangup(), pickup_by_exten(), and softhangup_exec().
01497 { 01498 ao2_iterator_destroy(i->active_iterator); 01499 ast_free(i); 01500 01501 return NULL; 01502 }
| struct ast_channel* ast_channel_iterator_next | ( | struct ast_channel_iterator * | i | ) | [read] |
Get the next channel for a channel iterator.
| i | the channel iterator that was created using one of the channel_iterator_xxx_new() functions. |
| 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 1558 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(), data_channels_provider_handler(), func_channels_read(), handle_chanlist(), handle_softhangup(), next_channel(), pickup_by_exten(), and softhangup_exec().
01559 { 01560 return ao2_iterator_next(i->active_iterator); 01561 }
| 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 5827 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(), fax_detect_framehook(), fax_gateway_framehook(), multiplexed_bridge_join(), parked_call_exec(), simple_bridge_join(), try_calling(), and wait_for_answer().
05828 { 05829 /* Some callers do not check return code, and we must try to set all call legs correctly */ 05830 int rc = 0; 05831 05832 /* Set up translation from the chan to the peer */ 05833 rc = ast_channel_make_compatible_helper(chan, peer); 05834 05835 if (rc < 0) 05836 return rc; 05837 05838 /* Set up translation from the peer to the chan */ 05839 rc = ast_channel_make_compatible_helper(peer, chan); 05840 05841 return rc; 05842 }
| 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 5769 of file channel.c.
References ast_channel_name(), ast_channel_setoption(), ast_format_cap_has_type(), ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_is_slinear(), ast_format_rate(), ast_format_set(), ast_format_slin_by_rate(), AST_FORMAT_TYPE_AUDIO, ast_getformatname(), ast_log(), ast_opt_generic_plc, 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::nativeformats, ast_channel::readformat, ast_channel::tech, and ast_channel::writeformat.
Referenced by ast_channel_make_compatible().
05770 { 05771 struct ast_format_cap *src_cap = from->nativeformats; /* shallow copy, do not destroy */ 05772 struct ast_format_cap *dst_cap = to->nativeformats; /* shallow copy, do not destroy */ 05773 struct ast_format best_src_fmt; 05774 struct ast_format best_dst_fmt; 05775 int use_slin; 05776 05777 /* See if the channel driver can natively make these two channels compatible */ 05778 if (from->tech->bridge && from->tech->bridge == to->tech->bridge && 05779 !ast_channel_setoption(from, AST_OPTION_MAKE_COMPATIBLE, to, sizeof(struct ast_channel *), 0)) { 05780 return 0; 05781 } 05782 05783 if ((ast_format_cmp(&from->readformat, &to->writeformat) != AST_FORMAT_CMP_NOT_EQUAL) && 05784 (ast_format_cmp(&to->readformat, &from->writeformat) != AST_FORMAT_CMP_NOT_EQUAL)) { 05785 /* Already compatible! Moving on ... */ 05786 return 0; 05787 } 05788 05789 /* If there's no audio in this call, don't bother with trying to find a translation path */ 05790 if (!ast_format_cap_has_type(src_cap, AST_FORMAT_TYPE_AUDIO) || !ast_format_cap_has_type(dst_cap, AST_FORMAT_TYPE_AUDIO)) 05791 return 0; 05792 05793 if (ast_translator_best_choice(dst_cap, src_cap, &best_src_fmt, &best_dst_fmt) < 0) { 05794 ast_log(LOG_WARNING, "No path to translate from %s to %s\n", ast_channel_name(from), ast_channel_name(to)); 05795 return -1; 05796 } 05797 05798 /* if the best path is not 'pass through', then 05799 * transcoding is needed; if desired, force transcode path 05800 * to use SLINEAR between channels, but only if there is 05801 * no direct conversion available. If generic PLC is 05802 * desired, then transcoding via SLINEAR is a requirement 05803 */ 05804 use_slin = ast_format_is_slinear(&best_src_fmt) || ast_format_is_slinear(&best_dst_fmt) ? 1 : 0; 05805 if ((ast_format_cmp(&best_src_fmt, &best_dst_fmt) == AST_FORMAT_CMP_NOT_EQUAL) && 05806 (ast_opt_generic_plc || ast_opt_transcode_via_slin) && 05807 (ast_translate_path_steps(&best_dst_fmt, &best_src_fmt) != 1 || use_slin)) { 05808 05809 int best_sample_rate = ast_format_rate(&best_src_fmt) > ast_format_rate(&best_dst_fmt) ? 05810 ast_format_rate(&best_src_fmt) : ast_format_rate(&best_dst_fmt); 05811 05812 /* pick the best signed linear format based upon what preserves the sample rate the best. */ 05813 ast_format_set(&best_dst_fmt, ast_format_slin_by_rate(best_sample_rate), 0); 05814 } 05815 05816 if (ast_set_read_format(from, &best_dst_fmt) < 0) { 05817 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %s\n", ast_channel_name(from), ast_getformatname(&best_dst_fmt)); 05818 return -1; 05819 } 05820 if (ast_set_write_format(to, &best_dst_fmt) < 0) { 05821 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %s\n", ast_channel_name(to), ast_getformatname(&best_dst_fmt)); 05822 return -1; 05823 } 05824 return 0; 05825 }
| 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 5967 of file channel.c.
References __ast_channel_masquerade().
Referenced by ast_async_goto(), ast_do_pickup(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), masq_park_call(), sip_park(), and skinny_transfer().
05968 { 05969 return __ast_channel_masquerade(original, clone, NULL); 05970 }
| 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 7570 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), errno, LOG_ERROR, ast_channel_tech::queryoption, and ast_channel::tech.
Referenced by ast_channel_get_cc_agent_type(), ast_channel_get_device_name(), ast_channel_get_t38_state(), local_queryoption(), rcvfax_exec(), and sndfax_exec().
07571 { 07572 int res; 07573 07574 ast_channel_lock(chan); 07575 if (!chan->tech->queryoption) { 07576 errno = ENOSYS; 07577 ast_channel_unlock(chan); 07578 return -1; 07579 } 07580 07581 if (block) 07582 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 07583 07584 res = chan->tech->queryoption(chan, option, data, datalen); 07585 ast_channel_unlock(chan); 07586 07587 return res; 07588 }
| void ast_channel_queue_connected_line_update | ( | struct ast_channel * | chan, | |
| const struct ast_party_connected_line * | connected, | |||
| const struct ast_set_party_connected_line * | update | |||
| ) |
Queue a connected line update frame on a channel.
| chan | Asterisk channel to indicate connected line information | |
| connected | Connected line information | |
| update | What connected line information to update. NULL if all. |
Definition at line 8818 of file channel.c.
References ast_connected_line_build_data(), AST_CONTROL_CONNECTED_LINE, and ast_queue_control_data().
Referenced by ast_do_pickup(), handle_request_invite(), handle_request_update(), handle_response_invite(), local_attended_transfer(), masquerade_colp_transfer(), misdn_queue_connected_line_update(), and sip_call().
08819 { 08820 unsigned char data[1024]; /* This should be large enough */ 08821 size_t datalen; 08822 08823 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update); 08824 if (datalen == (size_t) -1) { 08825 return; 08826 } 08827 08828 ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen); 08829 }
| void ast_channel_queue_redirecting_update | ( | struct ast_channel * | chan, | |
| const struct ast_party_redirecting * | redirecting, | |||
| const struct ast_set_party_redirecting * | update | |||
| ) |
Queue a redirecting update frame on a channel.
| chan | Asterisk channel to indicate redirecting id information | |
| redirecting | Redirecting id information | |
| update | What redirecting information to update. NULL if all. |
Definition at line 9325 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().
09326 { 09327 unsigned char data[1024]; /* This should be large enough */ 09328 size_t datalen; 09329 09330 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update); 09331 if (datalen == (size_t) -1) { 09332 return; 09333 } 09334 09335 ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen); 09336 }
| 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 5158 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().
05159 { 05160 switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */ 05161 { 05162 case 0: 05163 return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)"; 05164 case AST_CONTROL_HANGUP: 05165 return "Hangup"; 05166 case AST_CONTROL_RING: 05167 return "Local Ring"; 05168 case AST_CONTROL_RINGING: 05169 return "Remote end Ringing"; 05170 case AST_CONTROL_ANSWER: 05171 return "Remote end has Answered"; 05172 case AST_CONTROL_BUSY: 05173 return "Remote end is Busy"; 05174 case AST_CONTROL_CONGESTION: 05175 return "Congestion (circuits busy)"; 05176 default: 05177 return "Unknown Reason!!"; 05178 } 05179 }
| int ast_channel_redirecting_macro | ( | struct ast_channel * | autoservice_chan, | |
| struct ast_channel * | macro_chan, | |||
| const void * | redirecting_info, | |||
| int | is_caller, | |||
| int | is_frame | |||
| ) |
Run a redirecting interception macro and update a channel's redirecting 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. | |
| redirecting_info | Either an ast_party_redirecting or ast_frame pointer of type AST_CONTROL_REDIRECTING | |
| is_caller | If true, then run REDIRECTING_CALLER_SEND_MACRO, otherwise run REDIRECTING_CALLEE_SEND_MACRO | |
| is_frame | If true, then redirecting_info is an ast_frame pointer, otherwise it is an ast_party_redirecting pointer. |
| 0 | Success | |
| -1 | Either the macro does not exist, or there was an error while attempting to run the macro |
Definition at line 9377 of file channel.c.
References ast_app_run_macro(), ast_channel_lock, ast_channel_unlock, ast_channel_update_redirecting(), ast_party_redirecting_copy(), ast_redirecting_parse_data(), ast_strdupa, ast_strlen_zero(), ast_frame::data, ast_frame::datalen, pbx_builtin_getvar_helper(), ast_frame::ptr, ast_channel::redirecting, and S_OR.
Referenced by ast_bridge_call(), ast_generic_bridge(), call_forward_inherit(), do_forward(), feature_request_and_dial(), handle_frame(), local_bridge_loop(), remote_bridge_loop(), and wait_for_answer().
09378 { 09379 const char *macro; 09380 const char *macro_args; 09381 int retval; 09382 09383 ast_channel_lock(macro_chan); 09384 macro = pbx_builtin_getvar_helper(macro_chan, is_caller 09385 ? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO"); 09386 macro = ast_strdupa(S_OR(macro, "")); 09387 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller 09388 ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS"); 09389 macro_args = ast_strdupa(S_OR(macro_args, "")); 09390 09391 if (ast_strlen_zero(macro)) { 09392 ast_channel_unlock(macro_chan); 09393 return -1; 09394 } 09395 09396 if (is_frame) { 09397 const struct ast_frame *frame = redirecting_info; 09398 09399 ast_redirecting_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->redirecting); 09400 } else { 09401 const struct ast_party_redirecting *redirecting = redirecting_info; 09402 09403 ast_party_redirecting_copy(¯o_chan->redirecting, redirecting); 09404 } 09405 ast_channel_unlock(macro_chan); 09406 09407 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args); 09408 if (!retval) { 09409 ast_channel_lock(macro_chan); 09410 ast_channel_update_redirecting(macro_chan, ¯o_chan->redirecting, NULL); 09411 ast_channel_unlock(macro_chan); 09412 } 09413 09414 return retval; 09415 }
| 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 679 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().
00680 { 00681 struct chanlist *chan; 00682 00683 AST_RWLIST_WRLOCK(&backends); 00684 00685 AST_RWLIST_TRAVERSE(&backends, chan, list) { 00686 if (!strcasecmp(tech->type, chan->tech->type)) { 00687 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type); 00688 AST_RWLIST_UNLOCK(&backends); 00689 return -1; 00690 } 00691 } 00692 00693 if (!(chan = ast_calloc(1, sizeof(*chan)))) { 00694 AST_RWLIST_UNLOCK(&backends); 00695 return -1; 00696 } 00697 chan->tech = tech; 00698 AST_RWLIST_INSERT_HEAD(&backends, chan, list); 00699 00700 ast_debug(1, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description); 00701 00702 ast_verb(2, "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description); 00703 00704 AST_RWLIST_UNLOCK(&backends); 00705 00706 return 0; 00707 }
| 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 1702 of file channel.c.
References ao2_unlink, ast_channel_unref, and channels.
Referenced by agent_cleanup(), ast_do_masquerade(), ast_iax2_new(), ast_request(), bridge_request(), do_notify(), gtalk_newcall(), local_new(), and local_request().
01703 { 01704 /* Safe, even if already unlinked. */ 01705 ao2_unlink(channels, chan); 01706 return ast_channel_unref(chan); 01707 }
| 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 5756 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().
05757 { 05758 if (chan->tech->send_html) 05759 return chan->tech->send_html(chan, subclass, data, datalen); 05760 return -1; 05761 }
| 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 5763 of file channel.c.
References ast_channel_sendhtml(), and AST_HTML_URL.
Referenced by dial_exec_full(), sendurl_exec(), and try_calling().
05764 { 05765 return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1); 05766 }
| void ast_channel_set_caller | ( | struct ast_channel * | chan, | |
| const struct ast_party_caller * | caller, | |||
| const struct ast_set_party_caller * | update | |||
| ) |
Set the caller id information in the Asterisk channel.
| chan | Asterisk channel to set caller id information | |
| caller | Caller id information | |
| update | What caller information to update. NULL if all. |
Definition at line 6851 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_party_caller_set(), and ast_channel::caller.
06852 { 06853 if (&chan->caller == caller) { 06854 /* Don't set to self */ 06855 return; 06856 } 06857 06858 ast_channel_lock(chan); 06859 ast_party_caller_set(&chan->caller, caller, update); 06860 ast_channel_unlock(chan); 06861 }
| void ast_channel_set_caller_event | ( | struct ast_channel * | chan, | |
| const struct ast_party_caller * | caller, | |||
| const struct ast_set_party_caller * | update | |||
| ) |
Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name or number changed.
| chan | Asterisk channel to set caller id information | |
| caller | Caller id information | |
| update | What caller information to update. NULL if all. |
Definition at line 6863 of file channel.c.
References ast_cdr_setcid(), ast_channel_lock, ast_channel_unlock, ast_party_caller_set(), ast_channel::caller, ast_channel::cdr, ast_party_caller::id, ast_party_id::name, ast_party_id::number, report_new_callerid(), S_COR, ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.
Referenced by callerid_write(), dial_exec_full(), do_forward(), misdn_update_caller_id(), and ring_entry().
06864 { 06865 const char *pre_set_number; 06866 const char *pre_set_name; 06867 06868 if (&chan->caller == caller) { 06869 /* Don't set to self */ 06870 return; 06871 } 06872 06873 ast_channel_lock(chan); 06874 pre_set_number = 06875 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL); 06876 pre_set_name = S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL); 06877 ast_party_caller_set(&chan->caller, caller, update); 06878 if (S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL) 06879 != pre_set_number 06880 || S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL) 06881 != pre_set_name) { 06882 /* The caller id name or number changed. */ 06883 report_new_callerid(chan); 06884 } 06885 if (chan->cdr) { 06886 ast_cdr_setcid(chan->cdr, chan); 06887 } 06888 ast_channel_unlock(chan); 06889 }
| void ast_channel_set_connected_line | ( | struct ast_channel * | chan, | |
| const struct ast_party_connected_line * | connected, | |||
| const struct ast_set_party_connected_line * | update | |||
| ) |
Set the connected line information in the Asterisk channel.
| chan | Asterisk channel to set connected line information | |
| connected | Connected line information | |
| update | What connected line information to update. NULL if all. |
Definition at line 8178 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(), connectedline_write(), dial_exec_full(), and feature_request_and_dial().
08179 { 08180 if (&chan->connected == connected) { 08181 /* Don't set to self */ 08182 return; 08183 } 08184 08185 ast_channel_lock(chan); 08186 ast_party_connected_line_set(&chan->connected, connected, update); 08187 ast_channel_unlock(chan); 08188 }
| void ast_channel_set_fd | ( | struct ast_channel * | chan, | |
| int | which, | |||
| int | fd | |||
| ) |
Set the file descriptor on the channel
Definition at line 2403 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(), initialize_udptl(), jb_helper(), jingle_new(), mgcp_new(), misdn_new(), my_swap_subchannels(), nbs_new(), oss_new(), phone_new(), process_sdp(), setformat(), sip_new(), skinny_new(), start_rtp(), and swap_subs().
02404 { 02405 #ifdef HAVE_EPOLL 02406 struct epoll_event ev; 02407 struct ast_epoll_data *aed = NULL; 02408 02409 if (chan->fds[which] > -1) { 02410 epoll_ctl(chan->epfd, EPOLL_CTL_DEL, chan->fds[which], &ev); 02411 aed = chan->epfd_data[which]; 02412 } 02413 02414 /* If this new fd is valid, add it to the epoll */ 02415 if (fd > -1) { 02416 if (!aed && (!(aed = ast_calloc(1, sizeof(*aed))))) 02417 return; 02418 02419 chan->epfd_data[which] = aed; 02420 aed->chan = chan; 02421 aed->which = which; 02422 02423 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 02424 ev.data.ptr = aed; 02425 epoll_ctl(chan->epfd, EPOLL_CTL_ADD, fd, &ev); 02426 } else if (aed) { 02427 /* We don't have to keep around this epoll data structure now */ 02428 free(aed); 02429 chan->epfd_data[which] = NULL; 02430 } 02431 #endif 02432 chan->fds[which] = fd; 02433 return; 02434 }
| 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 6240 of file channel.c.
References ast_channel::_bridge, ast_bridged_channel(), ast_channel_change_linkedid(), ast_channel_linkedid(), ast_channel_uniqueid(), ast_strdupa, and oldest_linkedid().
Referenced by ast_bridge_call(), and ast_do_masquerade().
06241 { 06242 const char* linkedid=NULL; 06243 struct ast_channel *bridged; 06244 06245 linkedid = oldest_linkedid(ast_channel_linkedid(chan), ast_channel_linkedid(peer)); 06246 linkedid = oldest_linkedid(linkedid, ast_channel_uniqueid(chan)); 06247 linkedid = oldest_linkedid(linkedid, ast_channel_uniqueid(peer)); 06248 if (chan->_bridge) { 06249 bridged = ast_bridged_channel(chan); 06250 if (bridged != peer) { 06251 linkedid = oldest_linkedid(linkedid, ast_channel_linkedid(bridged)); 06252 linkedid = oldest_linkedid(linkedid, ast_channel_uniqueid(bridged)); 06253 } 06254 } 06255 if (peer->_bridge) { 06256 bridged = ast_bridged_channel(peer); 06257 if (bridged != chan) { 06258 linkedid = oldest_linkedid(linkedid, ast_channel_linkedid(bridged)); 06259 linkedid = oldest_linkedid(linkedid, ast_channel_uniqueid(bridged)); 06260 } 06261 } 06262 06263 /* just in case setting a stringfield to itself causes problems */ 06264 linkedid = ast_strdupa(linkedid); 06265 06266 ast_channel_change_linkedid(chan, linkedid); 06267 ast_channel_change_linkedid(peer, linkedid); 06268 if (chan->_bridge) { 06269 bridged = ast_bridged_channel(chan); 06270 if (bridged != peer) { 06271 ast_channel_change_linkedid(bridged, linkedid); 06272 } 06273 } 06274 if (peer->_bridge) { 06275 bridged = ast_bridged_channel(peer); 06276 if (bridged != chan) { 06277 ast_channel_change_linkedid(bridged, linkedid); 06278 } 06279 } 06280 }
| void ast_channel_set_redirecting | ( | struct ast_channel * | chan, | |
| const struct ast_party_redirecting * | redirecting, | |||
| const struct ast_set_party_redirecting * | update | |||
| ) |
Set the redirecting id information in the Asterisk channel.
| chan | Asterisk channel to set redirecting id information | |
| redirecting | Redirecting id information | |
| update | What redirecting information to update. NULL if all. |
Definition at line 8831 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_party_redirecting_set(), and ast_channel::redirecting.
Referenced by ast_indicate_data(), do_forward(), handle_request_invite(), handle_response(), misdn_copy_redirecting_to_ast(), redirecting_write(), and wait_for_answer().
08832 { 08833 if (&chan->redirecting == redirecting) { 08834 /* Don't set to self */ 08835 return; 08836 } 08837 08838 ast_channel_lock(chan); 08839 ast_party_redirecting_set(&chan->redirecting, redirecting, update); 08840 ast_channel_unlock(chan); 08841 }
| 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 7550 of file channel.c.
References ast_channel_lock, ast_channel_unlock, 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(), func_channel_write_real(), handle_tddmode(), play_record_review(), rcvfax_exec(), reset_volumes(), rpt(), rpt_exec(), set_format(), set_listen_volume(), set_security_requirements(), set_talk_volume(), sndfax_exec(), try_calling(), and vm_forwardoptions().
07551 { 07552 int res; 07553 07554 ast_channel_lock(chan); 07555 if (!chan->tech->setoption) { 07556 errno = ENOSYS; 07557 ast_channel_unlock(chan); 07558 return -1; 07559 } 07560 07561 if (block) 07562 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 07563 07564 res = chan->tech->setoption(chan, option, data, datalen); 07565 ast_channel_unlock(chan); 07566 07567 return res; 07568 }
| 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 650 of file channel.c.
References ast_channel_setwhentohangup_tv().
00651 { 00652 struct timeval when = { offset, }; 00653 ast_channel_setwhentohangup_tv(chan, when); 00654 }
| 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 643 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().
00644 { 00645 chan->whentohangup = ast_tvzero(offset) ? offset : ast_tvadd(offset, ast_tvnow()); 00646 ast_queue_frame(chan, &ast_null_frame); 00647 return; 00648 }
| static int ast_channel_softhangup_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 606 of file channel.c.
References ast_softhangup(), and AST_SOFTHANGUP_SHUTDOWN.
Referenced by ast_begin_shutdown().
00607 { 00608 struct ast_channel *chan = obj; 00609 00610 ast_softhangup(chan, AST_SOFTHANGUP_SHUTDOWN); 00611 00612 return 0; 00613 }
| 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 8052 of file channel.c.
References ast_activate_generator(), ast_calloc, ast_channel_name(), ast_debug, ast_format_copy(), AST_FORMAT_SLINEAR, ast_free, ast_log(), ast_set_write_format_by_id(), LOG_ERROR, ast_silence_generator::old_write_format, and ast_channel::writeformat.
Referenced by __ast_play_and_record(), ast_bridge_call(), ast_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), record_exec(), TransferCallStep1(), waitfor_exec(), and waitforring_exec().
08053 { 08054 struct ast_silence_generator *state; 08055 08056 if (!(state = ast_calloc(1, sizeof(*state)))) { 08057 return NULL; 08058 } 08059 08060 ast_format_copy(&state->old_write_format, &chan->writeformat); 08061 08062 if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) { 08063 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n"); 08064 ast_free(state); 08065 return NULL; 08066 } 08067 08068 ast_activate_generator(chan, &silence_generator, state); 08069 08070 ast_debug(1, "Started silence generator on '%s'\n", ast_channel_name(chan)); 08071 08072 return state; 08073 }
| 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 8075 of file channel.c.
References ast_channel_name(), ast_deactivate_generator(), ast_debug, ast_free, ast_log(), ast_set_write_format(), LOG_ERROR, and ast_silence_generator::old_write_format.
Referenced by __ast_play_and_record(), ast_bridge_call(), ast_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), HandleCallOutgoing(), key_dial_page(), record_exec(), unistim_hangup(), waitfor_exec(), and waitforring_exec().
08076 { 08077 if (!state) 08078 return; 08079 08080 ast_deactivate_generator(chan); 08081 08082 ast_debug(1, "Stopped silence generator on '%s'\n", ast_channel_name(chan)); 08083 08084 if (ast_set_write_format(chan, &state->old_write_format) < 0) 08085 ast_log(LOG_ERROR, "Could not return write format to its original state\n"); 08086 08087 ast_free(state); 08088 }
| int ast_channel_supports_html | ( | struct ast_channel * | channel | ) |
Checks for HTML support on a channel.
Definition at line 5751 of file channel.c.
References ast_channel_tech::send_html, and ast_channel::tech.
Referenced by dial_exec_full(), sendurl_exec(), and try_calling().
| int ast_channel_transfer_masquerade | ( | struct ast_channel * | target_chan, | |
| const struct ast_party_connected_line * | target_id, | |||
| int | target_held, | |||
| struct ast_channel * | transferee_chan, | |||
| const struct ast_party_connected_line * | transferee_id, | |||
| int | transferee_held | |||
| ) |
Setup a masquerade to transfer a call.
| target_chan | Target of the call transfer. (Masquerade original channel) | |
| target_id | New connected line information for the target channel. | |
| target_held | TRUE if the target call is on hold. | |
| transferee_chan | Transferee of the call transfer. (Masquerade clone channel) | |
| transferee_id | New connected line information for the transferee channel. | |
| transferee_held | TRUE if the transferee call is on hold. |
Party B transfers A to C.
Party A is connected to bridged channel B1. Party B is connected to channels C1 and C2. Party C is connected to bridged channel B2.
Party B -- C1 == B1 -- Party A __/ / Party B -- C2 == B2 -- Party C
Bridged channel B1 is masqueraded into channel C2. Where B1 is the masquerade clone channel and C2 is the masquerade original channel.
| 0 | on success. | |
| -1 | on error. |
Definition at line 6041 of file channel.c.
References __ast_channel_masquerade(), ast_calloc, ast_datastore_alloc, ast_datastore_free(), ast_datastore::data, party_connected_line_copy_transfer(), xfer_masquerade_ds::target_held, xfer_masquerade_ds::target_id, xfer_masquerade_ds::transferee_held, and xfer_masquerade_ds::transferee_id.
Referenced by analog_attempt_transfer(), and misdn_attempt_transfer().
06048 { 06049 struct ast_datastore *xfer_ds; 06050 struct xfer_masquerade_ds *xfer_colp; 06051 int res; 06052 06053 xfer_ds = ast_datastore_alloc(&xfer_ds_info, NULL); 06054 if (!xfer_ds) { 06055 return -1; 06056 } 06057 06058 xfer_colp = ast_calloc(1, sizeof(*xfer_colp)); 06059 if (!xfer_colp) { 06060 ast_datastore_free(xfer_ds); 06061 return -1; 06062 } 06063 party_connected_line_copy_transfer(&xfer_colp->target_id, target_id); 06064 xfer_colp->target_held = target_held; 06065 party_connected_line_copy_transfer(&xfer_colp->transferee_id, transferee_id); 06066 xfer_colp->transferee_held = transferee_held; 06067 xfer_ds->data = xfer_colp; 06068 06069 res = __ast_channel_masquerade(target_chan, transferee_chan, xfer_ds); 06070 if (res) { 06071 ast_datastore_free(xfer_ds); 06072 } 06073 return res; 06074 }
| 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 1408 of file channel.c.
References ast_clear_flag, and AST_FLAG_DEFER_DTMF.
Referenced by __adsi_transmit_messages(), find_cache(), and rpt_call().
01409 { 01410 if (chan) 01411 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF); 01412 }
| void ast_channel_unlink | ( | struct ast_channel * | chan | ) |
Remove a channel from the global channels container.
| chan | channel to remove |
Definition at line 9552 of file channel.c.
References ao2_unlink, and channels.
Referenced by create_msg_q_chan().
09553 { 09554 ao2_unlink(channels, chan); 09555 }
| void ast_channel_unregister | ( | const struct ast_channel_tech * | tech | ) |
Unregister channel driver.
Unregister a channel technology.
Definition at line 710 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().
00711 { 00712 struct chanlist *chan; 00713 00714 ast_debug(1, "Unregistering channel type '%s'\n", tech->type); 00715 00716 AST_RWLIST_WRLOCK(&backends); 00717 00718 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) { 00719 if (chan->tech == tech) { 00720 AST_LIST_REMOVE_CURRENT(list); 00721 ast_free(chan); 00722 ast_verb(2, "Unregistered channel type '%s'\n", tech->type); 00723 break; 00724 } 00725 } 00726 AST_LIST_TRAVERSE_SAFE_END; 00727 00728 AST_RWLIST_UNLOCK(&backends); 00729 }
| void ast_channel_update_connected_line | ( | struct ast_channel * | chan, | |
| const struct ast_party_connected_line * | connected, | |||
| const struct ast_set_party_connected_line * | update | |||
| ) |
Indicate that the connected line information has changed.
| chan | Asterisk channel to indicate connected line information | |
| connected | Connected line information | |
| update | What connected line information to update. NULL if all. |
Definition at line 8805 of file channel.c.
References ast_connected_line_build_data(), AST_CONTROL_CONNECTED_LINE, and ast_indicate_data().
Referenced by app_exec(), ast_channel_connected_line_macro(), ast_do_pickup(), atxfer_fail_cleanup(), builtin_atxfer(), connectedline_write(), parked_call_exec(), and wait_for_answer().
08806 { 08807 unsigned char data[1024]; /* This should be large enough */ 08808 size_t datalen; 08809 08810 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update); 08811 if (datalen == (size_t) -1) { 08812 return; 08813 } 08814 08815 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen); 08816 }
| void ast_channel_update_redirecting | ( | struct ast_channel * | chan, | |
| const struct ast_party_redirecting * | redirecting, | |||
| const struct ast_set_party_redirecting * | update | |||
| ) |
Indicate that the redirecting id has changed.
| chan | Asterisk channel to indicate redirecting id information | |
| redirecting | Redirecting id information | |
| update | What redirecting information to update. NULL if all. |
Definition at line 9312 of file channel.c.
References AST_CONTROL_REDIRECTING, ast_indicate_data(), and ast_redirecting_build_data().
Referenced by ast_channel_redirecting_macro(), call_forward_inherit(), do_forward(), redirecting_write(), and wait_for_answer().
09313 { 09314 unsigned char data[1024]; /* This should be large enough */ 09315 size_t datalen; 09316 09317 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update); 09318 if (datalen == (size_t) -1) { 09319 return; 09320 } 09321 09322 ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen); 09323 }
| void ast_channels_init | ( | void | ) |
Provided by channel.c
Definition at line 7966 of file channel.c.
References ao2_container_alloc, ARRAY_LEN, ast_channel_cmp_cb(), ast_channel_hash_cb(), ast_cli_register_multiple(), ast_data_register_multiple_core, ast_plc_reload(), channels, cli_channel, and NUM_CHANNEL_BUCKETS.
Referenced by main().
07967 { 07968 channels = ao2_container_alloc(NUM_CHANNEL_BUCKETS, 07969 ast_channel_hash_cb, ast_channel_cmp_cb); 07970 07971 ast_cli_register_multiple(cli_channel, ARRAY_LEN(cli_channel)); 07972 07973 ast_data_register_multiple_core(channel_providers, ARRAY_LEN(channel_providers)); 07974 07975 ast_plc_reload(); 07976 }
| struct ast_variable* ast_channeltype_list | ( | void | ) | [read] |
return an ast_variable list of channeltypes
Definition at line 202 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().
00203 { 00204 struct chanlist *cl; 00205 struct ast_variable *var = NULL, *prev = NULL; 00206 00207 AST_RWLIST_RDLOCK(&backends); 00208 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00209 if (prev) { 00210 if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description, ""))) 00211 prev = prev->next; 00212 } else { 00213 var = ast_variable_new(cl->tech->type, cl->tech->description, ""); 00214 prev = var; 00215 } 00216 } 00217 AST_RWLIST_UNLOCK(&backends); 00218 00219 return var; 00220 }
| 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 584 of file channel.c.
References ast_channel::_softhangup, ast_debug, 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(), call_forward_inherit(), 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(), func_channel_read(), handle_sendimage(), iax2_bridge(), launch_asyncagi(), local_bridge_loop(), local_fixup(), lua_check_hangup(), ospfinished_exec(), pbx_builtin_incomplete(), pbx_builtin_waitexten(), pbx_exec(), read_exec(), readexten_exec(), remote_bridge_loop(), rpt(), rpt_exec(), run_agi(), run_ras(), try_calling(), and wait_for_answer().
00585 { 00586 if (chan->_softhangup) /* yes if soft hangup flag set */ 00587 return 1; 00588 if (ast_tvzero(chan->whentohangup)) /* no if no hangup scheduled */ 00589 return 0; 00590 if (ast_tvdiff_ms(chan->whentohangup, ast_tvnow()) > 0) /* no if hangup time has not come yet. */ 00591 return 0; 00592 ast_debug(4, "Hangup time has come: %" PRIi64 "\n", ast_tvdiff_ms(chan->whentohangup, ast_tvnow())); 00593 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */ 00594 return 1; 00595 }
| int ast_check_hangup_locked | ( | struct ast_channel * | chan | ) |
Definition at line 597 of file channel.c.
References ast_channel_lock, ast_channel_unlock, and ast_check_hangup().
Referenced by action_redirect(), ast_channel_bridge(), and bridge_channel_feature().
00598 { 00599 int res; 00600 ast_channel_lock(chan); 00601 res = ast_check_hangup(chan); 00602 ast_channel_unlock(chan); 00603 return res; 00604 }
| int ast_connected_line_build_data | ( | unsigned char * | data, | |
| size_t | datalen, | |||
| const struct ast_party_connected_line * | connected, | |||
| const struct ast_set_party_connected_line * | update | |||
| ) |
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 | |
| update | What connected line information to build. NULL if all. |
| -1 | if error | |
| Amount | of data buffer used |
Definition at line 8545 of file channel.c.
References AST_CONNECTED_LINE_ID_PRESENTATION, AST_CONNECTED_LINE_NAME, AST_CONNECTED_LINE_NAME_CHAR_SET, AST_CONNECTED_LINE_NAME_PRESENTATION, AST_CONNECTED_LINE_NAME_VALID, AST_CONNECTED_LINE_NUMBER, AST_CONNECTED_LINE_NUMBER_PLAN, AST_CONNECTED_LINE_NUMBER_PRESENTATION, AST_CONNECTED_LINE_NUMBER_VALID, 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_CONNECTED_LINE_TAG, AST_CONNECTED_LINE_VERSION, ast_log(), ast_set_party_connected_line::id, ast_party_connected_line::id, LOG_WARNING, ast_party_id_ies::name, party_id_build_data(), ast_party_connected_line::source, ast_party_name_ies::str, and value.
Referenced by ast_channel_queue_connected_line_update(), ast_channel_update_connected_line(), local_attended_transfer(), local_indicate(), and masquerade_colp_transfer().
08546 { 08547 int32_t value; 08548 size_t pos = 0; 08549 int res; 08550 08551 static const struct ast_party_id_ies ies = { 08552 .name.str = AST_CONNECTED_LINE_NAME, 08553 .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET, 08554 .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION, 08555 .name.valid = AST_CONNECTED_LINE_NAME_VALID, 08556 08557 .number.str = AST_CONNECTED_LINE_NUMBER, 08558 .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN, 08559 .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION, 08560 .number.valid = AST_CONNECTED_LINE_NUMBER_VALID, 08561 08562 .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS, 08563 .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE, 08564 .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, 08565 .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID, 08566 08567 .tag = AST_CONNECTED_LINE_TAG, 08568 .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION, 08569 }; 08570 08571 /* 08572 * The size of integer values must be fixed in case the frame is 08573 * shipped to another machine. 08574 */ 08575 08576 /* Connected line frame version */ 08577 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08578 ast_log(LOG_WARNING, "No space left for connected line frame version\n"); 08579 return -1; 08580 } 08581 data[pos++] = AST_CONNECTED_LINE_VERSION; 08582 data[pos++] = 1; 08583 data[pos++] = 2;/* Version 1 did not have a version ie */ 08584 08585 res = party_id_build_data(data + pos, datalen - pos, &connected->id, 08586 "connected line", &ies, update ? &update->id : NULL); 08587 if (res < 0) { 08588 return -1; 08589 } 08590 pos += res; 08591 08592 /* Connected line source */ 08593 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 08594 ast_log(LOG_WARNING, "No space left for connected line source\n"); 08595 return -1; 08596 } 08597 data[pos++] = AST_CONNECTED_LINE_SOURCE; 08598 data[pos++] = sizeof(value); 08599 value = htonl(connected->source); 08600 memcpy(data + pos, &value, sizeof(value)); 08601 pos += sizeof(value); 08602 08603 return pos; 08604 }
| void ast_connected_line_copy_from_caller | ( | struct ast_party_connected_line * | dest, | |
| const struct ast_party_caller * | src | |||
| ) |
Copy the caller information to the connected line information.
| dest | Destination connected line information | |
| src | Source caller information |
Definition at line 8163 of file channel.c.
References ast_party_caller::ani, ast_party_connected_line::ani, ast_party_caller::ani2, ast_party_connected_line::ani2, ast_party_id_copy(), ast_party_caller::id, and ast_party_connected_line::id.
Referenced by app_exec(), ast_do_pickup(), begin_dial_channel(), builtin_atxfer(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), local_call(), parked_call_exec(), ring_entry(), and wait_for_answer().
08164 { 08165 ast_party_id_copy(&dest->id, &src->id); 08166 ast_party_id_copy(&dest->ani, &src->ani); 08167 dest->ani2 = src->ani2; 08168 }
| void ast_connected_line_copy_to_caller | ( | struct ast_party_caller * | 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 8170 of file channel.c.
References ast_party_connected_line::ani, ast_party_caller::ani, ast_party_connected_line::ani2, ast_party_caller::ani2, ast_party_id_copy(), ast_party_connected_line::id, and ast_party_caller::id.
Referenced by local_call(), and local_indicate().
08171 { 08172 ast_party_id_copy(&dest->id, &src->id); 08173 ast_party_id_copy(&dest->ani, &src->ani); 08174 08175 dest->ani2 = src->ani2; 08176 }
| 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 8606 of file channel.c.
References AST_CONNECTED_LINE_ID_PRESENTATION, AST_CONNECTED_LINE_NAME, AST_CONNECTED_LINE_NAME_CHAR_SET, AST_CONNECTED_LINE_NAME_PRESENTATION, AST_CONNECTED_LINE_NAME_VALID, AST_CONNECTED_LINE_NUMBER, AST_CONNECTED_LINE_NUMBER_PLAN, AST_CONNECTED_LINE_NUMBER_PRESENTATION, AST_CONNECTED_LINE_NUMBER_VALID, 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_CONNECTED_LINE_TAG, AST_CONNECTED_LINE_VERSION, ast_debug, ast_free, ast_log(), ast_malloc, AST_PARTY_CHAR_SET_ISO8859_1, ast_party_name::char_set, ast_party_id_ies::combined_presentation, ast_party_connected_line::id, LOG_WARNING, ast_party_id::name, ast_party_id::number, ast_party_subaddress::odd_even_indicator, ast_party_number::plan, ast_party_number::presentation, ast_party_name::presentation, ast_party_connected_line::source, ast_party_subaddress::str, ast_party_number::str, ast_party_name::str, ast_party_id::subaddress, ast_party_id::tag, ast_party_subaddress::type, ast_party_subaddress::valid, ast_party_number::valid, ast_party_name::valid, and value.
Referenced by __ast_read(), ast_channel_connected_line_macro(), ast_indicate_data(), feature_request_and_dial(), socket_process(), wait_for_answer(), and wait_for_winner().
08607 { 08608 size_t pos; 08609 unsigned char ie_len; 08610 unsigned char ie_id; 08611 int32_t value; 08612 int frame_version = 1; 08613 int combined_presentation = 0; 08614 int got_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 08615 08616 for (pos = 0; pos < datalen; pos += ie_len) { 08617 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) { 08618 ast_log(LOG_WARNING, "Invalid connected line update\n"); 08619 return -1; 08620 } 08621 ie_id = data[pos++]; 08622 ie_len = data[pos++]; 08623 if (datalen < pos + ie_len) { 08624 ast_log(LOG_WARNING, "Invalid connected line update\n"); 08625 return -1; 08626 } 08627 08628 switch (ie_id) { 08629 /* Connected line party frame version */ 08630 case AST_CONNECTED_LINE_VERSION: 08631 if (ie_len != 1) { 08632 ast_log(LOG_WARNING, "Invalid connected line frame version (%u)\n", 08633 (unsigned) ie_len); 08634 break; 08635 } 08636 frame_version = data[pos]; 08637 break; 08638 /* Connected line party id name */ 08639 case AST_CONNECTED_LINE_NAME: 08640 ast_free(connected->id.name.str); 08641 connected->id.name.str = ast_malloc(ie_len + 1); 08642 if (connected->id.name.str) { 08643 memcpy(connected->id.name.str, data + pos, ie_len); 08644 connected->id.name.str[ie_len] = 0; 08645 } 08646 break; 08647 case AST_CONNECTED_LINE_NAME_CHAR_SET: 08648 if (ie_len != 1) { 08649 ast_log(LOG_WARNING, "Invalid connected line name char set (%u)\n", 08650 (unsigned) ie_len); 08651 break; 08652 } 08653 connected->id.name.char_set = data[pos]; 08654 break; 08655 case AST_CONNECTED_LINE_NAME_PRESENTATION: 08656 if (ie_len != 1) { 08657 ast_log(LOG_WARNING, "Invalid connected line name presentation (%u)\n", 08658 (unsigned) ie_len); 08659 break; 08660 } 08661 connected->id.name.presentation = data[pos]; 08662 break; 08663 case AST_CONNECTED_LINE_NAME_VALID: 08664 if (ie_len != 1) { 08665 ast_log(LOG_WARNING, "Invalid connected line name valid (%u)\n", 08666 (unsigned) ie_len); 08667 break; 08668 } 08669 connected->id.name.valid = data[pos]; 08670 break; 08671 /* Connected line party id number */ 08672 case AST_CONNECTED_LINE_NUMBER: 08673 ast_free(connected->id.number.str); 08674 connected->id.number.str = ast_malloc(ie_len + 1); 08675 if (connected->id.number.str) { 08676 memcpy(connected->id.number.str, data + pos, ie_len); 08677 connected->id.number.str[ie_len] = 0; 08678 } 08679 break; 08680 case AST_CONNECTED_LINE_NUMBER_PLAN: 08681 if (ie_len != 1) { 08682 ast_log(LOG_WARNING, "Invalid connected line numbering plan (%u)\n", 08683 (unsigned) ie_len); 08684 break; 08685 } 08686 connected->id.number.plan = data[pos]; 08687 break; 08688 case AST_CONNECTED_LINE_NUMBER_PRESENTATION: 08689 if (ie_len != 1) { 08690 ast_log(LOG_WARNING, "Invalid connected line number presentation (%u)\n", 08691 (unsigned) ie_len); 08692 break; 08693 } 08694 connected->id.number.presentation = data[pos]; 08695 break; 08696 case AST_CONNECTED_LINE_NUMBER_VALID: 08697 if (ie_len != 1) { 08698 ast_log(LOG_WARNING, "Invalid connected line number valid (%u)\n", 08699 (unsigned) ie_len); 08700 break; 08701 } 08702 connected->id.number.valid = data[pos]; 08703 break; 08704 /* Connected line party id combined presentation */ 08705 case AST_CONNECTED_LINE_ID_PRESENTATION: 08706 if (ie_len != 1) { 08707 ast_log(LOG_WARNING, "Invalid connected line combined presentation (%u)\n", 08708 (unsigned) ie_len); 08709 break; 08710 } 08711 combined_presentation = data[pos]; 08712 got_combined_presentation = 1; 08713 break; 08714 /* Connected line party id subaddress */ 08715 case AST_CONNECTED_LINE_SUBADDRESS: 08716 ast_free(connected->id.subaddress.str); 08717 connected->id.subaddress.str = ast_malloc(ie_len + 1); 08718 if (connected->id.subaddress.str) { 08719 memcpy(connected->id.subaddress.str, data + pos, ie_len); 08720 connected->id.subaddress.str[ie_len] = 0; 08721 } 08722 break; 08723 case AST_CONNECTED_LINE_SUBADDRESS_TYPE: 08724 if (ie_len != 1) { 08725 ast_log(LOG_WARNING, "Invalid connected line type of subaddress (%u)\n", 08726 (unsigned) ie_len); 08727 break; 08728 } 08729 connected->id.subaddress.type = data[pos]; 08730 break; 08731 case AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN: 08732 if (ie_len != 1) { 08733 ast_log(LOG_WARNING, 08734 "Invalid connected line subaddress odd-even indicator (%u)\n", 08735 (unsigned) ie_len); 08736 break; 08737 } 08738 connected->id.subaddress.odd_even_indicator = data[pos]; 08739 break; 08740 case AST_CONNECTED_LINE_SUBADDRESS_VALID: 08741 if (ie_len != 1) { 08742 ast_log(LOG_WARNING, "Invalid connected line subaddress valid (%u)\n", 08743 (unsigned) ie_len); 08744 break; 08745 } 08746 connected->id.subaddress.valid = data[pos]; 08747 break; 08748 /* Connected line party tag */ 08749 case AST_CONNECTED_LINE_TAG: 08750 ast_free(connected->id.tag); 08751 connected->id.tag = ast_malloc(ie_len + 1); 08752 if (connected->id.tag) { 08753 memcpy(connected->id.tag, data + pos, ie_len); 08754 connected->id.tag[ie_len] = 0; 08755 } 08756 break; 08757 /* Connected line party source */ 08758 case AST_CONNECTED_LINE_SOURCE: 08759 if (ie_len != sizeof(value)) { 08760 ast_log(LOG_WARNING, "Invalid connected line source (%u)\n", 08761 (unsigned) ie_len); 08762 break; 08763 } 08764 memcpy(&value, data + pos, sizeof(value)); 08765 connected->source = ntohl(value); 08766 break; 08767 /* Connected line party unknown element */ 08768 default: 08769 ast_debug(1, "Unknown connected line element: %u (%u)\n", 08770 (unsigned) ie_id, (unsigned) ie_len); 08771 break; 08772 } 08773 } 08774 08775 switch (frame_version) { 08776 case 1: 08777 /* 08778 * The other end is an earlier version that we need to adjust 08779 * for compatibility. 08780 */ 08781 connected->id.name.valid = 1; 08782 connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 08783 connected->id.number.valid = 1; 08784 if (got_combined_presentation) { 08785 connected->id.name.presentation = combined_presentation; 08786 connected->id.number.presentation = combined_presentation; 08787 } 08788 break; 08789 case 2: 08790 /* The other end is at the same level as we are. */ 08791 break; 08792 default: 08793 /* 08794 * The other end is newer than we are. 08795 * We need to assume that they are compatible with us. 08796 */ 08797 ast_debug(1, "Connected line frame has newer version: %u\n", 08798 (unsigned) frame_version); 08799 break; 08800 } 08801 08802 return 0; 08803 }
| void ast_deactivate_generator | ( | struct ast_channel * | chan | ) |
Deactivate an active generator
Definition at line 2873 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().
02874 { 02875 ast_channel_lock(chan); 02876 if (chan->generatordata) { 02877 if (chan->generator && chan->generator->release) 02878 chan->generator->release(chan, chan->generatordata); 02879 chan->generatordata = NULL; 02880 chan->generator = NULL; 02881 ast_channel_set_fd(chan, AST_GENERATOR_FD, -1); 02882 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 02883 ast_settimeout(chan, 0, NULL, NULL); 02884 } 02885 ast_channel_unlock(chan); 02886 }
| int ast_do_masquerade | ( | struct ast_channel * | original | ) |
Masquerade a channel.
Start masquerading a channel.
Definition at line 6399 of file channel.c.
References __ast_change_name_nolink(), ast_channel::_bridge, ast_channel::_softhangup, ast_channel::_state, ast_channel::adsicpe, ast_channel::alertpipe, ao2_link, ao2_lock, ao2_unlink, ao2_unlock, ast_app_group_update(), ast_autochan_new_channel(), ast_bridged_channel(), ast_cause2str(), AST_CEL_BRIDGE_UPDATE, ast_cel_report_event(), ast_channel_accountcode(), ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_channel_language(), ast_channel_lock, ast_channel_musicclass(), ast_channel_name(), AST_CHANNEL_NAME, ast_channel_release(), ast_channel_set_fd(), ast_channel_set_linkgroup(), ast_channel_trylock, ast_channel_uniqueid(), ast_channel_unlock, AST_CONTROL_SRCCHANGE, AST_CONTROL_UNHOLD, ast_copy_string(), ast_datastore_free(), ast_debug, AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_format_cap_copy(), ast_format_copy(), AST_GENERATOR_FD, ast_getformatname(), ast_indicate(), ast_kill_tech, 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_manager_event, ast_manager_event_multichan, 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_test_flag, AST_TIMING_FD, ast_channel::blocker, ast_channel::caller, ast_channel::cdr, ast_datastore_info::chan_fixup, CHANNEL_DEADLOCK_AVOIDANCE, channels, clone_variables(), ast_channel::connected, ast_datastore::data, ast_channel::datastores, ast_channel::dialed, 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, LOG_WARNING, ast_channel::masq, ast_channel::masqr, masquerade_colp_transfer(), ast_channel::monitor, 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, xfer_masquerade_ds::transferee_held, ast_channel_tech::type, ast_channel::visible_indication, and ast_channel::writeformat.
Referenced by __ast_read(), ast_async_goto(), ast_do_pickup(), ast_hangup(), ast_waitfor_nandfds(), ast_write(), builtin_atxfer(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), local_attended_transfer(), masq_park_call(), and sip_park().
06400 { 06401 int x, i; 06402 int res=0; 06403 int origstate; 06404 int visible_indication; 06405 struct ast_frame *current; 06406 const struct ast_channel_tech *t; 06407 void *t_pvt; 06408 union { 06409 struct ast_party_dialed dialed; 06410 struct ast_party_caller caller; 06411 struct ast_party_connected_line connected; 06412 struct ast_party_redirecting redirecting; 06413 } exchange; 06414 struct ast_channel *clonechan, *chans[2]; 06415 struct ast_channel *bridged; 06416 struct ast_cdr *cdr; 06417 struct ast_datastore *xfer_ds; 06418 struct xfer_masquerade_ds *xfer_colp; 06419 struct ast_format rformat; 06420 struct ast_format wformat; 06421 struct ast_format tmp_format; 06422 char newn[AST_CHANNEL_NAME]; 06423 char orig[AST_CHANNEL_NAME]; 06424 char masqn[AST_CHANNEL_NAME]; 06425 char zombn[AST_CHANNEL_NAME]; 06426 06427 ast_format_copy(&rformat, &original->readformat); 06428 ast_format_copy(&wformat, &original->writeformat); 06429 06430 /* XXX This operation is a bit odd. We're essentially putting the guts of 06431 * the clone channel into the original channel. Start by killing off the 06432 * original channel's backend. While the features are nice, which is the 06433 * reason we're keeping it, it's still awesomely weird. XXX */ 06434 06435 /* The reasoning for the channels ao2_container lock here is complex. 06436 * 06437 * In order to check for a race condition, the original channel must 06438 * be locked. If it is determined that the masquerade should proceed 06439 * the original channel can absolutely not be unlocked until the end 06440 * of the function. Since after determining the masquerade should 06441 * continue requires the channels to be unlinked from the ao2_container, 06442 * the container lock must be held first to achieve proper locking order. 06443 */ 06444 ao2_lock(channels); 06445 06446 /* lock the original channel to determine if the masquerade is required or not */ 06447 ast_channel_lock(original); 06448 06449 /* 06450 * This checks to see if the masquerade has already happened or 06451 * not. There is a race condition that exists for this 06452 * function. Since all pvt and channel locks must be let go 06453 * before calling do_masquerade, it is possible that it could be 06454 * called multiple times for the same channel. This check 06455 * verifies whether or not the masquerade has already been 06456 * completed by another thread. 06457 */ 06458 while ((clonechan = original->masq) && ast_channel_trylock(clonechan)) { 06459 /* 06460 * A masq is needed but we could not get the clonechan lock 06461 * immediately. Since this function already holds the global 06462 * container lock, unlocking original for deadlock avoidance 06463 * will not result in any sort of masquerade race condition. If 06464 * masq is called by a different thread while this happens, it 06465 * will be stuck waiting until we unlock the container. 06466 */ 06467 CHANNEL_DEADLOCK_AVOIDANCE(original); 06468 } 06469 06470 /* 06471 * A final masq check must be done after deadlock avoidance for 06472 * clonechan above or we could get a double masq. This is 06473 * posible with ast_hangup at least. 06474 */ 06475 if (!clonechan) { 06476 /* masq already completed by another thread, or never needed to be done to begin with */ 06477 ast_channel_unlock(original); 06478 ao2_unlock(channels); 06479 return 0; 06480 } 06481 06482 /* Get any transfer masquerade connected line exchange data. */ 06483 xfer_ds = ast_channel_datastore_find(original, &xfer_ds_info, NULL); 06484 if (xfer_ds) { 06485 ast_channel_datastore_remove(original, xfer_ds); 06486 xfer_colp = xfer_ds->data; 06487 } else { 06488 xfer_colp = NULL; 06489 } 06490 06491 /* 06492 * Release any hold on the transferee channel before proceeding 06493 * with the masquerade. 06494 */ 06495 if (xfer_colp && xfer_colp->transferee_held) { 06496 ast_indicate(clonechan, AST_CONTROL_UNHOLD); 06497 } 06498 06499 /* clear the masquerade channels */ 06500 original->masq = NULL; 06501 clonechan->masqr = NULL; 06502 06503 /* unlink from channels container as name (which is the hash value) will change */ 06504 ao2_unlink(channels, original); 06505 ao2_unlink(channels, clonechan); 06506 06507 ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", 06508 ast_channel_name(clonechan), clonechan->_state, ast_channel_name(original), original->_state); 06509 06510 /* 06511 * Stop any visible indiction on the original channel so we can 06512 * transfer it to the clonechan taking the original's place. 06513 */ 06514 visible_indication = original->visible_indication; 06515 ast_indicate(original, -1); 06516 06517 chans[0] = clonechan; 06518 chans[1] = original; 06519 ast_manager_event_multichan(EVENT_FLAG_CALL, "Masquerade", 2, chans, 06520 "Clone: %s\r\n" 06521 "CloneState: %s\r\n" 06522 "Original: %s\r\n" 06523 "OriginalState: %s\r\n", 06524 ast_channel_name(clonechan), ast_state2str(clonechan->_state), ast_channel_name(original), ast_state2str(original->_state)); 06525 06526 /* Having remembered the original read/write formats, we turn off any translation on either 06527 one */ 06528 free_translation(clonechan); 06529 free_translation(original); 06530 06531 /* Save the original name */ 06532 ast_copy_string(orig, ast_channel_name(original), sizeof(orig)); 06533 /* Save the new name */ 06534 ast_copy_string(newn, ast_channel_name(clonechan), sizeof(newn)); 06535 /* Create the masq name */ 06536 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn); 06537 06538 /* Mangle the name of the clone channel */ 06539 __ast_change_name_nolink(clonechan, masqn); 06540 06541 /* Copy the name from the clone channel */ 06542 __ast_change_name_nolink(original, newn); 06543 06544 /* share linked id's */ 06545 ast_channel_set_linkgroup(original, clonechan); 06546 06547 /* Swap the technologies */ 06548 t = original->tech; 06549 original->tech = clonechan->tech; 06550 clonechan->tech = t; 06551 06552 /* Swap the cdrs */ 06553 cdr = original->cdr; 06554 original->cdr = clonechan->cdr; 06555 clonechan->cdr = cdr; 06556 06557 t_pvt = original->tech_pvt; 06558 original->tech_pvt = clonechan->tech_pvt; 06559 clonechan->tech_pvt = t_pvt; 06560 06561 /* Swap the alertpipes */ 06562 for (i = 0; i < 2; i++) { 06563 x = original->alertpipe[i]; 06564 original->alertpipe[i] = clonechan->alertpipe[i]; 06565 clonechan->alertpipe[i] = x; 06566 } 06567 06568 /* 06569 * Swap the readq's. The end result should be this: 06570 * 06571 * 1) All frames should be on the new (original) channel. 06572 * 2) Any frames that were already on the new channel before this 06573 * masquerade need to be at the end of the readq, after all of the 06574 * frames on the old (clone) channel. 06575 * 3) The alertpipe needs to get poked for every frame that was already 06576 * on the new channel, since we are now using the alert pipe from the 06577 * old (clone) channel. 06578 */ 06579 { 06580 AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq; 06581 AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL); 06582 06583 AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list); 06584 AST_LIST_APPEND_LIST(&original->readq, &clonechan->readq, frame_list); 06585 06586 while ((current = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) { 06587 AST_LIST_INSERT_TAIL(&original->readq, current, frame_list); 06588 if (original->alertpipe[1] > -1) { 06589 int poke = 0; 06590 06591 if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) { 06592 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 06593 } 06594 } 06595 } 06596 } 06597 06598 /* Swap the raw formats */ 06599 ast_format_copy(&tmp_format, &original->rawreadformat); 06600 ast_format_copy(&original->rawreadformat, &clonechan->rawreadformat); 06601 ast_format_copy(&clonechan->rawreadformat, &tmp_format); 06602 06603 ast_format_copy(&tmp_format, &original->rawwriteformat); 06604 ast_format_copy(&original->rawwriteformat, &clonechan->rawwriteformat); 06605 ast_format_copy(&clonechan->rawwriteformat, &tmp_format); 06606 06607 clonechan->_softhangup = AST_SOFTHANGUP_DEV; 06608 06609 /* And of course, so does our current state. Note we need not 06610 call ast_setstate since the event manager doesn't really consider 06611 these separate. We do this early so that the clone has the proper 06612 state of the original channel. */ 06613 origstate = original->_state; 06614 original->_state = clonechan->_state; 06615 clonechan->_state = origstate; 06616 06617 if (clonechan->tech->fixup && clonechan->tech->fixup(original, clonechan)) { 06618 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", ast_channel_name(clonechan)); 06619 } 06620 06621 /* Start by disconnecting the original's physical side */ 06622 if (clonechan->tech->hangup && clonechan->tech->hangup(clonechan)) { 06623 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n"); 06624 res = -1; 06625 goto done; 06626 } 06627 06628 /* 06629 * We just hung up the physical side of the channel. Set the 06630 * new zombie to use the kill channel driver for safety. 06631 */ 06632 clonechan->tech = &ast_kill_tech; 06633 06634 /* Mangle the name of the clone channel */ 06635 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); /* quick, hide the brains! */ 06636 __ast_change_name_nolink(clonechan, zombn); 06637 06638 /* Update the type. */ 06639 t_pvt = original->monitor; 06640 original->monitor = clonechan->monitor; 06641 clonechan->monitor = t_pvt; 06642 06643 /* Keep the same language. */ 06644 ast_channel_language_set(original, ast_channel_language(clonechan)); 06645 /* Copy the FD's other than the generator fd */ 06646 for (x = 0; x < AST_MAX_FDS; x++) { 06647 if (x != AST_GENERATOR_FD) 06648 ast_channel_set_fd(original, x, clonechan->fds[x]); 06649 } 06650 06651 ast_app_group_update(clonechan, original); 06652 06653 /* Move data stores over */ 06654 if (AST_LIST_FIRST(&clonechan->datastores)) { 06655 struct ast_datastore *ds; 06656 /* We use a safe traversal here because some fixup routines actually 06657 * remove the datastore from the list and free them. 06658 */ 06659 AST_LIST_TRAVERSE_SAFE_BEGIN(&clonechan->datastores, ds, entry) { 06660 if (ds->info->chan_fixup) 06661 ds->info->chan_fixup(ds->data, clonechan, original); 06662 } 06663 AST_LIST_TRAVERSE_SAFE_END; 06664 AST_LIST_APPEND_LIST(&original->datastores, &clonechan->datastores, entry); 06665 } 06666 06667 ast_autochan_new_channel(clonechan, original); 06668 06669 clone_variables(original, clonechan); 06670 /* Presense of ADSI capable CPE follows clone */ 06671 original->adsicpe = clonechan->adsicpe; 06672 /* Bridge remains the same */ 06673 /* CDR fields remain the same */ 06674 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 06675 /* Application and data remain the same */ 06676 /* Clone exception becomes real one, as with fdno */ 06677 ast_set_flag(original, ast_test_flag(clonechan, AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING)); 06678 original->fdno = clonechan->fdno; 06679 /* Schedule context remains the same */ 06680 /* Stream stuff stays the same */ 06681 /* Keep the original state. The fixup code will need to work with it most likely */ 06682 06683 /* 06684 * Just swap the whole structures, nevermind the allocations, 06685 * they'll work themselves out. 06686 */ 06687 exchange.dialed = original->dialed; 06688 original->dialed = clonechan->dialed; 06689 clonechan->dialed = exchange.dialed; 06690 06691 exchange.caller = original->caller; 06692 original->caller = clonechan->caller; 06693 clonechan->caller = exchange.caller; 06694 06695 exchange.connected = original->connected; 06696 original->connected = clonechan->connected; 06697 clonechan->connected = exchange.connected; 06698 06699 exchange.redirecting = original->redirecting; 06700 original->redirecting = clonechan->redirecting; 06701 clonechan->redirecting = exchange.redirecting; 06702 06703 report_new_callerid(original); 06704 06705 /* Restore original timing file descriptor */ 06706 ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd); 06707 06708 /* Our native formats are different now */ 06709 ast_format_cap_copy(original->nativeformats, clonechan->nativeformats); 06710 06711 /* Context, extension, priority, app data, jump table, remain the same */ 06712 /* pvt switches. pbx stays the same, as does next */ 06713 06714 /* Set the write format */ 06715 ast_set_write_format(original, &wformat); 06716 06717 /* Set the read format */ 06718 ast_set_read_format(original, &rformat); 06719 06720 /* Copy the music class */ 06721 ast_channel_musicclass_set(original, ast_channel_musicclass(clonechan)); 06722 06723 /* copy over accuntcode and set peeraccount across the bridge */ 06724 ast_channel_accountcode_set(original, S_OR(ast_channel_accountcode(clonechan), "")); 06725 if (original->_bridge) { 06726 /* XXX - should we try to lock original->_bridge here? */ 06727 ast_channel_peeraccount_set(original->_bridge, S_OR(ast_channel_accountcode(clonechan), "")); 06728 ast_cel_report_event(original, AST_CEL_BRIDGE_UPDATE, NULL, NULL, NULL); 06729 } 06730 06731 ast_debug(1, "Putting channel %s in %s/%s formats\n", ast_channel_name(original), 06732 ast_getformatname(&wformat), ast_getformatname(&rformat)); 06733 06734 /* Okay. Last thing is to let the channel driver know about all this mess, so he 06735 can fix up everything as best as possible */ 06736 if (original->tech->fixup) { 06737 if (original->tech->fixup(clonechan, original)) { 06738 ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n", 06739 original->tech->type, ast_channel_name(original)); 06740 res = -1; 06741 goto done; 06742 } 06743 } else 06744 ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)! Bad things may happen.\n", 06745 original->tech->type, ast_channel_name(original)); 06746 06747 /* 06748 * If an indication is currently playing, maintain it on the channel 06749 * that is taking the place of original 06750 * 06751 * This is needed because the masquerade is swapping out in the internals 06752 * of this channel, and the new channel private data needs to be made 06753 * aware of the current visible indication (RINGING, CONGESTION, etc.) 06754 */ 06755 if (visible_indication) { 06756 ast_indicate(original, visible_indication); 06757 } 06758 06759 /* Now, at this point, the "clone" channel is totally F'd up. We mark it as 06760 a zombie so nothing tries to touch it. If it's already been marked as a 06761 zombie, then free it now (since it already is considered invalid). */ 06762 if (ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) { 06763 ast_debug(1, "Destroying channel clone '%s'\n", ast_channel_name(clonechan)); 06764 ast_channel_unlock(clonechan); 06765 ast_manager_event(clonechan, EVENT_FLAG_CALL, "Hangup", 06766 "Channel: %s\r\n" 06767 "Uniqueid: %s\r\n" 06768 "Cause: %d\r\n" 06769 "Cause-txt: %s\r\n", 06770 ast_channel_name(clonechan), 06771 ast_channel_uniqueid(clonechan), 06772 clonechan->hangupcause, 06773 ast_cause2str(clonechan->hangupcause) 06774 ); 06775 clonechan = ast_channel_release(clonechan); 06776 } else { 06777 ast_debug(1, "Released clone lock on '%s'\n", ast_channel_name(clonechan)); 06778 ast_set_flag(clonechan, AST_FLAG_ZOMBIE); 06779 ast_queue_frame(clonechan, &ast_null_frame); 06780 } 06781 06782 /* Signal any blocker */ 06783 if (ast_test_flag(original, AST_FLAG_BLOCKING)) 06784 pthread_kill(original->blocker, SIGURG); 06785 ast_debug(1, "Done Masquerading %s (%d)\n", ast_channel_name(original), original->_state); 06786 06787 if ((bridged = ast_bridged_channel(original))) { 06788 ast_channel_lock(bridged); 06789 ast_indicate(bridged, AST_CONTROL_SRCCHANGE); 06790 ast_channel_unlock(bridged); 06791 } 06792 ast_indicate(original, AST_CONTROL_SRCCHANGE); 06793 06794 if (xfer_colp) { 06795 /* 06796 * After the masquerade, the original channel pointer actually 06797 * points to the new transferee channel and the bridged channel 06798 * is still the intended transfer target party. 06799 */ 06800 masquerade_colp_transfer(original, xfer_colp); 06801 } 06802 06803 done: 06804 if (xfer_ds) { 06805 ast_datastore_free(xfer_ds); 06806 } 06807 /* it is possible for the clone channel to disappear during this */ 06808 if (clonechan) { 06809 ast_channel_unlock(original); 06810 ast_channel_unlock(clonechan); 06811 ao2_link(channels, clonechan); 06812 ao2_link(channels, original); 06813 } else { 06814 ast_channel_unlock(original); 06815 ao2_link(channels, original); 06816 } 06817 06818 ao2_unlock(channels); 06819 06820 return res; 06821 }
| struct ast_channel* ast_dummy_channel_alloc | ( | void | ) | [read] |
Create a fake channel structure.
| NULL | failure | |
| non-NULL | successfully allocated channel |
The created dummy channel should be destroyed by ast_channel_unref(). Using ast_channel_release() needlessly grabs the channel container lock and can cause a deadlock as a result. Also grabbing the channel container lock reduces system performance.
Definition at line 1176 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(), syslog_log(), and write_cdr().
01178 { 01179 struct ast_channel *tmp; 01180 struct varshead *headp; 01181 01182 #if defined(REF_DEBUG) 01183 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel", 01184 file, line, function, 1); 01185 #elif defined(__AST_DEBUG_MALLOC) 01186 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel", 01187 file, line, function, 0); 01188 #else 01189 tmp = ao2_alloc(sizeof(*tmp), ast_dummy_channel_destructor); 01190 #endif 01191 if (!tmp) { 01192 /* Dummy channel structure allocation failure. */ 01193 return NULL; 01194 } 01195 01196 if ((ast_string_field_init(tmp, 128))) { 01197 return ast_channel_unref(tmp); 01198 } 01199 01200 headp = &tmp->varshead; 01201 AST_LIST_HEAD_INIT_NOLOCK(headp); 01202 01203 return tmp; 01204 }
| static void ast_dummy_channel_destructor | ( | void * | obj | ) | [static] |
Free a dummy channel structure.
Definition at line 2309 of file channel.c.
References ast_cdr_discard(), AST_LIST_REMOVE_HEAD, ast_party_caller_free(), ast_party_connected_line_free(), ast_party_dialed_free(), ast_party_redirecting_free(), ast_string_field_free_memory, ast_var_delete(), ast_channel::caller, ast_channel::cdr, ast_channel::connected, ast_channel::dialed, ast_channel::redirecting, and ast_channel::varshead.
Referenced by ast_dummy_channel_alloc().
02310 { 02311 struct ast_channel *chan = obj; 02312 struct ast_var_t *vardata; 02313 struct varshead *headp; 02314 02315 headp = &chan->varshead; 02316 02317 ast_party_dialed_free(&chan->dialed); 02318 ast_party_caller_free(&chan->caller); 02319 ast_party_connected_line_free(&chan->connected); 02320 ast_party_redirecting_free(&chan->redirecting); 02321 02322 /* loop over the variables list, freeing all data and deleting list items */ 02323 /* no need to lock the list, as the channel is already locked */ 02324 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) 02325 ast_var_delete(vardata); 02326 02327 if (chan->cdr) { 02328 ast_cdr_discard(chan->cdr); 02329 chan->cdr = NULL; 02330 } 02331 02332 ast_string_field_free_memory(chan); 02333 }
| 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 6975 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_FAILED, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, ast_channel_clear_softhangup(), ast_channel_connected_line_macro(), ast_channel_name(), ast_channel_redirecting_macro(), ast_clear_flag, AST_CONTROL_AOC, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_MCID, AST_CONTROL_REDIRECTING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_debug, AST_FEATURE_WARNING_ACTIVE, ast_format_cap_destroy(), ast_format_cap_dup(), ast_format_cap_identical(), 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, ast_bridge_config::feature_timer, ast_bridge_config::flags, ast_frame::frametype, ast_frame_subclass::integer, 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().
06978 { 06979 /* Copy voice back and forth between the two channels. */ 06980 struct ast_channel *cs[3]; 06981 struct ast_frame *f; 06982 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 06983 struct ast_format_cap *o0nativeformats; 06984 struct ast_format_cap *o1nativeformats; 06985 int watch_c0_dtmf; 06986 int watch_c1_dtmf; 06987 void *pvt0, *pvt1; 06988 /* Indicates whether a frame was queued into a jitterbuffer */ 06989 int frame_put_in_jb = 0; 06990 int jb_in_use; 06991 int to; 06992 06993 o0nativeformats = ast_format_cap_dup(c0->nativeformats); 06994 o1nativeformats = ast_format_cap_dup(c1->nativeformats); 06995 06996 if (!o0nativeformats || !o1nativeformats) { 06997 ast_format_cap_destroy(o0nativeformats); /* NULL safe */ 06998 ast_format_cap_destroy(o1nativeformats); /* NULL safe */ 06999 return AST_BRIDGE_FAILED; 07000 } 07001 07002 cs[0] = c0; 07003 cs[1] = c1; 07004 pvt0 = c0->tech_pvt; 07005 pvt1 = c1->tech_pvt; 07006 watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0; 07007 watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1; 07008 07009 /* Check the need of a jitterbuffer for each channel */ 07010 jb_in_use = ast_jb_do_usecheck(c0, c1); 07011 if (jb_in_use) 07012 ast_jb_empty_and_reset(c0, c1); 07013 07014 ast_poll_channel_add(c0, c1); 07015 07016 if (config->feature_timer > 0 && ast_tvzero(config->nexteventts)) { 07017 /* nexteventts is not set when the bridge is not scheduled to 07018 * break, so calculate when the bridge should possibly break 07019 * if a partial feature match timed out */ 07020 config->nexteventts = ast_tvadd(ast_tvnow(), ast_samp2tv(config->feature_timer, 1000)); 07021 } 07022 07023 for (;;) { 07024 struct ast_channel *who, *other; 07025 07026 if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) || 07027 (!ast_format_cap_identical(o0nativeformats, c0->nativeformats)) || 07028 (!ast_format_cap_identical(o1nativeformats, c1->nativeformats))) { 07029 /* Check for Masquerade, codec changes, etc */ 07030 res = AST_BRIDGE_RETRY; 07031 break; 07032 } 07033 if (config->nexteventts.tv_sec) { 07034 to = ast_tvdiff_ms(config->nexteventts, ast_tvnow()); 07035 if (to <= 0) { 07036 if (config->timelimit && !config->feature_timer && !ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) { 07037 res = AST_BRIDGE_RETRY; 07038 /* generic bridge ending to play warning */ 07039 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE); 07040 } else if (config->feature_timer) { 07041 /* feature timer expired - make sure we do not play warning */ 07042 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE); 07043 res = AST_BRIDGE_RETRY; 07044 } else { 07045 res = AST_BRIDGE_COMPLETE; 07046 } 07047 break; 07048 } 07049 } else { 07050 /* If a feature has been started and the bridge is configured to 07051 * to not break, leave the channel bridge when the feature timer 07052 * time has elapsed so the DTMF will be sent to the other side. 07053 */ 07054 if (!ast_tvzero(config->nexteventts)) { 07055 int diff = ast_tvdiff_ms(config->nexteventts, ast_tvnow()); 07056 if (diff <= 0) { 07057 res = AST_BRIDGE_RETRY; 07058 break; 07059 } 07060 } 07061 to = -1; 07062 } 07063 /* Calculate the appropriate max sleep interval - in general, this is the time, 07064 left to the closest jb delivery moment */ 07065 if (jb_in_use) 07066 to = ast_jb_get_when_to_wakeup(c0, c1, to); 07067 who = ast_waitfor_n(cs, 2, &to); 07068 if (!who) { 07069 /* No frame received within the specified timeout - check if we have to deliver now */ 07070 if (jb_in_use) 07071 ast_jb_get_and_deliver(c0, c1); 07072 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 07073 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07074 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE); 07075 } 07076 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07077 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE); 07078 } 07079 c0->_bridge = c1; 07080 c1->_bridge = c0; 07081 } 07082 continue; 07083 } 07084 f = ast_read(who); 07085 if (!f) { 07086 *fo = NULL; 07087 *rc = who; 07088 ast_debug(1, "Didn't get a frame from channel: %s\n", ast_channel_name(who)); 07089 break; 07090 } 07091 07092 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 07093 /* Try add the frame info the who's bridged channel jitterbuff */ 07094 if (jb_in_use) 07095 frame_put_in_jb = !ast_jb_put(other, f); 07096 07097 if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) { 07098 int bridge_exit = 0; 07099 07100 switch (f->subclass.integer) { 07101 case AST_CONTROL_AOC: 07102 case AST_CONTROL_MCID: 07103 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen); 07104 break; 07105 case AST_CONTROL_REDIRECTING: 07106 if (ast_channel_redirecting_macro(who, other, f, other == c0, 1)) { 07107 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen); 07108 } 07109 break; 07110 case AST_CONTROL_CONNECTED_LINE: 07111 if (ast_channel_connected_line_macro(who, other, f, other == c0, 1)) { 07112 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen); 07113 } 07114 break; 07115 case AST_CONTROL_HOLD: 07116 case AST_CONTROL_UNHOLD: 07117 case AST_CONTROL_VIDUPDATE: 07118 case AST_CONTROL_SRCUPDATE: 07119 case AST_CONTROL_SRCCHANGE: 07120 case AST_CONTROL_T38_PARAMETERS: 07121 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen); 07122 if (jb_in_use) { 07123 ast_jb_empty_and_reset(c0, c1); 07124 } 07125 break; 07126 default: 07127 *fo = f; 07128 *rc = who; 07129 bridge_exit = 1; 07130 ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass.integer, ast_channel_name(who)); 07131 break; 07132 } 07133 if (bridge_exit) 07134 break; 07135 } 07136 if ((f->frametype == AST_FRAME_VOICE) || 07137 (f->frametype == AST_FRAME_DTMF_BEGIN) || 07138 (f->frametype == AST_FRAME_DTMF) || 07139 (f->frametype == AST_FRAME_VIDEO) || 07140 (f->frametype == AST_FRAME_IMAGE) || 07141 (f->frametype == AST_FRAME_HTML) || 07142 (f->frametype == AST_FRAME_MODEM) || 07143 (f->frametype == AST_FRAME_TEXT)) { 07144 /* monitored dtmf causes exit from bridge */ 07145 int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf; 07146 07147 if (monitored_source && 07148 (f->frametype == AST_FRAME_DTMF_END || 07149 f->frametype == AST_FRAME_DTMF_BEGIN)) { 07150 *fo = f; 07151 *rc = who; 07152 ast_debug(1, "Got DTMF %s on channel (%s)\n", 07153 f->frametype == AST_FRAME_DTMF_END ? "end" : "begin", 07154 ast_channel_name(who)); 07155 07156 break; 07157 } 07158 /* Write immediately frames, not passed through jb */ 07159 if (!frame_put_in_jb) 07160 ast_write(other, f); 07161 07162 /* Check if we have to deliver now */ 07163 if (jb_in_use) 07164 ast_jb_get_and_deliver(c0, c1); 07165 } 07166 /* XXX do we want to pass on also frames not matched above ? */ 07167 ast_frfree(f); 07168 07169 #ifndef HAVE_EPOLL 07170 /* Swap who gets priority */ 07171 cs[2] = cs[0]; 07172 cs[0] = cs[1]; 07173 cs[1] = cs[2]; 07174 #endif 07175 } 07176 07177 ast_poll_channel_del(c0, c1); 07178 07179 ast_format_cap_destroy(o0nativeformats); 07180 ast_format_cap_destroy(o1nativeformats); 07181 07182 return res; 07183 }
| 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 732 of file channel.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, chanlist::tech, and ast_channel_tech::type.
Referenced by __ast_channel_alloc_ap(), _ast_device_state(), ast_cc_callback(), and ast_var_channel_types_table().
00733 { 00734 struct chanlist *chanls; 00735 const struct ast_channel_tech *ret = NULL; 00736 00737 AST_RWLIST_RDLOCK(&backends); 00738 00739 AST_RWLIST_TRAVERSE(&backends, chanls, list) { 00740 if (!strcasecmp(name, chanls->tech->type)) { 00741 ret = chanls->tech; 00742 break; 00743 } 00744 } 00745 00746 AST_RWLIST_UNLOCK(&backends); 00747 00748 return ret; 00749 }
| ast_group_t ast_get_group | ( | const char * | s | ) |
Definition at line 7742 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_real(), process_dahdi(), and read_agent_config().
07743 { 07744 char *piece; 07745 char *c; 07746 int start=0, finish=0, x; 07747 ast_group_t group = 0; 07748 07749 if (ast_strlen_zero(s)) 07750 return 0; 07751 07752 c = ast_strdupa(s); 07753 07754 while ((piece = strsep(&c, ","))) { 07755 if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) { 07756 /* Range */ 07757 } else if (sscanf(piece, "%30d", &start)) { 07758 /* Just one */ 07759 finish = start; 07760 } else { 07761 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece); 07762 continue; 07763 } 07764 for (x = start; x <= finish; x++) { 07765 if ((x > 63) || (x < 0)) { 07766 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x); 07767 } else 07768 group |= ((ast_group_t) 1 << x); 07769 } 07770 } 07771 return group; 07772 }
| int ast_hangup | ( | struct ast_channel * | chan | ) |
Hangup a channel.
Hang up a channel.
Definition at line 2584 of file channel.c.
References ao2_unlink, ast_assert, ast_autoservice_stop(), ast_cause2str(), ast_cc_offer(), 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_hangupsource(), ast_channel_lock, ast_channel_name(), ast_channel_uniqueid(), ast_channel_unlock, ast_channel_unref, ast_closestream(), ast_debug, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_log(), ast_manager_event, ast_sched_context_destroy(), ast_set_flag, ast_test_flag, ast_channel::blocker, ast_channel::blockproc, ast_channel::caller, ast_channel::cdr, channels, ast_channel::connected, destroy_hooks(), ast_cdr::disposition, EVENT_FLAG_CALL, free_translation(), ast_channel::generator, ast_channel::generatordata, ast_channel_tech::hangup, ast_channel::hangupcause, ast_party_connected_line::id, ast_party_caller::id, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_party_id::name, ast_party_id::number, pbx_builtin_getvar_helper(), ast_generator::release, S_COR, S_OR, ast_channel::sched, ast_party_name::str, ast_party_number::str, ast_channel::stream, ast_channel::tech, ast_party_name::valid, ast_party_number::valid, and ast_channel::vstream.
Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_pbx_run(), __ast_request_and_dial(), __oh323_new(), action_bridge(), alloc_playback_chan(), 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_availability(), check_compat(), check_goto_on_transfer(), clear_caller(), conf_free(), conf_run(), connect_link(), console_new(), create_msg_q_chan(), 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(), generic_recall(), gtalk_new(), handle_call_forward(), handle_callforward_button(), handle_frame(), handle_frame_ownerless(), handle_hd_hf(), handle_init_event(), handle_invite_replaces(), handle_request_invite(), handle_timeout_trip(), HandleCallOutgoing(), hangup_chan(), hangupcalls(), hanguptree(), iax2_request(), iax_park(), iax_park_thread(), jingle_new(), local_hangup(), manage_parked_call(), masq_park_call(), mgcp_new(), mgcp_ss(), monitor_dial(), mwi_thread(), my_distinctive_ring(), my_handle_notify_message(), nbs_new(), oss_new(), parkandannounce_exec(), parked_call_exec(), phone_new(), record_thread(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), setsubstate(), sip_park(), sip_park_thread(), sip_pickup_thread(), skinny_new(), skinny_ss(), try_calling(), unistim_new(), usbradio_new(), wait_for_answer(), and wait_for_winner().
02585 { 02586 char extra_str[64]; /* used for cel logging below */ 02587 int was_zombie; 02588 02589 ast_autoservice_stop(chan); 02590 02591 ast_channel_lock(chan); 02592 02593 /* 02594 * Do the masquerade if someone is setup to masquerade into us. 02595 * 02596 * NOTE: We must hold the channel lock after testing for a 02597 * pending masquerade and setting the channel as a zombie to 02598 * prevent __ast_channel_masquerade() from setting up a 02599 * masquerade with a dead channel. 02600 */ 02601 while (chan->masq) { 02602 ast_channel_unlock(chan); 02603 if (ast_do_masquerade(chan)) { 02604 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 02605 02606 /* Abort the loop or we might never leave. */ 02607 ast_channel_lock(chan); 02608 break; 02609 } 02610 ast_channel_lock(chan); 02611 } 02612 02613 if (chan->masqr) { 02614 /* 02615 * This channel is one which will be masqueraded into something. 02616 * Mark it as a zombie already so ast_do_masquerade() will know 02617 * to free it later. 02618 */ 02619 ast_set_flag(chan, AST_FLAG_ZOMBIE); 02620 destroy_hooks(chan); 02621 ast_channel_unlock(chan); 02622 return 0; 02623 } 02624 02625 if (!(was_zombie = ast_test_flag(chan, AST_FLAG_ZOMBIE))) { 02626 ast_set_flag(chan, AST_FLAG_ZOMBIE); 02627 } 02628 02629 ast_channel_unlock(chan); 02630 ao2_unlink(channels, chan); 02631 ast_channel_lock(chan); 02632 02633 destroy_hooks(chan); 02634 02635 free_translation(chan); 02636 /* Close audio stream */ 02637 if (chan->stream) { 02638 ast_closestream(chan->stream); 02639 chan->stream = NULL; 02640 } 02641 /* Close video stream */ 02642 if (chan->vstream) { 02643 ast_closestream(chan->vstream); 02644 chan->vstream = NULL; 02645 } 02646 if (chan->sched) { 02647 ast_sched_context_destroy(chan->sched); 02648 chan->sched = NULL; 02649 } 02650 02651 if (chan->generatordata) { /* Clear any tone stuff remaining */ 02652 if (chan->generator && chan->generator->release) { 02653 chan->generator->release(chan, chan->generatordata); 02654 } 02655 } 02656 chan->generatordata = NULL; 02657 chan->generator = NULL; 02658 02659 snprintf(extra_str, sizeof(extra_str), "%d,%s,%s", chan->hangupcause, ast_channel_hangupsource(chan), S_OR(pbx_builtin_getvar_helper(chan, "DIALSTATUS"), "")); 02660 ast_cel_report_event(chan, AST_CEL_HANGUP, NULL, extra_str, NULL); 02661 02662 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 02663 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 02664 "is blocked by thread %ld in procedure %s! Expect a failure\n", 02665 (long) pthread_self(), ast_channel_name(chan), (long)chan->blocker, chan->blockproc); 02666 ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0); 02667 } 02668 if (!was_zombie) { 02669 ast_debug(1, "Hanging up channel '%s'\n", ast_channel_name(chan)); 02670 02671 if (chan->tech->hangup) { 02672 chan->tech->hangup(chan); 02673 } 02674 } else { 02675 ast_debug(1, "Hanging up zombie '%s'\n", ast_channel_name(chan)); 02676 } 02677 02678 ast_channel_unlock(chan); 02679 02680 ast_cc_offer(chan); 02681 ast_manager_event(chan, EVENT_FLAG_CALL, "Hangup", 02682 "Channel: %s\r\n" 02683 "Uniqueid: %s\r\n" 02684 "CallerIDNum: %s\r\n" 02685 "CallerIDName: %s\r\n" 02686 "ConnectedLineNum: %s\r\n" 02687 "ConnectedLineName: %s\r\n" 02688 "Cause: %d\r\n" 02689 "Cause-txt: %s\r\n", 02690 ast_channel_name(chan), 02691 ast_channel_uniqueid(chan), 02692 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<unknown>"), 02693 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"), 02694 S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, "<unknown>"), 02695 S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, "<unknown>"), 02696 chan->hangupcause, 02697 ast_cause2str(chan->hangupcause) 02698 ); 02699 02700 if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) && 02701 !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) && 02702 (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) { 02703 ast_channel_lock(chan); 02704 ast_cdr_end(chan->cdr); 02705 ast_cdr_detach(chan->cdr); 02706 chan->cdr = NULL; 02707 ast_channel_unlock(chan); 02708 } 02709 02710 ast_channel_unref(chan); 02711 02712 return 0; 02713 }
| 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 4117 of file channel.c.
References ast_indicate_data().
Referenced by __ast_play_and_record(), agent_request(), alsa_call(), answer_trunk_chan(), app_exec(), ast_bridge_call(), ast_bridge_set_single_src_video_mode(), ast_bridge_update_talker_src_video_mode(), 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(), handle_request_refer(), local_attended_transfer(), manage_parked_call(), mgcp_ss(), monitor_dial(), oss_call(), park_call_full(), parked_call_exec(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_incomplete(), pbx_builtin_proceeding(), pbx_builtin_progress(), pbx_builtin_ringing(), pbx_builtin_waitexten(), queue_exec(), record_exec(), rna(), 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().
04118 { 04119 return ast_indicate_data(chan, condition, NULL, 0); 04120 }
| 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 4172 of file channel.c.
References ast_channel::_state, _XXX_AST_CONTROL_T38, ast_channel_lock, ast_channel_name(), 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_AOC, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_END_OF_Q, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_MCID, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_READ_ACTION, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_TRANSFER, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, AST_CONTROL_WINK, ast_debug, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, ast_framehook_list_is_empty(), ast_framehook_list_write_event(), ast_frdup(), ast_frfree, 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_frame::data, ast_frame::datalen, ast_channel::framehooks, ast_frame::frametype, ast_channel_tech::indicate, ast_frame_subclass::integer, is_visible_indication(), LOG_WARNING, ast_frame::ptr, ast_channel::redirecting, ast_frame::subclass, ast_channel::tech, ast_channel::visible_indication, and ast_channel::zone.
Referenced by __ast_read(), action_aocmessage(), agent_hangup(), ast_bridge_call(), ast_channel_update_connected_line(), ast_channel_update_redirecting(), ast_generic_bridge(), ast_handle_cc_control_frame(), ast_indicate(), disable_t38(), fax_gateway_indicate_t38(), feature_request_and_dial(), generic_fax_exec(), handle_frame(), local_bridge_loop(), login_exec(), manage_parked_call(), park_call_full(), pbx_builtin_waitexten(), receivefax_t38_init(), remote_bridge_loop(), sendfax_t38_init(), set_fax_t38_caps(), transmit_audio(), transmit_t38(), and wait_for_answer().
04174 { 04175 /* By using an enum, we'll get compiler warnings for values not handled 04176 * in switch statements. */ 04177 enum ast_control_frame_type condition = _condition; 04178 struct ast_tone_zone_sound *ts = NULL; 04179 int res; 04180 /* this frame is used by framehooks. if it is set, we must free it at the end of this function */ 04181 struct ast_frame *awesome_frame = NULL; 04182 04183 ast_channel_lock(chan); 04184 04185 /* Don't bother if the channel is about to go away, anyway. */ 04186 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 04187 res = -1; 04188 goto indicate_cleanup; 04189 } 04190 04191 if (!ast_framehook_list_is_empty(chan->framehooks)) { 04192 /* Do framehooks now, do it, go, go now */ 04193 struct ast_frame frame = { 04194 .frametype = AST_FRAME_CONTROL, 04195 .subclass.integer = condition, 04196 .data.ptr = (void *) data, /* this cast from const is only okay because we do the ast_frdup below */ 04197 .datalen = datalen 04198 }; 04199 04200 /* we have now committed to freeing this frame */ 04201 awesome_frame = ast_frdup(&frame); 04202 04203 /* who knows what we will get back! the anticipation is killing me. */ 04204 if (!(awesome_frame = ast_framehook_list_write_event(chan->framehooks, awesome_frame)) 04205 || awesome_frame->frametype != AST_FRAME_CONTROL) { 04206 04207 res = 0; 04208 goto indicate_cleanup; 04209 } 04210 04211 condition = awesome_frame->subclass.integer; 04212 data = awesome_frame->data.ptr; 04213 datalen = awesome_frame->datalen; 04214 } 04215 04216 switch (condition) { 04217 case AST_CONTROL_CONNECTED_LINE: 04218 { 04219 struct ast_party_connected_line connected; 04220 04221 ast_party_connected_line_set_init(&connected, &chan->connected); 04222 res = ast_connected_line_parse_data(data, datalen, &connected); 04223 if (!res) { 04224 ast_channel_set_connected_line(chan, &connected, NULL); 04225 } 04226 ast_party_connected_line_free(&connected); 04227 } 04228 break; 04229 04230 case AST_CONTROL_REDIRECTING: 04231 { 04232 struct ast_party_redirecting redirecting; 04233 04234 ast_party_redirecting_set_init(&redirecting, &chan->redirecting); 04235 res = ast_redirecting_parse_data(data, datalen, &redirecting); 04236 if (!res) { 04237 ast_channel_set_redirecting(chan, &redirecting, NULL); 04238 } 04239 ast_party_redirecting_free(&redirecting); 04240 } 04241 break; 04242 04243 default: 04244 break; 04245 } 04246 04247 if (is_visible_indication(condition)) { 04248 /* A new visible indication is requested. */ 04249 chan->visible_indication = condition; 04250 } else if (condition == AST_CONTROL_UNHOLD || _condition < 0) { 04251 /* Visible indication is cleared/stopped. */ 04252 chan->visible_indication = 0; 04253 } 04254 04255 if (chan->tech->indicate) { 04256 /* See if the channel driver can handle this condition. */ 04257 res = chan->tech->indicate(chan, condition, data, datalen); 04258 } else { 04259 res = -1; 04260 } 04261 04262 if (!res) { 04263 /* The channel driver successfully handled this indication */ 04264 res = 0; 04265 goto indicate_cleanup; 04266 } 04267 04268 /* The channel driver does not support this indication, let's fake 04269 * it by doing our own tone generation if applicable. */ 04270 04271 /*!\note If we compare the enumeration type, which does not have any 04272 * negative constants, the compiler may optimize this code away. 04273 * Therefore, we must perform an integer comparison here. */ 04274 if (_condition < 0) { 04275 /* Stop any tones that are playing */ 04276 ast_playtones_stop(chan); 04277 res = 0; 04278 goto indicate_cleanup; 04279 } 04280 04281 /* Handle conditions that we have tones for. */ 04282 switch (condition) { 04283 case _XXX_AST_CONTROL_T38: 04284 /* deprecated T.38 control frame */ 04285 res = -1; 04286 goto indicate_cleanup; 04287 case AST_CONTROL_T38_PARAMETERS: 04288 /* there is no way to provide 'default' behavior for these 04289 * control frames, so we need to return failure, but there 04290 * is also no value in the log message below being emitted 04291 * since failure to handle these frames is not an 'error' 04292 * so just return right now. in addition, we want to return 04293 * whatever value the channel driver returned, in case it 04294 * has some meaning.*/ 04295 goto indicate_cleanup; 04296 case AST_CONTROL_RINGING: 04297 ts = ast_get_indication_tone(chan->zone, "ring"); 04298 /* It is common practice for channel drivers to return -1 if trying 04299 * to indicate ringing on a channel which is up. The idea is to let the 04300 * core generate the ringing inband. However, we don't want the 04301 * warning message about not being able to handle the specific indication 04302 * to print nor do we want ast_indicate_data to return an "error" for this 04303 * condition 04304 */ 04305 if (chan->_state == AST_STATE_UP) { 04306 res = 0; 04307 } 04308 break; 04309 case AST_CONTROL_BUSY: 04310 ts = ast_get_indication_tone(chan->zone, "busy"); 04311 break; 04312 case AST_CONTROL_INCOMPLETE: 04313 case AST_CONTROL_CONGESTION: 04314 ts = ast_get_indication_tone(chan->zone, "congestion"); 04315 break; 04316 case AST_CONTROL_PROGRESS: 04317 case AST_CONTROL_PROCEEDING: 04318 case AST_CONTROL_VIDUPDATE: 04319 case AST_CONTROL_SRCUPDATE: 04320 case AST_CONTROL_SRCCHANGE: 04321 case AST_CONTROL_RADIO_KEY: 04322 case AST_CONTROL_RADIO_UNKEY: 04323 case AST_CONTROL_OPTION: 04324 case AST_CONTROL_WINK: 04325 case AST_CONTROL_FLASH: 04326 case AST_CONTROL_OFFHOOK: 04327 case AST_CONTROL_TAKEOFFHOOK: 04328 case AST_CONTROL_ANSWER: 04329 case AST_CONTROL_HANGUP: 04330 case AST_CONTROL_RING: 04331 case AST_CONTROL_HOLD: 04332 case AST_CONTROL_UNHOLD: 04333 case AST_CONTROL_TRANSFER: 04334 case AST_CONTROL_CONNECTED_LINE: 04335 case AST_CONTROL_REDIRECTING: 04336 case AST_CONTROL_CC: 04337 case AST_CONTROL_READ_ACTION: 04338 case AST_CONTROL_AOC: 04339 case AST_CONTROL_END_OF_Q: 04340 case AST_CONTROL_MCID: 04341 case AST_CONTROL_UPDATE_RTP_PEER: 04342 /* Nothing left to do for these. */ 04343 res = 0; 04344 break; 04345 } 04346 04347 if (ts) { 04348 /* We have a tone to play, yay. */ 04349 ast_debug(1, "Driver for channel '%s' does not support indication %d, emulating it\n", ast_channel_name(chan), condition); 04350 res = ast_playtones_start(chan, 0, ts->data, 1); 04351 ts = ast_tone_zone_sound_unref(ts); 04352 } 04353 04354 if (res) { 04355 /* not handled */ 04356 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, ast_channel_name(chan)); 04357 } 04358 04359 indicate_cleanup: 04360 ast_channel_unlock(chan); 04361 if (awesome_frame) { 04362 ast_frfree(awesome_frame); 04363 } 04364 04365 return res; 04366 }
| 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 7778 of file channel.c.
References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.
Referenced by load_module().
07781 { 07782 ast_moh_start_ptr = start_ptr; 07783 ast_moh_stop_ptr = stop_ptr; 07784 ast_moh_cleanup_ptr = cleanup_ptr; 07785 }
| int ast_internal_timing_enabled | ( | struct ast_channel * | chan | ) |
Check if the channel can run in internal timing mode.
| chan | The channel to check |
Definition at line 4102 of file channel.c.
References ast_opt_internal_timing, and ast_channel::timingfd.
Referenced by add_sdp(), and ast_read_generator_actions().
04103 { 04104 return (ast_opt_internal_timing && chan->timingfd > -1); 04105 }
| int ast_is_deferrable_frame | ( | const struct ast_frame * | frame | ) |
Should we keep this frame for later?
There are functions such as ast_safe_sleep which will service a channel to ensure that it does not have a large backlog of queued frames. When this happens, we want to hold on to specific frame types and just drop others. This function will tell if the frame we just read should be held onto.
| frame | The frame we just read |
| 1 | frame should be kept | |
| 0 | frame should be dropped |
Definition at line 1603 of file channel.c.
References 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, and ast_frame::frametype.
Referenced by ast_safe_sleep_conditional(), autoservice_run(), and feature_request_and_dial().
01604 { 01605 /* Do not add a default entry in this switch statement. Each new 01606 * frame type should be addressed directly as to whether it should 01607 * be queued up or not. 01608 */ 01609 switch (frame->frametype) { 01610 case AST_FRAME_CONTROL: 01611 case AST_FRAME_TEXT: 01612 case AST_FRAME_IMAGE: 01613 case AST_FRAME_HTML: 01614 return 1; 01615 01616 case AST_FRAME_DTMF_END: 01617 case AST_FRAME_DTMF_BEGIN: 01618 case AST_FRAME_VOICE: 01619 case AST_FRAME_VIDEO: 01620 case AST_FRAME_NULL: 01621 case AST_FRAME_IAX: 01622 case AST_FRAME_CNG: 01623 case AST_FRAME_MODEM: 01624 return 0; 01625 } 01626 return 0; 01627 }
| void ast_moh_cleanup | ( | struct ast_channel * | chan | ) |
Definition at line 7812 of file channel.c.
References ast_moh_cleanup_ptr.
Referenced by ast_channel_destructor().
07813 { 07814 if (ast_moh_cleanup_ptr) 07815 ast_moh_cleanup_ptr(chan); 07816 }
| int ast_moh_start | ( | struct ast_channel * | chan, | |
| const char * | mclass, | |||
| const char * | interpclass | |||
| ) |
Turn on music on hold on a given channel.
| chan | The channel structure that will get music on hold | |
| mclass | The class to use if the musicclass is not currently set on the channel structure. | |
| interpclass | The class to use if the musicclass is not currently set on the channel structure or in the mclass argument. |
| Zero | on success | |
| non-zero | on failure |
Definition at line 7795 of file channel.c.
References ast_moh_start_ptr, and ast_verb.
Referenced by alsa_indicate(), app_exec(), conf_handle_dtmf(), conf_run(), conf_start_moh(), confbridge_exec(), console_indicate(), dahdi_indicate(), dial_exec_full(), feature_exec_app(), gtalk_indicate(), handle_setmusic(), iax2_indicate(), jingle_indicate(), key_call(), leave_conference_bridge(), local_indicate(), mgcp_indicate(), misdn_indication(), moh_handle_digit(), monitor_dial(), oh323_indicate(), oss_indicate(), phone_indicate(), play_moh_exec(), post_join_marked(), post_join_unmarked(), queue_exec(), retrydial_exec(), rna(), say_periodic_announcement(), say_position(), sip_indicate(), skinny_indicate(), start_moh_exec(), TransferCallStep1(), unistim_indicate(), usbradio_indicate(), and wait_moh_exec().
07796 { 07797 if (ast_moh_start_ptr) 07798 return ast_moh_start_ptr(chan, mclass, interpclass); 07799 07800 ast_verb(3, "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : (interpclass ? interpclass : "default")); 07801 07802 return 0; 07803 }
| void ast_moh_stop | ( | struct ast_channel * | chan | ) |
Turn off music on hold on a given channel.
Turn off music on hold on a given channel
Definition at line 7806 of file channel.c.
References ast_moh_stop_ptr.
Referenced by alsa_indicate(), app_exec(), ast_quiet_chan(), conf_handle_dtmf(), conf_run(), confbridge_exec(), console_indicate(), dahdi_indicate(), dial_exec_full(), do_bridge_masquerade(), feature_exec_app(), gtalk_indicate(), handle_setmusic(), iax2_indicate(), jingle_indicate(), key_call(), key_dial_page(), local_indicate(), mgcp_indicate(), misdn_indication(), moh_handle_digit(), monitor_dial(), oh323_indicate(), oss_indicate(), phone_indicate(), play_moh_exec(), post_join_marked(), post_join_unmarked(), queue_exec(), retrydial_exec(), say_periodic_announcement(), say_position(), sip_indicate(), skinny_indicate(), stop_moh_exec(), try_calling(), unistim_hangup(), unistim_indicate(), usbradio_indicate(), wait_for_answer(), and wait_moh_exec().
07807 { 07808 if (ast_moh_stop_ptr) 07809 ast_moh_stop_ptr(chan); 07810 }
| void ast_party_caller_copy | ( | struct ast_party_caller * | dest, | |
| const struct ast_party_caller * | src | |||
| ) |
Copy the source caller information to the destination caller.
| dest | Destination caller | |
| src | Source caller |
Definition at line 2054 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_copy(), and ast_party_caller::id.
Referenced by wait_for_answer().
02055 { 02056 if (dest == src) { 02057 /* Don't copy to self */ 02058 return; 02059 } 02060 02061 ast_party_id_copy(&dest->id, &src->id); 02062 ast_party_id_copy(&dest->ani, &src->ani); 02063 dest->ani2 = src->ani2; 02064 }
| void ast_party_caller_free | ( | struct ast_party_caller * | doomed | ) |
Destroy the caller party contents.
| doomed | The caller party to destroy. |
Definition at line 2080 of file channel.c.
References ast_party_caller::ani, ast_party_id_free(), and ast_party_caller::id.
Referenced by ast_channel_destructor(), ast_dummy_channel_destructor(), callerid_write(), dial_trunk(), and sla_ring_station().
02081 { 02082 ast_party_id_free(&doomed->id); 02083 ast_party_id_free(&doomed->ani); 02084 }
| void ast_party_caller_init | ( | struct ast_party_caller * | init | ) |
Initialize the given caller structure.
| init | Caller structure to initialize. |
Definition at line 2047 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_init(), and ast_party_caller::id.
Referenced by __ast_channel_alloc_ap(), dial_trunk(), and sla_ring_station().
02048 { 02049 ast_party_id_init(&init->id); 02050 ast_party_id_init(&init->ani); 02051 init->ani2 = 0; 02052 }
| void ast_party_caller_set | ( | struct ast_party_caller * | dest, | |
| const struct ast_party_caller * | src, | |||
| const struct ast_set_party_caller * | update | |||
| ) |
Set the caller information based on another caller source.
| dest | The caller one wishes to update | |
| src | The new caller values to update the dest | |
| update | What caller information to update. NULL if all. |
Definition at line 2073 of file channel.c.
References ast_set_party_caller::ani, ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_set(), ast_set_party_caller::id, and ast_party_caller::id.
Referenced by ast_channel_set_caller(), ast_channel_set_caller_event(), and callerid_write().
02074 { 02075 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL); 02076 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL); 02077 dest->ani2 = src->ani2; 02078 }
| void ast_party_caller_set_init | ( | struct ast_party_caller * | init, | |
| const struct ast_party_caller * | guide | |||
| ) |
Initialize the given caller structure using the given guide for a set update operation.
| init | Caller structure to initialize. | |
| guide | Source caller to use as a guide in initializing. |
Definition at line 2066 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_set_init(), and ast_party_caller::id.
Referenced by callerid_write(), dial_exec_full(), do_forward(), misdn_update_caller_id(), and ring_entry().
02067 { 02068 ast_party_id_set_init(&init->id, &guide->id); 02069 ast_party_id_set_init(&init->ani, &guide->ani); 02070 init->ani2 = guide->ani2; 02071 }
| void ast_party_connected_line_collect_caller | ( | struct ast_party_connected_line * | connected, | |
| struct ast_party_caller * | caller | |||
| ) |
Collect the caller party information into a connected line structure.
| connected | Collected caller information for the connected line | |
| caller | Caller information. |
DO NOT call ast_party_connected_line_free() on the filled in connected line structure!
Definition at line 2123 of file channel.c.
References ast_party_caller::ani, ast_party_connected_line::ani, ast_party_caller::ani2, ast_party_connected_line::ani2, AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN, ast_party_caller::id, ast_party_connected_line::id, and ast_party_connected_line::source.
02124 { 02125 connected->id = caller->id; 02126 connected->ani = caller->ani; 02127 connected->ani2 = caller->ani2; 02128 connected->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN; 02129 }
| 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.
| dest | Destination connected line | |
| src | Source connected line |
Definition at line 2094 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_copy(), ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by __ast_read(), ast_call_forward(), ast_channel_connected_line_macro(), ast_do_pickup(), builtin_atxfer(), dial_exec_full(), do_forward(), local_attended_transfer(), misdn_attempt_transfer(), party_connected_line_copy_transfer(), try_calling(), and wait_for_answer().
02095 { 02096 if (dest == src) { 02097 /* Don't copy to self */ 02098 return; 02099 } 02100 02101 ast_party_id_copy(&dest->id, &src->id); 02102 ast_party_id_copy(&dest->ani, &src->ani); 02103 dest->ani2 = src->ani2; 02104 dest->source = src->source; 02105 }
| void ast_party_connected_line_free | ( | struct ast_party_connected_line * | doomed | ) |
Destroy the connected line information contents.
| doomed | The connected line information to destroy. |
Definition at line 2131 of file channel.c.
References ast_party_connected_line::ani, ast_party_id_free(), and ast_party_connected_line::id.
Referenced by __ast_read(), app_exec(), ast_channel_destructor(), ast_do_pickup(), ast_dummy_channel_destructor(), ast_indicate_data(), atxfer_fail_cleanup(), builtin_atxfer(), callattempt_free(), chanlist_free(), connectedline_write(), destroy_calling_tree(), feature_request_and_dial(), findmeexec(), local_attended_transfer(), misdn_attempt_transfer(), parked_call_exec(), socket_process(), wait_for_answer(), wait_for_winner(), and xfer_ds_destroy().
02132 { 02133 ast_party_id_free(&doomed->id); 02134 ast_party_id_free(&doomed->ani); 02135 }
| void ast_party_connected_line_init | ( | struct ast_party_connected_line * | init | ) |
Initialize the given connected line structure.
| init | Connected line structure to initialize. |
Definition at line 2086 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN, ast_party_id_init(), ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by __ast_channel_alloc_ap(), __ast_read(), ast_do_pickup(), builtin_atxfer(), do_forward(), handle_request_invite(), handle_request_update(), handle_response_invite(), local_attended_transfer(), misdn_attempt_transfer(), misdn_queue_connected_line_update(), parked_call_exec(), sip_call(), socket_process(), and wait_for_answer().
02087 { 02088 ast_party_id_init(&init->id); 02089 ast_party_id_init(&init->ani); 02090 init->ani2 = 0; 02091 init->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN; 02092 }
| void ast_party_connected_line_set | ( | struct ast_party_connected_line * | dest, | |
| const struct ast_party_connected_line * | src, | |||
| const struct ast_set_party_connected_line * | update | |||
| ) |
Set the connected line information based on another connected line source.
| dest | The connected line one wishes to update | |
| src | The new connected line values to update the dest | |
| update | What connected line information to update. NULL if all. |
Definition at line 2115 of file channel.c.
References ast_set_party_connected_line::ani, ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_set(), ast_set_party_connected_line::id, ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by ast_channel_set_connected_line(), wait_for_answer(), and wait_for_winner().
02116 { 02117 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL); 02118 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL); 02119 dest->ani2 = src->ani2; 02120 dest->source = src->source; 02121 }
| 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.
| init | Connected line structure to initialize. | |
| guide | Source connected line to use as a guide in initializing. |
Definition at line 2107 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_set_init(), ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by __ast_request_and_dial(), ast_indicate_data(), connectedline_write(), dial_exec_full(), feature_request_and_dial(), wait_for_answer(), and wait_for_winner().
02108 { 02109 ast_party_id_set_init(&init->id, &guide->id); 02110 ast_party_id_set_init(&init->ani, &guide->ani); 02111 init->ani2 = guide->ani2; 02112 init->source = guide->source; 02113 }
| void ast_party_dialed_copy | ( | struct ast_party_dialed * | dest, | |
| const struct ast_party_dialed * | src | |||
| ) |
Copy the source dialed party information to the destination dialed party.
| dest | Destination dialed party | |
| src | Source dialed party |
Definition at line 2005 of file channel.c.
References ast_free, ast_party_subaddress_copy(), ast_strdup, ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.
Referenced by local_call().
02006 { 02007 if (dest == src) { 02008 /* Don't copy to self */ 02009 return; 02010 } 02011 02012 ast_free(dest->number.str); 02013 dest->number.str = ast_strdup(src->number.str); 02014 dest->number.plan = src->number.plan; 02015 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress); 02016 dest->transit_network_select = src->transit_network_select; 02017 }
| void ast_party_dialed_free | ( | struct ast_party_dialed * | doomed | ) |
Destroy the dialed party contents.
| doomed | The dialed party to destroy. |
Definition at line 2040 of file channel.c.
References ast_free, ast_party_subaddress_free(), ast_party_dialed::number, ast_party_dialed::str, and ast_party_dialed::subaddress.
Referenced by ast_channel_destructor(), ast_dummy_channel_destructor(), and callerid_write().
02041 { 02042 ast_free(doomed->number.str); 02043 doomed->number.str = NULL; 02044 ast_party_subaddress_free(&doomed->subaddress); 02045 }
| void ast_party_dialed_init | ( | struct ast_party_dialed * | init | ) |
Initialize the given dialed structure.
| init | Dialed structure to initialize. |
Definition at line 1997 of file channel.c.
References ast_party_subaddress_init(), ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.
Referenced by __ast_channel_alloc_ap().
01998 { 01999 init->number.str = NULL; 02000 init->number.plan = 0;/* Unknown */ 02001 ast_party_subaddress_init(&init->subaddress); 02002 init->transit_network_select = 0; 02003 }
| void ast_party_dialed_set | ( | struct ast_party_dialed * | dest, | |
| const struct ast_party_dialed * | src | |||
| ) |
Set the dialed information based on another dialed source.
| dest | The dialed one wishes to update | |
| src | The new dialed values to update the dest |
Definition at line 2027 of file channel.c.
References ast_free, ast_party_subaddress_set(), ast_strdup, ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.
Referenced by callerid_write().
02028 { 02029 if (src->number.str && src->number.str != dest->number.str) { 02030 ast_free(dest->number.str); 02031 dest->number.str = ast_strdup(src->number.str); 02032 } 02033 dest->number.plan = src->number.plan; 02034 02035 ast_party_subaddress_set(&dest->subaddress, &src->subaddress); 02036 02037 dest->transit_network_select = src->transit_network_select; 02038 }
| void ast_party_dialed_set_init | ( | struct ast_party_dialed * | init, | |
| const struct ast_party_dialed * | guide | |||
| ) |
Initialize the given dialed structure using the given guide for a set update operation.
| init | Caller structure to initialize. | |
| guide | Source dialed to use as a guide in initializing. |
Definition at line 2019 of file channel.c.
References ast_party_subaddress_set_init(), ast_party_dialed::number, ast_party_dialed::plan, ast_party_dialed::str, ast_party_dialed::subaddress, and ast_party_dialed::transit_network_select.
Referenced by callerid_write().
02020 { 02021 init->number.str = NULL; 02022 init->number.plan = guide->number.plan; 02023 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress); 02024 init->transit_network_select = guide->transit_network_select; 02025 }
| void ast_party_id_copy | ( | struct ast_party_id * | dest, | |
| const struct ast_party_id * | src | |||
| ) |
Copy the source party id information to the destination party id.
| dest | Destination party id | |
| src | Source party id |
Definition at line 1876 of file channel.c.
References ast_free, ast_party_name_copy(), ast_party_number_copy(), ast_party_subaddress_copy(), ast_strdup, ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_connected_line_copy_from_caller(), ast_connected_line_copy_to_caller(), ast_party_caller_copy(), ast_party_connected_line_copy(), ast_party_redirecting_copy(), and parkandannounce_exec().
01877 { 01878 if (dest == src) { 01879 /* Don't copy to self */ 01880 return; 01881 } 01882 01883 ast_party_name_copy(&dest->name, &src->name); 01884 ast_party_number_copy(&dest->number, &src->number); 01885 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress); 01886 01887 ast_free(dest->tag); 01888 dest->tag = ast_strdup(src->tag); 01889 }
| void ast_party_id_free | ( | struct ast_party_id * | doomed | ) |
Destroy the party id contents.
| doomed | The party id to destroy. |
Definition at line 1922 of file channel.c.
References ast_free, ast_party_name_free(), ast_party_number_free(), ast_party_subaddress_free(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_free(), ast_party_connected_line_free(), ast_party_redirecting_free(), and parkandannounce_exec().
01923 { 01924 ast_party_name_free(&doomed->name); 01925 ast_party_number_free(&doomed->number); 01926 ast_party_subaddress_free(&doomed->subaddress); 01927 01928 ast_free(doomed->tag); 01929 doomed->tag = NULL; 01930 }
| void ast_party_id_init | ( | struct ast_party_id * | init | ) |
Initialize the given party id structure.
| init | Party id structure to initialize. |
Definition at line 1868 of file channel.c.
References ast_party_name_init(), ast_party_number_init(), ast_party_subaddress_init(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_init(), ast_party_connected_line_init(), ast_party_redirecting_init(), dial_exec_full(), and parkandannounce_exec().
01869 { 01870 ast_party_name_init(&init->name); 01871 ast_party_number_init(&init->number); 01872 ast_party_subaddress_init(&init->subaddress); 01873 init->tag = NULL; 01874 }
| int ast_party_id_presentation | ( | const struct ast_party_id * | id | ) |
Determine the overall presentation value for the given party.
| id | Party to determine the overall presentation value. |
Definition at line 1932 of file channel.c.
References AST_PRES_ALLOWED, AST_PRES_NUMBER_TYPE, AST_PRES_RESTRICTED, AST_PRES_RESTRICTION, AST_PRES_UNAVAILABLE, AST_PRES_USER_NUMBER_UNSCREENED, ast_party_id::name, ast_party_id::number, ast_party_number::valid, and ast_party_name::valid.
Referenced by add_rpid(), ast_str_retrieve_variable(), ast_var_channels_table(), callerpres_read(), iax2_call(), initreqprep(), oh323_call(), party_id_build_data(), party_id_read(), redirecting_read(), report_new_callerid(), setup_env(), sip_call(), and socket_process().
01933 { 01934 int number_priority; 01935 int number_value; 01936 int number_screening; 01937 int name_priority; 01938 int name_value; 01939 01940 /* Determine name presentation priority. */ 01941 if (!id->name.valid) { 01942 name_value = AST_PRES_UNAVAILABLE; 01943 name_priority = 3; 01944 } else { 01945 name_value = id->name.presentation & AST_PRES_RESTRICTION; 01946 switch (name_value) { 01947 case AST_PRES_RESTRICTED: 01948 name_priority = 0; 01949 break; 01950 case AST_PRES_ALLOWED: 01951 name_priority = 1; 01952 break; 01953 case AST_PRES_UNAVAILABLE: 01954 name_priority = 2; 01955 break; 01956 default: 01957 name_value = AST_PRES_UNAVAILABLE; 01958 name_priority = 3; 01959 break; 01960 } 01961 } 01962 01963 /* Determine number presentation priority. */ 01964 if (!id->number.valid) { 01965 number_screening = AST_PRES_USER_NUMBER_UNSCREENED; 01966 number_value = AST_PRES_UNAVAILABLE; 01967 number_priority = 3; 01968 } else { 01969 number_screening = id->number.presentation & AST_PRES_NUMBER_TYPE; 01970 number_value = id->number.presentation & AST_PRES_RESTRICTION; 01971 switch (number_value) { 01972 case AST_PRES_RESTRICTED: 01973 number_priority = 0; 01974 break; 01975 case AST_PRES_ALLOWED: 01976 number_priority = 1; 01977 break; 01978 case AST_PRES_UNAVAILABLE: 01979 number_priority = 2; 01980 break; 01981 default: 01982 number_screening = AST_PRES_USER_NUMBER_UNSCREENED; 01983 number_value = AST_PRES_UNAVAILABLE; 01984 number_priority = 3; 01985 break; 01986 } 01987 } 01988 01989 /* Select the wining presentation value. */ 01990 if (name_priority < number_priority) { 01991 number_value = name_value; 01992 } 01993 01994 return number_value | number_screening; 01995 }
| void ast_party_id_set | ( | struct ast_party_id * | dest, | |
| const struct ast_party_id * | src, | |||
| const struct ast_set_party_id * | update | |||
| ) |
Set the source party id information into the destination party id.
| dest | The id one wishes to update | |
| src | The new id values to update the dest | |
| update | What id information to update. NULL if all. |
Definition at line 1899 of file channel.c.
References ast_free, ast_party_name_set(), ast_party_number_set(), ast_party_subaddress_set(), ast_strdup, ast_party_id::name, ast_set_party_id::name, ast_party_id::number, ast_set_party_id::number, ast_party_id::subaddress, ast_set_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_set(), ast_party_connected_line_set(), and ast_party_redirecting_set().
01900 { 01901 if (dest == src) { 01902 /* Don't set to self */ 01903 return; 01904 } 01905 01906 if (!update || update->name) { 01907 ast_party_name_set(&dest->name, &src->name); 01908 } 01909 if (!update || update->number) { 01910 ast_party_number_set(&dest->number, &src->number); 01911 } 01912 if (!update || update->subaddress) { 01913 ast_party_subaddress_set(&dest->subaddress, &src->subaddress); 01914 } 01915 01916 if (src->tag && src->tag != dest->tag) { 01917 ast_free(dest->tag); 01918 dest->tag = ast_strdup(src->tag); 01919 } 01920 }
| void ast_party_id_set_init | ( | struct ast_party_id * | init, | |
| const struct ast_party_id * | guide | |||
| ) |
Initialize the given party id structure using the given guide for a set update operation.
| init | Party id structure to initialize. | |
| guide | Source party id to use as a guide in initializing. |
Definition at line 1891 of file channel.c.
References ast_party_name_set_init(), ast_party_number_set_init(), ast_party_subaddress_set_init(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_set_init(), ast_party_connected_line_set_init(), ast_party_redirecting_set_init(), and dial_exec_full().
01892 { 01893 ast_party_name_set_init(&init->name, &guide->name); 01894 ast_party_number_set_init(&init->number, &guide->number); 01895 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress); 01896 init->tag = NULL; 01897 }
| void ast_party_name_copy | ( | struct ast_party_name * | dest, | |
| const struct ast_party_name * | src | |||
| ) |
Copy the source party name information to the destination party name.
| dest | Destination party name | |
| src | Source party name |
Definition at line 1717 of file channel.c.
References ast_free, ast_strdup, ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.
Referenced by ast_party_id_copy().
01718 { 01719 if (dest == src) { 01720 /* Don't copy to self */ 01721 return; 01722 } 01723 01724 ast_free(dest->str); 01725 dest->str = ast_strdup(src->str); 01726 dest->char_set = src->char_set; 01727 dest->presentation = src->presentation; 01728 dest->valid = src->valid; 01729 }
| void ast_party_name_free | ( | struct ast_party_name * | doomed | ) |
Destroy the party name contents.
| doomed | The party name to destroy. |
Definition at line 1756 of file channel.c.
References ast_free, and ast_party_name::str.
Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_free(), and skinny_newcall().
| void ast_party_name_init | ( | struct ast_party_name * | init | ) |
Initialize the given name structure.
| init | Name structure to initialize. |
Definition at line 1709 of file channel.c.
References AST_PARTY_CHAR_SET_ISO8859_1, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.
Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_init(), and skinny_newcall().
01710 { 01711 init->str = NULL; 01712 init->char_set = AST_PARTY_CHAR_SET_ISO8859_1; 01713 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 01714 init->valid = 0; 01715 }
| void ast_party_name_set | ( | struct ast_party_name * | dest, | |
| const struct ast_party_name * | src | |||
| ) |
Set the source party name information into the destination party name.
| dest | The name one wishes to update | |
| src | The new name values to update the dest |
Definition at line 1739 of file channel.c.
References ast_free, ast_strdup, ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.
Referenced by ast_party_id_set().
01740 { 01741 if (dest == src) { 01742 /* Don't set to self */ 01743 return; 01744 } 01745 01746 if (src->str && src->str != dest->str) { 01747 ast_free(dest->str); 01748 dest->str = ast_strdup(src->str); 01749 } 01750 01751 dest->char_set = src->char_set; 01752 dest->presentation = src->presentation; 01753 dest->valid = src->valid; 01754 }
| void ast_party_name_set_init | ( | struct ast_party_name * | init, | |
| const struct ast_party_name * | guide | |||
| ) |
Initialize the given party name structure using the given guide for a set update operation.
| init | Party name structure to initialize. | |
| guide | Source party name to use as a guide in initializing. |
Definition at line 1731 of file channel.c.
References ast_party_name::char_set, ast_party_name::presentation, ast_party_name::str, and ast_party_name::valid.
Referenced by ast_party_id_set_init().
01732 { 01733 init->str = NULL; 01734 init->char_set = guide->char_set; 01735 init->presentation = guide->presentation; 01736 init->valid = guide->valid; 01737 }
| void ast_party_number_copy | ( | struct ast_party_number * | dest, | |
| const struct ast_party_number * | src | |||
| ) |
Copy the source party number information to the destination party number.
Definition at line 1770 of file channel.c.
References ast_free, ast_strdup, ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.
Referenced by ast_party_id_copy().
01771 { 01772 if (dest == src) { 01773 /* Don't copy to self */ 01774 return; 01775 } 01776 01777 ast_free(dest->str); 01778 dest->str = ast_strdup(src->str); 01779 dest->plan = src->plan; 01780 dest->presentation = src->presentation; 01781 dest->valid = src->valid; 01782 }
| void ast_party_number_free | ( | struct ast_party_number * | doomed | ) |
Destroy the party number contents.
| doomed | The party number to destroy. |
Definition at line 1809 of file channel.c.
References ast_free, and ast_party_number::str.
Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_free(), do_forward(), skinny_newcall(), and wait_for_answer().
| void ast_party_number_init | ( | struct ast_party_number * | init | ) |
Initialize the given number structure.
| init | Number structure to initialize. |
Definition at line 1762 of file channel.c.
References AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.
Referenced by __analog_ss_thread(), analog_ss_thread(), ast_party_id_init(), do_forward(), skinny_newcall(), and wait_for_answer().
01763 { 01764 init->str = NULL; 01765 init->plan = 0;/* Unknown */ 01766 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 01767 init->valid = 0; 01768 }
| void ast_party_number_set | ( | struct ast_party_number * | dest, | |
| const struct ast_party_number * | src | |||
| ) |
Set the source party number information into the destination party number.
Definition at line 1792 of file channel.c.
References ast_free, ast_strdup, ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.
Referenced by ast_party_id_set().
01793 { 01794 if (dest == src) { 01795 /* Don't set to self */ 01796 return; 01797 } 01798 01799 if (src->str && src->str != dest->str) { 01800 ast_free(dest->str); 01801 dest->str = ast_strdup(src->str); 01802 } 01803 01804 dest->plan = src->plan; 01805 dest->presentation = src->presentation; 01806 dest->valid = src->valid; 01807 }
| void ast_party_number_set_init | ( | struct ast_party_number * | init, | |
| const struct ast_party_number * | guide | |||
| ) |
Initialize the given party number structure using the given guide for a set update operation.
| init | Party number structure to initialize. | |
| guide | Source party number to use as a guide in initializing. |
Definition at line 1784 of file channel.c.
References ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, and ast_party_number::valid.
Referenced by ast_party_id_set_init().
01785 { 01786 init->str = NULL; 01787 init->plan = guide->plan; 01788 init->presentation = guide->presentation; 01789 init->valid = guide->valid; 01790 }
| 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.
| dest | Destination redirecting | |
| src | Source redirecting |
Definition at line 2145 of file channel.c.
References ast_party_id_copy(), ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, and ast_party_redirecting::to.
Referenced by ast_call_forward(), ast_channel_redirecting_macro(), begin_dial_channel(), call_forward_inherit(), dial_exec_full(), do_forward(), local_call(), ring_entry(), and wait_for_answer().
02146 { 02147 if (dest == src) { 02148 /* Don't copy to self */ 02149 return; 02150 } 02151 02152 ast_party_id_copy(&dest->from, &src->from); 02153 ast_party_id_copy(&dest->to, &src->to); 02154 dest->count = src->count; 02155 dest->reason = src->reason; 02156 }
| void ast_party_redirecting_free | ( | struct ast_party_redirecting * | doomed | ) |
Destroy the redirecting information contents.
| doomed | The redirecting information to destroy. |
Definition at line 2174 of file channel.c.
References ast_party_id_free(), ast_party_redirecting::from, and ast_party_redirecting::to.
Referenced by ast_channel_destructor(), ast_dummy_channel_destructor(), ast_indicate_data(), call_forward_inherit(), do_forward(), handle_request_invite(), handle_response(), handle_response_invite(), redirecting_write(), and wait_for_answer().
02175 { 02176 ast_party_id_free(&doomed->from); 02177 ast_party_id_free(&doomed->to); 02178 }
| void ast_party_redirecting_init | ( | struct ast_party_redirecting * | init | ) |
Initialize the given redirecting structure.
| init | Redirecting structure to initialize. |
Definition at line 2137 of file channel.c.
References ast_party_id_init(), AST_REDIRECTING_REASON_UNKNOWN, ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, and ast_party_redirecting::to.
Referenced by __ast_channel_alloc_ap(), call_forward_inherit(), do_forward(), handle_request_invite(), handle_response(), handle_response_invite(), and wait_for_answer().
02138 { 02139 ast_party_id_init(&init->from); 02140 ast_party_id_init(&init->to); 02141 init->count = 0; 02142 init->reason = AST_REDIRECTING_REASON_UNKNOWN; 02143 }
| void ast_party_redirecting_set | ( | struct ast_party_redirecting * | dest, | |
| const struct ast_party_redirecting * | src, | |||
| const struct ast_set_party_redirecting * | update | |||
| ) |
Set the redirecting information based on another redirecting source.
| dest | The redirecting one wishes to update | |
| src | The new redirecting values to update the dest | |
| update | What redirecting information to update. NULL if all. |
Definition at line 2166 of file channel.c.
References ast_party_id_set(), ast_party_redirecting::count, ast_set_party_redirecting::from, ast_party_redirecting::from, ast_party_redirecting::reason, ast_set_party_redirecting::to, and ast_party_redirecting::to.
Referenced by ast_channel_set_redirecting().
02167 { 02168 ast_party_id_set(&dest->from, &src->from, update ? &update->from : NULL); 02169 ast_party_id_set(&dest->to, &src->to, update ? &update->to : NULL); 02170 dest->reason = src->reason; 02171 dest->count = src->count; 02172 }
| 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.
| init | Redirecting id structure to initialize. | |
| guide | Source redirecting id to use as a guide in initializing. |
Definition at line 2158 of file channel.c.
References ast_party_id_set_init(), ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, and ast_party_redirecting::to.
Referenced by ast_indicate_data(), misdn_copy_redirecting_to_ast(), and redirecting_write().
02159 { 02160 ast_party_id_set_init(&init->from, &guide->from); 02161 ast_party_id_set_init(&init->to, &guide->to); 02162 init->count = guide->count; 02163 init->reason = guide->reason; 02164 }
| 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.
| dest | Destination party subaddress | |
| src | Source party subaddress |
Definition at line 1823 of file channel.c.
References ast_free, ast_strdup, ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.
Referenced by ast_party_dialed_copy(), and ast_party_id_copy().
01824 { 01825 if (dest == src) { 01826 /* Don't copy to self */ 01827 return; 01828 } 01829 01830 ast_free(dest->str); 01831 dest->str = ast_strdup(src->str); 01832 dest->type = src->type; 01833 dest->odd_even_indicator = src->odd_even_indicator; 01834 dest->valid = src->valid; 01835 }
| void ast_party_subaddress_free | ( | struct ast_party_subaddress * | doomed | ) |
Destroy the party subaddress contents.
| doomed | The party subaddress to destroy. |
Definition at line 1862 of file channel.c.
References ast_free, and ast_party_subaddress::str.
Referenced by ast_party_dialed_free(), and ast_party_id_free().
| void ast_party_subaddress_init | ( | struct ast_party_subaddress * | init | ) |
Initialize the given subaddress structure.
| init | Subaddress structure to initialize. |
Definition at line 1815 of file channel.c.
References ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.
Referenced by ast_party_dialed_init(), and ast_party_id_init().
01816 { 01817 init->str = NULL; 01818 init->type = 0; 01819 init->odd_even_indicator = 0; 01820 init->valid = 0; 01821 }
| 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.
| dest | The subaddress one wishes to update | |
| src | The new subaddress values to update the dest |
Definition at line 1845 of file channel.c.
References ast_free, ast_strdup, ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.
Referenced by ast_party_dialed_set(), and ast_party_id_set().
01846 { 01847 if (dest == src) { 01848 /* Don't set to self */ 01849 return; 01850 } 01851 01852 if (src->str && src->str != dest->str) { 01853 ast_free(dest->str); 01854 dest->str = ast_strdup(src->str); 01855 } 01856 01857 dest->type = src->type; 01858 dest->odd_even_indicator = src->odd_even_indicator; 01859 dest->valid = src->valid; 01860 }
| void ast_party_subaddress_set_init | ( | struct ast_party_subaddress * | init, | |
| const struct ast_party_subaddress * | guide | |||
| ) |
Initialize the given party subaddress structure using the given guide for a set update operation.
| init | Party subaddress structure to initialize. | |
| guide | Source party subaddress to use as a guide in initializing. |
Definition at line 1837 of file channel.c.
References ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.
Referenced by ast_party_dialed_set_init(), and ast_party_id_set_init().
01838 { 01839 init->str = NULL; 01840 init->type = guide->type; 01841 init->odd_even_indicator = guide->odd_even_indicator; 01842 init->valid = guide->valid; 01843 }
| int ast_plc_reload | ( | void | ) |
Reload genericplc configuration value from codecs.conf.
Implementation is in main/channel.c
Definition at line 7831 of file channel.c.
References ast_config_destroy(), ast_config_load, AST_OPT_FLAG_GENERIC_PLC, ast_options, ast_set2_flag, ast_true(), ast_variable_browse(), CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, ast_variable::name, ast_variable::next, ast_variable::value, and var.
Referenced by ast_channels_init().
07832 { 07833 struct ast_variable *var; 07834 struct ast_flags config_flags = { 0 }; 07835 struct ast_config *cfg = ast_config_load("codecs.conf", config_flags); 07836 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) 07837 return 0; 07838 for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) { 07839 if (!strcasecmp(var->name, "genericplc")) { 07840 ast_set2_flag(&ast_options, ast_true(var->value), AST_OPT_FLAG_GENERIC_PLC); 07841 } 07842 } 07843 ast_config_destroy(cfg); 07844 return 0; 07845 }
| void ast_poll_channel_add | ( | struct ast_channel * | chan0, | |
| struct ast_channel * | chan1 | |||
| ) |
Add a channel to an optimized waitfor
Definition at line 2437 of file channel.c.
References AST_MAX_FDS, and ast_channel::fds.
Referenced by ast_generic_bridge(), begin_dial_channel(), feature_request_and_dial(), local_bridge_loop(), remote_bridge_loop(), and wait_for_answer().
02438 { 02439 #ifdef HAVE_EPOLL 02440 struct epoll_event ev; 02441 int i = 0; 02442 02443 if (chan0->epfd == -1) 02444 return; 02445 02446 /* Iterate through the file descriptors on chan1, adding them to chan0 */ 02447 for (i = 0; i < AST_MAX_FDS; i++) { 02448 if (chan1->fds[i] == -1) 02449 continue; 02450 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 02451 ev.data.ptr = chan1->epfd_data[i]; 02452 epoll_ctl(chan0->epfd, EPOLL_CTL_ADD, chan1->fds[i], &ev); 02453 } 02454 02455 #endif 02456 return; 02457 }
| void ast_poll_channel_del | ( | struct ast_channel * | chan0, | |
| struct ast_channel * | chan1 | |||
| ) |
Delete a channel from an optimized waitfor
Definition at line 2460 of file channel.c.
References AST_MAX_FDS, and ast_channel::fds.
Referenced by ast_generic_bridge(), feature_request_and_dial(), local_bridge_loop(), monitor_dial(), remote_bridge_loop(), and wait_for_answer().
02461 { 02462 #ifdef HAVE_EPOLL 02463 struct epoll_event ev; 02464 int i = 0; 02465 02466 if (chan0->epfd == -1) 02467 return; 02468 02469 for (i = 0; i < AST_MAX_FDS; i++) { 02470 if (chan1->fds[i] == -1) 02471 continue; 02472 epoll_ctl(chan0->epfd, EPOLL_CTL_DEL, chan1->fds[i], &ev); 02473 } 02474 02475 #endif 02476 return; 02477 }
| char* ast_print_group | ( | char * | buf, | |
| int | buflen, | |||
| ast_group_t | group | |||
| ) |
Print call group and pickup group ---.
print call- and pickup groups into buffer
Definition at line 7979 of file channel.c.
References first.
Referenced by _sip_show_peer(), _skinny_show_line(), func_channel_read(), function_sippeer(), misdn_cfg_get_config_string(), print_group(), read_config(), and serialize_showchan().
07980 { 07981 unsigned int i; 07982 int first = 1; 07983 char num[3]; 07984 07985 buf[0] = '\0'; 07986 07987 if (!group) /* Return empty string if no group */ 07988 return buf; 07989 07990 for (i = 0; i <= 63; i++) { /* Max group is 63 */ 07991 if (group & ((ast_group_t) 1 << i)) { 07992 if (!first) { 07993 strncat(buf, ", ", buflen - strlen(buf) - 1); 07994 } else { 07995 first = 0; 07996 } 07997 snprintf(num, sizeof(num), "%u", i); 07998 strncat(buf, num, buflen - strlen(buf) - 1); 07999 } 08000 } 08001 return buf; 08002 }
| int ast_prod | ( | struct ast_channel * | chan | ) |
Send empty audio to prime a channel driver.
Definition at line 4512 of file channel.c.
References ast_channel::_state, ast_channel_name(), ast_debug, ast_format_copy(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), AST_STATE_UP, ast_write(), ast_frame::data, ast_frame_subclass::format, LOG_WARNING, ast_frame::ptr, ast_channel::rawwriteformat, ast_frame::src, and ast_frame::subclass.
Referenced by ast_activate_generator().
04513 { 04514 struct ast_frame a = { AST_FRAME_VOICE }; 04515 char nothing[128]; 04516 04517 /* Send an empty audio frame to get things moving */ 04518 if (chan->_state != AST_STATE_UP) { 04519 ast_debug(1, "Prodding channel '%s'\n", ast_channel_name(chan)); 04520 ast_format_copy(&a.subclass.format, &chan->rawwriteformat); 04521 a.data.ptr = nothing + AST_FRIENDLY_OFFSET; 04522 a.src = "ast_prod"; /* this better match check in ast_write */ 04523 if (ast_write(chan, &a)) 04524 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", ast_channel_name(chan)); 04525 } 04526 return 0; 04527 }
| int ast_queue_control | ( | struct ast_channel * | chan, | |
| enum ast_control_frame_type | control | |||
| ) |
Queue a control frame.
Queue a control frame with payload.
Definition at line 1381 of file channel.c.
References AST_FRAME_CONTROL, and ast_queue_frame().
Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_read(), __dahdi_exception(), __oh323_update_info(), analog_call(), analog_exception(), analog_hangup(), analog_ss_thread(), ast_do_pickup(), attempt_transfer(), auto_congest(), cb_events(), cli_console_answer(), cli_console_flash(), console_answer(), console_call(), console_sendtext(), dahdi_handle_event(), dahdi_hangup(), gtalk_is_answered(), gtalk_ringing_ack(), handle_hd_hf(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_refer(), HandleCallIncoming(), jingle_is_answered(), jingle_ringing_ack(), masquerade_colp_transfer(), misdn_facility_ie_handler(), multicast_rtp_call(), nbs_call(), phone_call(), process_sdp(), receive_digit(), remote_hold(), send_cause2ast(), setsubstate(), setup_rtp_connection(), skinny_call(), skinny_transfer(), unistim_call(), and update_state().
01382 { 01383 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control }; 01384 return ast_queue_frame(chan, &f); 01385 }
| 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.
| chan | channel to queue frame onto | |
| control | type of control frame | |
| data | pointer to payload data to be included in frame | |
| datalen | number of bytes of payload data |
| 0 | success | |
| non-zero | failure |
The channel does not need to be locked before calling this function.
Definition at line 1388 of file channel.c.
References AST_FRAME_CONTROL, and ast_queue_frame().
Referenced by __analog_handle_event(), analog_hangup(), ast_channel_queue_connected_line_update(), ast_channel_queue_redirecting_update(), change_t38_state(), dahdi_handle_event(), dahdi_hangup(), fax_gateway_indicate_t38(), handle_request_notify(), handle_response_refer(), iax2_queue_control_data(), iax2_transfer(), interpret_t38_parameters(), local_attended_transfer(), masquerade_colp_transfer(), process_sdp(), setsubstate(), and sip_sipredirect().
01390 { 01391 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control, .data.ptr = (void *) data, .datalen = datalen }; 01392 return ast_queue_frame(chan, &f); 01393 }
| int ast_queue_frame | ( | struct ast_channel * | chan, | |
| struct ast_frame * | f | |||
| ) |
Queue one or more frames to a channel's frame queue.
| chan | the channel to queue the frame(s) on | |
| f | the frame(s) to queue. Note that the frame(s) will be duplicated by this function. It is the responsibility of the caller to handle freeing the memory associated with the frame(s) being passed if necessary. |
| 0 | success | |
| non-zero | failure |
Definition at line 1326 of file channel.c.
References __ast_queue_frame().
Referenced by __ast_channel_masquerade(), __ast_read(), __oh323_rtp_create(), __oh323_update_info(), action_atxfer(), agent_request(), alsa_call(), ast_channel_setwhentohangup_tv(), ast_do_masquerade(), ast_dsp_process(), ast_queue_cc_frame(), ast_queue_control(), ast_queue_control_data(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_softhangup_nolock(), bridge_write(), cb_events(), cli_console_dial(), cli_console_sendtext(), conf_stop_record(), console_dial(), console_do_answer(), console_flash(), console_sendtext(), dahdi_queue_frame(), dahdi_read(), dictate_exec(), do_immediate_setup(), gtalk_handle_dtmf(), handle_keypad_button_message(), handle_request_info(), handle_request_invite(), handle_response_invite(), iax2_queue_frame(), jingle_handle_dtmf(), local_queue_frame(), mgcp_queue_frame(), oh323_simulate_dtmf_end(), oss_call(), process_sdp(), queue_dtmf_readq(), receive_digit(), receive_message(), rpt_call(), stream_monitor(), t38_tx_packet_handler(), unistim_do_senddigit(), unistim_senddigit_end(), usbradio_read(), and wakeup_sub().
01327 { 01328 return __ast_queue_frame(chan, fin, 0, NULL); 01329 }
| int ast_queue_frame_head | ( | struct ast_channel * | chan, | |
| struct ast_frame * | f | |||
| ) |
Queue one or more frames to the head of a channel's frame queue.
| chan | the channel to queue the frame(s) on | |
| f | the frame(s) to queue. Note that the frame(s) will be duplicated by this function. It is the responsibility of the caller to handle freeing the memory associated with the frame(s) being passed if necessary. |
| 0 | success | |
| non-zero | failure |
Definition at line 1331 of file channel.c.
References __ast_queue_frame().
Referenced by __ast_answer(), __ast_read(), ast_autoservice_stop(), ast_safe_sleep_conditional(), and feature_request_and_dial().
01332 { 01333 return __ast_queue_frame(chan, fin, 1, NULL); 01334 }
| int ast_queue_hangup | ( | struct ast_channel * | chan | ) |
Queue a hangup frame for channel.
Queue a hangup frame.
Definition at line 1337 of file channel.c.
References ast_channel::_softhangup, ast_channel_name(), ast_channel_trylock, ast_channel_uniqueid(), ast_channel_unlock, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), AST_SOFTHANGUP_DEV, EVENT_FLAG_CALL, and manager_event.
Referenced by cleanup_connection(), cli_console_hangup(), close_call(), gtalk_hangup_farend(), gtalk_is_answered(), handle_request_bye(), handle_request_cancel(), iax2_destroy(), iax2_queue_hangup(), jingle_hangup_farend(), local_fixup(), local_hangup(), mgcp_queue_hangup(), and setsubstate().
01338 { 01339 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP }; 01340 /* Yeah, let's not change a lock-critical value without locking */ 01341 if (!ast_channel_trylock(chan)) { 01342 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01343 manager_event(EVENT_FLAG_CALL, "HangupRequest", 01344 "Channel: %s\r\n" 01345 "Uniqueid: %s\r\n", 01346 ast_channel_name(chan), 01347 ast_channel_uniqueid(chan)); 01348 ast_channel_unlock(chan); 01349 } 01350 return ast_queue_frame(chan, &f); 01351 }
| int ast_queue_hangup_with_cause | ( | struct ast_channel * | chan, | |
| int | cause | |||
| ) |
Queue a hangup frame for channel.
Queue a hangup frame with hangupcause set.
Definition at line 1354 of file channel.c.
References ast_channel::_softhangup, ast_channel_name(), ast_channel_trylock, ast_channel_uniqueid(), ast_channel_unlock, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), AST_SOFTHANGUP_DEV, ast_frame::data, EVENT_FLAG_CALL, ast_channel::hangupcause, manager_event, and ast_frame::uint32.
Referenced by __analog_handle_event(), __oh323_update_info(), __sip_autodestruct(), close_call(), close_client(), console_hangup(), dahdi_handle_event(), handle_request_bye(), handle_response(), handle_response_invite(), HandleCallOutgoing(), hangup_chan(), hangup_connection(), misdn_answer(), retrans_pkt(), and TransferCallStep1().
01355 { 01356 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP }; 01357 01358 if (cause >= 0) 01359 f.data.uint32 = cause; 01360 01361 /* Yeah, let's not change a lock-critical value without locking */ 01362 if (!ast_channel_trylock(chan)) { 01363 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01364 if (cause < 0) 01365 f.data.uint32 = chan->hangupcause; 01366 01367 manager_event(EVENT_FLAG_CALL, "HangupRequest", 01368 "Channel: %s\r\n" 01369 "Uniqueid: %s\r\n" 01370 "Cause: %d\r\n", 01371 ast_channel_name(chan), 01372 ast_channel_uniqueid(chan), 01373 cause); 01374 ast_channel_unlock(chan); 01375 } 01376 01377 return ast_queue_frame(chan, &f); 01378 }
| int ast_raw_answer | ( | struct ast_channel * | chan, | |
| int | cdr_answer | |||
| ) |
Answer a channel.
| chan | channel to answer | |
| cdr_answer | flag to control whether any associated CDR should be marked as 'answered' |
Unlike ast_answer(), this function will not wait for media flow to begin. The caller should be careful before sending media to the channel before incoming media arrives, as the outgoing media may be lost.
| 0 | on success | |
| non-zero | on failure |
Definition at line 2715 of file channel.c.
References ast_channel::_state, ast_channel_tech::answer, ast_cdr_answer(), AST_CEL_ANSWER, ast_cel_report_event(), ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_indicate(), ast_setstate(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_test_flag, ast_channel::cdr, and ast_channel::tech.
Referenced by __ast_answer(), and ast_bridge_call().
02716 { 02717 int res = 0; 02718 02719 ast_channel_lock(chan); 02720 02721 /* You can't answer an outbound call */ 02722 if (ast_test_flag(chan, AST_FLAG_OUTGOING)) { 02723 ast_channel_unlock(chan); 02724 return 0; 02725 } 02726 02727 /* Stop if we're a zombie or need a soft hangup */ 02728 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02729 ast_channel_unlock(chan); 02730 return -1; 02731 } 02732 02733 ast_channel_unlock(chan); 02734 02735 switch (chan->_state) { 02736 case AST_STATE_RINGING: 02737 case AST_STATE_RING: 02738 ast_channel_lock(chan); 02739 if (chan->tech->answer) { 02740 res = chan->tech->answer(chan); 02741 } 02742 ast_setstate(chan, AST_STATE_UP); 02743 if (cdr_answer) { 02744 ast_cdr_answer(chan->cdr); 02745 } 02746 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 02747 ast_channel_unlock(chan); 02748 break; 02749 case AST_STATE_UP: 02750 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 02751 /* Calling ast_cdr_answer when it it has previously been called 02752 * is essentially a no-op, so it is safe. 02753 */ 02754 if (cdr_answer) { 02755 ast_cdr_answer(chan->cdr); 02756 } 02757 break; 02758 default: 02759 break; 02760 } 02761 02762 ast_indicate(chan, -1); 02763 02764 return res; 02765 }
| struct ast_frame* ast_read | ( | struct ast_channel * | chan | ) | [read] |
Reads a frame.
| chan | channel to read a frame from |
Definition at line 4107 of file channel.c.
References __ast_read().
Referenced by __adsi_transmit_messages(), __analog_ss_thread(), __ast_answer(), __ast_play_and_record(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), agent_read(), analog_ss_thread(), ast_bridge_handle_trip(), ast_generic_bridge(), ast_recvtext(), ast_safe_sleep_conditional(), ast_tonepair(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), async_agi_read_frame(), async_wait(), autoservice_run(), background_detect_exec(), channel_spy(), conf_flush(), conf_run(), dahdi_bridge(), dial_exec_full(), dictate_exec(), disa_exec(), disable_t38(), do_waiting(), echo_exec(), eivr_comm(), feature_request_and_dial(), find_cache(), generic_fax_exec(), handle_recordfile(), handle_speechrecognize(), iax2_bridge(), ices_exec(), isAnsweringMachine(), jack_exec(), local_bridge_loop(), manage_parked_call(), measurenoise(), misdn_bridge(), monitor_dial(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), receivefax_t38_init(), record_exec(), recordthread(), remote_bridge_loop(), rpt(), rpt_exec(), run_agi(), send_tone_burst(), send_waveform_to_channel(), sendfax_t38_init(), sendurl_exec(), speech_background(), transmit_audio(), transmit_t38(), wait_for_answer(), wait_for_hangup(), wait_for_winner(), waitforring_exec(), and waitstream_core().
04108 { 04109 return __ast_read(chan, 0); 04110 }
| static void ast_read_generator_actions | ( | struct ast_channel * | chan, | |
| struct ast_frame * | f | |||
| ) | [static] |
Definition at line 3462 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_deactivate_generator(), ast_debug, ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_rate(), AST_FRAME_CNG, ast_internal_timing_enabled(), ast_settimeout(), ast_frame::datalen, ast_frame_subclass::format, ast_frame::frametype, ast_generator::generate, ast_channel::generator, generator_force(), ast_channel::generatordata, ast_frame::samples, ast_frame::subclass, ast_channel::timingfd, ast_channel::timingfunc, and ast_channel::writeformat.
Referenced by __ast_read().
03463 { 03464 if (chan->generator && chan->generator->generate && chan->generatordata && !ast_internal_timing_enabled(chan)) { 03465 void *tmp = chan->generatordata; 03466 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = chan->generator->generate; 03467 int res; 03468 int samples; 03469 03470 if (chan->timingfunc) { 03471 ast_debug(1, "Generator got voice, switching to phase locked mode\n"); 03472 ast_settimeout(chan, 0, NULL, NULL); 03473 } 03474 03475 chan->generatordata = NULL; /* reset, to let writes go through */ 03476 03477 if (ast_format_cmp(&f->subclass.format, &chan->writeformat) == AST_FORMAT_CMP_NOT_EQUAL) { 03478 float factor; 03479 factor = ((float) ast_format_rate(&chan->writeformat)) / ((float) ast_format_rate(&f->subclass.format)); 03480 samples = (int) ( ((float) f->samples) * factor ); 03481 } else { 03482 samples = f->samples; 03483 } 03484 03485 /* This unlock is here based on two assumptions that hold true at this point in the 03486 * code. 1) this function is only called from within __ast_read() and 2) all generators 03487 * call ast_write() in their generate callback. 03488 * 03489 * The reason this is added is so that when ast_write is called, the lock that occurs 03490 * there will not recursively lock the channel. Doing this will cause intended deadlock 03491 * avoidance not to work in deeper functions 03492 */ 03493 ast_channel_unlock(chan); 03494 res = generate(chan, tmp, f->datalen, samples); 03495 ast_channel_lock(chan); 03496 chan->generatordata = tmp; 03497 if (res) { 03498 ast_debug(1, "Auto-deactivating generator\n"); 03499 ast_deactivate_generator(chan); 03500 } 03501 03502 } else if (f->frametype == AST_FRAME_CNG) { 03503 if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) { 03504 ast_debug(1, "Generator got CNG, switching to timed mode\n"); 03505 ast_settimeout(chan, 50, generator_force, chan); 03506 } 03507 } 03508 }
| struct ast_frame* ast_read_noaudio | ( | struct ast_channel * | chan | ) | [read] |
Reads a frame, returning AST_FRAME_NULL frame if audio.
| chan | channel to read a frame from |
Definition at line 4112 of file channel.c.
References __ast_read().
Referenced by ast_bridge_handle_trip(), and conf_run().
04113 { 04114 return __ast_read(chan, 1); 04115 }
| int ast_readstring | ( | struct ast_channel * | c, | |
| char * | s, | |||
| int | len, | |||
| int | timeout, | |||
| int | rtimeout, | |||
| char * | enders | |||
| ) |
Reads multiple digits.
| c | channel to read from | |
| s | string to read in to. Must be at least the size of your length | |
| len | how many digits to read (maximum) | |
| timeout | how long to timeout between digits | |
| rtimeout | timeout to wait on the first digit | |
| enders | digits to end the string |
Definition at line 5686 of file channel.c.
References ast_readstring_full().
Referenced by __adsi_transmit_messages(), ast_adsi_begin_download(), ast_adsi_get_cpeinfo(), ast_adsi_load_session(), ast_app_getdata(), dialout(), do_directory(), forward_message(), privacy_exec(), vm_authenticate(), vm_newuser(), and vm_options().
05687 { 05688 return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1); 05689 }
| int ast_readstring_full | ( | struct ast_channel * | c, | |
| char * | s, | |||
| int | len, | |||
| int | timeout, | |||
| int | ftimeout, | |||
| char * | enders, | |||
| int | audiofd, | |||
| int | ctrlfd | |||
| ) |
Definition at line 5691 of file channel.c.
References ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, AST_GETDATA_COMPLETE, AST_GETDATA_EMPTY_END_TERMINATED, AST_GETDATA_FAILED, AST_GETDATA_INTERRUPTED, AST_GETDATA_TIMEOUT, ast_opt_transmit_silence, ast_stopstream(), ast_test_flag, ast_waitfordigit_full(), ast_waitstream_full(), and ast_channel::stream.
Referenced by ast_app_getdata_full(), and ast_readstring().
05692 { 05693 int pos = 0; /* index in the buffer where we accumulate digits */ 05694 int to = ftimeout; 05695 05696 struct ast_silence_generator *silgen = NULL; 05697 05698 /* Stop if we're a zombie or need a soft hangup */ 05699 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 05700 return -1; 05701 if (!len) 05702 return -1; 05703 for (;;) { 05704 int d; 05705 if (c->stream) { 05706 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 05707 ast_stopstream(c); 05708 if (!silgen && ast_opt_transmit_silence) 05709 silgen = ast_channel_start_silence_generator(c); 05710 usleep(1000); 05711 if (!d) 05712 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 05713 } else { 05714 if (!silgen && ast_opt_transmit_silence) 05715 silgen = ast_channel_start_silence_generator(c); 05716 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 05717 } 05718 if (d < 0) { 05719 ast_channel_stop_silence_generator(c, silgen); 05720 return AST_GETDATA_FAILED; 05721 } 05722 if (d == 0) { 05723 s[pos] = '\0'; 05724 ast_channel_stop_silence_generator(c, silgen); 05725 return AST_GETDATA_TIMEOUT; 05726 } 05727 if (d == 1) { 05728 s[pos] = '\0'; 05729 ast_channel_stop_silence_generator(c, silgen); 05730 return AST_GETDATA_INTERRUPTED; 05731 } 05732 if (strchr(enders, d) && (pos == 0)) { 05733 s[pos] = '\0'; 05734 ast_channel_stop_silence_generator(c, silgen); 05735 return AST_GETDATA_EMPTY_END_TERMINATED; 05736 } 05737 if (!strchr(enders, d)) { 05738 s[pos++] = d; 05739 } 05740 if (strchr(enders, d) || (pos >= len)) { 05741 s[pos] = '\0'; 05742 ast_channel_stop_silence_generator(c, silgen); 05743 return AST_GETDATA_COMPLETE; 05744 } 05745 to = timeout; 05746 } 05747 /* Never reached */ 05748 return 0; 05749 }
| int ast_recvchar | ( | struct ast_channel * | chan, | |
| int | timeout | |||
| ) |
Receives a text character from a channel.
| chan | channel to act upon | |
| timeout | timeout in milliseconds (0 for infinite wait) |
Definition at line 4368 of file channel.c.
References ast_free, and ast_recvtext().
Referenced by handle_recvchar().
04369 { 04370 int c; 04371 char *buf = ast_recvtext(chan, timeout); 04372 if (buf == NULL) 04373 return -1; /* error or timeout */ 04374 c = *(unsigned char *)buf; 04375 ast_free(buf); 04376 return c; 04377 }
| char* ast_recvtext | ( | struct ast_channel * | chan, | |
| int | timeout | |||
| ) |
Receives a text string from a channel Read a string of text from a channel.
| chan | channel to act upon | |
| timeout | timeout in milliseconds (0 for infinite wait) |
Definition at line 4379 of file channel.c.
References ast_check_hangup(), AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_TEXT, ast_frfree, ast_read(), ast_strndup, ast_waitfor(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::ptr, and ast_frame::subclass.
Referenced by ast_recvchar(), and handle_recvtext().
04380 { 04381 int res, done = 0; 04382 char *buf = NULL; 04383 04384 while (!done) { 04385 struct ast_frame *f; 04386 if (ast_check_hangup(chan)) 04387 break; 04388 res = ast_waitfor(chan, timeout); 04389 if (res <= 0) /* timeout or error */ 04390 break; 04391 timeout = res; /* update timeout */ 04392 f = ast_read(chan); 04393 if (f == NULL) 04394 break; /* no frame */ 04395 if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP) 04396 done = 1; /* force a break */ 04397 else if (f->frametype == AST_FRAME_TEXT) { /* what we want */ 04398 buf = ast_strndup((char *) f->data.ptr, f->datalen); /* dup and break */ 04399 done = 1; 04400 } 04401 ast_frfree(f); 04402 } 04403 return buf; 04404 }
| int ast_redirecting_build_data | ( | unsigned char * | data, | |
| size_t | datalen, | |||
| const struct ast_party_redirecting * | redirecting, | |||
| const struct ast_set_party_redirecting * | update | |||
| ) |
Build the redirecting id data frame.
| data | Buffer to fill with the frame data | |
| datalen | Size of the buffer to fill | |
| redirecting | Redirecting id information | |
| update | What redirecting information to build. NULL if all. |
| -1 | if error | |
| Amount | of data buffer used |
Definition at line 8881 of file channel.c.
References ast_log(), AST_REDIRECTING_COUNT, AST_REDIRECTING_FROM_ID_PRESENTATION, AST_REDIRECTING_FROM_NAME, AST_REDIRECTING_FROM_NAME_CHAR_SET, AST_REDIRECTING_FROM_NAME_PRESENTATION, AST_REDIRECTING_FROM_NAME_VALID, AST_REDIRECTING_FROM_NUMBER, AST_REDIRECTING_FROM_NUMBER_PLAN, AST_REDIRECTING_FROM_NUMBER_PRESENTATION, AST_REDIRECTING_FROM_NUMBER_VALID, AST_REDIRECTING_FROM_SUBADDRESS, AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_FROM_SUBADDRESS_TYPE, AST_REDIRECTING_FROM_SUBADDRESS_VALID, AST_REDIRECTING_FROM_TAG, AST_REDIRECTING_TO_ID_PRESENTATION, AST_REDIRECTING_TO_NAME, AST_REDIRECTING_TO_NAME_CHAR_SET, AST_REDIRECTING_TO_NAME_PRESENTATION, AST_REDIRECTING_TO_NAME_VALID, AST_REDIRECTING_TO_NUMBER, AST_REDIRECTING_TO_NUMBER_PLAN, AST_REDIRECTING_TO_NUMBER_PRESENTATION, AST_REDIRECTING_TO_NUMBER_VALID, AST_REDIRECTING_TO_SUBADDRESS, AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_TO_SUBADDRESS_TYPE, AST_REDIRECTING_TO_SUBADDRESS_VALID, AST_REDIRECTING_TO_TAG, AST_REDIRECTING_VERSION, ast_party_redirecting::count, ast_set_party_redirecting::from, ast_party_redirecting::from, LOG_WARNING, ast_party_id_ies::name, party_id_build_data(), ast_party_redirecting::reason, ast_party_name_ies::str, ast_set_party_redirecting::to, ast_party_redirecting::to, and value.
Referenced by ast_channel_queue_redirecting_update(), ast_channel_update_redirecting(), and local_indicate().
08882 { 08883 int32_t value; 08884 size_t pos = 0; 08885 int res; 08886 08887 static const struct ast_party_id_ies from_ies = { 08888 .name.str = AST_REDIRECTING_FROM_NAME, 08889 .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET, 08890 .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION, 08891 .name.valid = AST_REDIRECTING_FROM_NAME_VALID, 08892 08893 .number.str = AST_REDIRECTING_FROM_NUMBER, 08894 .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN, 08895 .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION, 08896 .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID, 08897 08898 .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS, 08899 .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE, 08900 .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, 08901 .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID, 08902 08903 .tag = AST_REDIRECTING_FROM_TAG, 08904 .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION, 08905 }; 08906 static const struct ast_party_id_ies to_ies = { 08907 .name.str = AST_REDIRECTING_TO_NAME, 08908 .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET, 08909 .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION, 08910 .name.valid = AST_REDIRECTING_TO_NAME_VALID, 08911 08912 .number.str = AST_REDIRECTING_TO_NUMBER, 08913 .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN, 08914 .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION, 08915 .number.valid = AST_REDIRECTING_TO_NUMBER_VALID, 08916 08917 .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS, 08918 .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE, 08919 .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, 08920 .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID, 08921 08922 .tag = AST_REDIRECTING_TO_TAG, 08923 .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION, 08924 }; 08925 08926 /* Redirecting frame version */ 08927 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08928 ast_log(LOG_WARNING, "No space left for redirecting frame version\n"); 08929 return -1; 08930 } 08931 data[pos++] = AST_REDIRECTING_VERSION; 08932 data[pos++] = 1; 08933 data[pos++] = 2;/* Version 1 did not have a version ie */ 08934 08935 res = party_id_build_data(data + pos, datalen - pos, &redirecting->from, 08936 "redirecting-from", &from_ies, update ? &update->from : NULL); 08937 if (res < 0) { 08938 return -1; 08939 } 08940 pos += res; 08941 08942 res = party_id_build_data(data + pos, datalen - pos, &redirecting->to, 08943 "redirecting-to", &to_ies, update ? &update->to : NULL); 08944 if (res < 0) { 08945 return -1; 08946 } 08947 pos += res; 08948 08949 /* Redirecting reason */ 08950 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 08951 ast_log(LOG_WARNING, "No space left for redirecting reason\n"); 08952 return -1; 08953 } 08954 data[pos++] = AST_REDIRECTING_REASON; 08955 data[pos++] = sizeof(value); 08956 value = htonl(redirecting->reason); 08957 memcpy(data + pos, &value, sizeof(value)); 08958 pos += sizeof(value); 08959 08960 /* Redirecting count */ 08961 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 08962 ast_log(LOG_WARNING, "No space left for redirecting count\n"); 08963 return -1; 08964 } 08965 data[pos++] = AST_REDIRECTING_COUNT; 08966 data[pos++] = sizeof(value); 08967 value = htonl(redirecting->count); 08968 memcpy(data + pos, &value, sizeof(value)); 08969 pos += sizeof(value); 08970 08971 return pos; 08972 }
| int ast_redirecting_parse_data | ( | const unsigned char * | data, | |
| size_t | datalen, | |||
| struct ast_party_redirecting * | redirecting | |||
| ) |
Parse redirecting indication frame data.
| data | Buffer with the frame data to parse | |
| datalen | Size of the buffer | |
| redirecting | Extracted redirecting id information |
| 0 | on success. | |
| -1 | on error. |
The filled in id structure needs to be destroyed by ast_party_redirecting_free() when it is no longer needed.
Definition at line 8974 of file channel.c.
References ast_debug, ast_free, ast_log(), ast_malloc, AST_PARTY_CHAR_SET_ISO8859_1, AST_REDIRECTING_COUNT, AST_REDIRECTING_FROM_ID_PRESENTATION, AST_REDIRECTING_FROM_NAME, AST_REDIRECTING_FROM_NAME_CHAR_SET, AST_REDIRECTING_FROM_NAME_PRESENTATION, AST_REDIRECTING_FROM_NAME_VALID, AST_REDIRECTING_FROM_NUMBER, AST_REDIRECTING_FROM_NUMBER_PLAN, AST_REDIRECTING_FROM_NUMBER_PRESENTATION, AST_REDIRECTING_FROM_NUMBER_VALID, AST_REDIRECTING_FROM_SUBADDRESS, AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_FROM_SUBADDRESS_TYPE, AST_REDIRECTING_FROM_SUBADDRESS_VALID, AST_REDIRECTING_FROM_TAG, AST_REDIRECTING_TO_ID_PRESENTATION, AST_REDIRECTING_TO_NAME, AST_REDIRECTING_TO_NAME_CHAR_SET, AST_REDIRECTING_TO_NAME_PRESENTATION, AST_REDIRECTING_TO_NAME_VALID, AST_REDIRECTING_TO_NUMBER, AST_REDIRECTING_TO_NUMBER_PLAN, AST_REDIRECTING_TO_NUMBER_PRESENTATION, AST_REDIRECTING_TO_NUMBER_VALID, AST_REDIRECTING_TO_SUBADDRESS, AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_TO_SUBADDRESS_TYPE, AST_REDIRECTING_TO_SUBADDRESS_VALID, AST_REDIRECTING_TO_TAG, AST_REDIRECTING_VERSION, ast_party_name::char_set, ast_party_redirecting::count, ast_party_redirecting::from, LOG_WARNING, ast_party_id::name, ast_party_id::number, ast_party_subaddress::odd_even_indicator, ast_party_number::plan, ast_party_number::presentation, ast_party_name::presentation, ast_party_redirecting::reason, ast_party_subaddress::str, ast_party_number::str, ast_party_name::str, ast_party_id::subaddress, ast_party_id::tag, ast_party_redirecting::to, ast_party_subaddress::type, ast_party_subaddress::valid, ast_party_number::valid, ast_party_name::valid, and value.
Referenced by ast_channel_redirecting_macro(), and ast_indicate_data().
08975 { 08976 size_t pos; 08977 unsigned char ie_len; 08978 unsigned char ie_id; 08979 int32_t value; 08980 int frame_version = 1; 08981 int from_combined_presentation = 0; 08982 int got_from_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 08983 int to_combined_presentation = 0; 08984 int got_to_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 08985 08986 for (pos = 0; pos < datalen; pos += ie_len) { 08987 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) { 08988 ast_log(LOG_WARNING, "Invalid redirecting update\n"); 08989 return -1; 08990 } 08991 ie_id = data[pos++]; 08992 ie_len = data[pos++]; 08993 if (datalen < pos + ie_len) { 08994 ast_log(LOG_WARNING, "Invalid redirecting update\n"); 08995 return -1; 08996 } 08997 08998 switch (ie_id) { 08999 /* Redirecting frame version */ 09000 case AST_REDIRECTING_VERSION: 09001 if (ie_len != 1) { 09002 ast_log(LOG_WARNING, "Invalid redirecting frame version (%u)\n", 09003 (unsigned) ie_len); 09004 break; 09005 } 09006 frame_version = data[pos]; 09007 break; 09008 /* Redirecting-from party id name */ 09009 case AST_REDIRECTING_FROM_NAME: 09010 ast_free(redirecting->from.name.str); 09011 redirecting->from.name.str = ast_malloc(ie_len + 1); 09012 if (redirecting->from.name.str) { 09013 memcpy(redirecting->from.name.str, data + pos, ie_len); 09014 redirecting->from.name.str[ie_len] = 0; 09015 } 09016 break; 09017 case AST_REDIRECTING_FROM_NAME_CHAR_SET: 09018 if (ie_len != 1) { 09019 ast_log(LOG_WARNING, "Invalid redirecting-from name char set (%u)\n", 09020 (unsigned) ie_len); 09021 break; 09022 } 09023 redirecting->from.name.char_set = data[pos]; 09024 break; 09025 case AST_REDIRECTING_FROM_NAME_PRESENTATION: 09026 if (ie_len != 1) { 09027 ast_log(LOG_WARNING, "Invalid redirecting-from name presentation (%u)\n", 09028 (unsigned) ie_len); 09029 break; 09030 } 09031 redirecting->from.name.presentation = data[pos]; 09032 break; 09033 case AST_REDIRECTING_FROM_NAME_VALID: 09034 if (ie_len != 1) { 09035 ast_log(LOG_WARNING, "Invalid redirecting-from name valid (%u)\n", 09036 (unsigned) ie_len); 09037 break; 09038 } 09039 redirecting->from.name.valid = data[pos]; 09040 break; 09041 /* Redirecting-from party id number */ 09042 case AST_REDIRECTING_FROM_NUMBER: 09043 ast_free(redirecting->from.number.str); 09044 redirecting->from.number.str = ast_malloc(ie_len + 1); 09045 if (redirecting->from.number.str) { 09046 memcpy(redirecting->from.number.str, data + pos, ie_len); 09047 redirecting->from.number.str[ie_len] = 0; 09048 } 09049 break; 09050 case AST_REDIRECTING_FROM_NUMBER_PLAN: 09051 if (ie_len != 1) { 09052 ast_log(LOG_WARNING, "Invalid redirecting-from numbering plan (%u)\n", 09053 (unsigned) ie_len); 09054 break; 09055 } 09056 redirecting->from.number.plan = data[pos]; 09057 break; 09058 case AST_REDIRECTING_FROM_NUMBER_PRESENTATION: 09059 if (ie_len != 1) { 09060 ast_log(LOG_WARNING, "Invalid redirecting-from number presentation (%u)\n", 09061 (unsigned) ie_len); 09062 break; 09063 } 09064 redirecting->from.number.presentation = data[pos]; 09065 break; 09066 case AST_REDIRECTING_FROM_NUMBER_VALID: 09067 if (ie_len != 1) { 09068 ast_log(LOG_WARNING, "Invalid redirecting-from number valid (%u)\n", 09069 (unsigned) ie_len); 09070 break; 09071 } 09072 redirecting->from.number.valid = data[pos]; 09073 break; 09074 /* Redirecting-from party id combined presentation */ 09075 case AST_REDIRECTING_FROM_ID_PRESENTATION: 09076 if (ie_len != 1) { 09077 ast_log(LOG_WARNING, "Invalid redirecting-from combined presentation (%u)\n", 09078 (unsigned) ie_len); 09079 break; 09080 } 09081 from_combined_presentation = data[pos]; 09082 got_from_combined_presentation = 1; 09083 break; 09084 /* Redirecting-from party id subaddress */ 09085 case AST_REDIRECTING_FROM_SUBADDRESS: 09086 ast_free(redirecting->from.subaddress.str); 09087 redirecting->from.subaddress.str = ast_malloc(ie_len + 1); 09088 if (redirecting->from.subaddress.str) { 09089 memcpy(redirecting->from.subaddress.str, data + pos, ie_len); 09090 redirecting->from.subaddress.str[ie_len] = 0; 09091 } 09092 break; 09093 case AST_REDIRECTING_FROM_SUBADDRESS_TYPE: 09094 if (ie_len != 1) { 09095 ast_log(LOG_WARNING, "Invalid redirecting-from type of subaddress (%u)\n", 09096 (unsigned) ie_len); 09097 break; 09098 } 09099 redirecting->from.subaddress.type = data[pos]; 09100 break; 09101 case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN: 09102 if (ie_len != 1) { 09103 ast_log(LOG_WARNING, 09104 "Invalid redirecting-from subaddress odd-even indicator (%u)\n", 09105 (unsigned) ie_len); 09106 break; 09107 } 09108 redirecting->from.subaddress.odd_even_indicator = data[pos]; 09109 break; 09110 case AST_REDIRECTING_FROM_SUBADDRESS_VALID: 09111 if (ie_len != 1) { 09112 ast_log(LOG_WARNING, "Invalid redirecting-from subaddress valid (%u)\n", 09113 (unsigned) ie_len); 09114 break; 09115 } 09116 redirecting->from.subaddress.valid = data[pos]; 09117 break; 09118 /* Redirecting-from party id tag */ 09119 case AST_REDIRECTING_FROM_TAG: 09120 ast_free(redirecting->from.tag); 09121 redirecting->from.tag = ast_malloc(ie_len + 1); 09122 if (redirecting->from.tag) { 09123 memcpy(redirecting->from.tag, data + pos, ie_len); 09124 redirecting->from.tag[ie_len] = 0; 09125 } 09126 break; 09127 /* Redirecting-to party id name */ 09128 case AST_REDIRECTING_TO_NAME: 09129 ast_free(redirecting->to.name.str); 09130 redirecting->to.name.str = ast_malloc(ie_len + 1); 09131 if (redirecting->to.name.str) { 09132 memcpy(redirecting->to.name.str, data + pos, ie_len); 09133 redirecting->to.name.str[ie_len] = 0; 09134 } 09135 break; 09136 case AST_REDIRECTING_TO_NAME_CHAR_SET: 09137 if (ie_len != 1) { 09138 ast_log(LOG_WARNING, "Invalid redirecting-to name char set (%u)\n", 09139 (unsigned) ie_len); 09140 break; 09141 } 09142 redirecting->to.name.char_set = data[pos]; 09143 break; 09144 case AST_REDIRECTING_TO_NAME_PRESENTATION: 09145 if (ie_len != 1) { 09146 ast_log(LOG_WARNING, "Invalid redirecting-to name presentation (%u)\n", 09147 (unsigned) ie_len); 09148 break; 09149 } 09150 redirecting->to.name.presentation = data[pos]; 09151 break; 09152 case AST_REDIRECTING_TO_NAME_VALID: 09153 if (ie_len != 1) { 09154 ast_log(LOG_WARNING, "Invalid redirecting-to name valid (%u)\n", 09155 (unsigned) ie_len); 09156 break; 09157 } 09158 redirecting->to.name.valid = data[pos]; 09159 break; 09160 /* Redirecting-to party id number */ 09161 case AST_REDIRECTING_TO_NUMBER: 09162 ast_free(redirecting->to.number.str); 09163 redirecting->to.number.str = ast_malloc(ie_len + 1); 09164 if (redirecting->to.number.str) { 09165 memcpy(redirecting->to.number.str, data + pos, ie_len); 09166 redirecting->to.number.str[ie_len] = 0; 09167 } 09168 break; 09169 case AST_REDIRECTING_TO_NUMBER_PLAN: 09170 if (ie_len != 1) { 09171 ast_log(LOG_WARNING, "Invalid redirecting-to numbering plan (%u)\n", 09172 (unsigned) ie_len); 09173 break; 09174 } 09175 redirecting->to.number.plan = data[pos]; 09176 break; 09177 case AST_REDIRECTING_TO_NUMBER_PRESENTATION: 09178 if (ie_len != 1) { 09179 ast_log(LOG_WARNING, "Invalid redirecting-to number presentation (%u)\n", 09180 (unsigned) ie_len); 09181 break; 09182 } 09183 redirecting->to.number.presentation = data[pos]; 09184 break; 09185 case AST_REDIRECTING_TO_NUMBER_VALID: 09186 if (ie_len != 1) { 09187 ast_log(LOG_WARNING, "Invalid redirecting-to number valid (%u)\n", 09188 (unsigned) ie_len); 09189 break; 09190 } 09191 redirecting->to.number.valid = data[pos]; 09192 break; 09193 /* Redirecting-to party id combined presentation */ 09194 case AST_REDIRECTING_TO_ID_PRESENTATION: 09195 if (ie_len != 1) { 09196 ast_log(LOG_WARNING, "Invalid redirecting-to combined presentation (%u)\n", 09197 (unsigned) ie_len); 09198 break; 09199 } 09200 to_combined_presentation = data[pos]; 09201 got_to_combined_presentation = 1; 09202 break; 09203 /* Redirecting-to party id subaddress */ 09204 case AST_REDIRECTING_TO_SUBADDRESS: 09205 ast_free(redirecting->to.subaddress.str); 09206 redirecting->to.subaddress.str = ast_malloc(ie_len + 1); 09207 if (redirecting->to.subaddress.str) { 09208 memcpy(redirecting->to.subaddress.str, data + pos, ie_len); 09209 redirecting->to.subaddress.str[ie_len] = 0; 09210 } 09211 break; 09212 case AST_REDIRECTING_TO_SUBADDRESS_TYPE: 09213 if (ie_len != 1) { 09214 ast_log(LOG_WARNING, "Invalid redirecting-to type of subaddress (%u)\n", 09215 (unsigned) ie_len); 09216 break; 09217 } 09218 redirecting->to.subaddress.type = data[pos]; 09219 break; 09220 case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN: 09221 if (ie_len != 1) { 09222 ast_log(LOG_WARNING, 09223 "Invalid redirecting-to subaddress odd-even indicator (%u)\n", 09224 (unsigned) ie_len); 09225 break; 09226 } 09227 redirecting->to.subaddress.odd_even_indicator = data[pos]; 09228 break; 09229 case AST_REDIRECTING_TO_SUBADDRESS_VALID: 09230 if (ie_len != 1) { 09231 ast_log(LOG_WARNING, "Invalid redirecting-to subaddress valid (%u)\n", 09232 (unsigned) ie_len); 09233 break; 09234 } 09235 redirecting->to.subaddress.valid = data[pos]; 09236 break; 09237 /* Redirecting-to party id tag */ 09238 case AST_REDIRECTING_TO_TAG: 09239 ast_free(redirecting->to.tag); 09240 redirecting->to.tag = ast_malloc(ie_len + 1); 09241 if (redirecting->to.tag) { 09242 memcpy(redirecting->to.tag, data + pos, ie_len); 09243 redirecting->to.tag[ie_len] = 0; 09244 } 09245 break; 09246 /* Redirecting reason */ 09247 case AST_REDIRECTING_REASON: 09248 if (ie_len != sizeof(value)) { 09249 ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n", 09250 (unsigned) ie_len); 09251 break; 09252 } 09253 memcpy(&value, data + pos, sizeof(value)); 09254 redirecting->reason = ntohl(value); 09255 break; 09256 /* Redirecting count */ 09257 case AST_REDIRECTING_COUNT: 09258 if (ie_len != sizeof(value)) { 09259 ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n", 09260 (unsigned) ie_len); 09261 break; 09262 } 09263 memcpy(&value, data + pos, sizeof(value)); 09264 redirecting->count = ntohl(value); 09265 break; 09266 /* Redirecting unknown element */ 09267 default: 09268 ast_debug(1, "Unknown redirecting element: %u (%u)\n", 09269 (unsigned) ie_id, (unsigned) ie_len); 09270 break; 09271 } 09272 } 09273 09274 switch (frame_version) { 09275 case 1: 09276 /* 09277 * The other end is an earlier version that we need to adjust 09278 * for compatibility. 09279 */ 09280 redirecting->from.name.valid = 1; 09281 redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 09282 redirecting->from.number.valid = 1; 09283 if (got_from_combined_presentation) { 09284 redirecting->from.name.presentation = from_combined_presentation; 09285 redirecting->from.number.presentation = from_combined_presentation; 09286 } 09287 09288 redirecting->to.name.valid = 1; 09289 redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 09290 redirecting->to.number.valid = 1; 09291 if (got_to_combined_presentation) { 09292 redirecting->to.name.presentation = to_combined_presentation; 09293 redirecting->to.number.presentation = to_combined_presentation; 09294 } 09295 break; 09296 case 2: 09297 /* The other end is at the same level as we are. */ 09298 break; 09299 default: 09300 /* 09301 * The other end is newer than we are. 09302 * We need to assume that they are compatible with us. 09303 */ 09304 ast_debug(1, "Redirecting frame has newer version: %u\n", 09305 (unsigned) frame_version); 09306 break; 09307 } 09308 09309 return 0; 09310 }
| struct ast_channel* ast_request | ( | const char * | type, | |
| struct ast_format_cap * | request_cap, | |||
| const struct ast_channel * | requestor, | |||
| const char * | addr, | |||
| int * | cause | |||
| ) | [read] |
Requests a channel.
| type | type of channel to request | |
| request_cap | Format capabilities for requested channel | |
| requestor | channel asking for data | |
| addr | destination of the call | |
| cause | Cause of failure |
| NULL | failure | |
| non-NULL | channel on success |
Definition at line 5529 of file channel.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_NOSUCHDRIVER, AST_CAUSE_NOTDEFINED, ast_channel_release(), ast_format_cap_add(), ast_format_cap_destroy(), ast_format_cap_dup(), ast_format_cap_get_type(), ast_format_cap_remove_bytype(), ast_format_clear(), AST_FORMAT_TYPE_AUDIO, ast_getformatname_multiple(), ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_translator_best_choice(), ast_channel_tech::capabilities, LOG_WARNING, ast_channel_tech::requester, set_security_requirements(), chanlist::tech, and ast_channel_tech::type.
Referenced by __ast_request_and_dial(), alloc_playback_chan(), ast_call_forward(), attempt_reconnect(), begin_dial_channel(), build_conf(), chanavail_exec(), conf_run(), conf_start_record(), connect_link(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), ring_entry(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), and wait_for_answer().
05530 { 05531 struct chanlist *chan; 05532 struct ast_channel *c; 05533 int res; 05534 int foo; 05535 05536 if (!cause) 05537 cause = &foo; 05538 *cause = AST_CAUSE_NOTDEFINED; 05539 05540 if (AST_RWLIST_RDLOCK(&backends)) { 05541 ast_log(LOG_WARNING, "Unable to lock technology backend list\n"); 05542 return NULL; 05543 } 05544 05545 AST_RWLIST_TRAVERSE(&backends, chan, list) { 05546 struct ast_format_cap *tmp_cap; 05547 struct ast_format tmp_fmt; 05548 struct ast_format best_audio_fmt; 05549 struct ast_format_cap *joint_cap; 05550 05551 if (strcasecmp(type, chan->tech->type)) 05552 continue; 05553 05554 ast_format_clear(&best_audio_fmt); 05555 /* find the best audio format to use */ 05556 if ((tmp_cap = ast_format_cap_get_type(request_cap, AST_FORMAT_TYPE_AUDIO))) { 05557 /* We have audio - is it possible to connect the various calls to each other? 05558 (Avoid this check for calls without audio, like text+video calls) 05559 */ 05560 res = ast_translator_best_choice(tmp_cap, chan->tech->capabilities, &tmp_fmt, &best_audio_fmt); 05561 ast_format_cap_destroy(tmp_cap); 05562 if (res < 0) { 05563 char tmp1[256], tmp2[256]; 05564 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %s) to %s\n", type, 05565 ast_getformatname_multiple(tmp1, sizeof(tmp1), chan->tech->capabilities), 05566 ast_getformatname_multiple(tmp2, sizeof(tmp2), request_cap)); 05567 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05568 AST_RWLIST_UNLOCK(&backends); 05569 return NULL; 05570 } 05571 } 05572 AST_RWLIST_UNLOCK(&backends); 05573 if (!chan->tech->requester) 05574 return NULL; 05575 05576 /* XXX Only the audio format calculated as being the best for translation 05577 * purposes is used for the request. This needs to be re-evaluated. It may be 05578 * a better choice to send all the audio formats capable of being translated 05579 * during the request and allow the channel drivers to pick the best one. */ 05580 if (!(joint_cap = ast_format_cap_dup(request_cap))) { 05581 return NULL; 05582 } 05583 ast_format_cap_remove_bytype(joint_cap, AST_FORMAT_TYPE_AUDIO); 05584 ast_format_cap_add(joint_cap, &best_audio_fmt); 05585 05586 if (!(c = chan->tech->requester(type, joint_cap, requestor, addr, cause))) { 05587 ast_format_cap_destroy(joint_cap); 05588 return NULL; 05589 } 05590 joint_cap = ast_format_cap_destroy(joint_cap); 05591 05592 if (set_security_requirements(requestor, c)) { 05593 ast_log(LOG_WARNING, "Setting security requirements failed\n"); 05594 c = ast_channel_release(c); 05595 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05596 return NULL; 05597 } 05598 05599 /* no need to generate a Newchannel event here; it is done in the channel_alloc call */ 05600 return c; 05601 } 05602 05603 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 05604 *cause = AST_CAUSE_NOSUCHDRIVER; 05605 AST_RWLIST_UNLOCK(&backends); 05606 05607 return NULL; 05608 }
| struct ast_channel* ast_request_and_dial | ( | const char * | type, | |
| struct ast_format_cap * | cap, | |||
| const struct ast_channel * | requestor, | |||
| const char * | addr, | |||
| int | timeout, | |||
| int * | reason, | |||
| const char * | cid_num, | |||
| const char * | cid_name | |||
| ) | [read] |
Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.
| type | type of channel to request | |
| format | capabilities for requested channel | |
| requestor | channel asking for data | |
| addr | destination of the call | |
| 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) |
Definition at line 5484 of file channel.c.
References __ast_request_and_dial().
Referenced by ast_pbx_outgoing_exten(), and generic_recall().
05485 { 05486 return __ast_request_and_dial(type, cap, requestor, addr, timeout, outstate, cidnum, cidname, NULL); 05487 }
| int ast_safe_sleep | ( | struct ast_channel * | chan, | |
| int | ms | |||
| ) |
Wait, look for hangups.
Wait for a specified amount of time, looking for hangups.
Definition at line 1697 of file channel.c.
References ast_safe_sleep_conditional().
Referenced by __analog_ss_thread(), alarmreceiver_exec(), analog_ss_thread(), ast_adsi_transmit_message_full(), ast_dtmf_stream(), ast_senddigit(), builtin_atxfer(), builtin_parkcall(), conf_run(), dictate_exec(), disa_exec(), flash_exec(), function_ilink(), handle_callforward_button(), login_exec(), mgcp_ss(), milliwatt_exec(), misdn_check_l2l1(), old_milliwatt_exec(), park_call_exec(), pbx_builtin_wait(), play_moh_exec(), play_tone_pair(), playtone(), privacy_exec(), receive_ademco_contact_id(), rpt_call(), rpt_exec(), rpt_tele_thread(), send_morse(), send_tone_telemetry(), skinny_ss(), testclient_exec(), testserver_exec(), try_calling(), wait_for_hangup(), wait_interval(), wait_moh_exec(), waituntil_exec(), and zapateller_exec().
01698 { 01699 return ast_safe_sleep_conditional(chan, ms, NULL, NULL); 01700 }
| int ast_safe_sleep_conditional | ( | struct ast_channel * | chan, | |
| int | ms, | |||
| int(*)(void *) | cond, | |||
| void * | data | |||
| ) |
Wait, look for hangups and condition arg.
Wait for a specified amount of time, looking for hangups and a condition argument.
Definition at line 1630 of file channel.c.
References ast_channel_lock, ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_channel_unlock, ast_frfree, ast_frisolate(), ast_is_deferrable_frame(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_opt_transmit_silence, ast_queue_frame_head(), ast_read(), ast_waitfor(), cond, and ast_channel::generatordata.
Referenced by ast_safe_sleep(), and login_exec().
01631 { 01632 struct ast_frame *f; 01633 struct ast_silence_generator *silgen = NULL; 01634 int res = 0; 01635 AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames; 01636 01637 AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames); 01638 01639 /* If no other generator is present, start silencegen while waiting */ 01640 if (ast_opt_transmit_silence && !chan->generatordata) { 01641 silgen = ast_channel_start_silence_generator(chan); 01642 } 01643 01644 while (ms > 0) { 01645 struct ast_frame *dup_f = NULL; 01646 if (cond && ((*cond)(data) == 0)) { 01647 break; 01648 } 01649 ms = ast_waitfor(chan, ms); 01650 if (ms < 0) { 01651 res = -1; 01652 break; 01653 } 01654 if (ms > 0) { 01655 f = ast_read(chan); 01656 if (!f) { 01657 res = -1; 01658 break; 01659 } 01660 01661 if (!ast_is_deferrable_frame(f)) { 01662 ast_frfree(f); 01663 continue; 01664 } 01665 01666 if ((dup_f = ast_frisolate(f))) { 01667 if (dup_f != f) { 01668 ast_frfree(f); 01669 } 01670 AST_LIST_INSERT_HEAD(&deferred_frames, dup_f, frame_list); 01671 } 01672 } 01673 } 01674 01675 /* stop silgen if present */ 01676 if (silgen) { 01677 ast_channel_stop_silence_generator(chan, silgen); 01678 } 01679 01680 /* We need to free all the deferred frames, but we only need to 01681 * queue the deferred frames if there was no error and no 01682 * hangup was received 01683 */ 01684 ast_channel_lock(chan); 01685 while ((f = AST_LIST_REMOVE_HEAD(&deferred_frames, frame_list))) { 01686 if (!res) { 01687 ast_queue_frame_head(chan, f); 01688 } 01689 ast_frfree(f); 01690 } 01691 ast_channel_unlock(chan); 01692 01693 return res; 01694 }
| int ast_say_character_str | ( | struct ast_channel * | chan, | |
| const char * | str, | |||
| const char * | ints, | |||
| const char * | lang | |||
| ) |
function to pronounce character and phonetic strings
Definition at line 8141 of file channel.c.
References ast_say_character_str_full.
Referenced by common_exec(), pbx_builtin_saycharacters(), play_mailbox_owner(), rpt_tele_thread(), saycharstr(), saynode(), and vmsayname_exec().
08143 { 08144 return ast_say_character_str_full(chan, str, ints, lang, -1, -1); 08145 }
| int ast_say_digit_str | ( | struct ast_channel * | chan, | |
| const char * | num, | |||
| const char * | ints, | |||
| const char * | lang | |||
| ) |
says digits of a string
| chan | channel to act upon | |
| num | string to speak | |
| ints | which dtmf to interrupt on | |
| lang | language to speak in |
| 0 | on succes | |
| DTMF | if interrupted | |
| -1 | on failure |
Definition at line 8135 of file channel.c.
References ast_say_digit_str_full.
Referenced by __analog_ss_thread(), forward_message(), invent_message(), mgcp_ss(), pbx_builtin_saydigits(), and play_message_callerid().
08137 { 08138 return ast_say_digit_str_full(chan, str, ints, lang, -1, -1); 08139 }
| int ast_say_digits | ( | struct ast_channel * | chan, | |
| int | num, | |||
| const char * | ints, | |||
| const char * | lang | |||
| ) |
says digits
| chan | channel to act upon | |
| num | number to speak | |
| ints | which dtmf to interrupt on | |
| lang | language to speak |
| 0 | on success | |
| DTMF | if interrupted | |
| -1 | on failure |
Definition at line 8129 of file channel.c.
References ast_say_digits_full().
Referenced by common_exec(), conf_exec(), conf_run(), park_call_full(), parkandannounce_exec(), and rpt_tele_thread().
08131 { 08132 return ast_say_digits_full(chan, num, ints, lang, -1, -1); 08133 }
| int ast_say_digits_full | ( | struct ast_channel * | chan, | |
| int | num, | |||
| const char * | ints, | |||
| const char * | lang, | |||
| int | audiofd, | |||
| int | ctrlfd | |||
| ) |
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable.
Definition at line 8153 of file channel.c.
References ast_say_digit_str_full.
Referenced by ast_say_digits(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_it(), ast_say_number_full_ka(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_th(), ast_say_number_full_ur(), ast_say_number_full_vi(), ast_say_number_full_zh(), and say_init_mode().
08155 { 08156 char buf[256]; 08157 08158 snprintf(buf, sizeof(buf), "%d", num); 08159 08160 return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd); 08161 }
| int ast_say_enumeration | ( | struct ast_channel * | chan, | |
| int | num, | |||
| const char * | ints, | |||
| const char * | lang, | |||
| const char * | options | |||
| ) |
says an enumeration
| chan | channel to say them enumeration on | |
| num | number to say on the channel | |
| ints | which dtmf to interrupt on | |
| lang | language to speak the enumeration | |
| options | set to 'f' for female, 'm' for male, 'c' for commune, 'n' for neuter, 'p' for plural |
| 0 | on success | |
| DTMF | digit on interrupt | |
| -1 | on failure |
Definition at line 8123 of file channel.c.
References ast_say_enumeration_full.
Referenced by ast_say_date_da(), ast_say_date_de(), ast_say_date_with_format_da(), ast_say_date_with_format_de(), ast_say_date_with_format_en(), ast_say_date_with_format_pl(), and ast_say_date_with_format_vi().
08125 { 08126 return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1); 08127 }
| int ast_say_number | ( | struct ast_channel * | chan, | |
| int | num, | |||
| const char * | ints, | |||
| const char * | lang, | |||
| const char * | options | |||
| ) |
says a number
| chan | channel to say them number on | |
| num | number to say on the channel | |
| ints | which dtmf to interrupt on | |
| lang | language to speak the number | |
| options | set to 'f' for female, 'm' for male, 'c' for commune, 'n' for neuter, 'p' for plural |
| 0 | on success | |
| DTMF | digit on interrupt | |
| -1 | on failure |
Definition at line 8117 of file channel.c.
References ast_say_number_full.
Referenced by announce_user_count(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_gr(), ast_say_date_he(), ast_say_date_hu(), ast_say_date_ka(), ast_say_date_nl(), ast_say_date_pt(), ast_say_date_th(), ast_say_date_with_format_da(), ast_say_date_with_format_de(), ast_say_date_with_format_en(), ast_say_date_with_format_es(), ast_say_date_with_format_fr(), ast_say_date_with_format_it(), ast_say_date_with_format_nl(), ast_say_date_with_format_pl(), ast_say_date_with_format_pt(), ast_say_date_with_format_th(), ast_say_date_with_format_vi(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_he(), ast_say_datetime_from_now_ka(), ast_say_datetime_from_now_pt(), ast_say_datetime_he(), ast_say_datetime_pt(), ast_say_datetime_th(), ast_say_datetime_zh(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_gr(), ast_say_time_hu(), ast_say_time_ka(), ast_say_time_nl(), ast_say_time_pt(), ast_say_time_pt_BR(), ast_say_time_th(), ast_say_time_zh(), bridge_playfile(), conf_run(), count_exec(), dictate_exec(), get_folder(), gr_say_number_female(), pbx_builtin_saynumber(), play_message(), play_message_duration(), play_sound_helper(), rpt_tele_thread(), say_and_wait(), say_position(), saynum(), try_calling(), vm_intro_gr(), vm_intro_he(), vm_intro_multilang(), vm_intro_pt(), and vm_intro_pt_BR().
08119 { 08120 return ast_say_number_full(chan, num, ints, language, options, -1, -1); 08121 }
| int ast_say_phonetic_str | ( | struct ast_channel * | chan, | |
| const char * | str, | |||
| const char * | ints, | |||
| const char * | lang | |||
| ) |
Definition at line 8147 of file channel.c.
References ast_say_phonetic_str_full.
Referenced by pbx_builtin_sayphonetic().
08149 { 08150 return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1); 08151 }
| int ast_senddigit | ( | struct ast_channel * | chan, | |
| char | digit, | |||
| unsigned int | duration | |||
| ) |
Send a DTMF digit to a channel.
| chan | channel to act upon | |
| digit | the DTMF digit to send, encoded in ASCII | |
| duration | the duration of the digit ending in ms |
Definition at line 4502 of file channel.c.
References AST_DEFAULT_EMULATE_DTMF_DURATION, ast_safe_sleep(), ast_senddigit_begin(), ast_senddigit_end(), ast_channel_tech::send_digit_begin, and ast_channel::tech.
Referenced by ast_dtmf_stream(), dial_exec_full(), do_dtmf_phone(), manager_play_dtmf(), and rpt_call().
04503 { 04504 if (chan->tech->send_digit_begin) { 04505 ast_senddigit_begin(chan, digit); 04506 ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 04507 } 04508 04509 return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 04510 }
| int ast_senddigit_begin | ( | struct ast_channel * | chan, | |
| char | digit | |||
| ) |
Send a DTMF digit to a channel.
| chan | channel to act upon | |
| digit | the DTMF digit to send, encoded in ASCII |
Definition at line 4444 of file channel.c.
References ast_channel_name(), ast_debug, ast_playtones_start(), ast_channel_tech::send_digit_begin, and ast_channel::tech.
Referenced by agent_digit_begin(), ast_senddigit(), and ast_write().
04445 { 04446 /* Device does not support DTMF tones, lets fake 04447 * it by doing our own generation. */ 04448 static const char * const dtmf_tones[] = { 04449 "941+1336", /* 0 */ 04450 "697+1209", /* 1 */ 04451 "697+1336", /* 2 */ 04452 "697+1477", /* 3 */ 04453 "770+1209", /* 4 */ 04454 "770+1336", /* 5 */ 04455 "770+1477", /* 6 */ 04456 "852+1209", /* 7 */ 04457 "852+1336", /* 8 */ 04458 "852+1477", /* 9 */ 04459 "697+1633", /* A */ 04460 "770+1633", /* B */ 04461 "852+1633", /* C */ 04462 "941+1633", /* D */ 04463 "941+1209", /* * */ 04464 "941+1477" /* # */ 04465 }; 04466 04467 if (!chan->tech->send_digit_begin) 04468 return 0; 04469 04470 if (!chan->tech->send_digit_begin(chan, digit)) 04471 return 0; 04472 04473 if (digit >= '0' && digit <='9') 04474 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0); 04475 else if (digit >= 'A' && digit <= 'D') 04476 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0); 04477 else if (digit == '*') 04478 ast_playtones_start(chan, 0, dtmf_tones[14], 0); 04479 else if (digit == '#') 04480 ast_playtones_start(chan, 0, dtmf_tones[15], 0); 04481 else { 04482 /* not handled */ 04483 ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, ast_channel_name(chan)); 04484 } 04485 04486 return 0; 04487 }
| int ast_senddigit_end | ( | struct ast_channel * | chan, | |
| char | digit, | |||
| unsigned int | duration | |||
| ) |
Send a DTMF digit to a channel.
| chan | channel to act upon | |
| digit | the DTMF digit to send, encoded in ASCII | |
| duration | the duration of the digit ending in ms |
Definition at line 4489 of file channel.c.
References ast_playtones_stop(), ast_channel::generator, ast_channel_tech::send_digit_end, and ast_channel::tech.
Referenced by agent_digit_end(), ast_senddigit(), and ast_write().
04490 { 04491 int res = -1; 04492 04493 if (chan->tech->send_digit_end) 04494 res = chan->tech->send_digit_end(chan, digit, duration); 04495 04496 if (res && chan->generator) 04497 ast_playtones_stop(chan); 04498 04499 return 0; 04500 }
| int ast_sendtext | ( | struct ast_channel * | chan, | |
| const char * | text | |||
| ) |
Sends text to a channel.
| chan | channel to act upon | |
| text | string of text to send on the channel |
| 0 | on success | |
| -1 | on failure |
Definition at line 4406 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_format_cap_has_type(), ast_format_set(), AST_FORMAT_T140, AST_FORMAT_TYPE_TEXT, AST_FRAME_TEXT, AST_MALLOCD_DATA, ast_strdup, ast_strlen_zero(), ast_test_flag, CHECK_BLOCKING, ast_frame::data, ast_frame::datalen, ast_frame_subclass::format, ast_frame::frametype, ast_frame::mallocd, ast_channel::nativeformats, ast_frame::offset, ast_frame::ptr, ast_channel_tech::send_text, ast_frame::seqno, ast_frame::src, ast_frame::subclass, ast_channel::tech, and ast_channel_tech::write_text.
Referenced by action_sendtext(), agent_sendtext(), handle_sendtext(), send_newkey(), and sendtext_exec().
04407 { 04408 int res = 0; 04409 04410 ast_channel_lock(chan); 04411 /* Stop if we're a zombie or need a soft hangup */ 04412 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 04413 ast_channel_unlock(chan); 04414 return -1; 04415 } 04416 04417 if (ast_strlen_zero(text)) { 04418 ast_channel_unlock(chan); 04419 return 0; 04420 } 04421 04422 CHECK_BLOCKING(chan); 04423 if (chan->tech->write_text && (ast_format_cap_has_type(chan->nativeformats, AST_FORMAT_TYPE_TEXT))) { 04424 struct ast_frame f; 04425 04426 f.frametype = AST_FRAME_TEXT; 04427 f.src = "DIALPLAN"; 04428 f.mallocd = AST_MALLOCD_DATA; 04429 f.datalen = strlen(text); 04430 f.data.ptr = ast_strdup(text); 04431 f.offset = 0; 04432 f.seqno = 0; 04433 04434 ast_format_set(&f.subclass.format, AST_FORMAT_T140, 0); 04435 res = chan->tech->write_text(chan, &f); 04436 } else if (chan->tech->send_text) { 04437 res = chan->tech->send_text(chan, text); 04438 } 04439 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04440 ast_channel_unlock(chan); 04441 return res; 04442 }
| 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 and generate AMI event.
The channel does not need to be locked before calling this function.
Definition at line 6823 of file channel.c.
References ast_party_caller::ani, ast_cdr_setcid(), ast_channel_lock, ast_channel_unlock, ast_free, ast_strdup, ast_channel::caller, ast_channel::cdr, ast_party_caller::id, ast_party_id::name, ast_party_id::number, report_new_callerid(), ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.
Referenced by __analog_ss_thread(), analog_ss_thread(), cb_events(), disa_exec(), get_pai(), get_rpid(), handle_setcallerid(), mgcp_ss(), privacy_exec(), ring_entry(), rpt_exec(), skinny_newcall(), and socket_process().
06824 { 06825 ast_channel_lock(chan); 06826 06827 if (cid_num) { 06828 chan->caller.id.number.valid = 1; 06829 ast_free(chan->caller.id.number.str); 06830 chan->caller.id.number.str = ast_strdup(cid_num); 06831 } 06832 if (cid_name) { 06833 chan->caller.id.name.valid = 1; 06834 ast_free(chan->caller.id.name.str); 06835 chan->caller.id.name.str = ast_strdup(cid_name); 06836 } 06837 if (cid_ani) { 06838 chan->caller.ani.number.valid = 1; 06839 ast_free(chan->caller.ani.number.str); 06840 chan->caller.ani.number.str = ast_strdup(cid_ani); 06841 } 06842 if (chan->cdr) { 06843 ast_cdr_setcid(chan->cdr, chan); 06844 } 06845 06846 report_new_callerid(chan); 06847 06848 ast_channel_unlock(chan); 06849 }
| 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.
| chan | channel to set the field on | |
| source | a string describing the source of the hangup for this channel | |
| force |
Definition at line 2555 of file channel.c.
References ast_bridged_channel(), ast_channel_hangupsource(), ast_channel_lock, ast_channel_unlock, ast_strlen_zero(), and ast_channel::bridge.
Referenced by __dahdi_exception(), func_channel_write_real(), handle_hangup(), handle_request_bye(), handle_request_cancel(), handle_response_invite(), pbx_builtin_hangup(), and set_hangup_source_and_cause().
02556 { 02557 struct ast_channel *bridge; 02558 02559 ast_channel_lock(chan); 02560 if (force || ast_strlen_zero(ast_channel_hangupsource(chan))) { 02561 ast_channel_hangupsource_set(chan, source); 02562 } 02563 bridge = ast_bridged_channel(chan); 02564 ast_channel_unlock(chan); 02565 02566 if (bridge && (force || ast_strlen_zero(ast_channel_hangupsource(bridge)))) { 02567 ast_channel_lock(bridge); 02568 ast_channel_hangupsource_set(chan, source); 02569 ast_channel_unlock(bridge); 02570 } 02571 }
| static void ast_set_owners_and_peers | ( | struct ast_channel * | chan1, | |
| struct ast_channel * | chan2 | |||
| ) | [static] |
Definition at line 6283 of file channel.c.
References ast_channel_accountcode(), ast_channel_name(), ast_channel_peeraccount(), ast_debug, and ast_strlen_zero().
Referenced by ast_channel_bridge().
06285 { 06286 if (!ast_strlen_zero(ast_channel_accountcode(chan1)) && ast_strlen_zero(ast_channel_peeraccount(chan2))) { 06287 ast_debug(1, "setting peeraccount to %s for %s from data on channel %s\n", 06288 ast_channel_accountcode(chan1), ast_channel_name(chan2), ast_channel_name(chan1)); 06289 ast_channel_peeraccount_set(chan2, ast_channel_accountcode(chan1)); 06290 } 06291 if (!ast_strlen_zero(ast_channel_accountcode(chan2)) && ast_strlen_zero(ast_channel_peeraccount(chan1))) { 06292 ast_debug(1, "setting peeraccount to %s for %s from data on channel %s\n", 06293 ast_channel_accountcode(chan2), ast_channel_name(chan1), ast_channel_name(chan2)); 06294 ast_channel_peeraccount_set(chan1, ast_channel_accountcode(chan2)); 06295 } 06296 if (!ast_strlen_zero(ast_channel_peeraccount(chan1)) && ast_strlen_zero(ast_channel_accountcode(chan2))) { 06297 ast_debug(1, "setting accountcode to %s for %s from data on channel %s\n", 06298 ast_channel_peeraccount(chan1), ast_channel_name(chan2), ast_channel_name(chan1)); 06299 ast_channel_accountcode_set(chan2, ast_channel_peeraccount(chan1)); 06300 } 06301 if (!ast_strlen_zero(ast_channel_peeraccount(chan2)) && ast_strlen_zero(ast_channel_accountcode(chan1))) { 06302 ast_debug(1, "setting accountcode to %s for %s from data on channel %s\n", 06303 ast_channel_peeraccount(chan2), ast_channel_name(chan1), ast_channel_name(chan2)); 06304 ast_channel_accountcode_set(chan1, ast_channel_peeraccount(chan2)); 06305 } 06306 if (0 != strcmp(ast_channel_accountcode(chan1), ast_channel_peeraccount(chan2))) { 06307 ast_debug(1, "changing peeraccount from %s to %s on %s to match channel %s\n", 06308 ast_channel_peeraccount(chan2), ast_channel_peeraccount(chan1), ast_channel_name(chan2), ast_channel_name(chan1)); 06309 ast_channel_peeraccount_set(chan2, ast_channel_accountcode(chan1)); 06310 } 06311 if (0 != strcmp(ast_channel_accountcode(chan2), ast_channel_peeraccount(chan1))) { 06312 ast_debug(1, "changing peeraccount from %s to %s on %s to match channel %s\n", 06313 ast_channel_peeraccount(chan1), ast_channel_peeraccount(chan2), ast_channel_name(chan1), ast_channel_name(chan2)); 06314 ast_channel_peeraccount_set(chan1, ast_channel_accountcode(chan2)); 06315 } 06316 }
| int ast_set_read_format | ( | struct ast_channel * | chan, | |
| struct ast_format * | format | |||
| ) |
Sets read format on channel chan.
| chan | channel to change | |
| formats,format | to set for reading |
Definition at line 5056 of file channel.c.
References ast_format_cap_add(), ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_channel::rawreadformat, ast_channel::readformat, ast_channel::readtrans, and set_format().
Referenced by __ast_play_and_record(), __oh323_update_info(), ast_adsi_transmit_message_full(), ast_channel_make_compatible_helper(), ast_do_masquerade(), background_detect_exec(), bridge_channel_join(), bridge_make_compatible(), dictate_exec(), do_waiting(), eagi_exec(), echo_exec(), fax_detect_framehook(), fax_gateway_framehook(), generic_fax_exec(), gtalk_rtp_read(), handle_recordfile(), ices_exec(), isAnsweringMachine(), jingle_rtp_read(), measurenoise(), mgcp_rtp_read(), oh323_rtp_read(), process_sdp(), record_exec(), set_softmix_bridge_data(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), speech_background(), transmit_audio(), and unistim_rtp_read().
05057 { 05058 struct ast_format_cap *cap = ast_format_cap_alloc_nolock(); 05059 int res; 05060 if (!cap) { 05061 return -1; 05062 } 05063 ast_format_cap_add(cap, format); 05064 05065 res = set_format(chan, 05066 cap, 05067 &chan->rawreadformat, 05068 &chan->readformat, 05069 &chan->readtrans, 05070 0); 05071 05072 ast_format_cap_destroy(cap); 05073 return res; 05074 }
| int ast_set_read_format_by_id | ( | struct ast_channel * | chan, | |
| enum ast_format_id | id | |||
| ) |
Sets read format on channel chan by id.
| chan | channel to change | |
| format | id to set for reading, only used for formats without attributes |
Definition at line 5076 of file channel.c.
References ast_format_cap_add(), ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_format_set(), ast_channel::rawreadformat, ast_channel::readformat, ast_channel::readtrans, and set_format().
Referenced by __ast_play_and_record(), alarmreceiver_exec(), ast_adsi_transmit_message_full(), attempt_reconnect(), background_detect_exec(), build_conf(), conf_run(), connect_link(), dictate_exec(), do_waiting(), eagi_exec(), fax_detect_framehook(), fax_gateway_framehook(), generic_fax_exec(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), jack_exec(), measurenoise(), old_milliwatt_exec(), record_exec(), rpt(), rpt_exec(), and transmit_audio().
05077 { 05078 struct ast_format_cap *cap = ast_format_cap_alloc_nolock(); 05079 struct ast_format tmp_format; 05080 int res; 05081 if (!cap) { 05082 return -1; 05083 } 05084 ast_format_cap_add(cap, ast_format_set(&tmp_format, id, 0)); 05085 05086 res = set_format(chan, 05087 cap, 05088 &chan->rawreadformat, 05089 &chan->readformat, 05090 &chan->readtrans, 05091 0); 05092 05093 ast_format_cap_destroy(cap); 05094 return res; 05095 }
| int ast_set_read_format_from_cap | ( | struct ast_channel * | chan, | |
| struct ast_format_cap * | formats | |||
| ) |
Sets read format on channel chan from capabilities Set read format for channel to whichever component of "format" is best.
Definition at line 5097 of file channel.c.
References ast_channel::rawreadformat, ast_channel::readformat, ast_channel::readtrans, and set_format().
Referenced by agent_call(), and login_exec().
05098 { 05099 return set_format(chan, 05100 cap, 05101 &chan->rawreadformat, 05102 &chan->readformat, 05103 &chan->readtrans, 05104 0); 05105 }
| void ast_set_variables | ( | struct ast_channel * | chan, | |
| struct ast_variable * | vars | |||
| ) |
adds a list of channel variables to a channel
| chan | the channel | |
| vars | a linked list of variables |
Definition at line 8004 of file channel.c.
References ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), and ast_variable::value.
Referenced by __ast_request_and_dial(), ast_call_forward(), ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().
08005 { 08006 struct ast_variable *cur; 08007 08008 for (cur = vars; cur; cur = cur->next) 08009 pbx_builtin_setvar_helper(chan, cur->name, cur->value); 08010 }
| int ast_set_write_format | ( | struct ast_channel * | chan, | |
| struct ast_format * | format | |||
| ) |
Sets write format on channel chan.
| chan | channel to change | |
| formats,format | to set for writing |
Definition at line 5107 of file channel.c.
References ast_format_cap_add(), ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_channel::rawwriteformat, set_format(), ast_channel::writeformat, and ast_channel::writetrans.
Referenced by __oh323_update_info(), ast_adsi_transmit_message_full(), ast_channel_make_compatible_helper(), ast_channel_stop_silence_generator(), ast_do_masquerade(), ast_stopstream(), bridge_channel_join(), bridge_make_compatible(), chanspy_exec(), dahdiscan_exec(), echo_exec(), extenspy_exec(), generic_fax_exec(), gtalk_rtp_read(), jingle_rtp_read(), linear_release(), mgcp_rtp_read(), moh_alloc(), moh_files_release(), moh_files_write_format_change(), moh_release(), mp3_exec(), NBScat_exec(), oh323_rtp_read(), playtones_release(), process_sdp(), send_waveform_to_channel(), set_softmix_bridge_data(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), tonepair_release(), transmit_audio(), and unistim_rtp_read().
05108 { 05109 struct ast_format_cap *cap = ast_format_cap_alloc_nolock(); 05110 int res; 05111 if (!cap) { 05112 return -1; 05113 } 05114 ast_format_cap_add(cap, format); 05115 05116 res = set_format(chan, 05117 cap, 05118 &chan->rawwriteformat, 05119 &chan->writeformat, 05120 &chan->writetrans, 05121 1); 05122 05123 ast_format_cap_destroy(cap); 05124 return res; 05125 }
| int ast_set_write_format_by_id | ( | struct ast_channel * | chan, | |
| enum ast_format_id | id | |||
| ) |
Sets write format on channel chan.
| chan | channel to change | |
| format | id to set for writing, only used for formats without attributes |
Definition at line 5127 of file channel.c.
References ast_format_cap_add(), ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_format_set(), ast_channel::rawwriteformat, set_format(), ast_channel::writeformat, and ast_channel::writetrans.
Referenced by alarmreceiver_exec(), ast_adsi_transmit_message_full(), ast_channel_start_silence_generator(), ast_write(), attempt_reconnect(), build_conf(), chanspy_exec(), conf_run(), connect_link(), dahdiscan_exec(), extenspy_exec(), fax_gateway_framehook(), generic_fax_exec(), jack_exec(), linear_alloc(), mp3_exec(), NBScat_exec(), old_milliwatt_exec(), playtones_alloc(), rpt(), rpt_exec(), send_waveform_to_channel(), tonepair_alloc(), and transmit_audio().
05128 { 05129 struct ast_format_cap *cap = ast_format_cap_alloc_nolock(); 05130 struct ast_format tmp_format; 05131 int res; 05132 if (!cap) { 05133 return -1; 05134 } 05135 ast_format_cap_add(cap, ast_format_set(&tmp_format, id, 0)); 05136 05137 res = set_format(chan, 05138 cap, 05139 &chan->rawwriteformat, 05140 &chan->writeformat, 05141 &chan->writetrans, 05142 1); 05143 05144 ast_format_cap_destroy(cap); 05145 return res; 05146 }
| int ast_set_write_format_from_cap | ( | struct ast_channel * | chan, | |
| struct ast_format_cap * | formats | |||
| ) |
Sets write format on channel chan Set write format for channel to whichever component of "format" is best.
Definition at line 5148 of file channel.c.
References ast_channel::rawwriteformat, set_format(), ast_channel::writeformat, and ast_channel::writetrans.
Referenced by agent_call(), ast_openstream_full(), and login_exec().
05149 { 05150 return set_format(chan, 05151 cap, 05152 &chan->rawwriteformat, 05153 &chan->writeformat, 05154 &chan->writetrans, 05155 1); 05156 }
| int ast_setstate | ( | struct ast_channel * | chan, | |
| enum ast_channel_state | state | |||
| ) |
Change the state of a channel.
Definition at line 6891 of file channel.c.
References ast_channel::_state, ast_channel_name(), AST_CHANNEL_NAME, ast_channel_uniqueid(), ast_copy_string(), AST_DEVICE_UNKNOWN, ast_devstate_changed_literal(), ast_manager_event, ast_state2str(), ast_channel::caller, ast_channel::connected, EVENT_FLAG_CALL, ast_party_connected_line::id, ast_party_caller::id, ast_party_id::name, name, ast_party_id::number, S_COR, ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.
Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_read(), __dahdi_exception(), __oh323_update_info(), agent_call(), alsa_answer(), analog_answer(), analog_call(), analog_exception(), analog_ss_thread(), ast_raw_answer(), cb_events(), check_availability(), console_answer(), dahdi_answer(), dahdi_call(), dahdi_handle_event(), dahdi_indicate(), dahdi_read(), do_bridge_masquerade(), gtalk_call(), gtalk_newcall(), handle_invite_replaces(), handle_request_invite(), handle_response_invite(), iax2_call(), jingle_call(), jingle_newcall(), local_queue_frame(), mgcp_answer(), mgcp_call(), mgcp_ss(), misdn_call(), misdn_indication(), my_set_waitingfordt(), nbs_call(), nbs_hangup(), oh323_answer(), oss_answer(), pbx_builtin_busy(), pbx_builtin_congestion(), phone_answer(), phone_call(), phone_exception(), phone_hangup(), phone_write(), release_chan(), release_chan_early(), setsubstate(), sip_answer(), skinny_answer(), skinny_newcall(), unistim_answer(), unistim_call(), unistim_new(), unistim_ss(), update_state(), usbradio_answer(), and usbradio_call().
06892 { 06893 int oldstate = chan->_state; 06894 char name[AST_CHANNEL_NAME], *dashptr; 06895 06896 if (oldstate == state) 06897 return 0; 06898 06899 ast_copy_string(name, ast_channel_name(chan), sizeof(name)); 06900 if ((dashptr = strrchr(name, '-'))) { 06901 *dashptr = '\0'; 06902 } 06903 06904 chan->_state = state; 06905 06906 /* We have to pass AST_DEVICE_UNKNOWN here because it is entirely possible that the channel driver 06907 * for this channel is using the callback method for device state. If we pass in an actual state here 06908 * we override what they are saying the state is and things go amuck. */ 06909 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, name); 06910 06911 /* setstate used to conditionally report Newchannel; this is no more */ 06912 ast_manager_event(chan, EVENT_FLAG_CALL, "Newstate", 06913 "Channel: %s\r\n" 06914 "ChannelState: %d\r\n" 06915 "ChannelStateDesc: %s\r\n" 06916 "CallerIDNum: %s\r\n" 06917 "CallerIDName: %s\r\n" 06918 "ConnectedLineNum: %s\r\n" 06919 "ConnectedLineName: %s\r\n" 06920 "Uniqueid: %s\r\n", 06921 ast_channel_name(chan), chan->_state, ast_state2str(chan->_state), 06922 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""), 06923 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""), 06924 S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, ""), 06925 S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, ""), 06926 ast_channel_uniqueid(chan)); 06927 06928 return 0; 06929 }
| int ast_settimeout | ( | struct ast_channel * | c, | |
| unsigned int | rate, | |||
| int(*)(const void *data) | func, | |||
| void * | data | |||
| ) |
Enable or disable timer ticks for a channel.
| c | channel | |
| rate | number of timer ticks per second | |
| func | callback function | |
| data |
Definition at line 3332 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_debug, ast_timer_get_max_rate(), ast_timer_set_rate(), ast_channel::timer, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.
Referenced by ast_activate_generator(), ast_deactivate_generator(), ast_read_generator_actions(), ast_readaudio_callback(), and filestream_close().
03333 { 03334 int res; 03335 unsigned int real_rate = rate, max_rate; 03336 03337 ast_channel_lock(c); 03338 03339 if (c->timingfd == -1) { 03340 ast_channel_unlock(c); 03341 return -1; 03342 } 03343 03344 if (!func) { 03345 rate = 0; 03346 data = NULL; 03347 } 03348 03349 if (rate && rate > (max_rate = ast_timer_get_max_rate(c->timer))) { 03350 real_rate = max_rate; 03351 } 03352 03353 ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate); 03354 03355 res = ast_timer_set_rate(c->timer, real_rate); 03356 03357 c->timingfunc = func; 03358 c->timingdata = data; 03359 03360 ast_channel_unlock(c); 03361 03362 return res; 03363 }
| int ast_shutting_down | ( | void | ) |
Returns non-zero if Asterisk is being shut down.
Definition at line 637 of file channel.c.
Referenced by confbridge_exec(), and handle_request_options().
00638 { 00639 return shutting_down; 00640 }
| int ast_softhangup | ( | struct ast_channel * | chan, | |
| int | cause | |||
| ) |
Softly hangup a channel, lock.
Softly hangup up a channel.
Definition at line 2518 of file channel.c.
References ast_channel_lock, ast_channel_name(), ast_channel_uniqueid(), ast_channel_unlock, ast_softhangup_nolock(), EVENT_FLAG_CALL, and manager_event.
Referenced by __analog_handle_event(), __ast_module_user_hangup_all(), __ast_pbx_run(), __unload_module(), agent_hangup(), agent_logoff(), agent_read(), ast_bridge_call(), ast_channel_softhangup_cb(), ast_dial_join(), birdbath(), cc_generic_agent_stop_ringing(), conf_free(), connect_link(), dahdi_handle_event(), flush_telem(), function_ilink(), handle_hangup(), handle_link_data(), handle_softhangup(), login_exec(), manager_park(), mgcp_pktcgate_remove(), read_agent_config(), rpt(), rpt_call(), rpt_do_restart(), rpt_exec(), sla_handle_hold_event(), softhangup_exec(), start_spying(), startmon(), and unload_module().
02519 { 02520 int res; 02521 02522 ast_channel_lock(chan); 02523 res = ast_softhangup_nolock(chan, cause); 02524 manager_event(EVENT_FLAG_CALL, "SoftHangupRequest", 02525 "Channel: %s\r\n" 02526 "Uniqueid: %s\r\n" 02527 "Cause: %d\r\n", 02528 ast_channel_name(chan), 02529 ast_channel_uniqueid(chan), 02530 cause); 02531 ast_channel_unlock(chan); 02532 02533 return res; 02534 }
| int ast_softhangup_nolock | ( | struct ast_channel * | chan, | |
| int | cause | |||
| ) |
Softly hangup a channel, don't lock.
Softly hangup up a channel (no channel lock).
Definition at line 2505 of file channel.c.
References ast_channel::_softhangup, ast_channel_name(), ast_debug, AST_FLAG_BLOCKING, ast_null_frame, ast_queue_frame(), ast_test_flag, and ast_channel::blocker.
Referenced by __analog_handle_event(), action_hangup(), ast_async_goto(), ast_softhangup(), attempt_transfer(), check_pendings(), check_rtp_timeout(), dahdi_softhangup_all(), oh323_indicate(), proc_session_timer(), and sip_indicate().
02506 { 02507 ast_debug(1, "Soft-Hanging up channel '%s'\n", ast_channel_name(chan)); 02508 /* Inform channel driver that we need to be hung up, if it cares */ 02509 chan->_softhangup |= cause; 02510 ast_queue_frame(chan, &ast_null_frame); 02511 /* Interrupt any poll call or such */ 02512 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) 02513 pthread_kill(chan->blocker, SIGURG); 02514 return 0; 02515 }
| const char* ast_state2str | ( | enum ast_channel_state | state | ) |
Gives the string form of a given channel state.
Definition at line 779 of file channel.c.
References AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DIALING_OFFHOOK, AST_STATE_DOWN, AST_STATE_OFFHOOK, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_threadstorage_get(), STATE2STR_BUFSIZE, and state2str_threadbuf.
Referenced by __ast_channel_alloc_ap(), action_coreshowchannels(), action_status(), agent_hangup(), ast_channel_data_add_structure(), ast_do_masquerade(), ast_setstate(), attempt_transfer(), func_channel_read(), handle_chanlist(), handle_showchan(), local_attended_transfer(), mgcp_new(), serialize_showchan(), sip_hangup(), and update_connectedline().
00780 { 00781 char *buf; 00782 00783 switch (state) { 00784 case AST_STATE_DOWN: 00785 return "Down"; 00786 case AST_STATE_RESERVED: 00787 return "Rsrvd"; 00788 case AST_STATE_OFFHOOK: 00789 return "OffHook"; 00790 case AST_STATE_DIALING: 00791 return "Dialing"; 00792 case AST_STATE_RING: 00793 return "Ring"; 00794 case AST_STATE_RINGING: 00795 return "Ringing"; 00796 case AST_STATE_UP: 00797 return "Up"; 00798 case AST_STATE_BUSY: 00799 return "Busy"; 00800 case AST_STATE_DIALING_OFFHOOK: 00801 return "Dialing Offhook"; 00802 case AST_STATE_PRERING: 00803 return "Pre-ring"; 00804 default: 00805 if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE))) 00806 return "Unknown"; 00807 snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state); 00808 return buf; 00809 } 00810 }
| int ast_str2cause | ( | const char * | name | ) |
Convert a symbolic hangup cause to number.
Convert the string form of a cause code to a number.
Definition at line 765 of file channel.c.
References ARRAY_LEN, cause, and causes.
Referenced by pbx_builtin_hangup().
00766 { 00767 int x; 00768 00769 for (x = 0; x < ARRAY_LEN(causes); x++) 00770 if (!strncasecmp(causes[x].name, name, strlen(causes[x].name))) 00771 return causes[x].cause; 00772 00773 return -1; 00774 }
| int ast_tonepair | ( | struct ast_channel * | chan, | |
| int | freq1, | |||
| int | freq2, | |||
| int | duration, | |||
| int | vol | |||
| ) |
Play a tone pair for a given amount of time
Definition at line 7724 of file channel.c.
References ast_frfree, ast_read(), ast_tonepair_start(), ast_waitfor(), and ast_channel::generatordata.
Referenced by zapateller_exec().
07725 { 07726 int res; 07727 07728 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 07729 return res; 07730 07731 /* Give us some wiggle room */ 07732 while (chan->generatordata && ast_waitfor(chan, 100) >= 0) { 07733 struct ast_frame *f = ast_read(chan); 07734 if (f) 07735 ast_frfree(f); 07736 else 07737 return -1; 07738 } 07739 return 0; 07740 }
| int ast_tonepair_start | ( | struct ast_channel * | chan, | |
| int | freq1, | |||
| int | freq2, | |||
| int | duration, | |||
| int | vol | |||
| ) |
Start a tone going
Definition at line 7706 of file channel.c.
References ast_activate_generator(), tonepair_def::duration, tonepair_def::freq1, tonepair_def::freq2, and tonepair_def::vol.
Referenced by ast_tonepair(), pbx_builtin_waitexten(), play_dialtone(), play_tone_pair(), rpt_tele_thread(), and sendnoise().
07707 { 07708 struct tonepair_def d = { 0, }; 07709 07710 d.freq1 = freq1; 07711 d.freq2 = freq2; 07712 d.duration = duration; 07713 d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */ 07714 if (ast_activate_generator(chan, &tonepair, &d)) 07715 return -1; 07716 return 0; 07717 }
| void ast_tonepair_stop | ( | struct ast_channel * | chan | ) |
Stop a tone from playing
Definition at line 7719 of file channel.c.
References ast_deactivate_generator().
Referenced by sendnoise().
07720 { 07721 ast_deactivate_generator(chan); 07722 }
| int ast_transfer | ( | struct ast_channel * | chan, | |
| char * | dest | |||
| ) |
Transfer a call to dest, if the channel supports transfer.
Transfer a channel (if supported).
Called by:
Definition at line 5637 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_CONTROL_TRANSFER, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, ast_frfree, ast_read(), ast_test_flag, AST_TRANSFER_SUCCESS, ast_waitfor(), ast_frame::data, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::ptr, ast_frame::subclass, ast_channel::tech, and ast_channel_tech::transfer.
Referenced by transfer_exec().
05638 { 05639 int res = -1; 05640 05641 /* Stop if we're a zombie or need a soft hangup */ 05642 ast_channel_lock(chan); 05643 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 05644 if (chan->tech->transfer) { 05645 res = chan->tech->transfer(chan, dest); 05646 if (!res) 05647 res = 1; 05648 } else 05649 res = 0; 05650 } 05651 ast_channel_unlock(chan); 05652 05653 if (res <= 0) { 05654 return res; 05655 } 05656 05657 for (;;) { 05658 struct ast_frame *fr; 05659 05660 res = ast_waitfor(chan, -1); 05661 05662 if (res < 0 || !(fr = ast_read(chan))) { 05663 res = -1; 05664 break; 05665 } 05666 05667 if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_TRANSFER) { 05668 enum ast_control_transfer *message = fr->data.ptr; 05669 05670 if (*message == AST_TRANSFER_SUCCESS) { 05671 res = 1; 05672 } else { 05673 res = -1; 05674 } 05675 05676 ast_frfree(fr); 05677 break; 05678 } 05679 05680 ast_frfree(fr); 05681 } 05682 05683 return res; 05684 }
| char* ast_transfercapability2str | ( | int | transfercapability | ) | const |
Gives the string form of a given transfer capability.
| transfercapability | transfer capability to get the name of |
Definition at line 813 of file channel.c.
References AST_TRANS_CAP_3_1K_AUDIO, AST_TRANS_CAP_DIGITAL, AST_TRANS_CAP_DIGITAL_W_TONES, AST_TRANS_CAP_RESTRICTED_DIGITAL, AST_TRANS_CAP_SPEECH, and AST_TRANS_CAP_VIDEO.
Referenced by ast_channel_data_add_structure(), cb_events(), misdn_call(), and oh323_call().
00814 { 00815 switch (transfercapability) { 00816 case AST_TRANS_CAP_SPEECH: 00817 return "SPEECH"; 00818 case AST_TRANS_CAP_DIGITAL: 00819 return "DIGITAL"; 00820 case AST_TRANS_CAP_RESTRICTED_DIGITAL: 00821 return "RESTRICTED_DIGITAL"; 00822 case AST_TRANS_CAP_3_1K_AUDIO: 00823 return "3K1AUDIO"; 00824 case AST_TRANS_CAP_DIGITAL_W_TONES: 00825 return "DIGITAL_W_TONES"; 00826 case AST_TRANS_CAP_VIDEO: 00827 return "VIDEO"; 00828 default: 00829 return "UNKNOWN"; 00830 } 00831 }
| void ast_uninstall_music_functions | ( | void | ) |
Definition at line 7787 of file channel.c.
References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.
Referenced by unload_module().
07788 { 07789 ast_moh_start_ptr = NULL; 07790 ast_moh_stop_ptr = NULL; 07791 ast_moh_cleanup_ptr = NULL; 07792 }
| int ast_waitfor | ( | struct ast_channel * | chan, | |
| int | ms | |||
| ) |
Wait for input on a channel.
| chan | channel to wait on | |
| ms | length of time to wait on the channel |
| < | 0 on failure | |
| 0 | if nothing ever arrived | |
| the | # of ms remaining otherwise |
Definition at line 3316 of file channel.c.
References ast_waitfor_nandfds().
Referenced by __adsi_transmit_messages(), __analog_ss_thread(), __ast_answer(), __ast_play_and_record(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), analog_ss_thread(), ast_dtmf_stream(), ast_recvtext(), ast_safe_sleep_conditional(), ast_tonepair(), ast_transfer(), async_wait(), background_detect_exec(), channel_spy(), conf_flush(), dictate_exec(), disa_exec(), disable_t38(), do_waiting(), echo_exec(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), jack_exec(), launch_asyncagi(), measurenoise(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), receivefax_t38_init(), record_exec(), recordthread(), send_tone_burst(), send_waveform_to_channel(), sendfax_t38_init(), sendurl_exec(), speech_background(), transmit_audio(), transmit_t38(), wait_for_hangup(), waitforring_exec(), and waitstream_core().
03317 { 03318 int oldms = ms; /* -1 if no timeout */ 03319 03320 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms); 03321 if ((ms < 0) && (oldms < 0)) 03322 ms = 0; 03323 return ms; 03324 }
| struct ast_channel* ast_waitfor_n | ( | struct ast_channel ** | chan, | |
| int | n, | |||
| int * | ms | |||
| ) | [read] |
Waits for input on a group of channels Wait for input on an array of channels for a given # of milliseconds.
| chan | an array of pointers to channels | |
| n | number of channels that are to be waited upon | |
| ms | time "ms" is modified in-place, if applicable |
Definition at line 3311 of file channel.c.
References ast_waitfor_nandfds().
Referenced by ast_generic_bridge(), ast_udptl_bridge(), autoservice_run(), dahdi_bridge(), dial_exec_full(), feature_request_and_dial(), generic_thread_loop(), iax2_bridge(), local_bridge_loop(), misdn_bridge(), monitor_dial(), remote_bridge_loop(), rpt(), rpt_exec(), wait_for_answer(), and wait_for_winner().
03312 { 03313 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 03314 }
| int ast_waitfor_n_fd | ( | int * | fds, | |
| int | n, | |||
| int * | ms, | |||
| int * | exception | |||
| ) |
Wait for x amount of time on a file descriptor to have input.
Waits for input on an fd.
Definition at line 2952 of file channel.c.
References ast_waitfor_nandfds().
Referenced by dundi_lookup_internal(), dundi_precache_internal(), and softmix_bridge_thread().
02953 { 02954 int winner = -1; 02955 ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms); 02956 return winner; 02957 }
| struct ast_channel* ast_waitfor_nandfds | ( | struct ast_channel ** | c, | |
| int | n, | |||
| int * | fds, | |||
| int | nfds, | |||
| int * | exception, | |||
| int * | outfd, | |||
| int * | ms | |||
| ) | [read] |
Wait for x amount of time on a file descriptor to have input.
Waits for activity on a group of channels.
Definition at line 2964 of file channel.c.
References ast_channel::_softhangup, ast_add_fd(), ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, ast_log(), AST_MAX_FDS, ast_poll, ast_set_flag, AST_SOFTHANGUP_TIMEOUT, ast_tvcmp(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), CHECK_BLOCKING, errno, ast_channel::fdno, and LOG_WARNING.
Referenced by ast_waitfor(), ast_waitfor_n(), ast_waitfor_n_fd(), ast_waitfordigit_full(), bridge_channel_join_multithreaded(), conf_run(), eivr_comm(), find_cache(), generic_fax_exec(), multiplexed_thread_function(), run_agi(), and waitstream_core().
02967 { 02968 struct timeval start = { 0 , 0 }; 02969 struct pollfd *pfds = NULL; 02970 int res; 02971 long rms; 02972 int x, y, max; 02973 int sz; 02974 struct timeval now = { 0, 0 }; 02975 struct timeval whentohangup = { 0, 0 }, diff; 02976 struct ast_channel *winner = NULL; 02977 struct fdmap { 02978 int chan; 02979 int fdno; 02980 } *fdmap = NULL; 02981 02982 if ((sz = n * AST_MAX_FDS + nfds)) { 02983 pfds = alloca(sizeof(*pfds) * sz); 02984 fdmap = alloca(sizeof(*fdmap) * sz); 02985 } 02986 02987 if (outfd) 02988 *outfd = -99999; 02989 if (exception) 02990 *exception = 0; 02991 02992 /* Perform any pending masquerades */ 02993 for (x = 0; x < n; x++) { 02994 if (c[x]->masq && ast_do_masquerade(c[x])) { 02995 ast_log(LOG_WARNING, "Masquerade failed\n"); 02996 *ms = -1; 02997 return NULL; 02998 } 02999 03000 ast_channel_lock(c[x]); 03001 if (!ast_tvzero(c[x]->whentohangup)) { 03002 if (ast_tvzero(whentohangup)) 03003 now = ast_tvnow(); 03004 diff = ast_tvsub(c[x]->whentohangup, now); 03005 if (diff.tv_sec < 0 || ast_tvzero(diff)) { 03006 /* Should already be hungup */ 03007 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 03008 ast_channel_unlock(c[x]); 03009 return c[x]; 03010 } 03011 if (ast_tvzero(whentohangup) || ast_tvcmp(diff, whentohangup) < 0) 03012 whentohangup = diff; 03013 } 03014 ast_channel_unlock(c[x]); 03015 } 03016 /* Wait full interval */ 03017 rms = *ms; 03018 /* INT_MAX, not LONG_MAX, because it matters on 64-bit */ 03019 if (!ast_tvzero(whentohangup) && whentohangup.tv_sec < INT_MAX / 1000) { 03020 rms = whentohangup.tv_sec * 1000 + whentohangup.tv_usec / 1000; /* timeout in milliseconds */ 03021 if (*ms >= 0 && *ms < rms) { /* original *ms still smaller */ 03022 rms = *ms; 03023 } 03024 } else if (!ast_tvzero(whentohangup) && rms < 0) { 03025 /* Tiny corner case... call would need to last >24 days */ 03026 rms = INT_MAX; 03027 } 03028 /* 03029 * Build the pollfd array, putting the channels' fds first, 03030 * followed by individual fds. Order is important because 03031 * individual fd's must have priority over channel fds. 03032 */ 03033 max = 0; 03034 for (x = 0; x < n; x++) { 03035 for (y = 0; y < AST_MAX_FDS; y++) { 03036 fdmap[max].fdno = y; /* fd y is linked to this pfds */ 03037 fdmap[max].chan = x; /* channel x is linked to this pfds */ 03038 max += ast_add_fd(&pfds[max], c[x]->fds[y]); 03039 } 03040 CHECK_BLOCKING(c[x]); 03041 } 03042 /* Add the individual fds */ 03043 for (x = 0; x < nfds; x++) { 03044 fdmap[max].chan = -1; 03045 max += ast_add_fd(&pfds[max], fds[x]); 03046 } 03047 03048 if (*ms > 0) 03049 start = ast_tvnow(); 03050 03051 if (sizeof(int) == 4) { /* XXX fix timeout > 600000 on linux x86-32 */ 03052 do { 03053 int kbrms = rms; 03054 if (kbrms > 600000) 03055 kbrms = 600000; 03056 res = ast_poll(pfds, max, kbrms); 03057 if (!res) 03058 rms -= kbrms; 03059 } while (!res && (rms > 0)); 03060 } else { 03061 res = ast_poll(pfds, max, rms); 03062 } 03063 for (x = 0; x < n; x++) 03064 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 03065 if (res < 0) { /* Simulate a timeout if we were interrupted */ 03066 if (errno != EINTR) 03067 *ms = -1; 03068 return NULL; 03069 } 03070 if (!ast_tvzero(whentohangup)) { /* if we have a timeout, check who expired */ 03071 now = ast_tvnow(); 03072 for (x = 0; x < n; x++) { 03073 if (!ast_tvzero(c[x]->whentohangup) && ast_tvcmp(c[x]->whentohangup, now) <= 0) { 03074 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 03075 if (winner == NULL) 03076 winner = c[x]; 03077 } 03078 } 03079 } 03080 if (res == 0) { /* no fd ready, reset timeout and done */ 03081 *ms = 0; /* XXX use 0 since we may not have an exact timeout. */ 03082 return winner; 03083 } 03084 /* 03085 * Then check if any channel or fd has a pending event. 03086 * Remember to check channels first and fds last, as they 03087 * must have priority on setting 'winner' 03088 */ 03089 for (x = 0; x < max; x++) { 03090 res = pfds[x].revents; 03091 if (res == 0) 03092 continue; 03093 if (fdmap[x].chan >= 0) { /* this is a channel */ 03094 winner = c[fdmap[x].chan]; /* override previous winners */ 03095 if (res & POLLPRI) 03096 ast_set_flag(winner, AST_FLAG_EXCEPTION); 03097 else 03098 ast_clear_flag(winner, AST_FLAG_EXCEPTION); 03099 winner->fdno = fdmap[x].fdno; 03100 } else { /* this is an fd */ 03101 if (outfd) 03102 *outfd = pfds[x].fd; 03103 if (exception) 03104 *exception = (res & POLLPRI) ? -1 : 0; 03105 winner = NULL; 03106 } 03107 } 03108 if (*ms > 0) { 03109 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 03110 if (*ms < 0) 03111 *ms = 0; 03112 } 03113 return winner; 03114 }
| int ast_waitfordigit | ( | struct ast_channel * | c, | |
| int | ms | |||
| ) |
Waits for a digit.
| c | channel to wait for a digit on | |
| ms | how many milliseconds to wait |
Definition at line 3327 of file channel.c.
References ast_waitfordigit_full().
Referenced by __analog_ss_thread(), _while_exec(), advanced_options(), analog_my_getsigstr(), analog_ss_thread(), ast_adsi_get_cpeid(), ast_adsi_get_cpeinfo(), ast_adsi_print(), ast_adsi_read_encoded_dtmf(), ast_adsi_transmit_message_full(), ast_app_dtget(), ast_control_streamfile(), ast_record_review(), bridge_channel_feature(), builtin_atxfer(), collect_digits(), common_exec(), cpeid_exec(), dialout(), directory_exec(), forward_message(), get_folder(), ivr_dispatch(), mgcp_ss(), my_getsigstr(), pbx_builtin_waitexten(), play_record_review(), read_exec(), read_newoption(), readexten_exec(), retrydial_exec(), select_item_menu(), select_item_pause(), select_item_seq(), sendnoise(), testclient_exec(), testserver_exec(), vm_execmain(), vm_forwardoptions(), vm_instructions_en(), vm_options(), vm_tempgreeting(), wait_a_bit(), and wait_our_turn().
03328 { 03329 return ast_waitfordigit_full(c, ms, -1, -1); 03330 }
| int ast_waitfordigit_full | ( | struct ast_channel * | c, | |
| int | ms, | |||
| int | audiofd, | |||
| int | ctrlfd | |||
| ) |
Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading.
| c | channel to wait for a digit on | |
| ms | how many milliseconds to wait | |
| audiofd | audio file descriptor to write to if audio frames are received | |
| ctrlfd | control file descriptor to monitor for reading |
Definition at line 3365 of file channel.c.
References ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UPDATE_RTP_PEER, AST_FLAG_END_DTMF_ONLY, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_set_flag, ast_test_flag, ast_waitfor_nandfds(), ast_frame::data, ast_frame::datalen, errno, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, ast_frame::ptr, and ast_frame::subclass.
Referenced by ast_readstring_full(), ast_waitfordigit(), handle_getoption(), and handle_waitfordigit().
03366 { 03367 /* Stop if we're a zombie or need a soft hangup */ 03368 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 03369 return -1; 03370 03371 /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */ 03372 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY); 03373 03374 /* Wait for a digit, no more than ms milliseconds total. */ 03375 03376 while (ms) { 03377 struct ast_channel *rchan; 03378 int outfd=-1; 03379 03380 errno = 0; 03381 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 03382 03383 if (!rchan && outfd < 0 && ms) { 03384 if (errno == 0 || errno == EINTR) 03385 continue; 03386 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 03387 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03388 return -1; 03389 } else if (outfd > -1) { 03390 /* The FD we were watching has something waiting */ 03391 ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n"); 03392 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03393 return 1; 03394 } else if (rchan) { 03395 int res; 03396 struct ast_frame *f = ast_read(c); 03397 if (!f) 03398 return -1; 03399 03400 switch (f->frametype) { 03401 case AST_FRAME_DTMF_BEGIN: 03402 break; 03403 case AST_FRAME_DTMF_END: 03404 res = f->subclass.integer; 03405 ast_frfree(f); 03406 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03407 return res; 03408 case AST_FRAME_CONTROL: 03409 switch (f->subclass.integer) { 03410 case AST_CONTROL_HANGUP: 03411 ast_frfree(f); 03412 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03413 return -1; 03414 case AST_CONTROL_RINGING: 03415 case AST_CONTROL_ANSWER: 03416 case AST_CONTROL_SRCUPDATE: 03417 case AST_CONTROL_SRCCHANGE: 03418 case AST_CONTROL_CONNECTED_LINE: 03419 case AST_CONTROL_REDIRECTING: 03420 case AST_CONTROL_UPDATE_RTP_PEER: 03421 case -1: 03422 /* Unimportant */ 03423 break; 03424 default: 03425 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass.integer); 03426 break; 03427 } 03428 break; 03429 case AST_FRAME_VOICE: 03430 /* Write audio if appropriate */ 03431 if (audiofd > -1) { 03432 if (write(audiofd, f->data.ptr, f->datalen) < 0) { 03433 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 03434 } 03435 } 03436 default: 03437 /* Ignore */ 03438 break; 03439 } 03440 ast_frfree(f); 03441 } 03442 } 03443 03444 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03445 03446 return 0; /* Time is up */ 03447 }
| int ast_write | ( | struct ast_channel * | chan, | |
| struct ast_frame * | frame | |||
| ) |
Write a frame to a channel This function writes the given frame to the indicated channel.
| chan | destination channel of the frame | |
| frame | frame that will be written |
Definition at line 4644 of file channel.c.
References ast_channel::_softhangup, apply_plc(), ast_audiohook_detach_list(), AST_AUDIOHOOK_DIRECTION_WRITE, ast_audiohook_write_list(), ast_audiohook_write_list_empty(), ast_channel_lock, ast_channel_name(), ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_UNHOLD, ast_deactivate_generator(), ast_debug, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_WRITE_INT, AST_FLAG_ZOMBIE, ast_format_cap_iscompatible(), ast_format_cmp(), AST_FORMAT_CMP_EQUAL, AST_FORMAT_CMP_NOT_EQUAL, ast_format_rate(), AST_FORMAT_SLINEAR, AST_FORMAT_T140, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_frame_dump(), AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_framehook_list_write_event(), ast_frfree, ast_frisolate(), ast_getformatname(), ast_getformatname_multiple(), AST_LIST_NEXT, ast_log(), AST_MONITOR_RUNNING, ast_opt_generic_plc, ast_seekstream(), ast_senddigit_begin(), ast_senddigit_end(), ast_set_write_format_by_id(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_translate(), ast_writestream(), ast_channel::audiohooks, calc_monitor_jump(), CHECK_BLOCKING, ast_frame::data, ast_frame::datalen, DEBUGCHAN_FLAG, ast_filestream::fmt, ast_format_def::format, ast_frame_subclass::format, ast_channel::fout, FRAMECOUNT_INC, ast_channel::framehooks, ast_frame::frametype, ast_channel::generatordata, ast_format::id, ast_channel_tech::indicate, ast_channel::insmpl, ast_frame_subclass::integer, ast_frame::len, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::nativeformats, chanlist::next, ast_channel::outsmpl, ast_frame::ptr, ast_channel::rawwriteformat, ast_channel_monitor::read_stream, ast_frame::samples, SEEK_FORCECUR, send_dtmf_event(), ast_channel_tech::send_html, ast_channel_tech::send_text, ast_frame::src, ast_channel_monitor::state, ast_frame::subclass, ast_channel::tech, ast_channel_tech::write, ast_channel_monitor::write_stream, ast_channel_tech::write_text, ast_channel_tech::write_video, ast_channel::writeformat, and ast_channel::writetrans.
Referenced by adsi_careful_send(), agent_write(), ast_bridge_call(), ast_generic_bridge(), ast_prod(), ast_readaudio_callback(), ast_readvideo_callback(), ast_udptl_bridge(), ast_write_video(), conf_queue_dtmf(), conf_run(), dahdi_bridge(), dictate_exec(), echo_exec(), fax_generator_generate(), feature_request_and_dial(), function_ilink(), gen_generate(), generic_fax_exec(), handle_jack_audio(), handle_link_data(), iax2_bridge(), jb_get_and_deliver(), linear_generator(), local_bridge_loop(), milliwatt_generate(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), multiplexed_bridge_write(), NBScat_exec(), playtones_generator(), remote_bridge_loop(), rpt(), rpt_exec(), send_link_dtmf(), send_link_keyquery(), send_tone_burst(), send_usb_txt(), send_waveform_to_channel(), silence_generator_generate(), simple_bridge_write(), sms_generate(), softmix_bridge_poke(), softmix_bridge_write(), softmix_pass_dtmf(), softmix_pass_video_all(), softmix_pass_video_top_priority(), spandsp_fax_gw_t30_gen(), spy_generate(), t38_tx_packet_handler(), tonepair_generator(), and wait_for_answer().
04645 { 04646 int res = -1; 04647 struct ast_frame *f = NULL; 04648 int count = 0; 04649 04650 /*Deadlock avoidance*/ 04651 while(ast_channel_trylock(chan)) { 04652 /*cannot goto done since the channel is not locked*/ 04653 if(count++ > 10) { 04654 ast_debug(1, "Deadlock avoided for write to channel '%s'\n", ast_channel_name(chan)); 04655 return 0; 04656 } 04657 usleep(1); 04658 } 04659 /* Stop if we're a zombie or need a soft hangup */ 04660 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 04661 goto done; 04662 04663 /* Handle any pending masquerades */ 04664 if (chan->masq) { 04665 ast_channel_unlock(chan); 04666 if (ast_do_masquerade(chan)) { 04667 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 04668 return res; /* no need to goto done: chan is already unlocked for masq */ 04669 } 04670 ast_channel_lock(chan); 04671 } 04672 if (chan->masqr) { 04673 res = 0; /* XXX explain, why 0 ? */ 04674 goto done; 04675 } 04676 04677 /* Perform the framehook write event here. After the frame enters the framehook list 04678 * there is no telling what will happen, how awesome is that!!! */ 04679 if (!(fr = ast_framehook_list_write_event(chan->framehooks, fr))) { 04680 res = 0; 04681 goto done; 04682 } 04683 04684 if (chan->generatordata && (!fr->src || strcasecmp(fr->src, "ast_prod"))) { 04685 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) { 04686 ast_deactivate_generator(chan); 04687 } else { 04688 if (fr->frametype == AST_FRAME_DTMF_END) { 04689 /* There is a generator running while we're in the middle of a digit. 04690 * It's probably inband DTMF, so go ahead and pass it so it can 04691 * stop the generator */ 04692 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04693 ast_channel_unlock(chan); 04694 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len); 04695 ast_channel_lock(chan); 04696 CHECK_BLOCKING(chan); 04697 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_UNHOLD) { 04698 /* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */ 04699 res = (chan->tech->indicate == NULL) ? 0 : 04700 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen); 04701 } 04702 res = 0; /* XXX explain, why 0 ? */ 04703 goto done; 04704 } 04705 } 04706 /* High bit prints debugging */ 04707 if (chan->fout & DEBUGCHAN_FLAG) 04708 ast_frame_dump(ast_channel_name(chan), fr, ">>"); 04709 CHECK_BLOCKING(chan); 04710 switch (fr->frametype) { 04711 case AST_FRAME_CONTROL: 04712 res = (chan->tech->indicate == NULL) ? 0 : 04713 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen); 04714 break; 04715 case AST_FRAME_DTMF_BEGIN: 04716 if (chan->audiohooks) { 04717 struct ast_frame *old_frame = fr; 04718 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 04719 if (old_frame != fr) 04720 f = fr; 04721 } 04722 send_dtmf_event(chan, "Sent", fr->subclass.integer, "Yes", "No"); 04723 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04724 ast_channel_unlock(chan); 04725 res = ast_senddigit_begin(chan, fr->subclass.integer); 04726 ast_channel_lock(chan); 04727 CHECK_BLOCKING(chan); 04728 break; 04729 case AST_FRAME_DTMF_END: 04730 if (chan->audiohooks) { 04731 struct ast_frame *new_frame = fr; 04732 04733 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 04734 if (new_frame != fr) { 04735 ast_frfree(new_frame); 04736 } 04737 } 04738 send_dtmf_event(chan, "Sent", fr->subclass.integer, "No", "Yes"); 04739 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04740 ast_channel_unlock(chan); 04741 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len); 04742 ast_channel_lock(chan); 04743 CHECK_BLOCKING(chan); 04744 break; 04745 case AST_FRAME_TEXT: 04746 if (fr->subclass.integer == AST_FORMAT_T140) { 04747 res = (chan->tech->write_text == NULL) ? 0 : 04748 chan->tech->write_text(chan, fr); 04749 } else { 04750 res = (chan->tech->send_text == NULL) ? 0 : 04751 chan->tech->send_text(chan, (char *) fr->data.ptr); 04752 } 04753 break; 04754 case AST_FRAME_HTML: 04755 res = (chan->tech->send_html == NULL) ? 0 : 04756 chan->tech->send_html(chan, fr->subclass.integer, (char *) fr->data.ptr, fr->datalen); 04757 break; 04758 case AST_FRAME_VIDEO: 04759 /* XXX Handle translation of video codecs one day XXX */ 04760 res = (chan->tech->write_video == NULL) ? 0 : 04761 chan->tech->write_video(chan, fr); 04762 break; 04763 case AST_FRAME_MODEM: 04764 res = (chan->tech->write == NULL) ? 0 : 04765 chan->tech->write(chan, fr); 04766 break; 04767 case AST_FRAME_VOICE: 04768 if (chan->tech->write == NULL) 04769 break; /*! \todo XXX should return 0 maybe ? */ 04770 04771 if (ast_opt_generic_plc && fr->subclass.format.id == AST_FORMAT_SLINEAR) { 04772 apply_plc(chan, fr); 04773 } 04774 04775 /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */ 04776 if (ast_format_cmp(&fr->subclass.format, &chan->rawwriteformat) != AST_FORMAT_CMP_NOT_EQUAL) { 04777 f = fr; 04778 } else { 04779 /* XXX Something is not right we are not compatible with this frame bad things can happen 04780 * problems range from no/one-way audio to unexplained line hangups as a last resort try adjust the format 04781 * ideally we do not want to do this and this indicates a deeper problem for now we log these events to 04782 * eliminate user impact and help identify the problem areas 04783 * JIRA issues related to this :- 04784 * ASTERISK-14384, ASTERISK-17502, ASTERISK-17541, ASTERISK-18063, ASTERISK-18325, ASTERISK-18422*/ 04785 if ((!ast_format_cap_iscompatible(chan->nativeformats, &fr->subclass.format)) && 04786 (ast_format_cmp(&chan->writeformat, &fr->subclass.format) != AST_FORMAT_CMP_EQUAL)) { 04787 char nf[512]; 04788 ast_log(LOG_WARNING, "Codec mismatch on channel %s setting write format to %s from %s native formats %s\n", 04789 ast_channel_name(chan), ast_getformatname(&fr->subclass.format), ast_getformatname(&chan->writeformat), 04790 ast_getformatname_multiple(nf, sizeof(nf), chan->nativeformats)); 04791 ast_set_write_format_by_id(chan, fr->subclass.format.id); 04792 } 04793 04794 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr; 04795 } 04796 04797 if (!f) { 04798 res = 0; 04799 break; 04800 } 04801 04802 if (chan->audiohooks) { 04803 struct ast_frame *prev = NULL, *new_frame, *cur, *dup; 04804 int freeoldlist = 0; 04805 04806 if (f != fr) { 04807 freeoldlist = 1; 04808 } 04809 04810 /* Since ast_audiohook_write may return a new frame, and the cur frame is 04811 * an item in a list of frames, create a new list adding each cur frame back to it 04812 * regardless if the cur frame changes or not. */ 04813 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 04814 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, cur); 04815 04816 /* if this frame is different than cur, preserve the end of the list, 04817 * free the old frames, and set cur to be the new frame */ 04818 if (new_frame != cur) { 04819 04820 /* doing an ast_frisolate here seems silly, but we are not guaranteed the new_frame 04821 * isn't part of local storage, meaning if ast_audiohook_write is called multiple 04822 * times it may override the previous frame we got from it unless we dup it */ 04823 if ((dup = ast_frisolate(new_frame))) { 04824 AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list); 04825 if (freeoldlist) { 04826 AST_LIST_NEXT(cur, frame_list) = NULL; 04827 ast_frfree(cur); 04828 } 04829 if (new_frame != dup) { 04830 ast_frfree(new_frame); 04831 } 04832 cur = dup; 04833 } 04834 } 04835 04836 /* now, regardless if cur is new or not, add it to the new list, 04837 * if the new list has not started, cur will become the first item. */ 04838 if (prev) { 04839 AST_LIST_NEXT(prev, frame_list) = cur; 04840 } else { 04841 f = cur; /* set f to be the beginning of our new list */ 04842 } 04843 prev = cur; 04844 } 04845 } 04846 04847 /* If Monitor is running on this channel, then we have to write frames out there too */ 04848 /* the translator on chan->writetrans may have returned multiple frames 04849 from the single frame we passed in; if so, feed each one of them to the 04850 monitor */ 04851 if (chan->monitor && chan->monitor->write_stream) { 04852 struct ast_frame *cur; 04853 04854 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 04855 /* XXX must explain this code */ 04856 #ifndef MONITOR_CONSTANT_DELAY 04857 int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples; 04858 if (jump >= 0) { 04859 jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(&f->subclass.format), ast_format_rate(&chan->monitor->read_stream->fmt->format)); 04860 if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1) 04861 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 04862 chan->outsmpl += (chan->insmpl - chan->outsmpl) + cur->samples; 04863 } else { 04864 chan->outsmpl += cur->samples; 04865 } 04866 #else 04867 int jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 04868 if (jump - MONITOR_DELAY >= 0) { 04869 if (ast_seekstream(chan->monitor->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1) 04870 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 04871 chan->outsmpl += chan->insmpl - chan->outsmpl; 04872 } else { 04873 chan->outsmpl += cur->samples; 04874 } 04875 #endif 04876 if (chan->monitor->state == AST_MONITOR_RUNNING) { 04877 if (ast_writestream(chan->monitor->write_stream, cur) < 0) 04878 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 04879 } 04880 } 04881 } 04882 04883 /* the translator on chan->writetrans may have returned multiple frames 04884 from the single frame we passed in; if so, feed each one of them to the 04885 channel, freeing each one after it has been written */ 04886 if ((f != fr) && AST_LIST_NEXT(f, frame_list)) { 04887 struct ast_frame *cur, *next = NULL; 04888 unsigned int skip = 0; 04889 04890 cur = f; 04891 while (cur) { 04892 next = AST_LIST_NEXT(cur, frame_list); 04893 AST_LIST_NEXT(cur, frame_list) = NULL; 04894 if (!skip) { 04895 if ((res = chan->tech->write(chan, cur)) < 0) { 04896 chan->_softhangup |= AST_SOFTHANGUP_DEV; 04897 skip = 1; 04898 } else if (next) { 04899 /* don't do this for the last frame in the list, 04900 as the code outside the loop will do it once 04901 */ 04902 chan->fout = FRAMECOUNT_INC(chan->fout); 04903 } 04904 } 04905 ast_frfree(cur); 04906 cur = next; 04907 } 04908 04909 /* reset f so the code below doesn't attempt to free it */ 04910 f = NULL; 04911 } else { 04912 res = chan->tech->write(chan, f); 04913 } 04914 break; 04915 case AST_FRAME_NULL: 04916 case AST_FRAME_IAX: 04917 /* Ignore these */ 04918 res = 0; 04919 break; 04920 default: 04921 /* At this point, fr is the incoming frame and f is NULL. Channels do 04922 * not expect to get NULL as a frame pointer and will segfault. Hence, 04923 * we output the original frame passed in. */ 04924 res = chan->tech->write(chan, fr); 04925 break; 04926 } 04927 04928 if (f && f != fr) 04929 ast_frfree(f); 04930 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04931 04932 /* Consider a write failure to force a soft hangup */ 04933 if (res < 0) { 04934 chan->_softhangup |= AST_SOFTHANGUP_DEV; 04935 } else { 04936 chan->fout = FRAMECOUNT_INC(chan->fout); 04937 } 04938 done: 04939 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) { 04940 /* The list gets recreated if audiohooks are added again later */ 04941 ast_audiohook_detach_list(chan->audiohooks); 04942 chan->audiohooks = NULL; 04943 } 04944 ast_channel_unlock(chan); 04945 return res; 04946 }
| int ast_write_video | ( | struct ast_channel * | chan, | |
| struct ast_frame * | frame | |||
| ) |
Write video frame to a channel This function writes the given frame to the indicated channel.
| chan | destination channel of the frame | |
| frame | frame that will be written |
Definition at line 4529 of file channel.c.
References ast_write(), ast_channel::tech, and ast_channel_tech::write_video.
04530 { 04531 int res; 04532 if (!chan->tech->write_video) 04533 return 0; 04534 res = ast_write(chan, fr); 04535 if (!res) 04536 res = 1; 04537 return res; 04538 }
| static void bridge_play_sounds | ( | struct ast_channel * | c0, | |
| struct ast_channel * | c1 | |||
| ) | [static] |
Definition at line 7258 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_strdupa, bridge_playfile(), pbx_builtin_getvar_helper(), and pbx_builtin_setvar_helper().
Referenced by ast_channel_bridge().
07259 { 07260 const char *s, *sound; 07261 07262 /* See if we need to play an audio file to any side of the bridge */ 07263 07264 ast_channel_lock(c0); 07265 if ((s = pbx_builtin_getvar_helper(c0, "BRIDGE_PLAY_SOUND"))) { 07266 sound = ast_strdupa(s); 07267 ast_channel_unlock(c0); 07268 bridge_playfile(c0, c1, sound, 0); 07269 pbx_builtin_setvar_helper(c0, "BRIDGE_PLAY_SOUND", NULL); 07270 } else { 07271 ast_channel_unlock(c0); 07272 } 07273 07274 ast_channel_lock(c1); 07275 if ((s = pbx_builtin_getvar_helper(c1, "BRIDGE_PLAY_SOUND"))) { 07276 sound = ast_strdupa(s); 07277 ast_channel_unlock(c1); 07278 bridge_playfile(c1, c0, sound, 0); 07279 pbx_builtin_setvar_helper(c1, "BRIDGE_PLAY_SOUND", NULL); 07280 } else { 07281 ast_channel_unlock(c1); 07282 } 07283 }
| static void bridge_playfile | ( | struct ast_channel * | chan, | |
| struct ast_channel * | peer, | |||
| const char * | sound, | |||
| int | remain | |||
| ) | [static] |
Definition at line 6941 of file channel.c.
References ast_autoservice_start(), ast_autoservice_stop(), ast_channel_language(), AST_DIGIT_ANY, ast_say_number(), and ast_stream_and_wait().
Referenced by ast_channel_bridge(), and bridge_play_sounds().
06942 { 06943 int min = 0, sec = 0, check; 06944 06945 check = ast_autoservice_start(peer); 06946 if (check) 06947 return; 06948 06949 if (remain > 0) { 06950 if (remain / 60 > 1) { 06951 min = remain / 60; 06952 sec = remain % 60; 06953 } else { 06954 sec = remain; 06955 } 06956 } 06957 06958 if (!strcmp(sound,"timeleft")) { /* Queue support */ 06959 ast_stream_and_wait(chan, "vm-youhave", ""); 06960 if (min) { 06961 ast_say_number(chan, min, AST_DIGIT_ANY, ast_channel_language(chan), NULL); 06962 ast_stream_and_wait(chan, "queue-minutes", ""); 06963 } 06964 if (sec) { 06965 ast_say_number(chan, sec, AST_DIGIT_ANY, ast_channel_language(chan), NULL); 06966 ast_stream_and_wait(chan, "queue-seconds", ""); 06967 } 06968 } else { 06969 ast_stream_and_wait(chan, sound, ""); 06970 } 06971 06972 ast_autoservice_stop(peer); 06973 }
| static int calc_monitor_jump | ( | int | samples, | |
| int | sample_rate, | |||
| int | seek_rate | |||
| ) | [inline, static] |
calculates the number of samples to jump forward with in a monitor stream.
| number | of samples to seek forward after rate conversion. |
Definition at line 3555 of file channel.c.
Referenced by __ast_read(), and ast_write().
03556 { 03557 int diff = sample_rate - seek_rate; 03558 03559 if (diff > 0) { 03560 samples = samples / (float) (sample_rate / seek_rate); 03561 } else if (diff < 0) { 03562 samples = samples * (float) (seek_rate / sample_rate); 03563 } 03564 03565 return samples; 03566 }
| static void call_forward_inherit | ( | struct ast_channel * | new_chan, | |
| struct ast_channel * | parent, | |||
| struct ast_channel * | orig | |||
| ) | [static] |
Definition at line 5204 of file channel.c.
References ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_lock_both, ast_channel_redirecting_macro(), ast_channel_unlock, ast_channel_update_redirecting(), ast_check_hangup(), AST_FLAG_ZOMBIE, ast_party_redirecting_copy(), ast_party_redirecting_free(), ast_party_redirecting_init(), ast_test_flag, and ast_channel::redirecting.
Referenced by ast_call_forward().
05205 { 05206 if (!ast_test_flag(parent, AST_FLAG_ZOMBIE) && !ast_check_hangup(parent)) { 05207 struct ast_party_redirecting redirecting; 05208 05209 /* 05210 * The parent is not a ZOMBIE or hungup so update it with the 05211 * original channel's redirecting information. 05212 */ 05213 ast_party_redirecting_init(&redirecting); 05214 ast_channel_lock(orig); 05215 ast_party_redirecting_copy(&redirecting, &orig->redirecting); 05216 ast_channel_unlock(orig); 05217 if (ast_channel_redirecting_macro(orig, parent, &redirecting, 1, 0)) { 05218 ast_channel_update_redirecting(parent, &redirecting, NULL); 05219 } 05220 ast_party_redirecting_free(&redirecting); 05221 } 05222 05223 /* Safely inherit variables and datastores from the parent channel. */ 05224 ast_channel_lock_both(parent, new_chan); 05225 ast_channel_inherit_variables(parent, new_chan); 05226 ast_channel_datastore_inherit(parent, new_chan); 05227 ast_channel_unlock(new_chan); 05228 ast_channel_unlock(parent); 05229 }
| static void* channel_cc_params_copy | ( | void * | data | ) | [static] |
Definition at line 9417 of file channel.c.
References ast_cc_config_params_init, and ast_cc_copy_config_params().
09418 { 09419 const struct ast_cc_config_params *src = data; 09420 struct ast_cc_config_params *dest = ast_cc_config_params_init(); 09421 if (!dest) { 09422 return NULL; 09423 } 09424 ast_cc_copy_config_params(dest, src); 09425 return dest; 09426 }
| static void channel_cc_params_destroy | ( | void * | data | ) | [static] |
Definition at line 9428 of file channel.c.
References ast_cc_config_params_destroy().
09429 { 09430 struct ast_cc_config_params *cc_params = data; 09431 ast_cc_config_params_destroy(cc_params); 09432 }
| const char* channelreloadreason2txt | ( | enum channelreloadreason | reason | ) |
Convert enum channelreloadreason to text string for manager event.
\ brief Convert channel reloadreason (ENUM) to text string for manager event
Definition at line 8092 of file channel.c.
References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.
Referenced by reload_config().
08093 { 08094 switch (reason) { 08095 case CHANNEL_MODULE_LOAD: 08096 return "LOAD (Channel module load)"; 08097 08098 case CHANNEL_MODULE_RELOAD: 08099 return "RELOAD (Channel module reload)"; 08100 08101 case CHANNEL_CLI_RELOAD: 08102 return "CLIRELOAD (Channel module reload by CLI command)"; 08103 08104 default: 08105 return "MANAGERRELOAD (Channel module reload by manager)"; 08106 } 08107 };
| static void clone_variables | ( | struct ast_channel * | original, | |
| struct ast_channel * | clonechan | |||
| ) | [static] |
Clone channel variables from 'clone' channel into 'original' channel.
All variables except those related to app_groupcount are cloned. Variables are actually _removed_ from 'clone' channel, presumably because it will subsequently be destroyed.
Definition at line 6145 of file channel.c.
References AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_var_assign(), ast_var_t::entries, ast_var_t::name, ast_var_t::value, and ast_channel::varshead.
Referenced by ast_do_masquerade().
06146 { 06147 struct ast_var_t *current, *newvar; 06148 /* Append variables from clone channel into original channel */ 06149 /* XXX Is this always correct? We have to in order to keep MACROS working XXX */ 06150 if (AST_LIST_FIRST(&clonechan->varshead)) 06151 AST_LIST_APPEND_LIST(&original->varshead, &clonechan->varshead, entries); 06152 06153 /* then, dup the varshead list into the clone */ 06154 06155 AST_LIST_TRAVERSE(&original->varshead, current, entries) { 06156 newvar = ast_var_assign(current->name, current->value); 06157 if (newvar) 06158 AST_LIST_INSERT_TAIL(&clonechan->varshead, newvar, entries); 06159 } 06160 }
| static char* complete_channeltypes | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 316 of file channel.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, ast_cli_args::n, ast_cli_args::pos, chanlist::tech, ast_channel_tech::type, and ast_cli_args::word.
Referenced by handle_cli_core_show_channeltype().
00317 { 00318 struct chanlist *cl; 00319 int which = 0; 00320 int wordlen; 00321 char *ret = NULL; 00322 00323 if (a->pos != 3) 00324 return NULL; 00325 00326 wordlen = strlen(a->word); 00327 00328 AST_RWLIST_RDLOCK(&backends); 00329 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00330 if (!strncasecmp(a->word, cl->tech->type, wordlen) && ++which > a->n) { 00331 ret = ast_strdup(cl->tech->type); 00332 break; 00333 } 00334 } 00335 AST_RWLIST_UNLOCK(&backends); 00336 00337 return ret; 00338 }
| static int data_channels_provider_handler | ( | const struct ast_data_search * | search, | |
| struct ast_data * | root | |||
| ) | [static] |
Definition at line 7851 of file channel.c.
References ast_channel_data_add_structure(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_channel_unref, ast_data_add_node(), ast_data_remove_node(), ast_data_search_match(), ast_log(), and LOG_ERROR.
07853 { 07854 struct ast_channel *c; 07855 struct ast_channel_iterator *iter = NULL; 07856 struct ast_data *data_channel; 07857 07858 for (iter = ast_channel_iterator_all_new(); 07859 iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) { 07860 ast_channel_lock(c); 07861 07862 data_channel = ast_data_add_node(root, "channel"); 07863 if (!data_channel) { 07864 ast_channel_unlock(c); 07865 continue; 07866 } 07867 07868 if (ast_channel_data_add_structure(data_channel, c, 1) < 0) { 07869 ast_log(LOG_ERROR, "Unable to add channel structure for channel: %s\n", ast_channel_name(c)); 07870 } 07871 07872 ast_channel_unlock(c); 07873 07874 if (!ast_data_search_match(search, data_channel)) { 07875 ast_data_remove_node(root, data_channel); 07876 } 07877 } 07878 if (iter) { 07879 ast_channel_iterator_destroy(iter); 07880 } 07881 07882 return 0; 07883 }
| static int data_channeltypes_provider_handler | ( | const struct ast_data_search * | search, | |
| struct ast_data * | data_root | |||
| ) | [static] |
Definition at line 7889 of file channel.c.
References ast_channel_tech::answer, ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_node(), ast_data_add_str(), ast_data_remove_node(), ast_data_search_match(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_channel_tech::bridge, ast_channel_tech::bridged_channel, ast_channel_tech::call, ast_channel_tech::capabilities, ast_channel_tech::cc_callback, ast_channel_tech::description, ast_channel_tech::devicestate, ast_channel_tech::early_bridge, ast_channel_tech::exception, ast_channel_tech::fixup, ast_channel_tech::func_channel_read, ast_channel_tech::func_channel_write, ast_channel_tech::get_base_channel, ast_channel_tech::get_pvt_uniqueid, ast_channel_tech::hangup, ast_channel_tech::indicate, ast_channel_tech::queryoption, ast_channel_tech::read, ast_channel_tech::send_digit_begin, ast_channel_tech::send_digit_end, ast_channel_tech::send_html, ast_channel_tech::send_image, ast_channel_tech::send_text, ast_channel_tech::set_base_channel, ast_channel_tech::setoption, chanlist::tech, ast_channel_tech::transfer, ast_channel_tech::type, ast_channel_tech::write, ast_channel_tech::write_text, and ast_channel_tech::write_video.
07891 { 07892 struct chanlist *cl; 07893 struct ast_data *data_type; 07894 07895 AST_RWLIST_RDLOCK(&backends); 07896 AST_RWLIST_TRAVERSE(&backends, cl, list) { 07897 data_type = ast_data_add_node(data_root, "type"); 07898 if (!data_type) { 07899 continue; 07900 } 07901 ast_data_add_str(data_type, "name", cl->tech->type); 07902 ast_data_add_str(data_type, "description", cl->tech->description); 07903 ast_data_add_bool(data_type, "devicestate", cl->tech->devicestate ? 1 : 0); 07904 ast_data_add_bool(data_type, "indications", cl->tech->indicate ? 1 : 0); 07905 ast_data_add_bool(data_type, "transfer", cl->tech->transfer ? 1 : 0); 07906 ast_data_add_bool(data_type, "send_digit_begin", cl->tech->send_digit_begin ? 1 : 0); 07907 ast_data_add_bool(data_type, "send_digit_end", cl->tech->send_digit_end ? 1 : 0); 07908 ast_data_add_bool(data_type, "call", cl->tech->call ? 1 : 0); 07909 ast_data_add_bool(data_type, "hangup", cl->tech->hangup ? 1 : 0); 07910 ast_data_add_bool(data_type, "answer", cl->tech->answer ? 1 : 0); 07911 ast_data_add_bool(data_type, "read", cl->tech->read ? 1 : 0); 07912 ast_data_add_bool(data_type, "write", cl->tech->write ? 1 : 0); 07913 ast_data_add_bool(data_type, "send_text", cl->tech->send_text ? 1 : 0); 07914 ast_data_add_bool(data_type, "send_image", cl->tech->send_image ? 1 : 0); 07915 ast_data_add_bool(data_type, "send_html", cl->tech->send_html ? 1 : 0); 07916 ast_data_add_bool(data_type, "exception", cl->tech->exception ? 1 : 0); 07917 ast_data_add_bool(data_type, "bridge", cl->tech->bridge ? 1 : 0); 07918 ast_data_add_bool(data_type, "early_bridge", cl->tech->early_bridge ? 1 : 0); 07919 ast_data_add_bool(data_type, "fixup", cl->tech->fixup ? 1 : 0); 07920 ast_data_add_bool(data_type, "setoption", cl->tech->setoption ? 1 : 0); 07921 ast_data_add_bool(data_type, "queryoption", cl->tech->queryoption ? 1 : 0); 07922 ast_data_add_bool(data_type, "write_video", cl->tech->write_video ? 1 : 0); 07923 ast_data_add_bool(data_type, "write_text", cl->tech->write_text ? 1 : 0); 07924 ast_data_add_bool(data_type, "bridged_channel", cl->tech->bridged_channel ? 1 : 0); 07925 ast_data_add_bool(data_type, "func_channel_read", cl->tech->func_channel_read ? 1 : 0); 07926 ast_data_add_bool(data_type, "func_channel_write", cl->tech->func_channel_write ? 1 : 0); 07927 ast_data_add_bool(data_type, "get_base_channel", cl->tech->get_base_channel ? 1 : 0); 07928 ast_data_add_bool(data_type, "set_base_channel", cl->tech->set_base_channel ? 1 : 0); 07929 ast_data_add_bool(data_type, "get_pvt_uniqueid", cl->tech->get_pvt_uniqueid ? 1 : 0); 07930 ast_data_add_bool(data_type, "cc_callback", cl->tech->cc_callback ? 1 : 0); 07931 07932 ast_data_add_codecs(data_type, "capabilities", cl->tech->capabilities); 07933 07934 if (!ast_data_search_match(search, data_type)) { 07935 ast_data_remove_node(data_root, data_type); 07936 } 07937 } 07938 AST_RWLIST_UNLOCK(&backends); 07939 07940 return 0; 07941 }
| static void destroy_hooks | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 2573 of file channel.c.
References ast_audiohook_detach_list(), ast_framehook_list_destroy(), and ast_channel::audiohooks.
Referenced by ast_hangup().
02574 { 02575 if (chan->audiohooks) { 02576 ast_audiohook_detach_list(chan->audiohooks); 02577 chan->audiohooks = NULL; 02578 } 02579 02580 ast_framehook_list_destroy(chan); 02581 }
| static void free_translation | ( | struct ast_channel * | clonechan | ) | [static] |
Definition at line 2536 of file channel.c.
References ast_best_codec(), ast_format_cap_is_empty(), ast_format_clear(), ast_format_copy(), ast_translator_free_path(), ast_channel::nativeformats, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readtrans, and ast_channel::writetrans.
Referenced by ast_do_masquerade(), and ast_hangup().
02537 { 02538 if (clonechan->writetrans) 02539 ast_translator_free_path(clonechan->writetrans); 02540 if (clonechan->readtrans) 02541 ast_translator_free_path(clonechan->readtrans); 02542 clonechan->writetrans = NULL; 02543 clonechan->readtrans = NULL; 02544 if (ast_format_cap_is_empty(clonechan->nativeformats)) { 02545 ast_format_clear(&clonechan->rawwriteformat); 02546 ast_format_clear(&clonechan->rawreadformat); 02547 } else { 02548 struct ast_format tmpfmt; 02549 ast_best_codec(clonechan->nativeformats, &tmpfmt); 02550 ast_format_copy(&clonechan->rawwriteformat, &tmpfmt); 02551 ast_format_copy(&clonechan->rawreadformat, &tmpfmt); 02552 } 02553 }
| static int generator_force | ( | const void * | data | ) | [static] |
Definition at line 2897 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_deactivate_generator(), ast_debug, ast_format_rate(), ast_generator::generate, ast_channel::generator, ast_channel::generatordata, and ast_channel::writeformat.
Referenced by ast_activate_generator(), and ast_read_generator_actions().
02898 { 02899 /* Called if generator doesn't have data */ 02900 void *tmp; 02901 int res; 02902 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL; 02903 struct ast_channel *chan = (struct ast_channel *)data; 02904 02905 ast_channel_lock(chan); 02906 tmp = chan->generatordata; 02907 chan->generatordata = NULL; 02908 if (chan->generator) 02909 generate = chan->generator->generate; 02910 ast_channel_unlock(chan); 02911 02912 if (!tmp || !generate) 02913 return 0; 02914 02915 res = generate(chan, tmp, 0, ast_format_rate(&chan->writeformat) / 50); 02916 02917 chan->generatordata = tmp; 02918 02919 if (res) { 02920 ast_debug(1, "Auto-deactivating generator\n"); 02921 ast_deactivate_generator(chan); 02922 } 02923 02924 return 0; 02925 }
| static void generator_write_format_change | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 2888 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_channel::generator, ast_channel::generatordata, and ast_generator::write_format_change.
Referenced by set_format().
02889 { 02890 ast_channel_lock(chan); 02891 if (chan->generator && chan->generator->write_format_change) { 02892 chan->generator->write_format_change(chan, chan->generatordata); 02893 } 02894 ast_channel_unlock(chan); 02895 }
| static void handle_cause | ( | int | cause, | |
| int * | outstate | |||
| ) | [static] |
Definition at line 5181 of file channel.c.
References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CONTROL_BUSY, and AST_CONTROL_CONGESTION.
05182 { 05183 if (outstate) { 05184 /* compute error and return */ 05185 if (cause == AST_CAUSE_BUSY) 05186 *outstate = AST_CONTROL_BUSY; 05187 else if (cause == AST_CAUSE_CONGESTION) 05188 *outstate = AST_CONTROL_CONGESTION; 05189 else 05190 *outstate = 0; 05191 } 05192 }
| static char* handle_cli_core_show_channeltype | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Show details about a channel driver - CLI command.
Definition at line 341 of file channel.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_getformatname_multiple(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_channel_tech::capabilities, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_channeltypes(), ast_channel_tech::devicestate, ast_cli_args::fd, ast_channel_tech::indicate, ast_channel_tech::send_digit_begin, ast_channel_tech::send_digit_end, ast_channel_tech::send_html, ast_channel_tech::send_image, ast_channel_tech::send_text, chanlist::tech, ast_channel_tech::transfer, ast_channel_tech::type, and ast_cli_entry::usage.
00342 { 00343 struct chanlist *cl = NULL; 00344 char buf[512]; 00345 00346 switch (cmd) { 00347 case CLI_INIT: 00348 e->command = "core show channeltype"; 00349 e->usage = 00350 "Usage: core show channeltype <name>\n" 00351 " Show details about the specified channel type, <name>.\n"; 00352 return NULL; 00353 case CLI_GENERATE: 00354 return complete_channeltypes(a); 00355 } 00356 00357 if (a->argc != 4) 00358 return CLI_SHOWUSAGE; 00359 00360 AST_RWLIST_RDLOCK(&backends); 00361 00362 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00363 if (!strncasecmp(cl->tech->type, a->argv[3], strlen(cl->tech->type))) 00364 break; 00365 } 00366 00367 00368 if (!cl) { 00369 ast_cli(a->fd, "\n%s is not a registered channel driver.\n", a->argv[3]); 00370 AST_RWLIST_UNLOCK(&backends); 00371 return CLI_FAILURE; 00372 } 00373 00374 ast_cli(a->fd, 00375 "-- Info about channel driver: %s --\n" 00376 " Device State: %s\n" 00377 " Indication: %s\n" 00378 " Transfer : %s\n" 00379 " Capabilities: %s\n" 00380 " Digit Begin: %s\n" 00381 " Digit End: %s\n" 00382 " Send HTML : %s\n" 00383 " Image Support: %s\n" 00384 " Text Support: %s\n", 00385 cl->tech->type, 00386 (cl->tech->devicestate) ? "yes" : "no", 00387 (cl->tech->indicate) ? "yes" : "no", 00388 (cl->tech->transfer) ? "yes" : "no", 00389 ast_getformatname_multiple(buf, sizeof(buf), cl->tech->capabilities), 00390 (cl->tech->send_digit_begin) ? "yes" : "no", 00391 (cl->tech->send_digit_end) ? "yes" : "no", 00392 (cl->tech->send_html) ? "yes" : "no", 00393 (cl->tech->send_image) ? "yes" : "no", 00394 (cl->tech->send_text) ? "yes" : "no" 00395 00396 ); 00397 00398 AST_RWLIST_UNLOCK(&backends); 00399 00400 return CLI_SUCCESS; 00401 }
| static char* handle_cli_core_show_channeltypes | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Show channel types - CLI command.
Definition at line 275 of file channel.c.
References ast_cli_args::argc, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_channel_tech::description, ast_channel_tech::devicestate, ast_cli_args::fd, FORMAT, ast_channel_tech::indicate, chanlist::tech, ast_channel_tech::transfer, ast_channel_tech::type, and ast_cli_entry::usage.
00276 { 00277 #define FORMAT "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\n" 00278 struct chanlist *cl; 00279 int count_chan = 0; 00280 00281 switch (cmd) { 00282 case CLI_INIT: 00283 e->command = "core show channeltypes"; 00284 e->usage = 00285 "Usage: core show channeltypes\n" 00286 " Lists available channel types registered in your\n" 00287 " Asterisk server.\n"; 00288 return NULL; 00289 case CLI_GENERATE: 00290 return NULL; 00291 } 00292 00293 if (a->argc != 3) 00294 return CLI_SHOWUSAGE; 00295 00296 ast_cli(a->fd, FORMAT, "Type", "Description", "Devicestate", "Indications", "Transfer"); 00297 ast_cli(a->fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------"); 00298 00299 AST_RWLIST_RDLOCK(&backends); 00300 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00301 ast_cli(a->fd, FORMAT, cl->tech->type, cl->tech->description, 00302 (cl->tech->devicestate) ? "yes" : "no", 00303 (cl->tech->indicate) ? "yes" : "no", 00304 (cl->tech->transfer) ? "yes" : "no"); 00305 count_chan++; 00306 } 00307 AST_RWLIST_UNLOCK(&backends); 00308 00309 ast_cli(a->fd, "----------\n%d channel drivers registered.\n", count_chan); 00310 00311 return CLI_SUCCESS; 00312 00313 #undef FORMAT 00314 }
| static int attribute_const is_visible_indication | ( | enum ast_control_frame_type | condition | ) | [static] |
Definition at line 4122 of file channel.c.
References _XXX_AST_CONTROL_T38, AST_CONTROL_ANSWER, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_END_OF_Q, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_MCID, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_READ_ACTION, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_TRANSFER, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, and AST_CONTROL_WINK.
Referenced by ast_indicate_data().
04123 { 04124 /* Don't include a default case here so that we get compiler warnings 04125 * when a new type is added. */ 04126 04127 switch (condition) { 04128 case AST_CONTROL_PROGRESS: 04129 case AST_CONTROL_PROCEEDING: 04130 case AST_CONTROL_VIDUPDATE: 04131 case AST_CONTROL_SRCUPDATE: 04132 case AST_CONTROL_SRCCHANGE: 04133 case AST_CONTROL_RADIO_KEY: 04134 case AST_CONTROL_RADIO_UNKEY: 04135 case AST_CONTROL_OPTION: 04136 case AST_CONTROL_WINK: 04137 case AST_CONTROL_FLASH: 04138 case AST_CONTROL_OFFHOOK: 04139 case AST_CONTROL_TAKEOFFHOOK: 04140 case AST_CONTROL_ANSWER: 04141 case AST_CONTROL_HANGUP: 04142 case AST_CONTROL_CONNECTED_LINE: 04143 case AST_CONTROL_REDIRECTING: 04144 case AST_CONTROL_TRANSFER: 04145 case AST_CONTROL_T38_PARAMETERS: 04146 case _XXX_AST_CONTROL_T38: 04147 case AST_CONTROL_CC: 04148 case AST_CONTROL_READ_ACTION: 04149 case AST_CONTROL_AOC: 04150 case AST_CONTROL_END_OF_Q: 04151 case AST_CONTROL_MCID: 04152 case AST_CONTROL_UPDATE_RTP_PEER: 04153 break; 04154 04155 case AST_CONTROL_INCOMPLETE: 04156 case AST_CONTROL_CONGESTION: 04157 case AST_CONTROL_BUSY: 04158 case AST_CONTROL_RINGING: 04159 case AST_CONTROL_RING: 04160 case AST_CONTROL_HOLD: 04161 /* You can hear these */ 04162 return 1; 04163 04164 case AST_CONTROL_UNHOLD: 04165 /* This is a special case. You stop hearing this. */ 04166 break; 04167 } 04168 04169 return 0; 04170 }
| static struct ast_frame* kill_exception | ( | struct ast_channel * | chan | ) | [static, read] |
| static int kill_fixup | ( | struct ast_channel * | oldchan, | |
| struct ast_channel * | newchan | |||
| ) | [static] |
| static int kill_hangup | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 432 of file channel.c.
References ast_channel::tech_pvt.
00433 { 00434 chan->tech_pvt = NULL; 00435 return 0; 00436 }
| static struct ast_frame* kill_read | ( | struct ast_channel * | chan | ) | [static, read] |
| static int kill_write | ( | struct ast_channel * | chan, | |
| struct ast_frame * | frame | |||
| ) | [static] |
| static void manager_bridge_event | ( | int | onoff, | |
| int | type, | |||
| struct ast_channel * | c0, | |||
| struct ast_channel * | c1 | |||
| ) | [static] |
Send manager event for bridge link and unlink events.
| onoff | Link/Unlinked | |
| type | 1 for core, 2 for native | |
| c0 | first channel in bridge | |
| c1 | second channel in bridge |
Definition at line 7201 of file channel.c.
References ast_channel_name(), ast_channel_uniqueid(), ast_manager_event_multichan, ast_channel::caller, EVENT_FLAG_CALL, ast_party_caller::id, ast_party_id::number, S_COR, ast_party_number::str, and ast_party_number::valid.
Referenced by ast_channel_bridge().
07202 { 07203 struct ast_channel *chans[2] = { c0, c1 }; 07204 ast_manager_event_multichan(EVENT_FLAG_CALL, "Bridge", 2, chans, 07205 "Bridgestate: %s\r\n" 07206 "Bridgetype: %s\r\n" 07207 "Channel1: %s\r\n" 07208 "Channel2: %s\r\n" 07209 "Uniqueid1: %s\r\n" 07210 "Uniqueid2: %s\r\n" 07211 "CallerID1: %s\r\n" 07212 "CallerID2: %s\r\n", 07213 onoff ? "Link" : "Unlink", 07214 type == 1 ? "core" : "native", 07215 ast_channel_name(c0), ast_channel_name(c1), 07216 ast_channel_uniqueid(c0), ast_channel_uniqueid(c1), 07217 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, ""), 07218 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "")); 07219 }
| static void masquerade_colp_transfer | ( | struct ast_channel * | transferee, | |
| struct xfer_masquerade_ds * | colp | |||
| ) | [static] |
Definition at line 6351 of file channel.c.
References ast_channel_queue_connected_line_update(), ast_connected_line_build_data(), AST_CONTROL_READ_ACTION, AST_CONTROL_UNHOLD, AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO, ast_queue_control(), ast_queue_control_data(), frame_size, ast_control_read_action_payload::payload_size, xfer_masquerade_ds::target_held, xfer_masquerade_ds::target_id, and xfer_masquerade_ds::transferee_id.
Referenced by ast_do_masquerade().
06352 { 06353 struct ast_control_read_action_payload *frame_payload; 06354 int payload_size; 06355 int frame_size; 06356 unsigned char connected_line_data[1024]; 06357 06358 /* Release any hold on the target. */ 06359 if (colp->target_held) { 06360 ast_queue_control(transferee, AST_CONTROL_UNHOLD); 06361 } 06362 06363 /* 06364 * Since transferee may not actually be bridged to another channel, 06365 * there is no way for us to queue a frame so that its connected 06366 * line status will be updated. Instead, we use the somewhat 06367 * hackish approach of using a special control frame type that 06368 * instructs ast_read() to perform a specific action. In this 06369 * case, the frame we queue tells ast_read() to call the 06370 * connected line interception macro configured for transferee. 06371 */ 06372 payload_size = ast_connected_line_build_data(connected_line_data, 06373 sizeof(connected_line_data), &colp->target_id, NULL); 06374 if (payload_size != -1) { 06375 frame_size = payload_size + sizeof(*frame_payload); 06376 frame_payload = alloca(frame_size); 06377 frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO; 06378 frame_payload->payload_size = payload_size; 06379 memcpy(frame_payload->payload, connected_line_data, payload_size); 06380 ast_queue_control_data(transferee, AST_CONTROL_READ_ACTION, frame_payload, 06381 frame_size); 06382 } 06383 /* 06384 * In addition to queueing the read action frame so that the 06385 * connected line info on transferee will be updated, we also are 06386 * going to queue a plain old connected line update on transferee to 06387 * update the target. 06388 */ 06389 ast_channel_queue_connected_line_update(transferee, &colp->transferee_id, NULL); 06390 }
| static const char* oldest_linkedid | ( | const char * | a, | |
| const char * | b | |||
| ) | [static] |
Definition at line 6175 of file channel.c.
References ast_strlen_zero().
Referenced by ast_channel_set_linkgroup().
06176 { 06177 const char *satime, *saseq; 06178 const char *sbtime, *sbseq; 06179 const char *dash; 06180 06181 unsigned int atime, aseq, btime, bseq; 06182 06183 if (ast_strlen_zero(a)) 06184 return b; 06185 06186 if (ast_strlen_zero(b)) 06187 return a; 06188 06189 satime = a; 06190 sbtime = b; 06191 06192 /* jump over the system name */ 06193 if ((dash = strrchr(satime, '-'))) { 06194 satime = dash+1; 06195 } 06196 if ((dash = strrchr(sbtime, '-'))) { 06197 sbtime = dash+1; 06198 } 06199 06200 /* the sequence comes after the '.' */ 06201 saseq = strchr(satime, '.'); 06202 sbseq = strchr(sbtime, '.'); 06203 if (!saseq || !sbseq) 06204 return NULL; 06205 saseq++; 06206 sbseq++; 06207 06208 /* convert it all to integers */ 06209 atime = atoi(satime); /* note that atoi is ignoring the '.' after the time string */ 06210 btime = atoi(sbtime); /* note that atoi is ignoring the '.' after the time string */ 06211 aseq = atoi(saseq); 06212 bseq = atoi(sbseq); 06213 06214 /* and finally compare */ 06215 if (atime == btime) { 06216 return (aseq < bseq) ? a : b; 06217 } 06218 else { 06219 return (atime < btime) ? a : b; 06220 } 06221 }
| static void party_connected_line_copy_transfer | ( | struct ast_party_connected_line * | dest, | |
| const struct ast_party_connected_line * | src | |||
| ) | [static] |
Definition at line 5982 of file channel.c.
References AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, ast_party_connected_line_copy(), and ast_party_connected_line::source.
Referenced by ast_channel_transfer_masquerade().
05983 { 05984 struct ast_party_connected_line connected; 05985 05986 connected = *((struct ast_party_connected_line *) src); 05987 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; 05988 05989 /* Make sure empty strings will be erased. */ 05990 if (!connected.id.name.str) { 05991 connected.id.name.str = ""; 05992 } 05993 if (!connected.id.number.str) { 05994 connected.id.number.str = ""; 05995 } 05996 if (!connected.id.subaddress.str) { 05997 connected.id.subaddress.str = ""; 05998 } 05999 if (!connected.id.tag) { 06000 connected.id.tag = ""; 06001 } 06002 06003 ast_party_connected_line_copy(dest, &connected); 06004 }
| static int party_id_build_data | ( | unsigned char * | data, | |
| size_t | datalen, | |||
| const struct ast_party_id * | id, | |||
| const char * | label, | |||
| const struct ast_party_id_ies * | ies, | |||
| const struct ast_set_party_id * | update | |||
| ) | [static] |
Definition at line 8442 of file channel.c.
References ast_log(), ast_party_id_presentation(), ast_party_id_ies::combined_presentation, LOG_WARNING, ast_party_id_ies::name, ast_party_id::name, ast_set_party_id::name, ast_party_id_ies::number, ast_party_id::number, ast_set_party_id::number, party_name_build_data(), party_number_build_data(), party_subaddress_build_data(), ast_party_id_ies::subaddress, ast_party_id::subaddress, ast_set_party_id::subaddress, ast_party_id_ies::tag, and ast_party_id::tag.
Referenced by ast_connected_line_build_data(), and ast_redirecting_build_data().
08445 { 08446 size_t length; 08447 size_t pos = 0; 08448 int res; 08449 08450 /* 08451 * The size of integer values must be fixed in case the frame is 08452 * shipped to another machine. 08453 */ 08454 08455 if (!update || update->name) { 08456 res = party_name_build_data(data + pos, datalen - pos, &id->name, label, 08457 &ies->name); 08458 if (res < 0) { 08459 return -1; 08460 } 08461 pos += res; 08462 } 08463 08464 if (!update || update->number) { 08465 res = party_number_build_data(data + pos, datalen - pos, &id->number, label, 08466 &ies->number); 08467 if (res < 0) { 08468 return -1; 08469 } 08470 pos += res; 08471 } 08472 08473 if (!update || update->subaddress) { 08474 res = party_subaddress_build_data(data + pos, datalen - pos, &id->subaddress, 08475 label, &ies->subaddress); 08476 if (res < 0) { 08477 return -1; 08478 } 08479 pos += res; 08480 } 08481 08482 /* *************** Party id user tag **************************** */ 08483 if (id->tag) { 08484 length = strlen(id->tag); 08485 if (datalen < pos + (sizeof(data[0]) * 2) + length) { 08486 ast_log(LOG_WARNING, "No space left for %s tag\n", label); 08487 return -1; 08488 } 08489 data[pos++] = ies->tag; 08490 data[pos++] = length; 08491 memcpy(data + pos, id->tag, length); 08492 pos += length; 08493 } 08494 08495 /* *************** Party id combined presentation *************** */ 08496 if (!update || update->number) { 08497 int presentation; 08498 08499 if (!update || update->name) { 08500 presentation = ast_party_id_presentation(id); 08501 } else { 08502 /* 08503 * We must compromise because not all the information is available 08504 * to determine a combined presentation value. 08505 * We will only send the number presentation instead. 08506 */ 08507 presentation = id->number.presentation; 08508 } 08509 08510 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08511 ast_log(LOG_WARNING, "No space left for %s combined presentation\n", label); 08512 return -1; 08513 } 08514 data[pos++] = ies->combined_presentation; 08515 data[pos++] = 1; 08516 data[pos++] = presentation; 08517 } 08518 08519 return pos; 08520 }
| static int party_name_build_data | ( | unsigned char * | data, | |
| size_t | datalen, | |||
| const struct ast_party_name * | name, | |||
| const char * | label, | |||
| const struct ast_party_name_ies * | ies | |||
| ) | [static] |
Definition at line 8216 of file channel.c.
References ast_log(), ast_party_name::char_set, ast_party_name_ies::char_set, LOG_WARNING, ast_party_name::presentation, ast_party_name_ies::presentation, ast_party_name_ies::str, ast_party_name::str, ast_party_name::valid, and ast_party_name_ies::valid.
Referenced by party_id_build_data().
08217 { 08218 size_t length; 08219 size_t pos = 0; 08220 08221 /* 08222 * The size of integer values must be fixed in case the frame is 08223 * shipped to another machine. 08224 */ 08225 if (name->str) { 08226 length = strlen(name->str); 08227 if (datalen < pos + (sizeof(data[0]) * 2) + length) { 08228 ast_log(LOG_WARNING, "No space left for %s name\n", label); 08229 return -1; 08230 } 08231 data[pos++] = ies->str; 08232 data[pos++] = length; 08233 memcpy(data + pos, name->str, length); 08234 pos += length; 08235 } 08236 08237 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08238 ast_log(LOG_WARNING, "No space left for %s name char set\n", label); 08239 return -1; 08240 } 08241 data[pos++] = ies->char_set; 08242 data[pos++] = 1; 08243 data[pos++] = name->char_set; 08244 08245 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08246 ast_log(LOG_WARNING, "No space left for %s name presentation\n", label); 08247 return -1; 08248 } 08249 data[pos++] = ies->presentation; 08250 data[pos++] = 1; 08251 data[pos++] = name->presentation; 08252 08253 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08254 ast_log(LOG_WARNING, "No space left for %s name valid\n", label); 08255 return -1; 08256 } 08257 data[pos++] = ies->valid; 08258 data[pos++] = 1; 08259 data[pos++] = name->valid; 08260 08261 return pos; 08262 }
| static int party_number_build_data | ( | unsigned char * | data, | |
| size_t | datalen, | |||
| const struct ast_party_number * | number, | |||
| const char * | label, | |||
| const struct ast_party_number_ies * | ies | |||
| ) | [static] |
Definition at line 8290 of file channel.c.
References ast_log(), LOG_WARNING, ast_party_number::plan, ast_party_number_ies::plan, ast_party_number::presentation, ast_party_number_ies::presentation, ast_party_number_ies::str, ast_party_number::str, ast_party_number::valid, and ast_party_number_ies::valid.
Referenced by party_id_build_data().
08291 { 08292 size_t length; 08293 size_t pos = 0; 08294 08295 /* 08296 * The size of integer values must be fixed in case the frame is 08297 * shipped to another machine. 08298 */ 08299 if (number->str) { 08300 length = strlen(number->str); 08301 if (datalen < pos + (sizeof(data[0]) * 2) + length) { 08302 ast_log(LOG_WARNING, "No space left for %s number\n", label); 08303 return -1; 08304 } 08305 data[pos++] = ies->str; 08306 data[pos++] = length; 08307 memcpy(data + pos, number->str, length); 08308 pos += length; 08309 } 08310 08311 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08312 ast_log(LOG_WARNING, "No space left for %s numbering plan\n", label); 08313 return -1; 08314 } 08315 data[pos++] = ies->plan; 08316 data[pos++] = 1; 08317 data[pos++] = number->plan; 08318 08319 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08320 ast_log(LOG_WARNING, "No space left for %s number presentation\n", label); 08321 return -1; 08322 } 08323 data[pos++] = ies->presentation; 08324 data[pos++] = 1; 08325 data[pos++] = number->presentation; 08326 08327 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08328 ast_log(LOG_WARNING, "No space left for %s number valid\n", label); 08329 return -1; 08330 } 08331 data[pos++] = ies->valid; 08332 data[pos++] = 1; 08333 data[pos++] = number->valid; 08334 08335 return pos; 08336 }
| static int party_subaddress_build_data | ( | unsigned char * | data, | |
| size_t | datalen, | |||
| const struct ast_party_subaddress * | subaddress, | |||
| const char * | label, | |||
| const struct ast_party_subaddress_ies * | ies | |||
| ) | [static] |
Definition at line 8364 of file channel.c.
References ast_log(), LOG_WARNING, ast_party_subaddress::odd_even_indicator, ast_party_subaddress_ies::odd_even_indicator, ast_party_subaddress_ies::str, ast_party_subaddress::str, ast_party_subaddress::type, ast_party_subaddress_ies::type, ast_party_subaddress::valid, and ast_party_subaddress_ies::valid.
Referenced by party_id_build_data().
08365 { 08366 size_t length; 08367 size_t pos = 0; 08368 08369 /* 08370 * The size of integer values must be fixed in case the frame is 08371 * shipped to another machine. 08372 */ 08373 if (subaddress->str) { 08374 length = strlen(subaddress->str); 08375 if (datalen < pos + (sizeof(data[0]) * 2) + length) { 08376 ast_log(LOG_WARNING, "No space left for %s subaddress\n", label); 08377 return -1; 08378 } 08379 data[pos++] = ies->str; 08380 data[pos++] = length; 08381 memcpy(data + pos, subaddress->str, length); 08382 pos += length; 08383 } 08384 08385 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08386 ast_log(LOG_WARNING, "No space left for %s type of subaddress\n", label); 08387 return -1; 08388 } 08389 data[pos++] = ies->type; 08390 data[pos++] = 1; 08391 data[pos++] = subaddress->type; 08392 08393 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08394 ast_log(LOG_WARNING, 08395 "No space left for %s subaddress odd-even indicator\n", label); 08396 return -1; 08397 } 08398 data[pos++] = ies->odd_even_indicator; 08399 data[pos++] = 1; 08400 data[pos++] = subaddress->odd_even_indicator; 08401 08402 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08403 ast_log(LOG_WARNING, "No space left for %s subaddress valid\n", label); 08404 return -1; 08405 } 08406 data[pos++] = ies->valid; 08407 data[pos++] = 1; 08408 data[pos++] = subaddress->valid; 08409 08410 return pos; 08411 }
| static void plc_ds_destroy | ( | void * | data | ) | [static] |
Definition at line 4553 of file channel.c.
References ast_free, and plc_ds::samples_buf.
04554 { 04555 struct plc_ds *plc = data; 04556 ast_free(plc->samples_buf); 04557 ast_free(plc); 04558 }
| static void queue_dtmf_readq | ( | struct ast_channel * | chan, | |
| struct ast_frame * | f | |||
| ) | [inline, static] |
Definition at line 3510 of file channel.c.
References AST_FRAME_DTMF_END, ast_queue_frame(), ast_channel::dtmff, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::len, and ast_frame::subclass.
Referenced by __ast_read().
03511 { 03512 struct ast_frame *fr = &chan->dtmff; 03513 03514 fr->frametype = AST_FRAME_DTMF_END; 03515 fr->subclass.integer = f->subclass.integer; 03516 fr->len = f->len; 03517 03518 /* The only time this function will be called is for a frame that just came 03519 * out of the channel driver. So, we want to stick it on the tail of the 03520 * readq. */ 03521 03522 ast_queue_frame(chan, fr); 03523 }
| static void report_new_callerid | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6321 of file channel.c.
References ast_channel_name(), ast_channel_uniqueid(), ast_describe_caller_presentation(), ast_manager_event, ast_party_id_presentation(), ast_channel::caller, EVENT_FLAG_CALL, ast_party_caller::id, ast_party_id::name, ast_party_id::number, S_COR, ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.
Referenced by ast_channel_set_caller_event(), ast_do_masquerade(), and ast_set_callerid().
06322 { 06323 int pres; 06324 06325 pres = ast_party_id_presentation(&chan->caller.id); 06326 ast_manager_event(chan, EVENT_FLAG_CALL, "NewCallerid", 06327 "Channel: %s\r\n" 06328 "CallerIDNum: %s\r\n" 06329 "CallerIDName: %s\r\n" 06330 "Uniqueid: %s\r\n" 06331 "CID-CallingPres: %d (%s)\r\n", 06332 ast_channel_name(chan), 06333 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""), 06334 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""), 06335 ast_channel_uniqueid(chan), 06336 pres, 06337 ast_describe_caller_presentation(pres) 06338 ); 06339 }
| static void send_dtmf_event | ( | struct ast_channel * | chan, | |
| const char * | direction, | |||
| const char | digit, | |||
| const char * | begin, | |||
| const char * | end | |||
| ) | [static] |
Definition at line 3449 of file channel.c.
References ast_channel_name(), ast_channel_uniqueid(), ast_manager_event, and EVENT_FLAG_DTMF.
Referenced by __ast_read(), and ast_write().
03450 { 03451 ast_manager_event(chan, EVENT_FLAG_DTMF, 03452 "DTMF", 03453 "Channel: %s\r\n" 03454 "Uniqueid: %s\r\n" 03455 "Digit: %c\r\n" 03456 "Direction: %s\r\n" 03457 "Begin: %s\r\n" 03458 "End: %s\r\n", 03459 ast_channel_name(chan), ast_channel_uniqueid(chan), digit, direction, begin, end); 03460 }
| static int set_format | ( | struct ast_channel * | chan, | |
| struct ast_format_cap * | cap_set, | |||
| struct ast_format * | rawformat, | |||
| struct ast_format * | format, | |||
| struct ast_trans_pvt ** | trans, | |||
| const int | direction | |||
| ) | [static] |
Definition at line 4948 of file channel.c.
References ast_best_codec(), ast_channel_lock, ast_channel_name(), ast_channel_setoption(), ast_channel_unlock, ast_debug, ast_format_cap_set(), ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_copy(), ast_getformatname(), ast_getformatname_multiple(), ast_log(), AST_OPTION_FORMAT_READ, AST_OPTION_FORMAT_WRITE, ast_translator_best_choice(), ast_translator_build_path(), ast_translator_free_path(), generator_write_format_change(), ast_channel::generatordata, LOG_WARNING, and ast_channel::nativeformats.
Referenced by ast_set_read_format(), ast_set_read_format_by_id(), ast_set_read_format_from_cap(), ast_set_write_format(), ast_set_write_format_by_id(), and ast_set_write_format_from_cap().
04954 { 04955 struct ast_format_cap *cap_native = chan->nativeformats; 04956 struct ast_format best_set_fmt; 04957 struct ast_format best_native_fmt; 04958 int res; 04959 char from[200], to[200]; 04960 04961 ast_best_codec(cap_set, &best_set_fmt); 04962 04963 /* See if the underlying channel driver is capable of performing transcoding for us */ 04964 if (!ast_channel_setoption(chan, direction ? AST_OPTION_FORMAT_WRITE : AST_OPTION_FORMAT_READ, &best_set_fmt, sizeof(best_set_fmt), 0)) { 04965 ast_debug(1, "Channel driver natively set channel %s to %s format %s\n", ast_channel_name(chan), 04966 direction ? "write" : "read", ast_getformatname(&best_set_fmt)); 04967 04968 ast_channel_lock(chan); 04969 ast_format_copy(format, &best_set_fmt); 04970 ast_format_copy(rawformat, &best_set_fmt); 04971 ast_format_cap_set(chan->nativeformats, &best_set_fmt); 04972 ast_channel_unlock(chan); 04973 04974 if (*trans) { 04975 ast_translator_free_path(*trans); 04976 } 04977 *trans = NULL; 04978 /* If there is a generator on the channel, it needs to know about this 04979 * change if it is the write format. */ 04980 if (direction && chan->generatordata) { 04981 generator_write_format_change(chan); 04982 } 04983 return 0; 04984 } 04985 04986 /* Find a translation path from the native format to one of the desired formats */ 04987 if (!direction) { 04988 /* reading */ 04989 res = ast_translator_best_choice(cap_set, cap_native, &best_set_fmt, &best_native_fmt); 04990 } else { 04991 /* writing */ 04992 res = ast_translator_best_choice(cap_native, cap_set, &best_native_fmt, &best_set_fmt); 04993 } 04994 04995 if (res < 0) { 04996 ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n", 04997 ast_getformatname_multiple(from, sizeof(from), cap_native), 04998 ast_getformatname_multiple(to, sizeof(to), cap_set)); 04999 return -1; 05000 } 05001 05002 /* Now we have a good choice for both. */ 05003 ast_channel_lock(chan); 05004 05005 if ((ast_format_cmp(rawformat, &best_native_fmt) != AST_FORMAT_CMP_NOT_EQUAL) && 05006 (ast_format_cmp(format, &best_set_fmt) != AST_FORMAT_CMP_NOT_EQUAL) && 05007 ((ast_format_cmp(rawformat, format) != AST_FORMAT_CMP_NOT_EQUAL) || (*trans))) { 05008 /* the channel is already in these formats, so nothing to do */ 05009 ast_channel_unlock(chan); 05010 return 0; 05011 } 05012 05013 ast_format_copy(rawformat, &best_native_fmt); 05014 /* User perspective is fmt */ 05015 ast_format_copy(format, &best_set_fmt); 05016 05017 /* Free any read translation we have right now */ 05018 if (*trans) { 05019 ast_translator_free_path(*trans); 05020 *trans = NULL; 05021 } 05022 05023 /* Build a translation path from the raw format to the desired format */ 05024 if (ast_format_cmp(format, rawformat) != AST_FORMAT_CMP_NOT_EQUAL) { 05025 /* 05026 * If we were able to swap the native format to the format that 05027 * has been requested, then there is no need to try to build 05028 * a translation path. 05029 */ 05030 res = 0; 05031 } else { 05032 if (!direction) { 05033 /* reading */ 05034 *trans = ast_translator_build_path(format, rawformat); 05035 } else { 05036 /* writing */ 05037 *trans = ast_translator_build_path(rawformat, format); 05038 } 05039 res = *trans ? 0 : -1; 05040 } 05041 ast_channel_unlock(chan); 05042 05043 ast_debug(1, "Set channel %s to %s format %s\n", 05044 ast_channel_name(chan), 05045 direction ? "write" : "read", 05046 ast_getformatname(&best_set_fmt)); 05047 05048 /* If there is a generator on the channel, it needs to know about this 05049 * change if it is the write format. */ 05050 if (direction && chan->generatordata) { 05051 generator_write_format_change(chan); 05052 } 05053 return res; 05054 }
| static int set_security_requirements | ( | const struct ast_channel * | requestor, | |
| struct ast_channel * | out | |||
| ) | [static] |
Definition at line 5489 of file channel.c.
References ast_channel_datastore_find(), ast_channel_lock, ast_channel_setoption(), ast_channel_unlock, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, ast_datastore::data, ast_secure_call_store::media, secure_call_info, and ast_secure_call_store::signaling.
Referenced by ast_request().
05490 { 05491 int ops[2][2] = { 05492 {AST_OPTION_SECURE_SIGNALING, 0}, 05493 {AST_OPTION_SECURE_MEDIA, 0}, 05494 }; 05495 int i; 05496 struct ast_channel *r = (struct ast_channel *) requestor; /* UGLY */ 05497 struct ast_datastore *ds; 05498 05499 if (!requestor || !out) { 05500 return 0; 05501 } 05502 05503 ast_channel_lock(r); 05504 if ((ds = ast_channel_datastore_find(r, &secure_call_info, NULL))) { 05505 struct ast_secure_call_store *encrypt = ds->data; 05506 ops[0][1] = encrypt->signaling; 05507 ops[1][1] = encrypt->media; 05508 } else { 05509 ast_channel_unlock(r); 05510 return 0; 05511 } 05512 ast_channel_unlock(r); 05513 05514 for (i = 0; i < 2; i++) { 05515 if (ops[i][1]) { 05516 if (ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0)) { 05517 /* We require a security feature, but the channel won't provide it */ 05518 return -1; 05519 } 05520 } else { 05521 /* We don't care if we can't clear the option on a channel that doesn't support it */ 05522 ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0); 05523 } 05524 } 05525 05526 return 0; 05527 }
| static int should_skip_dtmf | ( | struct ast_channel * | chan | ) | [inline, static] |
Determine whether or not we should ignore DTMF in the readq.
Definition at line 3528 of file channel.c.
References AST_FLAG_DEFER_DTMF, AST_FLAG_EMULATE_DTMF, AST_MIN_DTMF_GAP, ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), and ast_channel::dtmf_tv.
Referenced by __ast_read().
03529 { 03530 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)) { 03531 /* We're in the middle of emulating a digit, or DTMF has been 03532 * explicitly deferred. Skip this digit, then. */ 03533 return 1; 03534 } 03535 03536 if (!ast_tvzero(chan->dtmf_tv) && 03537 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) { 03538 /* We're not in the middle of a digit, but it hasn't been long enough 03539 * since the last digit, so we'll have to skip DTMF for now. */ 03540 return 1; 03541 } 03542 03543 return 0; 03544 }
| static void* silence_generator_alloc | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
| static int silence_generator_generate | ( | struct ast_channel * | chan, | |
| void * | data, | |||
| int | len, | |||
| int | samples | |||
| ) | [static] |
Definition at line 8023 of file channel.c.
References ast_format_set(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_write(), ast_frame_subclass::format, ast_frame::frametype, and ast_frame::subclass.
08024 { 08025 short buf[samples]; 08026 struct ast_frame frame = { 08027 .frametype = AST_FRAME_VOICE, 08028 .data.ptr = buf, 08029 .samples = samples, 08030 .datalen = sizeof(buf), 08031 }; 08032 ast_format_set(&frame.subclass.format, AST_FORMAT_SLINEAR, 0); 08033 08034 memset(buf, 0, sizeof(buf)); 08035 08036 if (ast_write(chan, &frame)) 08037 return -1; 08038 08039 return 0; 08040 }
| static void silence_generator_release | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
| static void* tonepair_alloc | ( | struct ast_channel * | chan, | |
| void * | params | |||
| ) | [static] |
Definition at line 7624 of file channel.c.
References ast_calloc, ast_channel_name(), AST_FLAG_WRITE_INT, ast_format_copy(), AST_FORMAT_SLINEAR, ast_log(), ast_set_flag, ast_set_write_format_by_id(), cos, tonepair_def::duration, tonepair_state::duration, tonepair_state::fac1, tonepair_state::fac2, tonepair_def::freq1, tonepair_def::freq2, LOG_WARNING, M_PI, tonepair_state::modulate, tonepair_state::origwfmt, tonepair_release(), tonepair_state::v1_1, tonepair_state::v2_1, tonepair_state::v2_2, tonepair_state::v3_1, tonepair_state::v3_2, tonepair_def::vol, and ast_channel::writeformat.
07625 { 07626 struct tonepair_state *ts; 07627 struct tonepair_def *td = params; 07628 07629 if (!(ts = ast_calloc(1, sizeof(*ts)))) 07630 return NULL; 07631 ast_format_copy(&ts->origwfmt, &chan->writeformat); 07632 if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR)) { 07633 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", ast_channel_name(chan)); 07634 tonepair_release(NULL, ts); 07635 ts = NULL; 07636 } else { 07637 ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0; 07638 ts->v1_1 = 0; 07639 ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol; 07640 ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol; 07641 ts->v2_1 = 0; 07642 ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0; 07643 ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol; 07644 ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol; 07645 ts->duration = td->duration; 07646 ts->modulate = 0; 07647 } 07648 /* Let interrupts interrupt :) */ 07649 ast_set_flag(chan, AST_FLAG_WRITE_INT); 07650 return ts; 07651 }
| static int tonepair_generator | ( | struct ast_channel * | chan, | |
| void * | data, | |||
| int | len, | |||
| int | samples | |||
| ) | [static] |
Definition at line 7653 of file channel.c.
References ast_format_set(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_write(), ast_frame::data, tonepair_state::data, ast_frame::datalen, tonepair_state::duration, tonepair_state::f, tonepair_state::fac1, tonepair_state::fac2, ast_frame_subclass::format, ast_frame::frametype, LOG_WARNING, tonepair_state::modulate, ast_frame::offset, tonepair_state::pos, ast_frame::ptr, ast_frame::samples, ast_frame::subclass, tonepair_state::v1_1, tonepair_state::v1_2, tonepair_state::v2_1, tonepair_state::v2_2, tonepair_state::v3_1, and tonepair_state::v3_2.
07654 { 07655 struct tonepair_state *ts = data; 07656 int x; 07657 07658 /* we need to prepare a frame with 16 * timelen samples as we're 07659 * generating SLIN audio 07660 */ 07661 len = samples * 2; 07662 07663 if (len > sizeof(ts->data) / 2 - 1) { 07664 ast_log(LOG_WARNING, "Can't generate that much data!\n"); 07665 return -1; 07666 } 07667 memset(&ts->f, 0, sizeof(ts->f)); 07668 for (x=0;x<len/2;x++) { 07669 ts->v1_1 = ts->v2_1; 07670 ts->v2_1 = ts->v3_1; 07671 ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1; 07672 07673 ts->v1_2 = ts->v2_2; 07674 ts->v2_2 = ts->v3_2; 07675 ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2; 07676 if (ts->modulate) { 07677 int p; 07678 p = ts->v3_2 - 32768; 07679 if (p < 0) p = -p; 07680 p = ((p * 9) / 10) + 1; 07681 ts->data[x] = (ts->v3_1 * p) >> 15; 07682 } else 07683 ts->data[x] = ts->v3_1 + ts->v3_2; 07684 } 07685 ts->f.frametype = AST_FRAME_VOICE; 07686 ast_format_set(&ts->f.subclass.format, AST_FORMAT_SLINEAR, 0); 07687 ts->f.datalen = len; 07688 ts->f.samples = samples; 07689 ts->f.offset = AST_FRIENDLY_OFFSET; 07690 ts->f.data.ptr = ts->data; 07691 ast_write(chan, &ts->f); 07692 ts->pos += x; 07693 if (ts->duration > 0) { 07694 if (ts->pos >= ts->duration * 8) 07695 return -1; 07696 } 07697 return 0; 07698 }
| static void tonepair_release | ( | struct ast_channel * | chan, | |
| void * | params | |||
| ) | [static] |
Definition at line 7615 of file channel.c.
References ast_free, ast_set_write_format(), and tonepair_state::origwfmt.
Referenced by tonepair_alloc().
07616 { 07617 struct tonepair_state *ts = params; 07618 07619 if (chan) 07620 ast_set_write_format(chan, &ts->origwfmt); 07621 ast_free(ts); 07622 }
| static void update_bridge_vars | ( | struct ast_channel * | c0, | |
| struct ast_channel * | c1 | |||
| ) | [static] |
Definition at line 7221 of file channel.c.
References ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_strdupa, ast_strlen_zero(), ast_channel_tech::get_pvt_uniqueid, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and ast_channel::tech.
Referenced by ast_channel_bridge().
07222 { 07223 const char *c0_name; 07224 const char *c1_name; 07225 const char *c0_pvtid = NULL; 07226 const char *c1_pvtid = NULL; 07227 07228 ast_channel_lock(c1); 07229 c1_name = ast_strdupa(ast_channel_name(c1)); 07230 if (c1->tech->get_pvt_uniqueid) { 07231 c1_pvtid = ast_strdupa(c1->tech->get_pvt_uniqueid(c1)); 07232 } 07233 ast_channel_unlock(c1); 07234 07235 ast_channel_lock(c0); 07236 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER"))) { 07237 pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1_name); 07238 } 07239 if (c1_pvtid) { 07240 pbx_builtin_setvar_helper(c0, "BRIDGEPVTCALLID", c1_pvtid); 07241 } 07242 c0_name = ast_strdupa(ast_channel_name(c0)); 07243 if (c0->tech->get_pvt_uniqueid) { 07244 c0_pvtid = ast_strdupa(c0->tech->get_pvt_uniqueid(c0)); 07245 } 07246 ast_channel_unlock(c0); 07247 07248 ast_channel_lock(c1); 07249 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER"))) { 07250 pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0_name); 07251 } 07252 if (c0_pvtid) { 07253 pbx_builtin_setvar_helper(c1, "BRIDGEPVTCALLID", c0_pvtid); 07254 } 07255 ast_channel_unlock(c1); 07256 }
| static void xfer_ds_destroy | ( | void * | data | ) | [static] |
Definition at line 6027 of file channel.c.
References ast_free, ast_party_connected_line_free(), xfer_masquerade_ds::target_id, and xfer_masquerade_ds::transferee_id.
06028 { 06029 struct xfer_masquerade_ds *ds = data; 06030 06031 ast_party_connected_line_free(&ds->target_id); 06032 ast_party_connected_line_free(&ds->transferee_id); 06033 ast_free(ds); 06034 }
| struct ast_channel_tech ast_kill_tech |
Kill the channel channel driver technology descriptor.
The purpose of this channel technology is to encourage the channel to hangup as quickly as possible.
Definition at line 447 of file channel.c.
Referenced by ast_do_masquerade().
void(* ast_moh_cleanup_ptr)(struct ast_channel *) = NULL [static] |
Referenced by ast_install_music_functions(), ast_moh_cleanup(), and ast_uninstall_music_functions().
int(* ast_moh_start_ptr)(struct ast_channel *, const char *, const char *) = NULL [static] |
Referenced by ast_install_music_functions(), ast_moh_start(), and ast_uninstall_music_functions().
void(* ast_moh_stop_ptr)(struct ast_channel *) = NULL [static] |
Referenced by ast_install_music_functions(), ast_moh_stop(), and ast_uninstall_music_functions().
| int cause |
Definition at line 152 of file channel.c.
Referenced by __ast_read(), __ast_request_and_dial(), action_hangup(), alloc_playback_chan(), ast_call_forward(), ast_str2cause(), cb_events(), conf_start_record(), dial_exec_full(), dial_transfer(), do_forward(), dump_cause(), feature_request_and_dial(), oh323_hangup(), ospfinished_exec(), ospnext_exec(), parse_disconnect(), parse_release(), parse_release_complete(), parse_status(), pbx_builtin_hangup(), sms_messagerx(), and sms_messagerx2().
struct { ... } causes[] [static] |
map AST_CAUSE's to readable string representations
Referenced by ast_cause2str(), ast_str2cause(), and dump_cause().
struct ast_datastore_info cc_channel_datastore_info [static] |
Initial value:
{
.type = "Call Completion",
.duplicate = channel_cc_params_copy,
.destroy = channel_cc_params_destroy,
}
struct ast_data_entry channel_providers[] [static] |
Initial value:
{
AST_DATA_ENTRY("/asterisk/core/channels", &channels_provider),
AST_DATA_ENTRY("/asterisk/core/channeltypes", &channeltypes_provider),
}
struct ao2_container* channels [static] |
struct ast_data_handler channels_provider [static] |
Initial value:
{
.version = AST_DATA_HANDLER_VERSION,
.get = data_channels_provider_handler
}
struct ast_data_handler channeltypes_provider [static] |
Initial value:
{
.version = AST_DATA_HANDLER_VERSION,
.get = data_channeltypes_provider_handler
}
struct ast_cli_entry cli_channel[] [static] |
Initial value:
{
AST_CLI_DEFINE(handle_cli_core_show_channeltypes, "List available channel types"),
AST_CLI_DEFINE(handle_cli_core_show_channeltype, "Give more details on that channel type")
}
Definition at line 403 of file channel.c.
Referenced by ast_channels_init().
| unsigned long global_fin |
The current value of the debug flags is stored in the two variables global_fin and global_fout (declared in main/channel.c)
Definition at line 97 of file channel.c.
Referenced by handle_core_set_debug_channel().
| unsigned long global_fout |
struct ast_channel_tech null_tech [static] |
Initial value:
{
.type = "NULL",
.description = "Null channel (should not see this)",
}
Definition at line 903 of file channel.c.
Referenced by __ast_channel_alloc_ap(), and do_notify().
struct ast_datastore_info plc_ds_info [static] |
Initial value:
{
.type = "plc",
.destroy = plc_ds_destroy,
}
int shutting_down [static] |
struct ast_generator silence_generator [static] |
Initial value:
{
.alloc = silence_generator_alloc,
.release = silence_generator_release,
.generate = silence_generator_generate,
}
struct ast_threadstorage state2str_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_state2str_threadbuf , .custom_init = NULL , } [static] |
struct ast_generator tonepair [static] |
Initial value:
{
alloc: tonepair_alloc,
release: tonepair_release,
generate: tonepair_generator,
}
struct ast_datastore_info xfer_ds_info [static] |
Initial value:
{
.type = "xfer_colp",
.destroy = xfer_ds_destroy,
}
1.5.6