#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 | DATA_EXPORT_CHANNEL(MEMBER) |
#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. | |
ast_channel * | __ast_channel_alloc (int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const char *linkedid, const int amaflag, const char *file, int line, const char *function, const char *name_fmt,...) |
Create a channel structure. | |
static struct ast_channel *attribute_malloc | __ast_channel_alloc_ap (int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const char *linkedid, const int amaflag, const char *file, int line, const char *function, const char *name_fmt, va_list ap1, va_list ap2) |
Create a new channel structure. | |
static int | __ast_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) |
ast_channel * | __ast_request_and_dial (const char *type, format_t format, const struct ast_channel *requestor, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh) |
Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it. | |
static void | __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) |
format_t | ast_best_codec (format_t fmts) |
Pick the best audio codec. | |
ast_channel * | ast_bridged_channel (struct ast_channel *chan) |
Find bridged channel. | |
int | ast_call (struct ast_channel *chan, char *addr, int timeout) |
Make a call. | |
ast_channel * | ast_call_forward (struct ast_channel *caller, struct ast_channel *orig, int *timeout, format_t format, struct outgoing_helper *oh, int *outstate) |
Forwards a call to a new channel specified by the original channel's call_forward str. If possible, the new forwarded channel is created and returned while the original one is terminated. | |
void | ast_cancel_shutdown (void) |
Cancel a shutdown in progress. | |
const char * | ast_cause2str (int cause) |
Gives the string form of a given cause code. | |
void | ast_change_name (struct ast_channel *chan, const char *newname) |
Change channel name. | |
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. | |
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 the settings of when to hang a channel up. | |
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_data_add_structure (struct ast_data *tree, struct ast_channel *chan, int add_bridged) |
Insert into an astdata tree, the channel structure. | |
int | ast_channel_data_cmp_structure (const struct ast_data_search *tree, struct ast_channel *chan, const char *structure_name) |
Compare to channel structures using the data api. | |
int | ast_channel_datastore_add (struct ast_channel *chan, struct ast_datastore *datastore) |
Add a datastore to a channel. | |
ast_datastore * | ast_channel_datastore_alloc (const const struct ast_datastore_info *info, const char *uid) |
ast_datastore * | ast_channel_datastore_find (struct ast_channel *chan, const const struct ast_datastore_info *info, const char *uid) |
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) |
Defers DTMF so that you only read things like hangups and audio. | |
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). | |
ast_channel * | ast_channel_get_by_exten (const char *exten, const char *context) |
Find a channel by extension and context. | |
ast_channel * | ast_channel_get_by_name (const char *name) |
Find a channel by name. | |
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. | |
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 struct ast_channel * | ast_channel_get_full (const char *name, size_t name_len, const char *exten, const char *context) |
static int | ast_channel_hash_cb (const void *obj, const int flags) |
void | ast_channel_inherit_variables (const struct ast_channel *parent, struct ast_channel *child) |
Inherits channel variable from parent to child channel. | |
ast_channel_iterator * | ast_channel_iterator_all_new (void) |
Create a new channel iterator. | |
ast_channel_iterator * | ast_channel_iterator_by_exten_new (const char *exten, const char *context) |
Create a new channel iterator based on extension. | |
ast_channel_iterator * | ast_channel_iterator_by_name_new (const char *name, size_t name_len) |
Create a new channel iterator based on name. | |
ast_channel_iterator * | ast_channel_iterator_destroy (struct ast_channel_iterator *i) |
Destroy a channel iterator. | |
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 channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports. | |
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 linked id between chan and peer | |
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 hang a channel up. | |
static int | ast_channel_softhangup_cb (void *obj, void *arg, int flags) |
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_unregister (const struct ast_channel_tech *tech) |
Unregister a channel technology. | |
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) |
ast_variable * | ast_channeltype_list (void) |
return an ast_variable list of channeltypes | |
int | ast_check_hangup (struct ast_channel *chan) |
Check to see if a channel is needing hang up. | |
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. | |
AST_DATA_STRUCTURE (ast_channel, DATA_EXPORT_CHANNEL) | |
void | ast_deactivate_generator (struct ast_channel *chan) |
int | ast_do_masquerade (struct ast_channel *original) |
Start masquerading a channel. | |
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) |
ast_channel_tech * | ast_get_channel_tech (const char *name) |
Get a channel technology structure by name. | |
ast_group_t | ast_get_group (const char *s) |
int | ast_hangup (struct ast_channel *chan) |
Hang up a channel. | |
int | ast_indicate (struct ast_channel *chan, int condition) |
Indicates condition of channel. | |
int | ast_indicate_data (struct ast_channel *chan, int _condition, const void *data, size_t datalen) |
Indicates condition of channel, with payload. | |
void | ast_install_music_functions (int(*start_ptr)(struct ast_channel *, const char *, const char *), void(*stop_ptr)(struct ast_channel *), void(*cleanup_ptr)(struct ast_channel *)) |
int | ast_internal_timing_enabled (struct ast_channel *chan) |
Check if the channel can run in internal timing mode. | |
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- and pickup groups into buffer | |
int | ast_prod (struct ast_channel *chan) |
Send empty audio to prime a channel driver. | |
int | ast_queue_control (struct ast_channel *chan, enum ast_control_frame_type control) |
Queue a control frame with payload. | |
int | ast_queue_control_data (struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen) |
Queue a control frame with payload. | |
int | ast_queue_frame (struct ast_channel *chan, struct ast_frame *fin) |
Queue 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. | |
int | ast_queue_hangup_with_cause (struct ast_channel *chan, int cause) |
Queue a hangup frame with hangupcause set. | |
int | ast_raw_answer (struct ast_channel *chan, int cdr_answer) |
Answer a channel. | |
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) |
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. | |
ast_channel * | ast_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause) |
Requests a channel. | |
ast_channel * | ast_request_and_dial (const char *type, format_t format, const struct ast_channel *requestor, void *data, int timeout, int *outstate, const char *cidnum, const char *cidname) |
Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it. | |
int | ast_safe_sleep (struct ast_channel *chan, int ms) |
Wait for a specified amount of time, looking for hangups. | |
int | ast_safe_sleep_conditional (struct ast_channel *chan, int ms, int(*cond)(void *), void *data) |
Wait for a specified amount of time, looking for hangups and a condition argument. | |
int | ast_say_character_str (struct ast_channel *chan, const char *str, const char *ints, const char *lang) |
int | ast_say_digit_str (struct ast_channel *chan, const char *str, const char *ints, const char *lang) |
says digits of a string | |
int | ast_say_digits (struct ast_channel *chan, int num, const char *ints, const char *lang) |
says digits | |
int | ast_say_digits_full (struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd) |
int | ast_say_enumeration (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options) |
says an enumeration | |
int | ast_say_number (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options) |
says a number | |
int | ast_say_phonetic_str (struct ast_channel *chan, const char *str, const char *ints, const char *lang) |
int | ast_senddigit (struct ast_channel *chan, char digit, unsigned int duration) |
Send a DTMF digit to a channel. | |
int | ast_senddigit_begin (struct ast_channel *chan, char digit) |
Send a DTMF digit to a channel. | |
int | ast_senddigit_end (struct ast_channel *chan, char digit, unsigned int duration) |
Send a DTMF digit to a channel. | |
int | ast_sendtext (struct ast_channel *chan, const char *text) |
Sends text to a channel. | |
void | ast_set_callerid (struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani) |
Set caller ID number, name and ANI 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, format_t fmt) |
Sets read format on channel chan Set read format for channel to whichever component of "format" is best. | |
void | ast_set_variables (struct ast_channel *chan, struct ast_variable *vars) |
adds a list of channel variables to a channel | |
int | ast_set_write_format (struct ast_channel *chan, format_t fmt) |
Sets write format on channel chan Set write format for channel to whichever component of "format" is best. | |
int | ast_setstate (struct ast_channel *chan, enum ast_channel_state state) |
Change the state of a channel. | |
int | ast_settimeout (struct ast_channel *c, unsigned int rate, int(*func)(const void *data), void *data) |
Enable or disable timer ticks for a channel. | |
int | ast_shutting_down (void) |
Returns non-zero if Asterisk is being shut down. | |
int | ast_softhangup (struct ast_channel *chan, int cause) |
Softly hangup up a channel. | |
int | ast_softhangup_nolock (struct ast_channel *chan, int cause) |
Softly hangup up a channel (no channel lock). | |
const char * | ast_state2str (enum ast_channel_state state) |
Gives the string form of a given channel state. | |
int | ast_str2cause (const char *name) |
Convert the string form of a cause code to a 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 channel (if supported). | |
char * | ast_transfercapability2str (int transfercapability) |
Gives the string form of a given transfer capability. | |
int | ast_undestroyed_channels (void) |
void | ast_uninstall_music_functions (void) |
int | ast_waitfor (struct ast_channel *c, int ms) |
Wait for input on a channel. | |
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) |
Waits for input on an fd. | |
ast_channel * | ast_waitfor_nandfds (struct ast_channel **c, int n, int *fds, int nfds, int *exception, int *outfd, int *ms) |
Waits for activity on a group of channels. | |
int | ast_waitfordigit (struct ast_channel *c, int ms) |
Waits for a digit. | |
int | ast_waitfordigit_full (struct ast_channel *c, int ms, int audiofd, int cmdfd) |
Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading. | |
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) |
static void | channel_data_add_flags (struct ast_data *tree, struct ast_channel *chan) |
static struct ast_channel_iterator * | channel_iterator_search (const char *name, size_t name_len, const char *exten, const char *context) |
const char * | channelreloadreason2txt (enum channelreloadreason reason) |
Convert enum channelreloadreason to text string for manager event. | |
static void | clone_variables (struct ast_channel *original, struct ast_channel *clonechan) |
Clone channel variables from 'clone' channel into 'original' channel. | |
static char * | complete_channeltypes (struct ast_cli_args *a) |
static 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 | 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, format_t fmt, format_t *rawformat, format_t *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 | |
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 const struct ast_datastore_info | cc_channel_datastore_info |
static int | chancount |
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 const 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 109 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 112 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 116 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 8584 of file channel.c.
08584 { 08585 AST_CONNECTED_LINE_NUMBER, 08586 AST_CONNECTED_LINE_NAME, 08587 AST_CONNECTED_LINE_NUMBER_PLAN, 08588 AST_CONNECTED_LINE_ID_PRESENTATION,/* Combined number and name presentation. */ 08589 AST_CONNECTED_LINE_SOURCE, 08590 AST_CONNECTED_LINE_SUBADDRESS, 08591 AST_CONNECTED_LINE_SUBADDRESS_TYPE, 08592 AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, 08593 AST_CONNECTED_LINE_SUBADDRESS_VALID, 08594 AST_CONNECTED_LINE_TAG, 08595 AST_CONNECTED_LINE_VERSION, 08596 AST_CONNECTED_LINE_NAME_VALID, 08597 AST_CONNECTED_LINE_NAME_CHAR_SET, 08598 AST_CONNECTED_LINE_NAME_PRESENTATION, 08599 AST_CONNECTED_LINE_NUMBER_VALID, 08600 AST_CONNECTED_LINE_NUMBER_PRESENTATION, 08601 };
anonymous enum |
Element identifiers for redirecting indication frame data.
Definition at line 8905 of file channel.c.
08905 { 08906 AST_REDIRECTING_FROM_NUMBER, 08907 AST_REDIRECTING_FROM_NAME, 08908 AST_REDIRECTING_FROM_NUMBER_PLAN, 08909 AST_REDIRECTING_FROM_ID_PRESENTATION, 08910 AST_REDIRECTING_TO_NUMBER, 08911 AST_REDIRECTING_TO_NAME, 08912 AST_REDIRECTING_TO_NUMBER_PLAN, 08913 AST_REDIRECTING_TO_ID_PRESENTATION, 08914 AST_REDIRECTING_REASON, 08915 AST_REDIRECTING_COUNT, 08916 AST_REDIRECTING_FROM_SUBADDRESS, 08917 AST_REDIRECTING_FROM_SUBADDRESS_TYPE, 08918 AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, 08919 AST_REDIRECTING_FROM_SUBADDRESS_VALID, 08920 AST_REDIRECTING_TO_SUBADDRESS, 08921 AST_REDIRECTING_TO_SUBADDRESS_TYPE, 08922 AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, 08923 AST_REDIRECTING_TO_SUBADDRESS_VALID, 08924 AST_REDIRECTING_FROM_TAG, 08925 AST_REDIRECTING_TO_TAG, 08926 AST_REDIRECTING_VERSION, 08927 AST_REDIRECTING_FROM_NAME_VALID, 08928 AST_REDIRECTING_FROM_NAME_CHAR_SET, 08929 AST_REDIRECTING_FROM_NAME_PRESENTATION, 08930 AST_REDIRECTING_FROM_NUMBER_VALID, 08931 AST_REDIRECTING_FROM_NUMBER_PRESENTATION, 08932 AST_REDIRECTING_TO_NAME_VALID, 08933 AST_REDIRECTING_TO_NAME_CHAR_SET, 08934 AST_REDIRECTING_TO_NAME_PRESENTATION, 08935 AST_REDIRECTING_TO_NUMBER_VALID, 08936 AST_REDIRECTING_TO_NUMBER_PRESENTATION, 08937 };
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 2949 of file channel.c.
References ast_channel::_state, ast_channel_lock, ast_channel_unlock, AST_CONTROL_HANGUP, ast_debug, AST_FRAME_CNG, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_frisolate(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_log(), ast_queue_frame_head(), ast_raw_answer(), ast_read(), AST_STATE_RING, AST_STATE_RINGING, ast_waitfor(), chanlist::chan, errno, frames, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, MAX, ast_channel::name, and ast_frame::subclass.
Referenced by ast_answer(), pbx_builtin_answer(), and pbx_builtin_incomplete().
02950 { 02951 int res = 0; 02952 enum ast_channel_state old_state; 02953 02954 old_state = chan->_state; 02955 if ((res = ast_raw_answer(chan, cdr_answer))) { 02956 return res; 02957 } 02958 02959 switch (old_state) { 02960 case AST_STATE_RINGING: 02961 case AST_STATE_RING: 02962 /* wait for media to start flowing, but don't wait any longer 02963 * than 'delay' or 500 milliseconds, whichever is longer 02964 */ 02965 do { 02966 AST_LIST_HEAD_NOLOCK(, ast_frame) frames; 02967 struct ast_frame *cur, *new; 02968 int ms = MAX(delay, 500); 02969 unsigned int done = 0; 02970 02971 AST_LIST_HEAD_INIT_NOLOCK(&frames); 02972 02973 for (;;) { 02974 ms = ast_waitfor(chan, ms); 02975 if (ms < 0) { 02976 ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", chan->name, strerror(errno)); 02977 res = -1; 02978 break; 02979 } 02980 if (ms == 0) { 02981 ast_debug(2, "Didn't receive a media frame from %s within %d ms of answering. Continuing anyway\n", chan->name, MAX(delay, 500)); 02982 break; 02983 } 02984 cur = ast_read(chan); 02985 if (!cur || ((cur->frametype == AST_FRAME_CONTROL) && 02986 (cur->subclass.integer == AST_CONTROL_HANGUP))) { 02987 if (cur) { 02988 ast_frfree(cur); 02989 } 02990 res = -1; 02991 ast_debug(2, "Hangup of channel %s detected in answer routine\n", chan->name); 02992 break; 02993 } 02994 02995 if ((new = ast_frisolate(cur)) != cur) { 02996 ast_frfree(cur); 02997 } 02998 02999 AST_LIST_INSERT_HEAD(&frames, new, frame_list); 03000 03001 /* if a specific delay period was requested, continue 03002 * until that delay has passed. don't stop just because 03003 * incoming media has arrived. 03004 */ 03005 if (delay) { 03006 continue; 03007 } 03008 03009 switch (new->frametype) { 03010 /* all of these frametypes qualify as 'media' */ 03011 case AST_FRAME_VOICE: 03012 case AST_FRAME_VIDEO: 03013 case AST_FRAME_TEXT: 03014 case AST_FRAME_DTMF_BEGIN: 03015 case AST_FRAME_DTMF_END: 03016 case AST_FRAME_IMAGE: 03017 case AST_FRAME_HTML: 03018 case AST_FRAME_MODEM: 03019 done = 1; 03020 break; 03021 case AST_FRAME_CONTROL: 03022 case AST_FRAME_IAX: 03023 case AST_FRAME_NULL: 03024 case AST_FRAME_CNG: 03025 break; 03026 } 03027 03028 if (done) { 03029 break; 03030 } 03031 } 03032 03033 if (res == 0) { 03034 ast_channel_lock(chan); 03035 while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list))) { 03036 ast_queue_frame_head(chan, cur); 03037 ast_frfree(cur); 03038 } 03039 ast_channel_unlock(chan); 03040 } 03041 } while (0); 03042 break; 03043 default: 03044 break; 03045 } 03046 03047 return res; 03048 }
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 6107 of file channel.c.
References ast_manager_event, ast_string_field_set, chanlist::chan, EVENT_FLAG_CALL, name, ast_channel::name, and ast_channel::uniqueid.
Referenced by ast_change_name(), and ast_do_masquerade().
06108 { 06109 ast_manager_event(chan, EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid); 06110 ast_string_field_set(chan, name, newname); 06111 }
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.
NULL | failure | |
non-NULL | successfully allocated channel |
By default, new channels are set to the "s" extension and "default" context.
Definition at line 1355 of file channel.c.
References __ast_channel_alloc_ap().
01361 { 01362 va_list ap1, ap2; 01363 struct ast_channel *result; 01364 01365 va_start(ap1, name_fmt); 01366 va_start(ap2, name_fmt); 01367 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context, 01368 linkedid, amaflag, file, line, function, name_fmt, ap1, ap2); 01369 va_end(ap1); 01370 va_end(ap2); 01371 01372 return result; 01373 }
static struct ast_channel* attribute_malloc __ast_channel_alloc_ap | ( | int | needqueue, | |
int | state, | |||
const char * | cid_num, | |||
const char * | cid_name, | |||
const char * | acctcode, | |||
const char * | exten, | |||
const char * | context, | |||
const char * | linkedid, | |||
const int | amaflag, | |||
const char * | file, | |||
int | line, | |||
const char * | function, | |||
const char * | name_fmt, | |||
va_list | ap1, | |||
va_list | ap2 | |||
) | [static] |
Create a new channel structure.
Definition at line 1119 of file channel.c.
References __ao2_alloc_debug(), accountcode, ao2_alloc, ao2_link, 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_destructor(), ast_channel_set_fd(), ast_channel_unref, ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_default_accountcode, ast_default_amaflags, 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_state2str(), ast_strdup, ast_strdupa, ast_string_field_build, ast_string_field_build_va, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_timer_fd(), ast_timer_get_name(), ast_timer_open(), AST_TIMING_FD, channels, defaultlanguage, errno, EVENT_FLAG_CALL, chanlist::flags, language, LOG_WARNING, name, null_tech, S_OR, sched_context_create(), and chanlist::tech.
Referenced by __ast_channel_alloc(), and ast_channel_alloc().
01123 { 01124 struct ast_channel *tmp; 01125 int x; 01126 int flags; 01127 struct varshead *headp; 01128 char *tech = "", *tech2 = NULL; 01129 01130 /* If shutting down, don't allocate any new channels */ 01131 if (shutting_down) { 01132 ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n"); 01133 return NULL; 01134 } 01135 01136 #if defined(REF_DEBUG) 01137 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_channel_destructor, "", file, line, 01138 function, 1); 01139 #elif defined(__AST_DEBUG_MALLOC) 01140 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_channel_destructor, "", file, line, 01141 function, 0); 01142 #else 01143 tmp = ao2_alloc(sizeof(*tmp), ast_channel_destructor); 01144 #endif 01145 if (!tmp) { 01146 /* Channel structure allocation failure. */ 01147 return NULL; 01148 } 01149 01150 /* 01151 * Init file descriptors to unopened state so 01152 * the destructor can know not to close them. 01153 */ 01154 tmp->timingfd = -1; 01155 for (x = 0; x < ARRAY_LEN(tmp->alertpipe); ++x) { 01156 tmp->alertpipe[x] = -1; 01157 } 01158 for (x = 0; x < ARRAY_LEN(tmp->fds); ++x) { 01159 tmp->fds[x] = -1; 01160 } 01161 #ifdef HAVE_EPOLL 01162 tmp->epfd = epoll_create(25); 01163 #endif 01164 01165 if (!(tmp->sched = sched_context_create())) { 01166 ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n"); 01167 return ast_channel_unref(tmp); 01168 } 01169 01170 ast_party_dialed_init(&tmp->dialed); 01171 ast_party_caller_init(&tmp->caller); 01172 ast_party_connected_line_init(&tmp->connected); 01173 ast_party_redirecting_init(&tmp->redirecting); 01174 01175 if (cid_name) { 01176 tmp->caller.id.name.valid = 1; 01177 tmp->caller.id.name.str = ast_strdup(cid_name); 01178 if (!tmp->caller.id.name.str) { 01179 return ast_channel_unref(tmp); 01180 } 01181 } 01182 if (cid_num) { 01183 tmp->caller.id.number.valid = 1; 01184 tmp->caller.id.number.str = ast_strdup(cid_num); 01185 if (!tmp->caller.id.number.str) { 01186 return ast_channel_unref(tmp); 01187 } 01188 } 01189 01190 if ((tmp->timer = ast_timer_open())) { 01191 if (strcmp(ast_timer_get_name(tmp->timer), "timerfd")) { 01192 needqueue = 0; 01193 } 01194 tmp->timingfd = ast_timer_fd(tmp->timer); 01195 } 01196 01197 if (needqueue) { 01198 if (pipe(tmp->alertpipe)) { 01199 ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe! Try increasing max file descriptors with ulimit -n\n"); 01200 return ast_channel_unref(tmp); 01201 } else { 01202 flags = fcntl(tmp->alertpipe[0], F_GETFL); 01203 if (fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) { 01204 ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno)); 01205 return ast_channel_unref(tmp); 01206 } 01207 flags = fcntl(tmp->alertpipe[1], F_GETFL); 01208 if (fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK) < 0) { 01209 ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno)); 01210 return ast_channel_unref(tmp); 01211 } 01212 } 01213 } 01214 01215 /* 01216 * This is the last place the channel constructor can fail. 01217 * 01218 * The destructor takes advantage of this fact to ensure that the 01219 * AST_CEL_CHANNEL_END is not posted if we have not posted the 01220 * AST_CEL_CHANNEL_START yet. 01221 */ 01222 if ((ast_string_field_init(tmp, 128))) { 01223 return ast_channel_unref(tmp); 01224 } 01225 01226 /* Always watch the alertpipe */ 01227 ast_channel_set_fd(tmp, AST_ALERT_FD, tmp->alertpipe[0]); 01228 /* And timing pipe */ 01229 ast_channel_set_fd(tmp, AST_TIMING_FD, tmp->timingfd); 01230 01231 /* Initial state */ 01232 tmp->_state = state; 01233 01234 tmp->streamid = -1; 01235 01236 tmp->fin = global_fin; 01237 tmp->fout = global_fout; 01238 01239 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) { 01240 ast_string_field_build(tmp, uniqueid, "%li.%d", (long) time(NULL), 01241 ast_atomic_fetchadd_int(&uniqueint, 1)); 01242 } else { 01243 ast_string_field_build(tmp, uniqueid, "%s-%li.%d", ast_config_AST_SYSTEM_NAME, 01244 (long) time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1)); 01245 } 01246 01247 if (!ast_strlen_zero(linkedid)) { 01248 ast_string_field_set(tmp, linkedid, linkedid); 01249 } else { 01250 ast_string_field_set(tmp, linkedid, tmp->uniqueid); 01251 } 01252 01253 if (!ast_strlen_zero(name_fmt)) { 01254 char *slash, *slash2; 01255 /* Almost every channel is calling this function, and setting the name via the ast_string_field_build() call. 01256 * And they all use slightly different formats for their name string. 01257 * This means, to set the name here, we have to accept variable args, and call the string_field_build from here. 01258 * This means, that the stringfields must have a routine that takes the va_lists directly, and 01259 * uses them to build the string, instead of forming the va_lists internally from the vararg ... list. 01260 * This new function was written so this can be accomplished. 01261 */ 01262 ast_string_field_build_va(tmp, name, name_fmt, ap1, ap2); 01263 tech = ast_strdupa(tmp->name); 01264 if ((slash = strchr(tech, '/'))) { 01265 if ((slash2 = strchr(slash + 1, '/'))) { 01266 tech2 = slash + 1; 01267 *slash2 = '\0'; 01268 } 01269 *slash = '\0'; 01270 } 01271 } else { 01272 /* 01273 * Start the string with '-' so it becomes an empty string 01274 * in the destructor. 01275 */ 01276 ast_string_field_set(tmp, name, "-**Unknown**"); 01277 } 01278 01279 /* Reminder for the future: under what conditions do we NOT want to track cdrs on channels? */ 01280 01281 /* These 4 variables need to be set up for the cdr_init() to work right */ 01282 if (amaflag) 01283 tmp->amaflags = amaflag; 01284 else 01285 tmp->amaflags = ast_default_amaflags; 01286 01287 if (!ast_strlen_zero(acctcode)) 01288 ast_string_field_set(tmp, accountcode, acctcode); 01289 else 01290 ast_string_field_set(tmp, accountcode, ast_default_accountcode); 01291 01292 if (!ast_strlen_zero(context)) 01293 ast_copy_string(tmp->context, context, sizeof(tmp->context)); 01294 else 01295 strcpy(tmp->context, "default"); 01296 01297 if (!ast_strlen_zero(exten)) 01298 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); 01299 else 01300 strcpy(tmp->exten, "s"); 01301 01302 tmp->priority = 1; 01303 01304 tmp->cdr = ast_cdr_alloc(); 01305 ast_cdr_init(tmp->cdr, tmp); 01306 ast_cdr_start(tmp->cdr); 01307 01308 ast_atomic_fetchadd_int(&chancount, +1); 01309 ast_cel_report_event(tmp, AST_CEL_CHANNEL_START, NULL, NULL, NULL); 01310 01311 headp = &tmp->varshead; 01312 AST_LIST_HEAD_INIT_NOLOCK(headp); 01313 01314 AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores); 01315 01316 AST_LIST_HEAD_INIT_NOLOCK(&tmp->autochans); 01317 01318 ast_string_field_set(tmp, language, defaultlanguage); 01319 01320 tmp->tech = &null_tech; 01321 01322 ao2_link(channels, tmp); 01323 01324 /* 01325 * And now, since the channel structure is built, and has its name, let's 01326 * call the manager event generator with this Newchannel event. This is the 01327 * proper and correct place to make this call, but you sure do have to pass 01328 * a lot of data into this func to do it here! 01329 */ 01330 if (ast_get_channel_tech(tech) || (tech2 && ast_get_channel_tech(tech2))) { 01331 ast_manager_event(tmp, EVENT_FLAG_CALL, "Newchannel", 01332 "Channel: %s\r\n" 01333 "ChannelState: %d\r\n" 01334 "ChannelStateDesc: %s\r\n" 01335 "CallerIDNum: %s\r\n" 01336 "CallerIDName: %s\r\n" 01337 "AccountCode: %s\r\n" 01338 "Exten: %s\r\n" 01339 "Context: %s\r\n" 01340 "Uniqueid: %s\r\n", 01341 tmp->name, 01342 state, 01343 ast_state2str(state), 01344 S_OR(cid_num, ""), 01345 S_OR(cid_name, ""), 01346 tmp->accountcode, 01347 S_OR(exten, ""), 01348 S_OR(context, ""), 01349 tmp->uniqueid); 01350 } 01351 01352 return tmp; 01353 }
static int __ast_channel_masquerade | ( | struct ast_channel * | original, | |
struct ast_channel * | clonechan, | |||
struct ast_datastore * | xfer_ds | |||
) | [static] |
Definition at line 5871 of file channel.c.
References ast_channel::_bridge, ast_bridged_channel(), ast_channel_datastore_add(), ast_channel_lock_both, 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, ast_channel::name, and ast_channel::tech.
Referenced by ast_channel_masquerade(), and ast_channel_transfer_masquerade().
05872 { 05873 int res = -1; 05874 struct ast_channel *final_orig, *final_clone, *base; 05875 05876 for (;;) { 05877 final_orig = original; 05878 final_clone = clonechan; 05879 05880 ast_channel_lock_both(original, clonechan); 05881 05882 if (ast_test_flag(original, AST_FLAG_ZOMBIE) 05883 || ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) { 05884 /* Zombies! Run! */ 05885 ast_log(LOG_WARNING, 05886 "Can't setup masquerade. One or both channels is dead. (%s <-- %s)\n", 05887 original->name, clonechan->name); 05888 ast_channel_unlock(clonechan); 05889 ast_channel_unlock(original); 05890 return -1; 05891 } 05892 05893 /* 05894 * Each of these channels may be sitting behind a channel proxy 05895 * (i.e. chan_agent) and if so, we don't really want to 05896 * masquerade it, but its proxy 05897 */ 05898 if (original->_bridge 05899 && (original->_bridge != ast_bridged_channel(original)) 05900 && (original->_bridge->_bridge != original)) { 05901 final_orig = original->_bridge; 05902 } 05903 if (clonechan->_bridge 05904 && (clonechan->_bridge != ast_bridged_channel(clonechan)) 05905 && (clonechan->_bridge->_bridge != clonechan)) { 05906 final_clone = clonechan->_bridge; 05907 } 05908 if (final_clone->tech->get_base_channel 05909 && (base = final_clone->tech->get_base_channel(final_clone))) { 05910 final_clone = base; 05911 } 05912 05913 if ((final_orig != original) || (final_clone != clonechan)) { 05914 /* 05915 * Lots and lots of deadlock avoidance. The main one we're 05916 * competing with is ast_write(), which locks channels 05917 * recursively, when working with a proxy channel. 05918 */ 05919 if (ast_channel_trylock(final_orig)) { 05920 ast_channel_unlock(clonechan); 05921 ast_channel_unlock(original); 05922 05923 /* Try again */ 05924 continue; 05925 } 05926 if (ast_channel_trylock(final_clone)) { 05927 ast_channel_unlock(final_orig); 05928 ast_channel_unlock(clonechan); 05929 ast_channel_unlock(original); 05930 05931 /* Try again */ 05932 continue; 05933 } 05934 ast_channel_unlock(clonechan); 05935 ast_channel_unlock(original); 05936 original = final_orig; 05937 clonechan = final_clone; 05938 05939 if (ast_test_flag(original, AST_FLAG_ZOMBIE) 05940 || ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) { 05941 /* Zombies! Run! */ 05942 ast_log(LOG_WARNING, 05943 "Can't setup masquerade. One or both channels is dead. (%s <-- %s)\n", 05944 original->name, clonechan->name); 05945 ast_channel_unlock(clonechan); 05946 ast_channel_unlock(original); 05947 return -1; 05948 } 05949 } 05950 break; 05951 } 05952 05953 if (original == clonechan) { 05954 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name); 05955 ast_channel_unlock(clonechan); 05956 ast_channel_unlock(original); 05957 return -1; 05958 } 05959 05960 ast_debug(1, "Planning to masquerade channel %s into the structure of %s\n", 05961 clonechan->name, original->name); 05962 05963 if (!original->masqr && !original->masq && !clonechan->masq && !clonechan->masqr) { 05964 original->masq = clonechan; 05965 clonechan->masqr = original; 05966 if (xfer_ds) { 05967 ast_channel_datastore_add(original, xfer_ds); 05968 } 05969 ast_queue_frame(original, &ast_null_frame); 05970 ast_queue_frame(clonechan, &ast_null_frame); 05971 ast_debug(1, "Done planning to masquerade channel %s into the structure of %s\n", clonechan->name, original->name); 05972 res = 0; 05973 } else if (original->masq) { 05974 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 05975 original->masq->name, original->name); 05976 } else if (original->masqr) { 05977 /* not yet as a previously planned masq hasn't yet happened */ 05978 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 05979 original->name, original->masqr->name); 05980 } else if (clonechan->masq) { 05981 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 05982 clonechan->masq->name, clonechan->name); 05983 } else { /* (clonechan->masqr) */ 05984 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 05985 clonechan->name, clonechan->masqr->name); 05986 } 05987 05988 ast_channel_unlock(clonechan); 05989 ast_channel_unlock(original); 05990 05991 return res; 05992 }
static int __ast_queue_frame | ( | struct ast_channel * | chan, | |
struct ast_frame * | fin, | |||
int | head, | |||
struct ast_frame * | after | |||
) | [static] |
Definition at line 1410 of file channel.c.
References ast_channel::alertpipe, ast_channel_lock, 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, chanlist::chan, errno, f, frames, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, ast_channel::name, ast_channel::readq, ast_frame::subclass, ast_channel::timer, and ast_channel::timingfd.
Referenced by __ast_read(), ast_queue_frame(), and ast_queue_frame_head().
01411 { 01412 struct ast_frame *f; 01413 struct ast_frame *cur; 01414 unsigned int new_frames = 0; 01415 unsigned int new_voice_frames = 0; 01416 unsigned int queued_frames = 0; 01417 unsigned int queued_voice_frames = 0; 01418 AST_LIST_HEAD_NOLOCK(, ast_frame) frames; 01419 01420 ast_channel_lock(chan); 01421 01422 /* 01423 * Check the last frame on the queue if we are queuing the new 01424 * frames after it. 01425 */ 01426 cur = AST_LIST_LAST(&chan->readq); 01427 if (cur && cur->frametype == AST_FRAME_CONTROL && !head && (!after || after == cur)) { 01428 switch (cur->subclass.integer) { 01429 case AST_CONTROL_END_OF_Q: 01430 if (fin->frametype == AST_FRAME_CONTROL 01431 && fin->subclass.integer == AST_CONTROL_HANGUP) { 01432 /* 01433 * Destroy the end-of-Q marker frame so we can queue the hangup 01434 * frame in its place. 01435 */ 01436 AST_LIST_REMOVE(&chan->readq, cur, frame_list); 01437 ast_frfree(cur); 01438 01439 /* 01440 * This has degenerated to a normal queue append anyway. Since 01441 * we just destroyed the last frame in the queue we must make 01442 * sure that "after" is NULL or bad things will happen. 01443 */ 01444 after = NULL; 01445 break; 01446 } 01447 /* Fall through */ 01448 case AST_CONTROL_HANGUP: 01449 /* Don't queue anything. */ 01450 ast_channel_unlock(chan); 01451 return 0; 01452 default: 01453 break; 01454 } 01455 } 01456 01457 /* Build copies of all the new frames and count them */ 01458 AST_LIST_HEAD_INIT_NOLOCK(&frames); 01459 for (cur = fin; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 01460 if (!(f = ast_frdup(cur))) { 01461 if (AST_LIST_FIRST(&frames)) { 01462 ast_frfree(AST_LIST_FIRST(&frames)); 01463 } 01464 ast_channel_unlock(chan); 01465 return -1; 01466 } 01467 01468 AST_LIST_INSERT_TAIL(&frames, f, frame_list); 01469 new_frames++; 01470 if (f->frametype == AST_FRAME_VOICE) { 01471 new_voice_frames++; 01472 } 01473 } 01474 01475 /* Count how many frames exist on the queue */ 01476 AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) { 01477 queued_frames++; 01478 if (cur->frametype == AST_FRAME_VOICE) { 01479 queued_voice_frames++; 01480 } 01481 } 01482 01483 if ((queued_frames + new_frames > 128 || queued_voice_frames + new_voice_frames > 96)) { 01484 int count = 0; 01485 ast_log(LOG_WARNING, "Exceptionally long %squeue length queuing to %s\n", queued_frames + new_frames > 128 ? "" : "voice ", chan->name); 01486 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, cur, frame_list) { 01487 /* Save the most recent frame */ 01488 if (!AST_LIST_NEXT(cur, frame_list)) { 01489 break; 01490 } else if (cur->frametype == AST_FRAME_VOICE || cur->frametype == AST_FRAME_VIDEO || cur->frametype == AST_FRAME_NULL) { 01491 if (++count > 64) { 01492 break; 01493 } 01494 AST_LIST_REMOVE_CURRENT(frame_list); 01495 ast_frfree(cur); 01496 } 01497 } 01498 AST_LIST_TRAVERSE_SAFE_END; 01499 } 01500 01501 if (after) { 01502 AST_LIST_INSERT_LIST_AFTER(&chan->readq, &frames, after, frame_list); 01503 } else { 01504 if (head) { 01505 AST_LIST_APPEND_LIST(&frames, &chan->readq, frame_list); 01506 AST_LIST_HEAD_INIT_NOLOCK(&chan->readq); 01507 } 01508 AST_LIST_APPEND_LIST(&chan->readq, &frames, frame_list); 01509 } 01510 01511 if (chan->alertpipe[1] > -1) { 01512 int blah[new_frames]; 01513 01514 memset(blah, 1, sizeof(blah)); 01515 if (write(chan->alertpipe[1], &blah, sizeof(blah)) != (sizeof(blah))) { 01516 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s (qlen = %d): %s!\n", 01517 chan->name, queued_frames, strerror(errno)); 01518 } 01519 } else if (chan->timingfd > -1) { 01520 ast_timer_enable_continuous(chan->timer); 01521 } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 01522 pthread_kill(chan->blocker, SIGURG); 01523 } 01524 01525 ast_channel_unlock(chan); 01526 01527 return 0; 01528 }
static struct ast_frame* __ast_read | ( | struct ast_channel * | chan, | |
int | dropaudio | |||
) | [static] |
Definition at line 3750 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_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_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_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, chanlist::chan, ast_channel::connected, chanlist::connected, DEBUGCHAN_FLAG, ast_generator::digit, ast_channel::dtmf_tv, ast_channel::dtmff, ast_channel::emulate_dtmf_digit, ast_channel::emulate_dtmf_duration, errno, ast_channel_tech::exception, f, ast_channel::fdno, ast_channel::fds, ast_channel::fin, chanlist::flags, ast_filestream::fmt, ast_format::format, FRAMECOUNT_INC, ast_channel::framehooks, ast_generator::generate, ast_channel::generator, ast_channel::generatordata, ast_channel::hangupcause, ast_channel::insmpl, LOG_DTMF, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_channel::masq, ast_channel::monitor, ast_channel::music_state, ast_channel::name, ast_channel::nativeformats, ast_channel::outsmpl, ast_control_read_action_payload::payload, ast_control_read_action_payload::payload_size, queue_dtmf_readq(), ast_channel_tech::read, ast_channel_monitor::read_stream, ast_channel::readq, ast_channel::readtrans, SEEK_FORCECUR, send_dtmf_event(), should_skip_dtmf(), ast_channel_monitor::state, ast_channel::tech, ast_channel::timer, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.
Referenced by ast_read(), and ast_read_noaudio().
03751 { 03752 struct ast_frame *f = NULL; /* the return value */ 03753 int blah; 03754 int prestate; 03755 int cause = 0; 03756 03757 /* this function is very long so make sure there is only one return 03758 * point at the end (there are only two exceptions to this). 03759 */ 03760 03761 if (chan->masq) { 03762 ast_do_masquerade(chan); 03763 return &ast_null_frame; 03764 } 03765 03766 /* if here, no masq has happened, lock the channel and proceed */ 03767 ast_channel_lock(chan); 03768 03769 /* Stop if we're a zombie or need a soft hangup */ 03770 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 03771 if (chan->generator) 03772 ast_deactivate_generator(chan); 03773 03774 /* 03775 * It is possible for chan->_softhangup to be set and there 03776 * still be control frames that need to be read. Instead of 03777 * just going to 'done' in the case of ast_check_hangup(), we 03778 * need to queue the end-of-Q frame so that it can mark the end 03779 * of the read queue. If there are frames to be read, 03780 * ast_queue_control() will be called repeatedly, but will only 03781 * queue the first end-of-Q frame. 03782 */ 03783 if (chan->_softhangup) { 03784 ast_queue_control(chan, AST_CONTROL_END_OF_Q); 03785 } else { 03786 goto done; 03787 } 03788 } else { 03789 #ifdef AST_DEVMODE 03790 /* 03791 * The ast_waitfor() code records which of the channel's file 03792 * descriptors reported that data is available. In theory, 03793 * ast_read() should only be called after ast_waitfor() reports 03794 * that a channel has data available for reading. However, 03795 * there still may be some edge cases throughout the code where 03796 * ast_read() is called improperly. This can potentially cause 03797 * problems, so if this is a developer build, make a lot of 03798 * noise if this happens so that it can be addressed. 03799 * 03800 * One of the potential problems is blocking on a dead channel. 03801 */ 03802 if (chan->fdno == -1) { 03803 ast_log(LOG_ERROR, 03804 "ast_read() on chan '%s' called with no recorded file descriptor.\n", 03805 chan->name); 03806 } 03807 #endif 03808 } 03809 03810 prestate = chan->_state; 03811 if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD) { 03812 enum ast_timer_event res; 03813 03814 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 03815 03816 res = ast_timer_get_event(chan->timer); 03817 03818 switch (res) { 03819 case AST_TIMING_EVENT_EXPIRED: 03820 ast_timer_ack(chan->timer, 1); 03821 03822 if (chan->timingfunc) { 03823 /* save a copy of func/data before unlocking the channel */ 03824 int (*func)(const void *) = chan->timingfunc; 03825 void *data = chan->timingdata; 03826 chan->fdno = -1; 03827 ast_channel_unlock(chan); 03828 func(data); 03829 } else { 03830 ast_timer_set_rate(chan->timer, 0); 03831 chan->fdno = -1; 03832 ast_channel_unlock(chan); 03833 } 03834 03835 /* cannot 'goto done' because the channel is already unlocked */ 03836 return &ast_null_frame; 03837 03838 case AST_TIMING_EVENT_CONTINUOUS: 03839 if (AST_LIST_EMPTY(&chan->readq) || 03840 !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) { 03841 ast_timer_disable_continuous(chan->timer); 03842 } 03843 break; 03844 } 03845 03846 } else if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) { 03847 /* if the AST_GENERATOR_FD is set, call the generator with args 03848 * set to -1 so it can do whatever it needs to. 03849 */ 03850 void *tmp = chan->generatordata; 03851 chan->generatordata = NULL; /* reset to let ast_write get through */ 03852 chan->generator->generate(chan, tmp, -1, -1); 03853 chan->generatordata = tmp; 03854 f = &ast_null_frame; 03855 chan->fdno = -1; 03856 goto done; 03857 } 03858 03859 /* Read and ignore anything on the alertpipe, but read only 03860 one sizeof(blah) per frame that we send from it */ 03861 if (chan->alertpipe[0] > -1) { 03862 int flags = fcntl(chan->alertpipe[0], F_GETFL); 03863 /* For some odd reason, the alertpipe occasionally loses nonblocking status, 03864 * which immediately causes a deadlock scenario. Detect and prevent this. */ 03865 if ((flags & O_NONBLOCK) == 0) { 03866 ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", chan->name); 03867 if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) { 03868 ast_log(LOG_WARNING, "Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno)); 03869 f = &ast_null_frame; 03870 goto done; 03871 } 03872 } 03873 if (read(chan->alertpipe[0], &blah, sizeof(blah)) < 0) { 03874 if (errno != EINTR && errno != EAGAIN) 03875 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 03876 } 03877 } 03878 03879 03880 /* Check for pending read queue */ 03881 if (!AST_LIST_EMPTY(&chan->readq)) { 03882 int skip_dtmf = should_skip_dtmf(chan); 03883 03884 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, f, frame_list) { 03885 /* We have to be picky about which frame we pull off of the readq because 03886 * there are cases where we want to leave DTMF frames on the queue until 03887 * some later time. */ 03888 03889 if ( (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && skip_dtmf) { 03890 continue; 03891 } 03892 03893 AST_LIST_REMOVE_CURRENT(frame_list); 03894 break; 03895 } 03896 AST_LIST_TRAVERSE_SAFE_END; 03897 03898 if (!f) { 03899 /* There were no acceptable frames on the readq. */ 03900 f = &ast_null_frame; 03901 if (chan->alertpipe[0] > -1) { 03902 int poke = 0; 03903 /* Restore the state of the alertpipe since we aren't ready for any 03904 * of the frames in the readq. */ 03905 if (write(chan->alertpipe[1], &poke, sizeof(poke)) != sizeof(poke)) { 03906 ast_log(LOG_ERROR, "Failed to write to alertpipe: %s\n", strerror(errno)); 03907 } 03908 } 03909 } 03910 03911 /* Interpret hangup and end-of-Q frames to return NULL */ 03912 /* XXX why not the same for frames from the channel ? */ 03913 if (f->frametype == AST_FRAME_CONTROL) { 03914 switch (f->subclass.integer) { 03915 case AST_CONTROL_HANGUP: 03916 chan->_softhangup |= AST_SOFTHANGUP_DEV; 03917 cause = f->data.uint32; 03918 /* Fall through */ 03919 case AST_CONTROL_END_OF_Q: 03920 ast_frfree(f); 03921 f = NULL; 03922 break; 03923 default: 03924 break; 03925 } 03926 } 03927 } else { 03928 chan->blocker = pthread_self(); 03929 if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) { 03930 if (chan->tech->exception) 03931 f = chan->tech->exception(chan); 03932 else { 03933 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name); 03934 f = &ast_null_frame; 03935 } 03936 /* Clear the exception flag */ 03937 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 03938 } else if (chan->tech && chan->tech->read) 03939 f = chan->tech->read(chan); 03940 else 03941 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name); 03942 } 03943 03944 /* 03945 * Reset the recorded file descriptor that triggered this read so that we can 03946 * easily detect when ast_read() is called without properly using ast_waitfor(). 03947 */ 03948 chan->fdno = -1; 03949 03950 /* Perform the framehook read event here. After the frame enters the framehook list 03951 * there is no telling what will happen, <insert mad scientist laugh here>!!! */ 03952 f = ast_framehook_list_read_event(chan->framehooks, f); 03953 03954 if (f) { 03955 struct ast_frame *readq_tail = AST_LIST_LAST(&chan->readq); 03956 struct ast_control_read_action_payload *read_action_payload; 03957 struct ast_party_connected_line connected; 03958 03959 /* if the channel driver returned more than one frame, stuff the excess 03960 into the readq for the next ast_read call 03961 */ 03962 if (AST_LIST_NEXT(f, frame_list)) { 03963 ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list)); 03964 ast_frfree(AST_LIST_NEXT(f, frame_list)); 03965 AST_LIST_NEXT(f, frame_list) = NULL; 03966 } 03967 03968 switch (f->frametype) { 03969 case AST_FRAME_CONTROL: 03970 if (f->subclass.integer == AST_CONTROL_ANSWER) { 03971 if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) { 03972 ast_debug(1, "Ignoring answer on an inbound call!\n"); 03973 ast_frfree(f); 03974 f = &ast_null_frame; 03975 } else if (prestate == AST_STATE_UP && ast_bridged_channel(chan)) { 03976 ast_debug(1, "Dropping duplicate answer!\n"); 03977 ast_frfree(f); 03978 f = &ast_null_frame; 03979 } else { 03980 /* Answer the CDR */ 03981 ast_setstate(chan, AST_STATE_UP); 03982 /* removed a call to ast_cdr_answer(chan->cdr) from here. */ 03983 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 03984 } 03985 } else if (f->subclass.integer == AST_CONTROL_READ_ACTION) { 03986 read_action_payload = f->data.ptr; 03987 switch (read_action_payload->action) { 03988 case AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO: 03989 ast_party_connected_line_init(&connected); 03990 ast_party_connected_line_copy(&connected, &chan->connected); 03991 if (ast_connected_line_parse_data(read_action_payload->payload, 03992 read_action_payload->payload_size, &connected)) { 03993 ast_party_connected_line_free(&connected); 03994 break; 03995 } 03996 ast_channel_unlock(chan); 03997 if (ast_channel_connected_line_macro(NULL, chan, &connected, 1, 0)) { 03998 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, 03999 read_action_payload->payload, 04000 read_action_payload->payload_size); 04001 } 04002 ast_party_connected_line_free(&connected); 04003 ast_channel_lock(chan); 04004 break; 04005 } 04006 ast_frfree(f); 04007 f = &ast_null_frame; 04008 } 04009 break; 04010 case AST_FRAME_DTMF_END: 04011 send_dtmf_event(chan, "Received", f->subclass.integer, "No", "Yes"); 04012 ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass.integer, chan->name, f->len); 04013 /* Queue it up if DTMF is deferred, or if DTMF emulation is forced. */ 04014 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) || ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) { 04015 queue_dtmf_readq(chan, f); 04016 ast_frfree(f); 04017 f = &ast_null_frame; 04018 } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) { 04019 if (!ast_tvzero(chan->dtmf_tv) && 04020 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) { 04021 /* If it hasn't been long enough, defer this digit */ 04022 queue_dtmf_readq(chan, f); 04023 ast_frfree(f); 04024 f = &ast_null_frame; 04025 } else { 04026 /* There was no begin, turn this into a begin and send the end later */ 04027 f->frametype = AST_FRAME_DTMF_BEGIN; 04028 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF); 04029 chan->emulate_dtmf_digit = f->subclass.integer; 04030 chan->dtmf_tv = ast_tvnow(); 04031 if (f->len) { 04032 if (f->len > AST_MIN_DTMF_DURATION) 04033 chan->emulate_dtmf_duration = f->len; 04034 else 04035 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION; 04036 } else 04037 chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION; 04038 ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass.integer, chan->emulate_dtmf_duration, chan->name); 04039 } 04040 if (chan->audiohooks) { 04041 struct ast_frame *old_frame = f; 04042 /*! 04043 * \todo XXX It is possible to write a digit to the audiohook twice 04044 * if the digit was originally read while the channel was in autoservice. */ 04045 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 04046 if (old_frame != f) 04047 ast_frfree(old_frame); 04048 } 04049 } else { 04050 struct timeval now = ast_tvnow(); 04051 if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) { 04052 ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass.integer, chan->name); 04053 ast_clear_flag(chan, AST_FLAG_IN_DTMF); 04054 if (!f->len) 04055 f->len = ast_tvdiff_ms(now, chan->dtmf_tv); 04056 04057 /* detect tones that were received on 04058 * the wire with durations shorter than 04059 * AST_MIN_DTMF_DURATION and set f->len 04060 * to the actual duration of the DTMF 04061 * frames on the wire. This will cause 04062 * dtmf emulation to be triggered later 04063 * on. 04064 */ 04065 if (ast_tvdiff_ms(now, chan->dtmf_tv) < AST_MIN_DTMF_DURATION) { 04066 f->len = ast_tvdiff_ms(now, chan->dtmf_tv); 04067 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, chan->name); 04068 } 04069 } else if (!f->len) { 04070 ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass.integer, chan->name); 04071 f->len = AST_MIN_DTMF_DURATION; 04072 } 04073 if (f->len < AST_MIN_DTMF_DURATION && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) { 04074 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, chan->name); 04075 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF); 04076 chan->emulate_dtmf_digit = f->subclass.integer; 04077 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len; 04078 ast_frfree(f); 04079 f = &ast_null_frame; 04080 } else { 04081 ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass.integer, chan->name); 04082 if (f->len < AST_MIN_DTMF_DURATION) { 04083 f->len = AST_MIN_DTMF_DURATION; 04084 } 04085 chan->dtmf_tv = now; 04086 } 04087 if (chan->audiohooks) { 04088 struct ast_frame *old_frame = f; 04089 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 04090 if (old_frame != f) 04091 ast_frfree(old_frame); 04092 } 04093 } 04094 break; 04095 case AST_FRAME_DTMF_BEGIN: 04096 send_dtmf_event(chan, "Received", f->subclass.integer, "Yes", "No"); 04097 ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass.integer, chan->name); 04098 if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) || 04099 (!ast_tvzero(chan->dtmf_tv) && 04100 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) { 04101 ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass.integer, chan->name); 04102 ast_frfree(f); 04103 f = &ast_null_frame; 04104 } else { 04105 ast_set_flag(chan, AST_FLAG_IN_DTMF); 04106 chan->dtmf_tv = ast_tvnow(); 04107 ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass.integer, chan->name); 04108 } 04109 break; 04110 case AST_FRAME_NULL: 04111 /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration 04112 * is reached , because we want to make sure we pass at least one 04113 * voice frame through before starting the next digit, to ensure a gap 04114 * between DTMF digits. */ 04115 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) { 04116 struct timeval now = ast_tvnow(); 04117 if (!chan->emulate_dtmf_duration) { 04118 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF); 04119 chan->emulate_dtmf_digit = 0; 04120 } else if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) { 04121 chan->emulate_dtmf_duration = 0; 04122 ast_frfree(f); 04123 f = &chan->dtmff; 04124 f->frametype = AST_FRAME_DTMF_END; 04125 f->subclass.integer = chan->emulate_dtmf_digit; 04126 f->len = ast_tvdiff_ms(now, chan->dtmf_tv); 04127 chan->dtmf_tv = now; 04128 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF); 04129 chan->emulate_dtmf_digit = 0; 04130 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, chan->name); 04131 if (chan->audiohooks) { 04132 struct ast_frame *old_frame = f; 04133 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 04134 if (old_frame != f) { 04135 ast_frfree(old_frame); 04136 } 04137 } 04138 } 04139 } 04140 break; 04141 case AST_FRAME_VOICE: 04142 /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration 04143 * is reached , because we want to make sure we pass at least one 04144 * voice frame through before starting the next digit, to ensure a gap 04145 * between DTMF digits. */ 04146 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) { 04147 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF); 04148 chan->emulate_dtmf_digit = 0; 04149 } 04150 04151 if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) { 04152 if (dropaudio) 04153 ast_read_generator_actions(chan, f); 04154 ast_frfree(f); 04155 f = &ast_null_frame; 04156 } 04157 04158 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_IN_DTMF)) { 04159 struct timeval now = ast_tvnow(); 04160 if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) { 04161 chan->emulate_dtmf_duration = 0; 04162 ast_frfree(f); 04163 f = &chan->dtmff; 04164 f->frametype = AST_FRAME_DTMF_END; 04165 f->subclass.integer = chan->emulate_dtmf_digit; 04166 f->len = ast_tvdiff_ms(now, chan->dtmf_tv); 04167 chan->dtmf_tv = now; 04168 if (chan->audiohooks) { 04169 struct ast_frame *old_frame = f; 04170 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 04171 if (old_frame != f) 04172 ast_frfree(old_frame); 04173 } 04174 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, chan->name); 04175 } else { 04176 /* Drop voice frames while we're still in the middle of the digit */ 04177 ast_frfree(f); 04178 f = &ast_null_frame; 04179 } 04180 } else if ((f->frametype == AST_FRAME_VOICE) && !(f->subclass.codec & chan->nativeformats)) { 04181 /* This frame is not one of the current native formats -- drop it on the floor */ 04182 char to[200]; 04183 ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n", 04184 chan->name, ast_getformatname(f->subclass.codec), ast_getformatname_multiple(to, sizeof(to), chan->nativeformats)); 04185 ast_frfree(f); 04186 f = &ast_null_frame; 04187 } else if ((f->frametype == AST_FRAME_VOICE)) { 04188 /* Send frame to audiohooks if present */ 04189 if (chan->audiohooks) { 04190 struct ast_frame *old_frame = f; 04191 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 04192 if (old_frame != f) 04193 ast_frfree(old_frame); 04194 } 04195 if (chan->monitor && chan->monitor->read_stream ) { 04196 /* XXX what does this do ? */ 04197 #ifndef MONITOR_CONSTANT_DELAY 04198 int jump = chan->outsmpl - chan->insmpl - 4 * f->samples; 04199 if (jump >= 0) { 04200 jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 04201 if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1) 04202 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 04203 chan->insmpl += (chan->outsmpl - chan->insmpl) + f->samples; 04204 } else 04205 chan->insmpl+= f->samples; 04206 #else 04207 int jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 04208 if (jump - MONITOR_DELAY >= 0) { 04209 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1) 04210 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 04211 chan->insmpl += chan->outsmpl - chan->insmpl; 04212 } else 04213 chan->insmpl += f->samples; 04214 #endif 04215 if (chan->monitor->state == AST_MONITOR_RUNNING) { 04216 if (ast_writestream(chan->monitor->read_stream, f) < 0) 04217 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n"); 04218 } 04219 } 04220 04221 if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL) { 04222 f = &ast_null_frame; 04223 } 04224 04225 /* it is possible for the translation process on chan->readtrans to have 04226 produced multiple frames from the single input frame we passed it; if 04227 this happens, queue the additional frames *before* the frames we may 04228 have queued earlier. if the readq was empty, put them at the head of 04229 the queue, and if it was not, put them just after the frame that was 04230 at the end of the queue. 04231 */ 04232 if (AST_LIST_NEXT(f, frame_list)) { 04233 if (!readq_tail) { 04234 ast_queue_frame_head(chan, AST_LIST_NEXT(f, frame_list)); 04235 } else { 04236 __ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list), 0, readq_tail); 04237 } 04238 ast_frfree(AST_LIST_NEXT(f, frame_list)); 04239 AST_LIST_NEXT(f, frame_list) = NULL; 04240 } 04241 04242 /* Run generator sitting on the line if timing device not available 04243 * and synchronous generation of outgoing frames is necessary */ 04244 ast_read_generator_actions(chan, f); 04245 } 04246 break; 04247 default: 04248 /* Just pass it on! */ 04249 break; 04250 } 04251 } else { 04252 /* Make sure we always return NULL in the future */ 04253 if (!chan->_softhangup) { 04254 chan->_softhangup |= AST_SOFTHANGUP_DEV; 04255 } 04256 if (cause) 04257 chan->hangupcause = cause; 04258 if (chan->generator) 04259 ast_deactivate_generator(chan); 04260 /* We no longer End the CDR here */ 04261 } 04262 04263 /* High bit prints debugging */ 04264 if (chan->fin & DEBUGCHAN_FLAG) 04265 ast_frame_dump(chan->name, f, "<<"); 04266 chan->fin = FRAMECOUNT_INC(chan->fin); 04267 04268 done: 04269 if (chan->music_state && chan->generator && chan->generator->digit && f && f->frametype == AST_FRAME_DTMF_END) 04270 chan->generator->digit(chan, f->subclass.integer); 04271 04272 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) { 04273 /* The list gets recreated if audiohooks are added again later */ 04274 ast_audiohook_detach_list(chan->audiohooks); 04275 chan->audiohooks = NULL; 04276 } 04277 ast_channel_unlock(chan); 04278 return f; 04279 }
struct ast_channel* __ast_request_and_dial | ( | const char * | type, | |
format_t | format, | |||
const struct ast_channel * | requestor, | |||
void * | data, | |||
int | timeout, | |||
int * | reason, | |||
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.
type | type of channel to request | |
format | requested channel format | |
requestor | channel requesting data | |
data | data to pass to the channel requester | |
timeout | maximum amount of time to wait for an answer | |
reason | why unsuccessful (if unsuccessful) | |
cid_num | Caller-ID Number | |
cid_name | Caller-ID Name (ascii) | |
oh | Outgoing helper |
Definition at line 5341 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_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_callerid(), ast_set_flag, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_waitfor(), ast_channel::call_forward, cause, ast_channel::cdr, chanlist::chan, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_channel::connected, chanlist::connected, ast_channel::context, outgoing_helper::context, ast_channel::exten, outgoing_helper::exten, f, handle_cause(), ast_channel::hangupcause, ast_party_connected_line::id, 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_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().
05342 { 05343 int dummy_outstate; 05344 int cause = 0; 05345 struct ast_channel *chan; 05346 int res = 0; 05347 int last_subclass = 0; 05348 struct ast_party_connected_line connected; 05349 05350 if (outstate) 05351 *outstate = 0; 05352 else 05353 outstate = &dummy_outstate; /* make outstate always a valid pointer */ 05354 05355 chan = ast_request(type, format, requestor, data, &cause); 05356 if (!chan) { 05357 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 05358 handle_cause(cause, outstate); 05359 return NULL; 05360 } 05361 05362 if (oh) { 05363 if (oh->vars) { 05364 ast_set_variables(chan, oh->vars); 05365 } 05366 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) { 05367 /* 05368 * Use the oh values instead of the function parameters for the 05369 * outgoing CallerID. 05370 */ 05371 cid_num = oh->cid_num; 05372 cid_name = oh->cid_name; 05373 } 05374 if (oh->parent_channel) { 05375 /* Safely inherit variables and datastores from the parent channel. */ 05376 ast_channel_lock_both(oh->parent_channel, chan); 05377 ast_channel_inherit_variables(oh->parent_channel, chan); 05378 ast_channel_datastore_inherit(oh->parent_channel, chan); 05379 ast_channel_unlock(oh->parent_channel); 05380 ast_channel_unlock(chan); 05381 } 05382 if (oh->account) { 05383 ast_channel_lock(chan); 05384 ast_cdr_setaccount(chan, oh->account); 05385 ast_channel_unlock(chan); 05386 } 05387 } 05388 05389 /* 05390 * I seems strange to set the CallerID on an outgoing call leg 05391 * to whom we are calling, but this function's callers are doing 05392 * various Originate methods. This call leg goes to the local 05393 * user. Once the local user answers, the dialplan needs to be 05394 * able to access the CallerID from the CALLERID function as if 05395 * the local user had placed this call. 05396 */ 05397 ast_set_callerid(chan, cid_num, cid_name, cid_num); 05398 05399 ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED); 05400 ast_party_connected_line_set_init(&connected, &chan->connected); 05401 if (cid_num) { 05402 connected.id.number.valid = 1; 05403 connected.id.number.str = (char *) cid_num; 05404 connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 05405 } 05406 if (cid_name) { 05407 connected.id.name.valid = 1; 05408 connected.id.name.str = (char *) cid_name; 05409 connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 05410 } 05411 ast_channel_set_connected_line(chan, &connected, NULL); 05412 05413 if (ast_call(chan, data, 0)) { /* ast_call failed... */ 05414 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data); 05415 } else { 05416 res = 1; /* mark success in case chan->_state is already AST_STATE_UP */ 05417 while (timeout && chan->_state != AST_STATE_UP) { 05418 struct ast_frame *f; 05419 res = ast_waitfor(chan, timeout); 05420 if (res == 0) { /* timeout, treat it like ringing */ 05421 *outstate = AST_CONTROL_RINGING; 05422 break; 05423 } 05424 if (res < 0) /* error or done */ 05425 break; 05426 if (timeout > -1) 05427 timeout = res; 05428 if (!ast_strlen_zero(chan->call_forward)) { 05429 if (!(chan = ast_call_forward(NULL, chan, NULL, format, oh, outstate))) { 05430 return NULL; 05431 } 05432 continue; 05433 } 05434 05435 f = ast_read(chan); 05436 if (!f) { 05437 *outstate = AST_CONTROL_HANGUP; 05438 res = 0; 05439 break; 05440 } 05441 if (f->frametype == AST_FRAME_CONTROL) { 05442 switch (f->subclass.integer) { 05443 case AST_CONTROL_RINGING: /* record but keep going */ 05444 *outstate = f->subclass.integer; 05445 break; 05446 05447 case AST_CONTROL_BUSY: 05448 ast_cdr_busy(chan->cdr); 05449 *outstate = f->subclass.integer; 05450 timeout = 0; 05451 break; 05452 05453 case AST_CONTROL_INCOMPLETE: 05454 ast_cdr_failed(chan->cdr); 05455 *outstate = AST_CONTROL_CONGESTION; 05456 timeout = 0; 05457 break; 05458 05459 case AST_CONTROL_CONGESTION: 05460 ast_cdr_failed(chan->cdr); 05461 *outstate = f->subclass.integer; 05462 timeout = 0; 05463 break; 05464 05465 case AST_CONTROL_ANSWER: 05466 ast_cdr_answer(chan->cdr); 05467 *outstate = f->subclass.integer; 05468 timeout = 0; /* trick to force exit from the while() */ 05469 break; 05470 05471 /* Ignore these */ 05472 case AST_CONTROL_PROGRESS: 05473 case AST_CONTROL_PROCEEDING: 05474 case AST_CONTROL_HOLD: 05475 case AST_CONTROL_UNHOLD: 05476 case AST_CONTROL_VIDUPDATE: 05477 case AST_CONTROL_SRCUPDATE: 05478 case AST_CONTROL_SRCCHANGE: 05479 case AST_CONTROL_CONNECTED_LINE: 05480 case AST_CONTROL_REDIRECTING: 05481 case AST_CONTROL_CC: 05482 case -1: /* Ignore -- just stopping indications */ 05483 break; 05484 05485 default: 05486 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass.integer); 05487 } 05488 last_subclass = f->subclass.integer; 05489 } 05490 ast_frfree(f); 05491 } 05492 } 05493 05494 /* Final fixups */ 05495 if (oh) { 05496 if (!ast_strlen_zero(oh->context)) 05497 ast_copy_string(chan->context, oh->context, sizeof(chan->context)); 05498 if (!ast_strlen_zero(oh->exten)) 05499 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten)); 05500 if (oh->priority) 05501 chan->priority = oh->priority; 05502 } 05503 if (chan->_state == AST_STATE_UP) 05504 *outstate = AST_CONTROL_ANSWER; 05505 05506 if (res <= 0) { 05507 ast_channel_lock(chan); 05508 if (AST_CONTROL_RINGING == last_subclass) { 05509 chan->hangupcause = AST_CAUSE_NO_ANSWER; 05510 } 05511 if (!chan->cdr && (chan->cdr = ast_cdr_alloc())) { 05512 ast_cdr_init(chan->cdr, chan); 05513 } 05514 if (chan->cdr) { 05515 char tmp[256]; 05516 05517 snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data); 05518 ast_cdr_setapp(chan->cdr, "Dial", tmp); 05519 ast_cdr_update(chan); 05520 ast_cdr_start(chan->cdr); 05521 ast_cdr_end(chan->cdr); 05522 /* If the cause wasn't handled properly */ 05523 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) { 05524 ast_cdr_failed(chan->cdr); 05525 } 05526 } 05527 ast_channel_unlock(chan); 05528 ast_hangup(chan); 05529 chan = NULL; 05530 } 05531 return chan; 05532 }
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 4722 of file channel.c.
References ast_calloc, ast_channel_datastore_remove(), ast_datastore_free(), ast_free, AST_FRIENDLY_OFFSET, chanlist::chan, 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().
04723 { 04724 int num_new_samples = frame->samples; 04725 struct plc_ds *plc = datastore->data; 04726 04727 /* As a general note, let me explain the somewhat odd calculations used when taking 04728 * the frame offset into account here. According to documentation in frame.h, the frame's 04729 * offset field indicates the number of bytes that the audio is offset. The plc->samples_buf 04730 * is not an array of bytes, but rather an array of 16-bit integers since it holds SLIN 04731 * samples. So I had two choices to make here with the offset. 04732 * 04733 * 1. Make the offset AST_FRIENDLY_OFFSET bytes. The main downside for this is that 04734 * I can't just add AST_FRIENDLY_OFFSET to the plc->samples_buf and have the pointer 04735 * arithmetic come out right. I would have to do some odd casting or division for this to 04736 * work as I wanted. 04737 * 2. Make the offset AST_FRIENDLY_OFFSET * 2 bytes. This allows the pointer arithmetic 04738 * to work out better with the plc->samples_buf. The downside here is that the buffer's 04739 * allocation contains an extra 64 bytes of unused space. 04740 * 04741 * I decided to go with option 2. This is why in the calloc statement and the statement that 04742 * sets the frame's offset, AST_FRIENDLY_OFFSET is multiplied by 2. 04743 */ 04744 04745 /* If this audio frame has no samples to fill in, ignore it */ 04746 if (!num_new_samples) { 04747 return; 04748 } 04749 04750 /* First, we need to be sure that our buffer is large enough to accomodate 04751 * the samples we need to fill in. This will likely only occur on the first 04752 * frame we write. 04753 */ 04754 if (plc->num_samples < num_new_samples) { 04755 ast_free(plc->samples_buf); 04756 plc->samples_buf = ast_calloc(1, (num_new_samples * sizeof(*plc->samples_buf)) + (AST_FRIENDLY_OFFSET * 2)); 04757 if (!plc->samples_buf) { 04758 ast_channel_datastore_remove(chan, datastore); 04759 ast_datastore_free(datastore); 04760 return; 04761 } 04762 plc->num_samples = num_new_samples; 04763 } 04764 04765 if (frame->datalen == 0) { 04766 plc_fillin(&plc->plc_state, plc->samples_buf + AST_FRIENDLY_OFFSET, frame->samples); 04767 frame->data.ptr = plc->samples_buf + AST_FRIENDLY_OFFSET; 04768 frame->datalen = num_new_samples * 2; 04769 frame->offset = AST_FRIENDLY_OFFSET * 2; 04770 } else { 04771 plc_rx(&plc->plc_state, frame->data.ptr, frame->samples); 04772 } 04773 }
static void apply_plc | ( | struct ast_channel * | chan, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 4775 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(), chanlist::chan, ast_datastore::data, and plc_ds_info.
Referenced by ast_write().
04776 { 04777 struct ast_datastore *datastore; 04778 struct plc_ds *plc; 04779 04780 datastore = ast_channel_datastore_find(chan, &plc_ds_info, NULL); 04781 if (datastore) { 04782 plc = datastore->data; 04783 adjust_frame_for_plc(chan, frame, datastore); 04784 return; 04785 } 04786 04787 datastore = ast_datastore_alloc(&plc_ds_info, NULL); 04788 if (!datastore) { 04789 return; 04790 } 04791 plc = ast_calloc(1, sizeof(*plc)); 04792 if (!plc) { 04793 ast_datastore_free(datastore); 04794 return; 04795 } 04796 datastore->data = plc; 04797 ast_channel_datastore_add(chan, datastore); 04798 adjust_frame_for_plc(chan, frame, datastore); 04799 }
int ast_activate_generator | ( | struct ast_channel * | chan, | |
struct ast_generator * | gen, | |||
void * | params | |||
) |
Activate a given generator
Definition at line 3100 of file channel.c.
References ast_generator::alloc, ast_channel_lock, ast_channel_unlock, ast_prod(), ast_settimeout(), chanlist::chan, gen, ast_channel::generator, generator_force(), ast_channel::generatordata, and ast_generator::release.
Referenced by ast_channel_start_silence_generator(), ast_linear_stream(), ast_playtones_start(), ast_tonepair_start(), channel_spy(), eivr_comm(), old_milliwatt_exec(), and transmit_audio().
03101 { 03102 int res = 0; 03103 03104 ast_channel_lock(chan); 03105 if (chan->generatordata) { 03106 if (chan->generator && chan->generator->release) 03107 chan->generator->release(chan, chan->generatordata); 03108 chan->generatordata = NULL; 03109 } 03110 if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) { 03111 res = -1; 03112 } 03113 if (!res) { 03114 ast_settimeout(chan, 50, generator_force, chan); 03115 chan->generator = gen; 03116 } 03117 ast_channel_unlock(chan); 03118 03119 ast_prod(chan); 03120 03121 return res; 03122 }
int ast_active_channels | ( | void | ) |
returns number of active/allocated channels
Definition at line 837 of file channel.c.
References ao2_container_count(), and channels.
Referenced by action_corestatus(), ast_var_channels(), ast_var_channels_table(), handle_chanlist(), handle_show_settings(), and really_quit().
00838 { 00839 return channels ? ao2_container_count(channels) : 0; 00840 }
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 3050 of file channel.c.
References __ast_answer(), and chanlist::chan.
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(), builtin_parkcall(), common_exec(), conf_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(), 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().
03051 { 03052 return __ast_answer(chan, 0, 1); 03053 }
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 827 of file channel.c.
References ao2_callback, ast_channel_softhangup_cb(), channels, OBJ_MULTIPLE, and OBJ_NODATA.
Referenced by can_safely_quit().
00828 { 00829 shutting_down = 1; 00830 00831 if (hangup) { 00832 ao2_callback(channels, OBJ_NODATA | OBJ_MULTIPLE, ast_channel_softhangup_cb, NULL); 00833 } 00834 }
Pick the best audio codec.
Pick the best codec Choose the best codec... Uhhh... Yah.
Okay, ulaw is used by all telephony equipment, so start with it
Unless of course, you're a silly European, so then prefer ALAW
G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority
Okay, well, signed linear is easy to translate into other stuff
G.726 is standard ADPCM, in RFC3551 packing order
G.726 is standard ADPCM, in AAL2 packing order
ADPCM has great sound quality and is still pretty easy to translate
Okay, we're down to vocoders now, so pick GSM because it's small and easier to translate and sounds pretty good
iLBC is not too bad
Speex is free, but computationally more expensive than GSM
Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough to use it
G.729a is faster than 723 and slightly less expensive
Down to G.723.1 which is proprietary but at least designed for voice
Definition at line 1051 of file channel.c.
References ARRAY_LEN, AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_AUDIO_MASK, 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_SIREN14, AST_FORMAT_SIREN7, AST_FORMAT_SLINEAR, AST_FORMAT_SLINEAR16, AST_FORMAT_SPEEX, AST_FORMAT_SPEEX16, AST_FORMAT_TESTLAW, AST_FORMAT_ULAW, ast_getformatname_multiple(), ast_log(), LOG_WARNING, and prefs.
Referenced by __oh323_new(), agent_call(), ast_codec_choose(), ast_iax2_new(), ast_speech_new(), bridge_make_compatible(), builtin_atxfer(), echo_exec(), findmeexec(), gtalk_new(), handle_open_receive_channel_ack_message(), iax2_request(), jingle_new(), local_new(), login_exec(), mgcp_new(), multicast_rtp_request(), set_format(), sip_new(), skinny_new(), skinny_set_rtp_peer(), socket_process(), start_rtp(), transmit_connect(), and unistim_new().
01052 { 01053 /* This just our opinion, expressed in code. We are asked to choose 01054 the best codec to use, given no information */ 01055 int x; 01056 static const format_t prefs[] = 01057 { 01058 /*! Okay, ulaw is used by all telephony equipment, so start with it */ 01059 AST_FORMAT_ULAW, 01060 /*! Unless of course, you're a silly European, so then prefer ALAW */ 01061 AST_FORMAT_ALAW, 01062 AST_FORMAT_G719, 01063 AST_FORMAT_SIREN14, 01064 AST_FORMAT_SIREN7, 01065 AST_FORMAT_TESTLAW, 01066 /*! G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority */ 01067 AST_FORMAT_G722, 01068 /*! Okay, well, signed linear is easy to translate into other stuff */ 01069 AST_FORMAT_SLINEAR16, 01070 AST_FORMAT_SLINEAR, 01071 /*! G.726 is standard ADPCM, in RFC3551 packing order */ 01072 AST_FORMAT_G726, 01073 /*! G.726 is standard ADPCM, in AAL2 packing order */ 01074 AST_FORMAT_G726_AAL2, 01075 /*! ADPCM has great sound quality and is still pretty easy to translate */ 01076 AST_FORMAT_ADPCM, 01077 /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to 01078 translate and sounds pretty good */ 01079 AST_FORMAT_GSM, 01080 /*! iLBC is not too bad */ 01081 AST_FORMAT_ILBC, 01082 /*! Speex is free, but computationally more expensive than GSM */ 01083 AST_FORMAT_SPEEX16, 01084 AST_FORMAT_SPEEX, 01085 /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough 01086 to use it */ 01087 AST_FORMAT_LPC10, 01088 /*! G.729a is faster than 723 and slightly less expensive */ 01089 AST_FORMAT_G729A, 01090 /*! Down to G.723.1 which is proprietary but at least designed for voice */ 01091 AST_FORMAT_G723_1, 01092 }; 01093 char buf[512]; 01094 01095 /* Strip out video */ 01096 fmts &= AST_FORMAT_AUDIO_MASK; 01097 01098 /* Find the first preferred codec in the format given */ 01099 for (x = 0; x < ARRAY_LEN(prefs); x++) { 01100 if (fmts & prefs[x]) 01101 return prefs[x]; 01102 } 01103 01104 ast_log(LOG_WARNING, "Don't know any of %s formats\n", ast_getformatname_multiple(buf, sizeof(buf), fmts)); 01105 01106 return 0; 01107 }
struct ast_channel* ast_bridged_channel | ( | struct ast_channel * | chan | ) |
Find bridged channel.
chan | Current channel |
Definition at line 6994 of file channel.c.
References ast_channel::_bridge, ast_channel_tech::bridged_channel, chanlist::chan, 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(), 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(), sig_pri_attempt_transfer(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), sip_hangup(), sip_set_rtp_peer(), skinny_transfer(), socket_process(), start_spying(), startmon(), TransferCallStep1(), and unistim_hangup().
06995 { 06996 struct ast_channel *bridged; 06997 bridged = chan->_bridge; 06998 if (bridged && bridged->tech->bridged_channel) 06999 bridged = bridged->tech->bridged_channel(chan, bridged); 07000 return bridged; 07001 }
int ast_call | ( | struct ast_channel * | chan, | |
char * | addr, | |||
int | timeout | |||
) |
Make a call.
chan | which channel to make the call on | |
addr | destination of the call (Should be treated as const char *) | |
timeout | time to wait on for connect |
Definition at line 5645 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, chanlist::chan, and ast_channel::tech.
Referenced by __ast_request_and_dial(), ast_call_forward(), begin_dial_channel(), dial_exec_full(), dial_transfer(), do_forward(), do_idle_thread(), feature_request_and_dial(), findmeexec(), play_sound_file(), and ring_entry().
05646 { 05647 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 05648 If the remote end does not answer within the timeout, then do NOT hang up, but 05649 return anyway. */ 05650 int res = -1; 05651 /* Stop if we're a zombie or need a soft hangup */ 05652 ast_channel_lock(chan); 05653 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 05654 if (chan->cdr) { 05655 ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED); 05656 } 05657 if (chan->tech->call) 05658 res = chan->tech->call(chan, addr, timeout); 05659 ast_set_flag(chan, AST_FLAG_OUTGOING); 05660 } 05661 ast_channel_unlock(chan); 05662 return res; 05663 }
struct ast_channel* ast_call_forward | ( | struct ast_channel * | caller, | |
struct ast_channel * | orig, | |||
int * | timeout, | |||
format_t | format, | |||
struct outgoing_helper * | oh, | |||
int * | outstate | |||
) |
Forwards a call to a new channel specified by the original channel's call_forward str. If possible, the new forwarded channel is created and returned while the original one is terminated.
caller | in channel that requested orig | |
orig | channel being replaced by the call forward channel | |
timeout | maximum amount of time to wait for setup of new forward channel | |
format | requested channel format | |
oh | outgoing helper used with original channel | |
outstate | reason why unsuccessful (if uncuccessful) |
Definition at line 5271 of file channel.c.
References outgoing_helper::account, ast_channel::accountcode, accountcode, ast_call(), AST_CDR_FLAG_ORIGINATED, ast_cdr_setaccount(), 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(), ast_string_field_set, ast_channel::call_forward, call_forward_inherit(), ast_channel::caller, 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().
05272 { 05273 char tmpchan[256]; 05274 struct ast_channel *new_chan = NULL; 05275 char *data, *type; 05276 int cause = 0; 05277 int res; 05278 05279 /* gather data and request the new forward channel */ 05280 ast_copy_string(tmpchan, orig->call_forward, sizeof(tmpchan)); 05281 if ((data = strchr(tmpchan, '/'))) { 05282 *data++ = '\0'; 05283 type = tmpchan; 05284 } else { 05285 const char *forward_context; 05286 ast_channel_lock(orig); 05287 forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT"); 05288 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", orig->call_forward, S_OR(forward_context, orig->context)); 05289 ast_channel_unlock(orig); 05290 data = tmpchan; 05291 type = "Local"; 05292 } 05293 if (!(new_chan = ast_request(type, format, orig, data, &cause))) { 05294 ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause); 05295 handle_cause(cause, outstate); 05296 ast_hangup(orig); 05297 return NULL; 05298 } 05299 05300 /* Copy/inherit important information into new channel */ 05301 if (oh) { 05302 if (oh->vars) { 05303 ast_set_variables(new_chan, oh->vars); 05304 } 05305 if (oh->parent_channel) { 05306 call_forward_inherit(new_chan, oh->parent_channel, orig); 05307 } 05308 if (oh->account) { 05309 ast_channel_lock(new_chan); 05310 ast_cdr_setaccount(new_chan, oh->account); 05311 ast_channel_unlock(new_chan); 05312 } 05313 } else if (caller) { /* no outgoing helper so use caller if avaliable */ 05314 call_forward_inherit(new_chan, caller, orig); 05315 } 05316 05317 ast_channel_lock_both(orig, new_chan); 05318 ast_copy_flags(new_chan->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED); 05319 ast_string_field_set(new_chan, accountcode, orig->accountcode); 05320 ast_party_connected_line_copy(&new_chan->connected, &orig->connected); 05321 ast_party_redirecting_copy(&new_chan->redirecting, &orig->redirecting); 05322 ast_channel_unlock(new_chan); 05323 ast_channel_unlock(orig); 05324 05325 /* call new channel */ 05326 res = ast_call(new_chan, data, 0); 05327 if (timeout) { 05328 *timeout = res; 05329 } 05330 if (res) { 05331 ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data); 05332 ast_hangup(orig); 05333 ast_hangup(new_chan); 05334 return NULL; 05335 } 05336 ast_hangup(orig); 05337 05338 return new_chan; 05339 }
void ast_cancel_shutdown | ( | void | ) |
Cancel a shutdown in progress.
Cancels an existing shutdown and returns to normal operation
Definition at line 848 of file channel.c.
Referenced by handle_abort_shutdown().
00849 { 00850 shutting_down = 0; 00851 }
const char* ast_cause2str | ( | int | state | ) |
Gives the string form of a given cause code.
state | cause to get the description of |
Definition at line 969 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().
00970 { 00971 int x; 00972 00973 for (x = 0; x < ARRAY_LEN(causes); x++) { 00974 if (causes[x].cause == cause) 00975 return causes[x].desc; 00976 } 00977 00978 return "Unknown"; 00979 }
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 6113 of file channel.c.
References __ast_change_name_nolink(), ao2_link, ao2_lock, ao2_unlink, ao2_unlock, ast_channel_lock, ast_channel_unlock, chanlist::chan, and channels.
Referenced by update_name().
06114 { 06115 /* We must re-link, as the hash value will change here. */ 06116 ao2_lock(channels); 06117 ast_channel_lock(chan); 06118 ao2_unlink(channels, chan); 06119 __ast_change_name_nolink(chan, newname); 06120 ao2_link(channels, chan); 06121 ast_channel_unlock(chan); 06122 ao2_unlock(channels); 06123 }
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, | |||
... | ||||
) |
Definition at line 9603 of file channel.c.
References __ast_channel_alloc_ap().
09608 { 09609 va_list ap1, ap2; 09610 struct ast_channel *result; 09611 09612 09613 va_start(ap1, name_fmt); 09614 va_start(ap2, name_fmt); 09615 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context, 09616 linkedid, amaflag, __FILE__, __LINE__, __FUNCTION__, name_fmt, ap1, ap2); 09617 va_end(ap1); 09618 va_end(ap2); 09619 09620 return result; 09621 }
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 7337 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_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_framehook_list_is_empty(), ast_generic_bridge(), ast_indicate(), ast_log(), ast_manager_event_multichan, ast_samp2tv(), ast_set_flag, ast_set_owners_and_peers(), AST_SOFTHANGUP_UNBRIDGE, ast_test_flag, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), ast_verb, ast_channel::audiohooks, ast_channel_tech::bridge, bridge_play_sounds(), bridge_playfile(), ast_channel::caller, config, EVENT_FLAG_CALL, ast_channel::framehooks, ast_channel::generator, ast_party_caller::id, LOG_WARNING, manager_bridge_event(), ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, ast_party_id::number, ast_channel::readformat, S_COR, ast_channel_tech::send_digit_begin, ast_party_number::str, ast_channel::tech, ast_channel::uniqueid, update_bridge_vars(), ast_party_number::valid, and ast_channel::writeformat.
Referenced by ast_bridge_call().
07339 { 07340 struct ast_channel *chans[2] = { c0, c1 }; 07341 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 07342 format_t o0nativeformats; 07343 format_t o1nativeformats; 07344 long time_left_ms=0; 07345 char caller_warning = 0; 07346 char callee_warning = 0; 07347 07348 *fo = NULL; 07349 07350 if (c0->_bridge) { 07351 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 07352 c0->name, c0->_bridge->name); 07353 return -1; 07354 } 07355 if (c1->_bridge) { 07356 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 07357 c1->name, c1->_bridge->name); 07358 return -1; 07359 } 07360 07361 /* Stop if we're a zombie or need a soft hangup */ 07362 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 07363 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 07364 return -1; 07365 07366 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING); 07367 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING); 07368 07369 if (ast_tvzero(config->start_time)) { 07370 config->start_time = ast_tvnow(); 07371 if (config->start_sound) { 07372 if (caller_warning) { 07373 bridge_playfile(c0, c1, config->start_sound, config->timelimit / 1000); 07374 } 07375 if (callee_warning) { 07376 bridge_playfile(c1, c0, config->start_sound, config->timelimit / 1000); 07377 } 07378 } 07379 } 07380 07381 /* Keep track of bridge */ 07382 c0->_bridge = c1; 07383 c1->_bridge = c0; 07384 07385 ast_set_owners_and_peers(c0, c1); 07386 07387 o0nativeformats = c0->nativeformats; 07388 o1nativeformats = c1->nativeformats; 07389 07390 if (config->feature_timer && !ast_tvzero(config->nexteventts)) { 07391 config->nexteventts = ast_tvadd(config->feature_start_time, ast_samp2tv(config->feature_timer, 1000)); 07392 } else if (config->timelimit) { 07393 time_left_ms = config->timelimit - ast_tvdiff_ms(ast_tvnow(), config->start_time); 07394 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 07395 if ((caller_warning || callee_warning) && config->play_warning) { 07396 long next_warn = config->play_warning; 07397 if (time_left_ms < config->play_warning && config->warning_freq > 0) { 07398 /* At least one warning was played, which means we are returning after feature */ 07399 long warns_passed = (config->play_warning - time_left_ms) / config->warning_freq; 07400 /* It is 'warns_passed * warning_freq' NOT '(warns_passed + 1) * warning_freq', 07401 because nexteventts will be updated once again in the 'if (!to)' block */ 07402 next_warn = config->play_warning - warns_passed * config->warning_freq; 07403 } 07404 config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(next_warn, 1000)); 07405 } 07406 } else { 07407 config->nexteventts.tv_sec = 0; 07408 config->nexteventts.tv_usec = 0; 07409 } 07410 07411 if (!c0->tech->send_digit_begin) 07412 ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY); 07413 if (!c1->tech->send_digit_begin) 07414 ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY); 07415 manager_bridge_event(1, 1, c0, c1); 07416 07417 /* Before we enter in and bridge these two together tell them both the source of audio has changed */ 07418 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 07419 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 07420 07421 for (/* ever */;;) { 07422 struct timeval now = { 0, }; 07423 int to; 07424 07425 to = -1; 07426 07427 if (!ast_tvzero(config->nexteventts)) { 07428 now = ast_tvnow(); 07429 to = ast_tvdiff_ms(config->nexteventts, now); 07430 if (to <= 0) { 07431 if (!config->timelimit) { 07432 res = AST_BRIDGE_COMPLETE; 07433 break; 07434 } 07435 to = 0; 07436 } 07437 } 07438 07439 if (config->timelimit) { 07440 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time); 07441 if (time_left_ms < to) 07442 to = time_left_ms; 07443 07444 if (time_left_ms <= 0) { 07445 if (caller_warning && config->end_sound) 07446 bridge_playfile(c0, c1, config->end_sound, 0); 07447 if (callee_warning && config->end_sound) 07448 bridge_playfile(c1, c0, config->end_sound, 0); 07449 *fo = NULL; 07450 res = 0; 07451 break; 07452 } 07453 07454 if (!to) { 07455 if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) { 07456 int t = (time_left_ms + 500) / 1000; /* round to nearest second */ 07457 if (caller_warning) 07458 bridge_playfile(c0, c1, config->warning_sound, t); 07459 if (callee_warning) 07460 bridge_playfile(c1, c0, config->warning_sound, t); 07461 } 07462 07463 if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) { 07464 config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000)); 07465 } else { 07466 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 07467 } 07468 } 07469 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE); 07470 } 07471 07472 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 07473 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07474 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE); 07475 } 07476 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07477 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE); 07478 } 07479 c0->_bridge = c1; 07480 c1->_bridge = c0; 07481 ast_debug(1, "Unbridge signal received. Ending native bridge.\n"); 07482 continue; 07483 } 07484 07485 /* Stop if we're a zombie or need a soft hangup */ 07486 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 07487 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) { 07488 *fo = NULL; 07489 res = 0; 07490 ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n", 07491 c0->name, c1->name, 07492 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No", 07493 ast_check_hangup(c0) ? "Yes" : "No", 07494 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No", 07495 ast_check_hangup(c1) ? "Yes" : "No"); 07496 break; 07497 } 07498 07499 update_bridge_vars(c0, c1); 07500 07501 bridge_play_sounds(c0, c1); 07502 07503 if (c0->tech->bridge && 07504 /* if < 1 ms remains use generic bridging for accurate timing */ 07505 (!config->timelimit || to > 1000 || to == 0) && 07506 (c0->tech->bridge == c1->tech->bridge) && 07507 !c0->monitor && !c1->monitor && 07508 !c0->audiohooks && !c1->audiohooks && 07509 ast_framehook_list_is_empty(c0->framehooks) && ast_framehook_list_is_empty(c1->framehooks) && 07510 !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) { 07511 int timeoutms = to - 1000 > 0 ? to - 1000 : to; 07512 /* Looks like they share a bridge method and nothing else is in the way */ 07513 ast_set_flag(c0, AST_FLAG_NBRIDGE); 07514 ast_set_flag(c1, AST_FLAG_NBRIDGE); 07515 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, timeoutms)) == AST_BRIDGE_COMPLETE) { 07516 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans, 07517 "Channel1: %s\r\n" 07518 "Channel2: %s\r\n" 07519 "Uniqueid1: %s\r\n" 07520 "Uniqueid2: %s\r\n" 07521 "CallerID1: %s\r\n" 07522 "CallerID2: %s\r\n", 07523 c0->name, c1->name, 07524 c0->uniqueid, c1->uniqueid, 07525 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"), 07526 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>")); 07527 07528 ast_debug(1, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name); 07529 07530 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 07531 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 07532 07533 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 07534 continue; 07535 } 07536 07537 c0->_bridge = NULL; 07538 c1->_bridge = NULL; 07539 return res; 07540 } else { 07541 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 07542 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 07543 } 07544 switch (res) { 07545 case AST_BRIDGE_RETRY: 07546 if (config->play_warning) { 07547 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE); 07548 } 07549 continue; 07550 default: 07551 ast_verb(3, "Native bridging %s and %s ended\n", c0->name, c1->name); 07552 /* fallthrough */ 07553 case AST_BRIDGE_FAILED_NOWARN: 07554 break; 07555 } 07556 } 07557 07558 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) || 07559 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) && 07560 !(c0->generator || c1->generator)) { 07561 if (ast_channel_make_compatible(c0, c1)) { 07562 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 07563 manager_bridge_event(0, 1, c0, c1); 07564 return AST_BRIDGE_FAILED; 07565 } 07566 o0nativeformats = c0->nativeformats; 07567 o1nativeformats = c1->nativeformats; 07568 } 07569 07570 update_bridge_vars(c0, c1); 07571 07572 res = ast_generic_bridge(c0, c1, config, fo, rc); 07573 if (res != AST_BRIDGE_RETRY) { 07574 break; 07575 } else if (config->feature_timer) { 07576 /* feature timer expired but has not been updated, sending to ast_bridge_call to do so */ 07577 break; 07578 } 07579 } 07580 07581 ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY); 07582 ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY); 07583 07584 /* Now that we have broken the bridge the source will change yet again */ 07585 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 07586 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 07587 07588 c0->_bridge = NULL; 07589 c1->_bridge = NULL; 07590 07591 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans, 07592 "Channel1: %s\r\n" 07593 "Channel2: %s\r\n" 07594 "Uniqueid1: %s\r\n" 07595 "Uniqueid2: %s\r\n" 07596 "CallerID1: %s\r\n" 07597 "CallerID2: %s\r\n", 07598 c0->name, c1->name, 07599 c0->uniqueid, c1->uniqueid, 07600 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"), 07601 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>")); 07602 ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name); 07603 07604 return res; 07605 }
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.
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 1606 of file channel.c.
References ao2_callback_data, and channels.
Referenced by 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().
01608 { 01609 return ao2_callback_data(channels, ao2_flags, cb_fn, arg, data); 01610 }
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 9509 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, cc_channel_datastore_info, and ast_datastore::data.
Referenced by ast_channel_get_cc_config_params(), dahdi_new(), local_call(), local_request(), and sip_new().
09511 { 09512 struct ast_cc_config_params *cc_params; 09513 struct ast_datastore *cc_datastore; 09514 09515 if (!(cc_params = ast_cc_config_params_init())) { 09516 return -1; 09517 } 09518 09519 if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL))) { 09520 ast_cc_config_params_destroy(cc_params); 09521 return -1; 09522 } 09523 09524 if (base_params) { 09525 ast_cc_copy_config_params(cc_params, base_params); 09526 } 09527 cc_datastore->data = cc_params; 09528 ast_channel_datastore_add(chan, cc_datastore); 09529 return 0; 09530 }
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 6253 of file channel.c.
References ast_assert, ast_cel_check_retire_linkedid(), ast_cel_linkedid_ref(), ast_string_field_set, chanlist::chan, and ast_channel::linkedid.
Referenced by ast_channel_set_linkgroup().
06254 { 06255 ast_assert(linkedid != NULL); 06256 /* if the linkedid for this channel is being changed from something, check... */ 06257 if (!strcmp(chan->linkedid, linkedid)) { 06258 return; 06259 } 06260 06261 ast_cel_check_retire_linkedid(chan); 06262 ast_string_field_set(chan, linkedid, linkedid); 06263 ast_cel_linkedid_ref(linkedid); 06264 }
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 2674 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, chanlist::chan, ast_frame::frametype, ast_frame_subclass::integer, ast_channel::readq, and ast_frame::subclass.
Referenced by __ast_pbx_run(), ast_channel_bridge(), check_goto_on_transfer(), and collect_digits().
02675 { 02676 ast_channel_lock(chan); 02677 02678 chan->_softhangup &= ~flag; 02679 02680 if (!chan->_softhangup) { 02681 struct ast_frame *fr; 02682 02683 /* If we have completely cleared the softhangup flag, 02684 * then we need to fully abort the hangup process. This requires 02685 * pulling the END_OF_Q frame out of the channel frame queue if it 02686 * still happens to be there. */ 02687 02688 fr = AST_LIST_LAST(&chan->readq); 02689 if (fr && fr->frametype == AST_FRAME_CONTROL && 02690 fr->subclass.integer == AST_CONTROL_END_OF_Q) { 02691 AST_LIST_REMOVE(&chan->readq, fr, frame_list); 02692 ast_frfree(fr); 02693 } 02694 } 02695 02696 ast_channel_unlock(chan); 02697 }
static int ast_channel_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1692 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_strlen_zero(), chanlist::chan, CMP_MATCH, ast_channel::context, ast_channel::exten, ast_channel::macrocontext, ast_channel::macroexten, ast_channel::name, and ast_channel::uniqueid.
01693 { 01694 struct ast_channel *chan = obj, *cmp_args = arg; 01695 size_t name_len; 01696 int ret = CMP_MATCH; 01697 01698 /* This is sort of a hack. Basically, we're using an arbitrary field 01699 * in ast_channel to pass the name_len for a prefix match. If this 01700 * gets changed, then the uses of ao2_find() must be changed, too. */ 01701 name_len = cmp_args->rings; 01702 01703 ast_channel_lock(chan); 01704 01705 if (!ast_strlen_zero(cmp_args->name)) { /* match by name */ 01706 if ((!name_len && strcasecmp(chan->name, cmp_args->name)) || 01707 (name_len && strncasecmp(chan->name, cmp_args->name, name_len))) { 01708 ret = 0; /* name match failed */ 01709 } 01710 } else if (!ast_strlen_zero(cmp_args->exten)) { 01711 if (cmp_args->context && strcasecmp(chan->context, cmp_args->context) && 01712 strcasecmp(chan->macrocontext, cmp_args->context)) { 01713 ret = 0; /* context match failed */ 01714 } 01715 if (ret && strcasecmp(chan->exten, cmp_args->exten) && 01716 strcasecmp(chan->macroexten, cmp_args->exten)) { 01717 ret = 0; /* exten match failed */ 01718 } 01719 } else if (!ast_strlen_zero(cmp_args->uniqueid)) { 01720 if ((!name_len && strcasecmp(chan->uniqueid, cmp_args->uniqueid)) || 01721 (name_len && strncasecmp(chan->uniqueid, cmp_args->uniqueid, name_len))) { 01722 ret = 0; /* uniqueid match failed */ 01723 } 01724 } else { 01725 ret = 0; 01726 } 01727 01728 ast_channel_unlock(chan); 01729 01730 return ret; 01731 }
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 889 of file channel.c.
References ast_channel_cmpwhentohangup_tv(), and chanlist::chan.
00890 { 00891 struct timeval when = { offset, }; 00892 return ast_channel_cmpwhentohangup_tv(chan, when); 00893 }
int ast_channel_cmpwhentohangup_tv | ( | struct ast_channel * | chan, | |
struct timeval | offset | |||
) |
Compare a offset with the settings of when to hang a channel up.
chan | channel on which to check for hangup | |
offset | offset in seconds and microseconds from current time |
Definition at line 874 of file channel.c.
References ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), chanlist::chan, and ast_channel::whentohangup.
Referenced by ast_channel_cmpwhentohangup().
00875 { 00876 struct timeval whentohangup; 00877 00878 if (ast_tvzero(chan->whentohangup)) 00879 return ast_tvzero(offset) ? 0 : -1; 00880 00881 if (ast_tvzero(offset)) 00882 return 1; 00883 00884 whentohangup = ast_tvadd(offset, ast_tvnow()); 00885 00886 return ast_tvdiff_ms(whentohangup, chan->whentohangup); 00887 }
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 |
Make constants so that caller and frame can be more expressive than just '1' and '0'
Definition at line 9396 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_party_connected_line_free(), ast_party_connected_line_init(), ast_strdupa, ast_strlen_zero(), 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(), atxfer_fail_cleanup(), builtin_atxfer(), feature_request_and_dial(), handle_frame(), parked_call_exec(), remote_bridge_loop(), and wait_for_answer().
09397 { 09398 const char *macro; 09399 const char *macro_args; 09400 int retval; 09401 09402 ast_channel_lock(macro_chan); 09403 macro = pbx_builtin_getvar_helper(macro_chan, is_caller 09404 ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO"); 09405 macro = ast_strdupa(S_OR(macro, "")); 09406 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller 09407 ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS"); 09408 macro_args = ast_strdupa(S_OR(macro_args, "")); 09409 09410 if (ast_strlen_zero(macro)) { 09411 ast_channel_unlock(macro_chan); 09412 return -1; 09413 } 09414 09415 if (is_frame) { 09416 const struct ast_frame *frame = connected_info; 09417 09418 ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->connected); 09419 } else { 09420 const struct ast_party_connected_line *connected = connected_info; 09421 09422 ast_party_connected_line_copy(¯o_chan->connected, connected); 09423 } 09424 ast_channel_unlock(macro_chan); 09425 09426 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args); 09427 if (!retval) { 09428 struct ast_party_connected_line saved_connected; 09429 09430 ast_party_connected_line_init(&saved_connected); 09431 ast_channel_lock(macro_chan); 09432 ast_party_connected_line_copy(&saved_connected, ¯o_chan->connected); 09433 ast_channel_unlock(macro_chan); 09434 ast_channel_update_connected_line(macro_chan, &saved_connected, NULL); 09435 ast_party_connected_line_free(&saved_connected); 09436 } 09437 09438 return retval; 09439 }
int ast_channel_data_add_structure | ( | struct ast_data * | tree, | |
struct ast_channel * | chan, | |||
int | add_bridged | |||
) |
Insert into an astdata tree, the channel structure.
[in] | tree | The ast data tree. |
[in] | chan | The channel structure to add to tree. |
[in] | add_bridged | Add the bridged channel to the structure. |
<0 | on error. | |
0 | on success. |
Definition at line 347 of file channel.c.
References ast_channel::_softhangup, ast_channel::_state, ast_channel::amaflags, ast_bridged_channel(), ast_cause2str(), ast_cdr_data_add_structure(), ast_cdr_flags2str(), ast_channel_data_add_structure(), ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), ast_data_add_structure, ast_data_add_uint(), AST_SOFTHANGUP_APPUNLOAD, AST_SOFTHANGUP_ASYNCGOTO, AST_SOFTHANGUP_DEV, AST_SOFTHANGUP_EXPLICIT, AST_SOFTHANGUP_SHUTDOWN, AST_SOFTHANGUP_TIMEOUT, AST_SOFTHANGUP_UNBRIDGE, ast_state2str(), ast_tone_zone_data_add_structure(), ast_transfercapability2str(), ast_channel::cdr, chanlist::chan, channel_data_add_flags(), ast_channel::hangupcause, ast_channel::nativeformats, ast_channel::oldwriteformat, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::transfercapability, ast_channel::whentohangup, ast_channel::writeformat, and ast_channel::zone.
Referenced by agents_data_provider_get(), ast_channel_data_add_structure(), data_channels_provider_handler(), queues_data_provider_get_helper(), and user_add_provider_cb().
00349 { 00350 struct ast_channel *bc; 00351 struct ast_data *data_bridged; 00352 struct ast_data *data_cdr; 00353 struct ast_data *data_flags; 00354 struct ast_data *data_zones; 00355 struct ast_data *enum_node; 00356 struct ast_data *data_softhangup; 00357 #if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */ 00358 struct ast_data *data_callerid; 00359 char value_str[100]; 00360 #endif 00361 00362 if (!tree) { 00363 return -1; 00364 } 00365 00366 ast_data_add_structure(ast_channel, tree, chan); 00367 00368 if (add_bridged) { 00369 bc = ast_bridged_channel(chan); 00370 if (bc) { 00371 data_bridged = ast_data_add_node(tree, "bridged"); 00372 if (!data_bridged) { 00373 return -1; 00374 } 00375 ast_channel_data_add_structure(data_bridged, bc, 0); 00376 } 00377 } 00378 00379 ast_data_add_codecs(tree, "oldwriteformat", chan->oldwriteformat); 00380 ast_data_add_codecs(tree, "nativeformats", chan->nativeformats); 00381 ast_data_add_codecs(tree, "readformat", chan->readformat); 00382 ast_data_add_codecs(tree, "writeformat", chan->writeformat); 00383 ast_data_add_codecs(tree, "rawreadformat", chan->rawreadformat); 00384 ast_data_add_codecs(tree, "rawwriteformat", chan->rawwriteformat); 00385 00386 /* state */ 00387 enum_node = ast_data_add_node(tree, "state"); 00388 if (!enum_node) { 00389 return -1; 00390 } 00391 ast_data_add_str(enum_node, "text", ast_state2str(chan->_state)); 00392 ast_data_add_int(enum_node, "value", chan->_state); 00393 00394 /* hangupcause */ 00395 enum_node = ast_data_add_node(tree, "hangupcause"); 00396 if (!enum_node) { 00397 return -1; 00398 } 00399 ast_data_add_str(enum_node, "text", ast_cause2str(chan->hangupcause)); 00400 ast_data_add_int(enum_node, "value", chan->hangupcause); 00401 00402 /* amaflags */ 00403 enum_node = ast_data_add_node(tree, "amaflags"); 00404 if (!enum_node) { 00405 return -1; 00406 } 00407 ast_data_add_str(enum_node, "text", ast_cdr_flags2str(chan->amaflags)); 00408 ast_data_add_int(enum_node, "value", chan->amaflags); 00409 00410 /* transfercapability */ 00411 enum_node = ast_data_add_node(tree, "transfercapability"); 00412 if (!enum_node) { 00413 return -1; 00414 } 00415 ast_data_add_str(enum_node, "text", ast_transfercapability2str(chan->transfercapability)); 00416 ast_data_add_int(enum_node, "value", chan->transfercapability); 00417 00418 /* _softphangup */ 00419 data_softhangup = ast_data_add_node(tree, "softhangup"); 00420 if (!data_softhangup) { 00421 return -1; 00422 } 00423 ast_data_add_bool(data_softhangup, "dev", chan->_softhangup & AST_SOFTHANGUP_DEV); 00424 ast_data_add_bool(data_softhangup, "asyncgoto", chan->_softhangup & AST_SOFTHANGUP_ASYNCGOTO); 00425 ast_data_add_bool(data_softhangup, "shutdown", chan->_softhangup & AST_SOFTHANGUP_SHUTDOWN); 00426 ast_data_add_bool(data_softhangup, "timeout", chan->_softhangup & AST_SOFTHANGUP_TIMEOUT); 00427 ast_data_add_bool(data_softhangup, "appunload", chan->_softhangup & AST_SOFTHANGUP_APPUNLOAD); 00428 ast_data_add_bool(data_softhangup, "explicit", chan->_softhangup & AST_SOFTHANGUP_EXPLICIT); 00429 ast_data_add_bool(data_softhangup, "unbridge", chan->_softhangup & AST_SOFTHANGUP_UNBRIDGE); 00430 00431 /* channel flags */ 00432 data_flags = ast_data_add_node(tree, "flags"); 00433 if (!data_flags) { 00434 return -1; 00435 } 00436 channel_data_add_flags(data_flags, chan); 00437 00438 ast_data_add_uint(tree, "timetohangup", chan->whentohangup.tv_sec); 00439 00440 #if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */ 00441 /* callerid */ 00442 data_callerid = ast_data_add_node(tree, "callerid"); 00443 if (!data_callerid) { 00444 return -1; 00445 } 00446 ast_data_add_structure(ast_callerid, data_callerid, &(chan->cid)); 00447 /* insert the callerid ton */ 00448 enum_node = ast_data_add_node(data_callerid, "cid_ton"); 00449 if (!enum_node) { 00450 return -1; 00451 } 00452 ast_data_add_int(enum_node, "value", chan->cid.cid_ton); 00453 snprintf(value_str, sizeof(value_str), "TON: %s/Plan: %s", 00454 party_number_ton2str(chan->cid.cid_ton), 00455 party_number_plan2str(chan->cid.cid_ton)); 00456 ast_data_add_str(enum_node, "text", value_str); 00457 #endif 00458 00459 /* tone zone */ 00460 if (chan->zone) { 00461 data_zones = ast_data_add_node(tree, "zone"); 00462 if (!data_zones) { 00463 return -1; 00464 } 00465 ast_tone_zone_data_add_structure(data_zones, chan->zone); 00466 } 00467 00468 /* insert cdr */ 00469 data_cdr = ast_data_add_node(tree, "cdr"); 00470 if (!data_cdr) { 00471 return -1; 00472 } 00473 00474 ast_cdr_data_add_structure(data_cdr, chan->cdr, 1); 00475 00476 return 0; 00477 }
int ast_channel_data_cmp_structure | ( | const struct ast_data_search * | tree, | |
struct ast_channel * | chan, | |||
const char * | structure_name | |||
) |
Compare to channel structures using the data api.
[in] | tree | The search tree generated by the data api. |
[in] | chan | The channel to compare. |
[in] | structure_name | The name of the node of the channel structure. |
0 | The structure matches. | |
1 | The structure doesn't matches. |
Definition at line 479 of file channel.c.
References ast_data_search_cmp_structure, and chanlist::chan.
00481 { 00482 return ast_data_search_cmp_structure(tree, ast_channel, chan, structure_name); 00483 }
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 2557 of file channel.c.
References AST_LIST_INSERT_HEAD, chanlist::chan, ast_channel::datastores, and ast_datastore::entry.
Referenced by __ast_channel_masquerade(), _macro_exec(), acf_curlopt_write(), acf_iaxvar_write(), add_features_datastore(), add_to_agi(), apply_plc(), ast_cel_fabricate_channel_from_event(), 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(), 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(), lua_get_state(), mute_add_audiohook(), pitchshift_helper(), raise_exception(), set_chan_app_data(), setup_inheritance_datastore(), setup_mixmonitor_ds(), setup_transfer_datastore(), shared_write(), smdi_msg_retrieve_read(), socket_process(), speech_create(), speex_write(), srv_datastore_setup(), and volume_write().
02558 { 02559 int res = 0; 02560 02561 AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry); 02562 02563 return res; 02564 }
struct ast_datastore* ast_channel_datastore_alloc | ( | const const struct ast_datastore_info * | info, | |
const char * | uid | |||
) |
Definition at line 2530 of file channel.c.
References ast_datastore_alloc, and ast_datastore::info.
02531 { 02532 return ast_datastore_alloc(info, uid); 02533 }
struct ast_datastore* ast_channel_datastore_find | ( | struct ast_channel * | chan, | |
const const struct ast_datastore_info * | info, | |||
const char * | uid | |||
) |
Definition at line 2571 of file channel.c.
References AST_LIST_TRAVERSE, chanlist::chan, ast_channel::datastores, ast_datastore::entry, ast_datastore::info, and ast_datastore::uid.
02572 { 02573 struct ast_datastore *datastore = NULL; 02574 02575 if (info == NULL) 02576 return NULL; 02577 02578 AST_LIST_TRAVERSE(&chan->datastores, datastore, entry) { 02579 if (datastore->info != info) { 02580 continue; 02581 } 02582 02583 if (uid == NULL) { 02584 /* matched by type only */ 02585 break; 02586 } 02587 02588 if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) { 02589 /* Matched by type AND uid */ 02590 break; 02591 } 02592 } 02593 02594 return datastore; 02595 }
int ast_channel_datastore_free | ( | struct ast_datastore * | datastore | ) |
Free a channel data store object.
Definition at line 2535 of file channel.c.
References ast_datastore_free().
02536 { 02537 return ast_datastore_free(datastore); 02538 }
int ast_channel_datastore_inherit | ( | struct ast_channel * | from, | |
struct ast_channel * | to | |||
) |
Inherit datastores from a parent to a child.
Definition at line 2540 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::entry, 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(), and ring_entry().
02541 { 02542 struct ast_datastore *datastore = NULL, *datastore2; 02543 02544 AST_LIST_TRAVERSE(&from->datastores, datastore, entry) { 02545 if (datastore->inheritance > 0) { 02546 datastore2 = ast_datastore_alloc(datastore->info, datastore->uid); 02547 if (datastore2) { 02548 datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL; 02549 datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1; 02550 AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry); 02551 } 02552 } 02553 } 02554 return 0; 02555 }
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 2566 of file channel.c.
References AST_LIST_REMOVE, chanlist::chan, ast_channel::datastores, and ast_datastore::entry.
Referenced by acf_fetch(), adjust_frame_for_plc(), ast_do_masquerade(), ast_do_pickup(), clear_dialed_interfaces(), dial_exec_full(), disable_jack_hook(), exec_odbcfinish(), frame_trace_helper(), lua_get_state(), queue_transfer_fixup(), speech_background(), speech_destroy(), speex_write(), srv_query_read(), and stop_mixmonitor_exec().
02567 { 02568 return AST_LIST_REMOVE(&chan->datastores, datastore, entry) ? 0 : -1; 02569 }
int ast_channel_defer_dtmf | ( | struct ast_channel * | chan | ) |
Defers DTMF so that you only read things like hangups and audio.
Definition at line 1588 of file channel.c.
References AST_FLAG_DEFER_DTMF, ast_set_flag, ast_test_flag, and chanlist::chan.
Referenced by find_cache().
01589 { 01590 int pre = 0; 01591 01592 if (chan) { 01593 pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF); 01594 ast_set_flag(chan, AST_FLAG_DEFER_DTMF); 01595 } 01596 return pre; 01597 }
static void ast_channel_destructor | ( | void * | obj | ) | [static] |
Free a channel structure.
Definition at line 2371 of file channel.c.
References ast_channel::alertpipe, ast_app_group_discard(), ast_atomic_fetchadd_int(), ast_cdr_discard(), AST_CEL_CHANNEL_END, ast_cel_check_retire_linkedid(), ast_cel_report_event(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_unlock, ast_copy_string(), ast_datastore_free(), AST_DEVICE_UNKNOWN, ast_devstate_changed_literal(), ast_free, ast_frfree, ast_jb_destroy(), AST_LIST_REMOVE_HEAD, ast_log(), AST_MAX_FDS, ast_moh_cleanup(), ast_party_caller_free(), ast_party_connected_line_free(), ast_party_dialed_free(), ast_party_redirecting_free(), ast_string_field_free_memory, ast_timer_close(), ast_tone_zone_unref(), ast_translator_free_path(), ast_var_delete(), ast_channel::caller, ast_channel::cdr, chanlist::chan, ast_channel::connected, ast_channel::datastores, ast_channel::dialed, ast_datastore::entry, f, free, LOG_WARNING, ast_channel::monitor, ast_channel::music_state, ast_channel::name, ast_channel::pbx, ast_channel::readq, ast_channel::readtrans, ast_channel::redirecting, ast_channel::sched, sched_context_destroy(), ast_channel_monitor::stop, ast_channel::tech_pvt, ast_channel::timer, ast_channel::varshead, ast_channel::writetrans, and ast_channel::zone.
Referenced by __ast_channel_alloc_ap().
02372 { 02373 struct ast_channel *chan = obj; 02374 int fd; 02375 #ifdef HAVE_EPOLL 02376 int i; 02377 #endif 02378 struct ast_var_t *vardata; 02379 struct ast_frame *f; 02380 struct varshead *headp; 02381 struct ast_datastore *datastore; 02382 char device_name[AST_CHANNEL_NAME]; 02383 02384 if (chan->name) { 02385 /* The string fields were initialized. */ 02386 ast_cel_report_event(chan, AST_CEL_CHANNEL_END, NULL, NULL, NULL); 02387 ast_cel_check_retire_linkedid(chan); 02388 } 02389 02390 /* Get rid of each of the data stores on the channel */ 02391 ast_channel_lock(chan); 02392 while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry))) 02393 /* Free the data store */ 02394 ast_datastore_free(datastore); 02395 ast_channel_unlock(chan); 02396 02397 /* Lock and unlock the channel just to be sure nobody has it locked still 02398 due to a reference that was stored in a datastore. (i.e. app_chanspy) */ 02399 ast_channel_lock(chan); 02400 ast_channel_unlock(chan); 02401 02402 if (chan->tech_pvt) { 02403 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name); 02404 ast_free(chan->tech_pvt); 02405 } 02406 02407 if (chan->sched) 02408 sched_context_destroy(chan->sched); 02409 02410 if (chan->name) { 02411 char *dashptr; 02412 02413 /* The string fields were initialized. */ 02414 ast_copy_string(device_name, chan->name, sizeof(device_name)); 02415 if ((dashptr = strrchr(device_name, '-'))) { 02416 *dashptr = '\0'; 02417 } 02418 } else { 02419 device_name[0] = '\0'; 02420 } 02421 02422 /* Stop monitoring */ 02423 if (chan->monitor) 02424 chan->monitor->stop( chan, 0 ); 02425 02426 /* If there is native format music-on-hold state, free it */ 02427 if (chan->music_state) 02428 ast_moh_cleanup(chan); 02429 02430 /* Free translators */ 02431 if (chan->readtrans) 02432 ast_translator_free_path(chan->readtrans); 02433 if (chan->writetrans) 02434 ast_translator_free_path(chan->writetrans); 02435 if (chan->pbx) 02436 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name); 02437 02438 ast_party_dialed_free(&chan->dialed); 02439 ast_party_caller_free(&chan->caller); 02440 ast_party_connected_line_free(&chan->connected); 02441 ast_party_redirecting_free(&chan->redirecting); 02442 02443 /* Close pipes if appropriate */ 02444 if ((fd = chan->alertpipe[0]) > -1) 02445 close(fd); 02446 if ((fd = chan->alertpipe[1]) > -1) 02447 close(fd); 02448 if (chan->timer) { 02449 ast_timer_close(chan->timer); 02450 } 02451 #ifdef HAVE_EPOLL 02452 for (i = 0; i < AST_MAX_FDS; i++) { 02453 if (chan->epfd_data[i]) 02454 free(chan->epfd_data[i]); 02455 } 02456 close(chan->epfd); 02457 #endif 02458 while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list))) 02459 ast_frfree(f); 02460 02461 /* loop over the variables list, freeing all data and deleting list items */ 02462 /* no need to lock the list, as the channel is already locked */ 02463 headp = &chan->varshead; 02464 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) 02465 ast_var_delete(vardata); 02466 02467 ast_app_group_discard(chan); 02468 02469 /* Destroy the jitterbuffer */ 02470 ast_jb_destroy(chan); 02471 02472 if (chan->cdr) { 02473 ast_cdr_discard(chan->cdr); 02474 chan->cdr = NULL; 02475 } 02476 02477 if (chan->zone) { 02478 chan->zone = ast_tone_zone_unref(chan->zone); 02479 } 02480 02481 ast_string_field_free_memory(chan); 02482 02483 if (device_name[0]) { 02484 /* 02485 * We have a device name to notify of a new state. 02486 * 02487 * Queue an unknown state, because, while we know that this particular 02488 * instance is dead, we don't know the state of all other possible 02489 * instances. 02490 */ 02491 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name); 02492 } 02493 ast_atomic_fetchadd_int(&chancount, -1); 02494 }
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 7237 of file channel.c.
References ast_channel_tech::early_bridge, and ast_channel::tech.
Referenced by dial_exec_full().
07238 { 07239 /* Make sure we can early bridge, if not error out */ 07240 if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge))) 07241 return -1; 07242 07243 return c0->tech->early_bridge(c0, c1); 07244 }
struct ast_channel* ast_channel_get_by_exten | ( | const char * | exten, | |
const char * | context | |||
) |
Find a channel by extension and context.
a | channel that is at the specified extension and context | |
NULL | if no channel was found |
Definition at line 1785 of file channel.c.
References ast_channel_get_full().
01786 { 01787 return ast_channel_get_full(NULL, 0, exten, context); 01788 }
struct ast_channel* ast_channel_get_by_name | ( | const char * | name | ) |
Find a channel by name.
a | channel with the name specified by the argument | |
NULL | if no channel was found |
Definition at line 1775 of file channel.c.
References ast_channel_get_full().
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_mute_mixmonitor(), manager_mutestream(), manager_optimize_away(), manager_park(), manager_play_dtmf(), park_call_full(), pbx_builtin_importvar(), senddtmf_exec(), shared_read(), shared_write(), start_monitor_action(), and stop_monitor_action().
01776 { 01777 return ast_channel_get_full(name, 0, NULL, NULL); 01778 }
struct ast_channel* ast_channel_get_by_name_prefix | ( | const char * | name, | |
size_t | name_len | |||
) |
Find a channel by a name prefix.
a | channel with the name prefix specified by the arguments | |
NULL | if no channel was found |
Definition at line 1780 of file channel.c.
References ast_channel_get_full().
Referenced by action_aocmessage(), action_bridge(), ast_parse_device_state(), bridge_exec(), cc_generic_agent_stop_ringing(), common_exec(), handle_cli_mixmonitor(), shared_read(), and shared_write().
01781 { 01782 return ast_channel_get_full(name, name_len, NULL, NULL); 01783 }
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 9571 of file channel.c.
References ast_channel_queryoption(), ast_copy_string(), AST_OPTION_CC_AGENT_TYPE, and ast_channel::name.
Referenced by find_agent_callbacks().
09572 { 09573 int len = size; 09574 char *slash; 09575 09576 if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE, agent_type, &len, 0)) { 09577 return 0; 09578 } 09579 09580 ast_copy_string(agent_type, chan->name, size); 09581 if ((slash = strchr(agent_type, '/'))) { 09582 *slash = '\0'; 09583 } 09584 return 0; 09585 }
struct ast_cc_config_params* ast_channel_get_cc_config_params | ( | struct ast_channel * | chan | ) |
Get the CCSS parameters from a channel.
chan | Channel to retrieve parameters from |
NULL | Failure | |
non-NULL | The parameters desired |
Definition at line 9532 of file channel.c.
References ast_assert, ast_channel_cc_params_init(), ast_channel_datastore_find(), cc_channel_datastore_info, 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(), local_request(), sig_pri_cc_available(), and sig_pri_cc_generic_check().
09533 { 09534 struct ast_datastore *cc_datastore; 09535 09536 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) { 09537 /* If we can't find the datastore, it almost definitely means that the channel type being 09538 * used has not had its driver modified to parse CC config parameters. The best action 09539 * to take here is to create the parameters on the spot with the defaults set. 09540 */ 09541 if (ast_channel_cc_params_init(chan, NULL)) { 09542 return NULL; 09543 } 09544 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) { 09545 /* Should be impossible */ 09546 return NULL; 09547 } 09548 } 09549 09550 ast_assert(cc_datastore->data != NULL); 09551 return cc_datastore->data; 09552 }
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 9554 of file channel.c.
References ast_channel_queryoption(), ast_copy_string(), AST_OPTION_DEVICE_NAME, and ast_channel::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(), sig_pri_call(), sig_pri_cc_available(), sig_pri_cc_generic_check(), sip_call(), and sip_handle_cc().
09555 { 09556 int len = name_buffer_length; 09557 char *dash; 09558 if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME, device_name, &len, 0)) { 09559 return 0; 09560 } 09561 09562 /* Dang. Do it the old-fashioned way */ 09563 ast_copy_string(device_name, chan->name, name_buffer_length); 09564 if ((dash = strrchr(device_name, '-'))) { 09565 *dash = '\0'; 09566 } 09567 09568 return 0; 09569 }
static struct ast_channel* ast_channel_get_full | ( | const char * | name, | |
size_t | name_len, | |||
const char * | exten, | |||
const char * | context | |||
) | [static] |
Definition at line 1733 of file channel.c.
References ao2_find, ast_copy_string(), ast_strlen_zero(), chanlist::chan, channels, ast_channel::context, ast_channel::exten, ast_channel::name, OBJ_POINTER, and ast_channel::uniqueid.
Referenced by ast_channel_get_by_exten(), ast_channel_get_by_name(), and ast_channel_get_by_name_prefix().
01735 { 01736 struct ast_channel tmp_chan = { 01737 .name = name, 01738 /* This is sort of a hack. Basically, we're using an arbitrary field 01739 * in ast_channel to pass the name_len for a prefix match. If this 01740 * gets changed, then the compare callback must be changed, too. */ 01741 .rings = name_len, 01742 }; 01743 struct ast_channel *chan; 01744 01745 if (exten) { 01746 ast_copy_string(tmp_chan.exten, exten, sizeof(tmp_chan.exten)); 01747 } 01748 01749 if (context) { 01750 ast_copy_string(tmp_chan.context, context, sizeof(tmp_chan.context)); 01751 } 01752 01753 if ((chan = ao2_find(channels, &tmp_chan, 01754 (!ast_strlen_zero(name) && (name_len == 0)) ? OBJ_POINTER : 0))) { 01755 return chan; 01756 } 01757 01758 if (!name) { 01759 return NULL; 01760 } 01761 01762 /* If name was specified, but the result was NULL, 01763 * try a search on uniqueid, instead. */ 01764 01765 { 01766 struct ast_channel tmp_chan2 = { 01767 .uniqueid = name, 01768 .rings = name_len, 01769 }; 01770 01771 return ao2_find(channels, &tmp_chan2, 0); 01772 } 01773 }
static int ast_channel_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 7876 of file channel.c.
References ast_str_case_hash(), ast_strlen_zero(), and ast_channel::name.
07877 { 07878 const struct ast_channel *chan = obj; 07879 07880 /* If the name isn't set, return 0 so that the ao2_find() search will 07881 * start in the first bucket. */ 07882 if (ast_strlen_zero(chan->name)) { 07883 return 0; 07884 } 07885 07886 return ast_str_case_hash(chan->name); 07887 }
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 6125 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(), and ring_entry().
06126 { 06127 struct ast_var_t *current, *newvar; 06128 const char *varname; 06129 06130 AST_LIST_TRAVERSE(&parent->varshead, current, entries) { 06131 int vartype = 0; 06132 06133 varname = ast_var_full_name(current); 06134 if (!varname) 06135 continue; 06136 06137 if (varname[0] == '_') { 06138 vartype = 1; 06139 if (varname[1] == '_') 06140 vartype = 2; 06141 } 06142 06143 switch (vartype) { 06144 case 1: 06145 newvar = ast_var_assign(&varname[1], ast_var_value(current)); 06146 if (newvar) { 06147 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 06148 ast_debug(1, "Copying soft-transferable variable %s.\n", ast_var_name(newvar)); 06149 } 06150 break; 06151 case 2: 06152 newvar = ast_var_assign(varname, ast_var_value(current)); 06153 if (newvar) { 06154 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 06155 ast_debug(1, "Copying hard-transferable variable %s.\n", ast_var_name(newvar)); 06156 } 06157 break; 06158 default: 06159 ast_debug(1, "Not copying variable %s.\n", ast_var_name(current)); 06160 break; 06161 } 06162 } 06163 }
struct ast_channel_iterator* ast_channel_iterator_all_new | ( | void | ) |
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 1673 of file channel.c.
References 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().
01674 { 01675 struct ast_channel_iterator *i; 01676 01677 if (!(i = ast_calloc(1, sizeof(*i)))) { 01678 return NULL; 01679 } 01680 01681 i->simple_iterator = ao2_iterator_init(channels, 0); 01682 i->active_iterator = &i->simple_iterator; 01683 01684 return i; 01685 }
struct ast_channel_iterator* ast_channel_iterator_by_exten_new | ( | const char * | exten, | |
const char * | context | |||
) |
Create a new channel iterator based on extension.
NULL | on failure | |
a | new channel iterator based on the specified parameters |
Definition at line 1663 of file channel.c.
References channel_iterator_search().
Referenced by common_exec(), and pickup_by_exten().
01664 { 01665 return channel_iterator_search(NULL, 0, exten, context); 01666 }
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.
NULL | on failure | |
a | new channel iterator based on the specified parameters |
Definition at line 1668 of file channel.c.
References channel_iterator_search().
Referenced by ast_complete_channels(), common_exec(), and softhangup_exec().
01669 { 01670 return channel_iterator_search(name, name_len, NULL, NULL); 01671 }
struct ast_channel_iterator* ast_channel_iterator_destroy | ( | struct ast_channel_iterator * | i | ) |
Destroy a channel iterator.
Definition at line 1621 of file channel.c.
References ast_channel_iterator::active_iterator, ao2_iterator_destroy(), and ast_free.
Referenced by action_coreshowchannels(), 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().
01622 { 01623 ao2_iterator_destroy(i->active_iterator); 01624 ast_free(i); 01625 01626 return NULL; 01627 }
struct ast_channel* ast_channel_iterator_next | ( | struct ast_channel_iterator * | i | ) |
Get the next channel for a channel iterator.
the | next channel that matches the parameters used when the iterator was created. | |
NULL,if | no more channels match the iterator parameters. |
Definition at line 1687 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().
01688 { 01689 return ao2_iterator_next(i->active_iterator); 01690 }
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 5854 of file channel.c.
References ast_channel_make_compatible_helper(), and chanlist::chan.
Referenced by action_bridge(), app_exec(), ast_channel_bridge(), bridge_exec(), check_compat(), dial_exec_full(), do_forward(), multiplexed_bridge_join(), parked_call_exec(), simple_bridge_join(), and wait_for_answer().
05855 { 05856 /* Some callers do not check return code, and we must try to set all call legs correctly */ 05857 int rc = 0; 05858 05859 /* Set up translation from the chan to the peer */ 05860 rc = ast_channel_make_compatible_helper(chan, peer); 05861 05862 if (rc < 0) 05863 return rc; 05864 05865 /* Set up translation from the peer to the chan */ 05866 rc = ast_channel_make_compatible_helper(peer, chan); 05867 05868 return rc; 05869 }
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 5804 of file channel.c.
References ast_channel_setoption(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_SLINEAR, 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::name, ast_channel::nativeformats, ast_channel::readformat, ast_channel::tech, and ast_channel::writeformat.
Referenced by ast_channel_make_compatible().
05805 { 05806 format_t src, dst; 05807 int use_slin; 05808 05809 /* See if the channel driver can natively make these two channels compatible */ 05810 if (from->tech->bridge && from->tech->bridge == to->tech->bridge && 05811 !ast_channel_setoption(from, AST_OPTION_MAKE_COMPATIBLE, to, sizeof(struct ast_channel *), 0)) { 05812 return 0; 05813 } 05814 05815 if (from->readformat == to->writeformat && from->writeformat == to->readformat) { 05816 /* Already compatible! Moving on ... */ 05817 return 0; 05818 } 05819 05820 /* Set up translation from the 'from' channel to the 'to' channel */ 05821 src = from->nativeformats; 05822 dst = to->nativeformats; 05823 05824 /* If there's no audio in this call, don't bother with trying to find a translation path */ 05825 if ((src & AST_FORMAT_AUDIO_MASK) == 0 || (dst & AST_FORMAT_AUDIO_MASK) == 0) 05826 return 0; 05827 05828 if (ast_translator_best_choice(&dst, &src) < 0) { 05829 ast_log(LOG_WARNING, "No path to translate from %s to %s\n", from->name, to->name); 05830 return -1; 05831 } 05832 05833 /* if the best path is not 'pass through', then 05834 * transcoding is needed; if desired, force transcode path 05835 * to use SLINEAR between channels, but only if there is 05836 * no direct conversion available. If generic PLC is 05837 * desired, then transcoding via SLINEAR is a requirement 05838 */ 05839 use_slin = (src == AST_FORMAT_SLINEAR || dst == AST_FORMAT_SLINEAR); 05840 if ((src != dst) && (ast_opt_generic_plc || ast_opt_transcode_via_slin) && 05841 (ast_translate_path_steps(dst, src) != 1 || use_slin)) 05842 dst = AST_FORMAT_SLINEAR; 05843 if (ast_set_read_format(from, dst) < 0) { 05844 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %s\n", from->name, ast_getformatname(dst)); 05845 return -1; 05846 } 05847 if (ast_set_write_format(to, dst) < 0) { 05848 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %s\n", to->name, ast_getformatname(dst)); 05849 return -1; 05850 } 05851 return 0; 05852 }
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 5994 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().
05995 { 05996 return __ast_channel_masquerade(original, clone, NULL); 05997 }
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 7628 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), chanlist::chan, 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().
07629 { 07630 int res; 07631 07632 ast_channel_lock(chan); 07633 if (!chan->tech->queryoption) { 07634 errno = ENOSYS; 07635 ast_channel_unlock(chan); 07636 return -1; 07637 } 07638 07639 if (block) 07640 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 07641 07642 res = chan->tech->queryoption(chan, option, data, datalen); 07643 ast_channel_unlock(chan); 07644 07645 return res; 07646 }
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 8876 of file channel.c.
References ast_connected_line_build_data(), AST_CONTROL_CONNECTED_LINE, ast_queue_control_data(), connected, and update().
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(), sig_pri_handle_subcmds(), and sip_call().
08877 { 08878 unsigned char data[1024]; /* This should be large enough */ 08879 size_t datalen; 08880 08881 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update); 08882 if (datalen == (size_t) -1) { 08883 return; 08884 } 08885 08886 ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen); 08887 }
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 9383 of file channel.c.
References AST_CONTROL_REDIRECTING, ast_queue_control_data(), ast_redirecting_build_data(), and update().
Referenced by cb_events(), handle_response_invite(), misdn_facility_ie_handler(), and sig_pri_handle_subcmds().
09384 { 09385 unsigned char data[1024]; /* This should be large enough */ 09386 size_t datalen; 09387 09388 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update); 09389 if (datalen == (size_t) -1) { 09390 return; 09391 } 09392 09393 ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen); 09394 }
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 5198 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().
05199 { 05200 switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */ 05201 { 05202 case 0: 05203 return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)"; 05204 case AST_CONTROL_HANGUP: 05205 return "Hangup"; 05206 case AST_CONTROL_RING: 05207 return "Local Ring"; 05208 case AST_CONTROL_RINGING: 05209 return "Remote end Ringing"; 05210 case AST_CONTROL_ANSWER: 05211 return "Remote end has Answered"; 05212 case AST_CONTROL_BUSY: 05213 return "Remote end is Busy"; 05214 case AST_CONTROL_CONGESTION: 05215 return "Congestion (circuits busy)"; 05216 default: 05217 return "Unknown Reason!!"; 05218 } 05219 }
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 |
Make constants so that caller and frame can be more expressive than just '1' and '0'
Definition at line 9441 of file channel.c.
References ast_app_run_macro(), ast_channel_lock, ast_channel_unlock, ast_channel_update_redirecting(), ast_party_redirecting_copy(), ast_party_redirecting_free(), ast_party_redirecting_init(), 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(), call_forward_inherit(), do_forward(), feature_request_and_dial(), handle_frame(), and remote_bridge_loop().
09442 { 09443 const char *macro; 09444 const char *macro_args; 09445 int retval; 09446 09447 ast_channel_lock(macro_chan); 09448 macro = pbx_builtin_getvar_helper(macro_chan, is_caller 09449 ? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO"); 09450 macro = ast_strdupa(S_OR(macro, "")); 09451 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller 09452 ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS"); 09453 macro_args = ast_strdupa(S_OR(macro_args, "")); 09454 09455 if (ast_strlen_zero(macro)) { 09456 ast_channel_unlock(macro_chan); 09457 return -1; 09458 } 09459 09460 if (is_frame) { 09461 const struct ast_frame *frame = redirecting_info; 09462 09463 ast_redirecting_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->redirecting); 09464 } else { 09465 const struct ast_party_redirecting *redirecting = redirecting_info; 09466 09467 ast_party_redirecting_copy(¯o_chan->redirecting, redirecting); 09468 } 09469 ast_channel_unlock(macro_chan); 09470 09471 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args); 09472 if (!retval) { 09473 struct ast_party_redirecting saved_redirecting; 09474 09475 ast_party_redirecting_init(&saved_redirecting); 09476 ast_channel_lock(macro_chan); 09477 ast_party_redirecting_copy(&saved_redirecting, ¯o_chan->redirecting); 09478 ast_channel_unlock(macro_chan); 09479 ast_channel_update_redirecting(macro_chan, &saved_redirecting, NULL); 09480 ast_party_redirecting_free(&saved_redirecting); 09481 } 09482 09483 return retval; 09484 }
int ast_channel_register | ( | const struct ast_channel_tech * | tech | ) |
Register a channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports.
tech | Structure defining channel technology or "type" |
Definition at line 896 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, chanlist::chan, chanlist::list, LOG_WARNING, ast_channel::tech, chanlist::tech, and ast_channel_tech::type.
Referenced by load_module(), and unload_module().
00897 { 00898 struct chanlist *chan; 00899 00900 AST_RWLIST_WRLOCK(&backends); 00901 00902 AST_RWLIST_TRAVERSE(&backends, chan, list) { 00903 if (!strcasecmp(tech->type, chan->tech->type)) { 00904 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type); 00905 AST_RWLIST_UNLOCK(&backends); 00906 return -1; 00907 } 00908 } 00909 00910 if (!(chan = ast_calloc(1, sizeof(*chan)))) { 00911 AST_RWLIST_UNLOCK(&backends); 00912 return -1; 00913 } 00914 chan->tech = tech; 00915 AST_RWLIST_INSERT_HEAD(&backends, chan, list); 00916 00917 ast_debug(1, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description); 00918 00919 ast_verb(2, "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description); 00920 00921 AST_RWLIST_UNLOCK(&backends); 00922 00923 return 0; 00924 }
struct ast_channel* ast_channel_release | ( | struct ast_channel * | chan | ) |
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 1889 of file channel.c.
References ao2_unlink, ast_channel_unref, chanlist::chan, and channels.
Referenced by agent_cleanup(), ast_iax2_new(), ast_request(), bridge_request(), do_notify(), gtalk_newcall(), local_new(), and local_request().
01890 { 01891 /* Safe, even if already unlinked. */ 01892 ao2_unlink(channels, chan); 01893 return ast_channel_unref(chan); 01894 }
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 5791 of file channel.c.
References chanlist::chan, ast_channel_tech::send_html, and ast_channel::tech.
Referenced by agent_sendhtml(), and ast_channel_sendurl().
05792 { 05793 if (chan->tech->send_html) 05794 return chan->tech->send_html(chan, subclass, data, datalen); 05795 return -1; 05796 }
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 5798 of file channel.c.
References ast_channel_sendhtml(), AST_HTML_URL, and chanlist::chan.
Referenced by dial_exec_full(), and sendurl_exec().
05799 { 05800 return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1); 05801 }
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 6913 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_party_caller_set(), ast_channel::caller, chanlist::chan, and update().
06914 { 06915 if (&chan->caller == caller) { 06916 /* Don't set to self */ 06917 return; 06918 } 06919 06920 ast_channel_lock(chan); 06921 ast_party_caller_set(&chan->caller, caller, update); 06922 ast_channel_unlock(chan); 06923 }
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 6925 of file channel.c.
References ast_cdr_setcid(), ast_channel_lock, ast_channel_unlock, ast_party_caller_set(), ast_channel::caller, ast_channel::cdr, chanlist::chan, 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, update(), ast_party_name::valid, and ast_party_number::valid.
Referenced by callerid_write(), dial_exec_full(), do_forward(), misdn_update_caller_id(), ring_entry(), and sig_pri_handle_subcmds().
06926 { 06927 const char *pre_set_number; 06928 const char *pre_set_name; 06929 06930 if (&chan->caller == caller) { 06931 /* Don't set to self */ 06932 return; 06933 } 06934 06935 ast_channel_lock(chan); 06936 pre_set_number = 06937 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL); 06938 pre_set_name = S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL); 06939 ast_party_caller_set(&chan->caller, caller, update); 06940 if (S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL) 06941 != pre_set_number 06942 || S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL) 06943 != pre_set_name) { 06944 /* The caller id name or number changed. */ 06945 report_new_callerid(chan); 06946 } 06947 if (chan->cdr) { 06948 ast_cdr_setcid(chan->cdr, chan); 06949 } 06950 ast_channel_unlock(chan); 06951 }
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 8236 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_party_connected_line_set(), connected, ast_channel::connected, and update().
Referenced by __ast_request_and_dial(), ast_indicate_data(), connectedline_write(), dial_exec_full(), and feature_request_and_dial().
08237 { 08238 if (&chan->connected == connected) { 08239 /* Don't set to self */ 08240 return; 08241 } 08242 08243 ast_channel_lock(chan); 08244 ast_party_connected_line_set(&chan->connected, connected, update); 08245 ast_channel_unlock(chan); 08246 }
void ast_channel_set_fd | ( | struct ast_channel * | chan, | |
int | which, | |||
int | fd | |||
) |
Set the file descriptor on the channel
Definition at line 2598 of file channel.c.
References ast_calloc, chanlist::chan, ast_channel::data, ast_channel::fds, and free.
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(), jingle_new(), mgcp_new(), misdn_new(), my_swap_subchannels(), nbs_new(), oss_new(), phone_new(), process_sdp(), setformat(), sip_new(), sip_set_rtp_peer(), skinny_new(), start_rtp(), and swap_subs().
02599 { 02600 #ifdef HAVE_EPOLL 02601 struct epoll_event ev; 02602 struct ast_epoll_data *aed = NULL; 02603 02604 if (chan->fds[which] > -1) { 02605 epoll_ctl(chan->epfd, EPOLL_CTL_DEL, chan->fds[which], &ev); 02606 aed = chan->epfd_data[which]; 02607 } 02608 02609 /* If this new fd is valid, add it to the epoll */ 02610 if (fd > -1) { 02611 if (!aed && (!(aed = ast_calloc(1, sizeof(*aed))))) 02612 return; 02613 02614 chan->epfd_data[which] = aed; 02615 aed->chan = chan; 02616 aed->which = which; 02617 02618 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 02619 ev.data.ptr = aed; 02620 epoll_ctl(chan->epfd, EPOLL_CTL_ADD, fd, &ev); 02621 } else if (aed) { 02622 /* We don't have to keep around this epoll data structure now */ 02623 free(aed); 02624 chan->epfd_data[which] = NULL; 02625 } 02626 #endif 02627 chan->fds[which] = fd; 02628 return; 02629 }
void ast_channel_set_linkgroup | ( | struct ast_channel * | chan, | |
struct ast_channel * | peer | |||
) |
propagate the linked id between chan and peer
Definition at line 6270 of file channel.c.
References ast_channel::_bridge, ast_bridged_channel(), ast_channel_change_linkedid(), ast_strdupa, chanlist::chan, ast_channel::linkedid, oldest_linkedid(), and ast_channel::uniqueid.
Referenced by ast_bridge_call(), and ast_do_masquerade().
06271 { 06272 const char* linkedid=NULL; 06273 struct ast_channel *bridged; 06274 06275 linkedid = oldest_linkedid(chan->linkedid, peer->linkedid); 06276 linkedid = oldest_linkedid(linkedid, chan->uniqueid); 06277 linkedid = oldest_linkedid(linkedid, peer->uniqueid); 06278 if (chan->_bridge) { 06279 bridged = ast_bridged_channel(chan); 06280 if (bridged != peer) { 06281 linkedid = oldest_linkedid(linkedid, bridged->linkedid); 06282 linkedid = oldest_linkedid(linkedid, bridged->uniqueid); 06283 } 06284 } 06285 if (peer->_bridge) { 06286 bridged = ast_bridged_channel(peer); 06287 if (bridged != chan) { 06288 linkedid = oldest_linkedid(linkedid, bridged->linkedid); 06289 linkedid = oldest_linkedid(linkedid, bridged->uniqueid); 06290 } 06291 } 06292 06293 /* just in case setting a stringfield to itself causes problems */ 06294 linkedid = ast_strdupa(linkedid); 06295 06296 ast_channel_change_linkedid(chan, linkedid); 06297 ast_channel_change_linkedid(peer, linkedid); 06298 if (chan->_bridge) { 06299 bridged = ast_bridged_channel(chan); 06300 if (bridged != peer) { 06301 ast_channel_change_linkedid(bridged, linkedid); 06302 } 06303 } 06304 if (peer->_bridge) { 06305 bridged = ast_bridged_channel(peer); 06306 if (bridged != chan) { 06307 ast_channel_change_linkedid(bridged, linkedid); 06308 } 06309 } 06310 }
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 8889 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_party_redirecting_set(), ast_channel::redirecting, and update().
Referenced by ast_indicate_data(), handle_request_invite(), handle_response(), misdn_copy_redirecting_to_ast(), redirecting_write(), and sig_pri_handle_subcmds().
08890 { 08891 if (&chan->redirecting == redirecting) { 08892 /* Don't set to self */ 08893 return; 08894 } 08895 08896 ast_channel_lock(chan); 08897 ast_party_redirecting_set(&chan->redirecting, redirecting, update); 08898 ast_channel_unlock(chan); 08899 }
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 7608 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), chanlist::chan, 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(), set_format(), set_listen_volume(), set_security_requirements(), set_talk_volume(), sndfax_exec(), and vm_forwardoptions().
07609 { 07610 int res; 07611 07612 ast_channel_lock(chan); 07613 if (!chan->tech->setoption) { 07614 errno = ENOSYS; 07615 ast_channel_unlock(chan); 07616 return -1; 07617 } 07618 07619 if (block) 07620 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 07621 07622 res = chan->tech->setoption(chan, option, data, datalen); 07623 ast_channel_unlock(chan); 07624 07625 return res; 07626 }
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 867 of file channel.c.
References ast_channel_setwhentohangup_tv(), and chanlist::chan.
00868 { 00869 struct timeval when = { offset, }; 00870 ast_channel_setwhentohangup_tv(chan, when); 00871 }
void ast_channel_setwhentohangup_tv | ( | struct ast_channel * | chan, | |
struct timeval | offset | |||
) |
Set when to hang a channel up.
chan | channel on which to check for hang up | |
offset | offset in seconds and useconds relative to the current time of when to hang up |
Definition at line 860 of file channel.c.
References ast_null_frame, ast_queue_frame(), ast_tvadd(), ast_tvnow(), ast_tvzero(), chanlist::chan, and ast_channel::whentohangup.
Referenced by action_timeout(), ast_channel_setwhentohangup(), handle_autohangup(), sig_pri_send_aoce_termination_request(), and timeout_write().
00861 { 00862 chan->whentohangup = ast_tvzero(offset) ? offset : ast_tvadd(offset, ast_tvnow()); 00863 ast_queue_frame(chan, &ast_null_frame); 00864 return; 00865 }
static int ast_channel_softhangup_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 818 of file channel.c.
References ast_softhangup(), AST_SOFTHANGUP_SHUTDOWN, and chanlist::chan.
Referenced by ast_begin_shutdown().
00819 { 00820 struct ast_channel *chan = obj; 00821 00822 ast_softhangup(chan, AST_SOFTHANGUP_SHUTDOWN); 00823 00824 return 0; 00825 }
struct ast_silence_generator* ast_channel_start_silence_generator | ( | struct ast_channel * | chan | ) |
Starts a silence generator on the given channel.
chan | The channel to generate silence on |
Definition at line 8110 of file channel.c.
References ast_activate_generator(), ast_calloc, ast_debug, AST_FORMAT_SLINEAR, ast_free, ast_log(), ast_set_write_format(), LOG_ERROR, ast_channel::name, ast_silence_generator::old_write_format, silence_generator, state, 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(), TransferCallStep1(), waitfor_exec(), and waitforring_exec().
08111 { 08112 struct ast_silence_generator *state; 08113 08114 if (!(state = ast_calloc(1, sizeof(*state)))) { 08115 return NULL; 08116 } 08117 08118 state->old_write_format = chan->writeformat; 08119 08120 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) { 08121 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n"); 08122 ast_free(state); 08123 return NULL; 08124 } 08125 08126 ast_activate_generator(chan, &silence_generator, state); 08127 08128 ast_debug(1, "Started silence generator on '%s'\n", chan->name); 08129 08130 return state; 08131 }
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 8133 of file channel.c.
References ast_deactivate_generator(), ast_debug, ast_free, ast_log(), ast_set_write_format(), LOG_ERROR, ast_channel::name, and state.
Referenced by ast_bridge_call(), ast_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), HandleCallOutgoing(), key_dial_page(), unistim_hangup(), waitfor_exec(), and waitforring_exec().
08134 { 08135 if (!state) 08136 return; 08137 08138 ast_deactivate_generator(chan); 08139 08140 ast_debug(1, "Stopped silence generator on '%s'\n", chan->name); 08141 08142 if (ast_set_write_format(chan, state->old_write_format) < 0) 08143 ast_log(LOG_ERROR, "Could not return write format to its original state\n"); 08144 08145 ast_free(state); 08146 }
int ast_channel_supports_html | ( | struct ast_channel * | channel | ) |
Checks for HTML support on a channel.
Definition at line 5786 of file channel.c.
References chanlist::chan, ast_channel_tech::send_html, and ast_channel::tech.
Referenced by dial_exec_full(), and sendurl_exec().
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 6068 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_id, xfer_masquerade_ds::transferee_id, and xfer_ds_info.
Referenced by analog_attempt_transfer(), misdn_attempt_transfer(), and sig_pri_attempt_transfer().
06075 { 06076 struct ast_datastore *xfer_ds; 06077 struct xfer_masquerade_ds *xfer_colp; 06078 int res; 06079 06080 xfer_ds = ast_datastore_alloc(&xfer_ds_info, NULL); 06081 if (!xfer_ds) { 06082 return -1; 06083 } 06084 06085 xfer_colp = ast_calloc(1, sizeof(*xfer_colp)); 06086 if (!xfer_colp) { 06087 ast_datastore_free(xfer_ds); 06088 return -1; 06089 } 06090 party_connected_line_copy_transfer(&xfer_colp->target_id, target_id); 06091 xfer_colp->target_held = target_held; 06092 party_connected_line_copy_transfer(&xfer_colp->transferee_id, transferee_id); 06093 xfer_colp->transferee_held = transferee_held; 06094 xfer_ds->data = xfer_colp; 06095 06096 res = __ast_channel_masquerade(target_chan, transferee_chan, xfer_ds); 06097 if (res) { 06098 ast_datastore_free(xfer_ds); 06099 } 06100 return res; 06101 }
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 1600 of file channel.c.
References ast_clear_flag, AST_FLAG_DEFER_DTMF, and chanlist::chan.
Referenced by find_cache().
01601 { 01602 if (chan) 01603 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF); 01604 }
void ast_channel_unregister | ( | const struct ast_channel_tech * | tech | ) |
Unregister a channel technology.
tech | Structure defining channel technology or "type" that was previously registered |
Definition at line 927 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::chan, chanlist::list, ast_channel::tech, chanlist::tech, and ast_channel_tech::type.
Referenced by __unload_module(), load_module(), and unload_module().
00928 { 00929 struct chanlist *chan; 00930 00931 ast_debug(1, "Unregistering channel type '%s'\n", tech->type); 00932 00933 AST_RWLIST_WRLOCK(&backends); 00934 00935 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) { 00936 if (chan->tech == tech) { 00937 AST_LIST_REMOVE_CURRENT(list); 00938 ast_free(chan); 00939 ast_verb(2, "Unregistered channel type '%s'\n", tech->type); 00940 break; 00941 } 00942 } 00943 AST_LIST_TRAVERSE_SAFE_END; 00944 00945 AST_RWLIST_UNLOCK(&backends); 00946 }
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 8863 of file channel.c.
References ast_connected_line_build_data(), AST_CONTROL_CONNECTED_LINE, ast_indicate_data(), connected, and update().
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().
08864 { 08865 unsigned char data[1024]; /* This should be large enough */ 08866 size_t datalen; 08867 08868 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update); 08869 if (datalen == (size_t) -1) { 08870 return; 08871 } 08872 08873 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen); 08874 }
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 9370 of file channel.c.
References AST_CONTROL_REDIRECTING, ast_indicate_data(), ast_redirecting_build_data(), and update().
Referenced by ast_channel_redirecting_macro(), call_forward_inherit(), do_forward(), and redirecting_write().
09371 { 09372 unsigned char data[1024]; /* This should be large enough */ 09373 size_t datalen; 09374 09375 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update); 09376 if (datalen == (size_t) -1) { 09377 return; 09378 } 09379 09380 ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen); 09381 }
void ast_channels_init | ( | void | ) |
Provided by channel.c
Definition at line 8024 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(), channel_providers, channels, cli_channel, and NUM_CHANNEL_BUCKETS.
Referenced by main().
08025 { 08026 channels = ao2_container_alloc(NUM_CHANNEL_BUCKETS, 08027 ast_channel_hash_cb, ast_channel_cmp_cb); 08028 08029 ast_cli_register_multiple(cli_channel, ARRAY_LEN(cli_channel)); 08030 08031 ast_data_register_multiple_core(channel_providers, ARRAY_LEN(channel_providers)); 08032 08033 ast_plc_reload(); 08034 }
struct ast_variable* ast_channeltype_list | ( | void | ) |
return an ast_variable list of channeltypes
Definition at line 252 of file channel.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_variable_new(), ast_channel_tech::description, chanlist::list, chanlist::tech, ast_channel_tech::type, and var.
Referenced by ast_var_channel_types(), and ast_var_channel_types_table().
00253 { 00254 struct chanlist *cl; 00255 struct ast_variable *var = NULL, *prev = NULL; 00256 00257 AST_RWLIST_RDLOCK(&backends); 00258 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00259 if (prev) { 00260 if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description, ""))) 00261 prev = prev->next; 00262 } else { 00263 var = ast_variable_new(cl->tech->type, cl->tech->description, ""); 00264 prev = var; 00265 } 00266 } 00267 AST_RWLIST_UNLOCK(&backends); 00268 00269 return var; 00270 }
int ast_check_hangup | ( | struct ast_channel * | chan | ) |
Check to see if a channel is needing hang up.
chan | channel on which to check for hang up This function determines if the channel is being requested to be hung up. |
Definition at line 796 of file channel.c.
References ast_channel::_softhangup, ast_debug, AST_SOFTHANGUP_TIMEOUT, ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), chanlist::chan, 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(), launch_asyncagi(), local_fixup(), lua_check_hangup(), ospfinished_exec(), pbx_builtin_incomplete(), pbx_builtin_waitexten(), pbx_exec(), read_exec(), readexten_exec(), remote_bridge_loop(), run_agi(), and run_ras().
00797 { 00798 if (chan->_softhangup) /* yes if soft hangup flag set */ 00799 return 1; 00800 if (ast_tvzero(chan->whentohangup)) /* no if no hangup scheduled */ 00801 return 0; 00802 if (ast_tvdiff_ms(chan->whentohangup, ast_tvnow()) > 0) /* no if hangup time has not come yet. */ 00803 return 0; 00804 ast_debug(4, "Hangup time has come: %" PRIi64 "\n", ast_tvdiff_ms(chan->whentohangup, ast_tvnow())); 00805 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */ 00806 return 1; 00807 }
int ast_check_hangup_locked | ( | struct ast_channel * | chan | ) |
Definition at line 809 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), and chanlist::chan.
Referenced by action_redirect(), and ast_channel_bridge().
00810 { 00811 int res; 00812 ast_channel_lock(chan); 00813 res = ast_check_hangup(chan); 00814 ast_channel_unlock(chan); 00815 return res; 00816 }
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 8603 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(), connected, LOG_WARNING, ast_party_id_ies::name, party_id_build_data(), ast_party_name_ies::str, update(), and value.
Referenced by ast_channel_queue_connected_line_update(), ast_channel_update_connected_line(), local_attended_transfer(), local_indicate(), and masquerade_colp_transfer().
08604 { 08605 int32_t value; 08606 size_t pos = 0; 08607 int res; 08608 08609 static const struct ast_party_id_ies ies = { 08610 .name.str = AST_CONNECTED_LINE_NAME, 08611 .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET, 08612 .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION, 08613 .name.valid = AST_CONNECTED_LINE_NAME_VALID, 08614 08615 .number.str = AST_CONNECTED_LINE_NUMBER, 08616 .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN, 08617 .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION, 08618 .number.valid = AST_CONNECTED_LINE_NUMBER_VALID, 08619 08620 .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS, 08621 .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE, 08622 .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, 08623 .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID, 08624 08625 .tag = AST_CONNECTED_LINE_TAG, 08626 .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION, 08627 }; 08628 08629 /* 08630 * The size of integer values must be fixed in case the frame is 08631 * shipped to another machine. 08632 */ 08633 08634 /* Connected line frame version */ 08635 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08636 ast_log(LOG_WARNING, "No space left for connected line frame version\n"); 08637 return -1; 08638 } 08639 data[pos++] = AST_CONNECTED_LINE_VERSION; 08640 data[pos++] = 1; 08641 data[pos++] = 2;/* Version 1 did not have a version ie */ 08642 08643 res = party_id_build_data(data + pos, datalen - pos, &connected->id, 08644 "connected line", &ies, update ? &update->id : NULL); 08645 if (res < 0) { 08646 return -1; 08647 } 08648 pos += res; 08649 08650 /* Connected line source */ 08651 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 08652 ast_log(LOG_WARNING, "No space left for connected line source\n"); 08653 return -1; 08654 } 08655 data[pos++] = AST_CONNECTED_LINE_SOURCE; 08656 data[pos++] = sizeof(value); 08657 value = htonl(connected->source); 08658 memcpy(data + pos, &value, sizeof(value)); 08659 pos += sizeof(value); 08660 08661 return pos; 08662 }
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 8221 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().
08222 { 08223 ast_party_id_copy(&dest->id, &src->id); 08224 ast_party_id_copy(&dest->ani, &src->ani); 08225 dest->ani2 = src->ani2; 08226 }
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 8228 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().
08229 { 08230 ast_party_id_copy(&dest->id, &src->id); 08231 ast_party_id_copy(&dest->ani, &src->ani); 08232 08233 dest->ani2 = src->ani2; 08234 }
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 8664 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_free, ast_log(), ast_malloc, AST_PARTY_CHAR_SET_ISO8859_1, ast_party_id_ies::combined_presentation, connected, LOG_DEBUG, LOG_WARNING, and value.
Referenced by __ast_read(), ast_channel_connected_line_macro(), ast_indicate_data(), feature_request_and_dial(), socket_process(), and wait_for_winner().
08665 { 08666 size_t pos; 08667 unsigned char ie_len; 08668 unsigned char ie_id; 08669 int32_t value; 08670 int frame_version = 1; 08671 int combined_presentation = 0; 08672 int got_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 08673 08674 for (pos = 0; pos < datalen; pos += ie_len) { 08675 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) { 08676 ast_log(LOG_WARNING, "Invalid connected line update\n"); 08677 return -1; 08678 } 08679 ie_id = data[pos++]; 08680 ie_len = data[pos++]; 08681 if (datalen < pos + ie_len) { 08682 ast_log(LOG_WARNING, "Invalid connected line update\n"); 08683 return -1; 08684 } 08685 08686 switch (ie_id) { 08687 /* Connected line party frame version */ 08688 case AST_CONNECTED_LINE_VERSION: 08689 if (ie_len != 1) { 08690 ast_log(LOG_WARNING, "Invalid connected line frame version (%u)\n", 08691 (unsigned) ie_len); 08692 break; 08693 } 08694 frame_version = data[pos]; 08695 break; 08696 /* Connected line party id name */ 08697 case AST_CONNECTED_LINE_NAME: 08698 ast_free(connected->id.name.str); 08699 connected->id.name.str = ast_malloc(ie_len + 1); 08700 if (connected->id.name.str) { 08701 memcpy(connected->id.name.str, data + pos, ie_len); 08702 connected->id.name.str[ie_len] = 0; 08703 } 08704 break; 08705 case AST_CONNECTED_LINE_NAME_CHAR_SET: 08706 if (ie_len != 1) { 08707 ast_log(LOG_WARNING, "Invalid connected line name char set (%u)\n", 08708 (unsigned) ie_len); 08709 break; 08710 } 08711 connected->id.name.char_set = data[pos]; 08712 break; 08713 case AST_CONNECTED_LINE_NAME_PRESENTATION: 08714 if (ie_len != 1) { 08715 ast_log(LOG_WARNING, "Invalid connected line name presentation (%u)\n", 08716 (unsigned) ie_len); 08717 break; 08718 } 08719 connected->id.name.presentation = data[pos]; 08720 break; 08721 case AST_CONNECTED_LINE_NAME_VALID: 08722 if (ie_len != 1) { 08723 ast_log(LOG_WARNING, "Invalid connected line name valid (%u)\n", 08724 (unsigned) ie_len); 08725 break; 08726 } 08727 connected->id.name.valid = data[pos]; 08728 break; 08729 /* Connected line party id number */ 08730 case AST_CONNECTED_LINE_NUMBER: 08731 ast_free(connected->id.number.str); 08732 connected->id.number.str = ast_malloc(ie_len + 1); 08733 if (connected->id.number.str) { 08734 memcpy(connected->id.number.str, data + pos, ie_len); 08735 connected->id.number.str[ie_len] = 0; 08736 } 08737 break; 08738 case AST_CONNECTED_LINE_NUMBER_PLAN: 08739 if (ie_len != 1) { 08740 ast_log(LOG_WARNING, "Invalid connected line numbering plan (%u)\n", 08741 (unsigned) ie_len); 08742 break; 08743 } 08744 connected->id.number.plan = data[pos]; 08745 break; 08746 case AST_CONNECTED_LINE_NUMBER_PRESENTATION: 08747 if (ie_len != 1) { 08748 ast_log(LOG_WARNING, "Invalid connected line number presentation (%u)\n", 08749 (unsigned) ie_len); 08750 break; 08751 } 08752 connected->id.number.presentation = data[pos]; 08753 break; 08754 case AST_CONNECTED_LINE_NUMBER_VALID: 08755 if (ie_len != 1) { 08756 ast_log(LOG_WARNING, "Invalid connected line number valid (%u)\n", 08757 (unsigned) ie_len); 08758 break; 08759 } 08760 connected->id.number.valid = data[pos]; 08761 break; 08762 /* Connected line party id combined presentation */ 08763 case AST_CONNECTED_LINE_ID_PRESENTATION: 08764 if (ie_len != 1) { 08765 ast_log(LOG_WARNING, "Invalid connected line combined presentation (%u)\n", 08766 (unsigned) ie_len); 08767 break; 08768 } 08769 combined_presentation = data[pos]; 08770 got_combined_presentation = 1; 08771 break; 08772 /* Connected line party id subaddress */ 08773 case AST_CONNECTED_LINE_SUBADDRESS: 08774 ast_free(connected->id.subaddress.str); 08775 connected->id.subaddress.str = ast_malloc(ie_len + 1); 08776 if (connected->id.subaddress.str) { 08777 memcpy(connected->id.subaddress.str, data + pos, ie_len); 08778 connected->id.subaddress.str[ie_len] = 0; 08779 } 08780 break; 08781 case AST_CONNECTED_LINE_SUBADDRESS_TYPE: 08782 if (ie_len != 1) { 08783 ast_log(LOG_WARNING, "Invalid connected line type of subaddress (%u)\n", 08784 (unsigned) ie_len); 08785 break; 08786 } 08787 connected->id.subaddress.type = data[pos]; 08788 break; 08789 case AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN: 08790 if (ie_len != 1) { 08791 ast_log(LOG_WARNING, 08792 "Invalid connected line subaddress odd-even indicator (%u)\n", 08793 (unsigned) ie_len); 08794 break; 08795 } 08796 connected->id.subaddress.odd_even_indicator = data[pos]; 08797 break; 08798 case AST_CONNECTED_LINE_SUBADDRESS_VALID: 08799 if (ie_len != 1) { 08800 ast_log(LOG_WARNING, "Invalid connected line subaddress valid (%u)\n", 08801 (unsigned) ie_len); 08802 break; 08803 } 08804 connected->id.subaddress.valid = data[pos]; 08805 break; 08806 /* Connected line party tag */ 08807 case AST_CONNECTED_LINE_TAG: 08808 ast_free(connected->id.tag); 08809 connected->id.tag = ast_malloc(ie_len + 1); 08810 if (connected->id.tag) { 08811 memcpy(connected->id.tag, data + pos, ie_len); 08812 connected->id.tag[ie_len] = 0; 08813 } 08814 break; 08815 /* Connected line party source */ 08816 case AST_CONNECTED_LINE_SOURCE: 08817 if (ie_len != sizeof(value)) { 08818 ast_log(LOG_WARNING, "Invalid connected line source (%u)\n", 08819 (unsigned) ie_len); 08820 break; 08821 } 08822 memcpy(&value, data + pos, sizeof(value)); 08823 connected->source = ntohl(value); 08824 break; 08825 /* Connected line party unknown element */ 08826 default: 08827 ast_log(LOG_DEBUG, "Unknown connected line element: %u (%u)\n", 08828 (unsigned) ie_id, (unsigned) ie_len); 08829 break; 08830 } 08831 } 08832 08833 switch (frame_version) { 08834 case 1: 08835 /* 08836 * The other end is an earlier version that we need to adjust 08837 * for compatibility. 08838 */ 08839 connected->id.name.valid = 1; 08840 connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 08841 connected->id.number.valid = 1; 08842 if (got_combined_presentation) { 08843 connected->id.name.presentation = combined_presentation; 08844 connected->id.number.presentation = combined_presentation; 08845 } 08846 break; 08847 case 2: 08848 /* The other end is at the same level as we are. */ 08849 break; 08850 default: 08851 /* 08852 * The other end is newer than we are. 08853 * We need to assume that they are compatible with us. 08854 */ 08855 ast_log(LOG_DEBUG, "Connected line frame has newer version: %u\n", 08856 (unsigned) frame_version); 08857 break; 08858 } 08859 08860 return 0; 08861 }
AST_DATA_STRUCTURE | ( | ast_channel | , | |
DATA_EXPORT_CHANNEL | ||||
) |
void ast_deactivate_generator | ( | struct ast_channel * | chan | ) |
Deactivate an active generator
Definition at line 3055 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(), chanlist::chan, 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().
03056 { 03057 ast_channel_lock(chan); 03058 if (chan->generatordata) { 03059 if (chan->generator && chan->generator->release) 03060 chan->generator->release(chan, chan->generatordata); 03061 chan->generatordata = NULL; 03062 chan->generator = NULL; 03063 ast_channel_set_fd(chan, AST_GENERATOR_FD, -1); 03064 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 03065 ast_settimeout(chan, 0, NULL, NULL); 03066 } 03067 ast_channel_unlock(chan); 03068 }
int ast_do_masquerade | ( | struct ast_channel * | original | ) |
Start masquerading a channel.
< TRUE if the clonechan was a zombie before the masquerade.
Definition at line 6429 of file channel.c.
References __ast_change_name_nolink(), ast_channel::_bridge, ast_channel::_softhangup, ast_channel::_state, accountcode, 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_datastore_find(), ast_channel_datastore_remove(), ast_channel_lock, ast_channel_lock_both, AST_CHANNEL_NAME, ast_channel_ref, ast_channel_set_fd(), ast_channel_set_linkgroup(), ast_channel_unlock, ast_channel_unref, 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_GENERATOR_FD, ast_getformatname(), ast_indicate(), ast_kill_tech, AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_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_string_field_set, ast_test_flag, AST_TIMING_FD, ast_channel::blocker, ast_channel::caller, ast_channel::cdr, ast_datastore_info::chan_fixup, channels, clone_variables(), ast_channel::connected, chanlist::connected, ast_datastore::data, ast_channel::datastores, ast_channel::dialed, ast_datastore::entry, errno, EVENT_FLAG_CALL, ast_channel::fdno, ast_channel::fds, ast_channel_tech::fixup, free_translation(), ast_datastore::info, ast_channel::language, language, LOG_WARNING, ast_channel::masq, ast_channel::masqr, masquerade_colp_transfer(), ast_channel::monitor, musicclass, ast_channel::name, ast_channel::nativeformats, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::readq, ast_channel::redirecting, report_new_callerid(), S_OR, ast_channel::tech, ast_channel::tech_pvt, ast_channel::timingfd, xfer_masquerade_ds::transferee_held, ast_channel_tech::type, ast_channel::visible_indication, ast_channel::writeformat, and xfer_ds_info.
Referenced by __ast_read(), ast_async_goto(), ast_do_pickup(), ast_hangup(), ast_waitfor_nandfds(), ast_write(), builtin_atxfer(), check_bridge(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), local_attended_transfer(), masq_park_call(), and sip_park().
06430 { 06431 int x; 06432 int i; 06433 int origstate; 06434 int visible_indication; 06435 int clone_was_zombie = 0;/*!< TRUE if the clonechan was a zombie before the masquerade. */ 06436 struct ast_frame *current; 06437 const struct ast_channel_tech *t; 06438 void *t_pvt; 06439 union { 06440 struct ast_party_dialed dialed; 06441 struct ast_party_caller caller; 06442 struct ast_party_connected_line connected; 06443 struct ast_party_redirecting redirecting; 06444 } exchange; 06445 struct ast_channel *clonechan, *chans[2]; 06446 struct ast_channel *bridged; 06447 struct ast_cdr *cdr; 06448 struct ast_datastore *xfer_ds; 06449 struct xfer_masquerade_ds *xfer_colp; 06450 format_t rformat; 06451 format_t wformat; 06452 format_t tmp_format; 06453 char newn[AST_CHANNEL_NAME]; 06454 char orig[AST_CHANNEL_NAME]; 06455 char masqn[AST_CHANNEL_NAME]; 06456 char zombn[AST_CHANNEL_NAME]; 06457 06458 /* XXX This operation is a bit odd. We're essentially putting the guts of 06459 * the clone channel into the original channel. Start by killing off the 06460 * original channel's backend. While the features are nice, which is the 06461 * reason we're keeping it, it's still awesomely weird. XXX */ 06462 06463 /* 06464 * The reasoning for the channels ao2_container lock here is 06465 * complex. 06466 * 06467 * There is a race condition that exists for this function. 06468 * Since all pvt and channel locks must be let go before calling 06469 * ast_do_masquerade, it is possible that it could be called 06470 * multiple times for the same channel. In order to prevent the 06471 * race condition with competing threads to do the masquerade 06472 * and new masquerade attempts, the channels container must be 06473 * locked for the entire masquerade. The original and clonechan 06474 * need to be unlocked earlier to avoid potential deadlocks with 06475 * the chan_local deadlock avoidance method. 06476 * 06477 * The container lock blocks competing masquerade attempts from 06478 * starting as well as being necessary for proper locking order 06479 * because the channels must to be unlinked to change their 06480 * names. 06481 * 06482 * The original and clonechan locks must be held while the 06483 * channel contents are shuffled around for the masquerade. 06484 * 06485 * The masq and masqr pointers need to be left alone until the 06486 * masquerade has restabilized the channels to prevent another 06487 * masquerade request until the AST_FLAG_ZOMBIE can be set on 06488 * the clonechan. 06489 */ 06490 ao2_lock(channels); 06491 06492 /* 06493 * Lock the original channel to determine if the masquerade is 06494 * still required. 06495 */ 06496 ast_channel_lock(original); 06497 06498 clonechan = original->masq; 06499 if (!clonechan) { 06500 /* 06501 * The masq is already completed by another thread or never 06502 * needed to be done to begin with. 06503 */ 06504 ast_channel_unlock(original); 06505 ao2_unlock(channels); 06506 return 0; 06507 } 06508 06509 /* Bump the refs to ensure that they won't dissapear on us. */ 06510 ast_channel_ref(original); 06511 ast_channel_ref(clonechan); 06512 06513 /* unlink from channels container as name (which is the hash value) will change */ 06514 ao2_unlink(channels, original); 06515 ao2_unlink(channels, clonechan); 06516 06517 /* Get any transfer masquerade connected line exchange data. */ 06518 xfer_ds = ast_channel_datastore_find(original, &xfer_ds_info, NULL); 06519 if (xfer_ds) { 06520 ast_channel_datastore_remove(original, xfer_ds); 06521 xfer_colp = xfer_ds->data; 06522 } else { 06523 xfer_colp = NULL; 06524 } 06525 06526 /* 06527 * Stop any visible indication on the original channel so we can 06528 * transfer it to the clonechan taking the original's place. 06529 */ 06530 visible_indication = original->visible_indication; 06531 ast_channel_unlock(original); 06532 ast_indicate(original, -1); 06533 06534 /* 06535 * Release any hold on the transferee channel before going any 06536 * further with the masquerade. 06537 */ 06538 if (xfer_colp && xfer_colp->transferee_held) { 06539 ast_indicate(clonechan, AST_CONTROL_UNHOLD); 06540 } 06541 06542 /* Start the masquerade channel contents rearangement. */ 06543 ast_channel_lock_both(original, clonechan); 06544 06545 ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", 06546 clonechan->name, clonechan->_state, original->name, original->_state); 06547 06548 chans[0] = clonechan; 06549 chans[1] = original; 06550 ast_manager_event_multichan(EVENT_FLAG_CALL, "Masquerade", 2, chans, 06551 "Clone: %s\r\n" 06552 "CloneState: %s\r\n" 06553 "Original: %s\r\n" 06554 "OriginalState: %s\r\n", 06555 clonechan->name, ast_state2str(clonechan->_state), original->name, ast_state2str(original->_state)); 06556 06557 /* 06558 * Remember the original read/write formats. We turn off any 06559 * translation on either one 06560 */ 06561 rformat = original->readformat; 06562 wformat = original->writeformat; 06563 free_translation(clonechan); 06564 free_translation(original); 06565 06566 /* Save the original name */ 06567 ast_copy_string(orig, original->name, sizeof(orig)); 06568 /* Save the new name */ 06569 ast_copy_string(newn, clonechan->name, sizeof(newn)); 06570 /* Create the masq name */ 06571 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn); 06572 06573 /* Mangle the name of the clone channel */ 06574 __ast_change_name_nolink(clonechan, masqn); 06575 06576 /* Copy the name from the clone channel */ 06577 __ast_change_name_nolink(original, newn); 06578 06579 /* share linked id's */ 06580 ast_channel_set_linkgroup(original, clonechan); 06581 06582 /* Swap the technologies */ 06583 t = original->tech; 06584 original->tech = clonechan->tech; 06585 clonechan->tech = t; 06586 06587 t_pvt = original->tech_pvt; 06588 original->tech_pvt = clonechan->tech_pvt; 06589 clonechan->tech_pvt = t_pvt; 06590 06591 /* Swap the cdrs */ 06592 cdr = original->cdr; 06593 original->cdr = clonechan->cdr; 06594 clonechan->cdr = cdr; 06595 06596 /* Swap the alertpipes */ 06597 for (i = 0; i < 2; i++) { 06598 x = original->alertpipe[i]; 06599 original->alertpipe[i] = clonechan->alertpipe[i]; 06600 clonechan->alertpipe[i] = x; 06601 } 06602 06603 /* 06604 * Swap the readq's. The end result should be this: 06605 * 06606 * 1) All frames should be on the new (original) channel. 06607 * 2) Any frames that were already on the new channel before this 06608 * masquerade need to be at the end of the readq, after all of the 06609 * frames on the old (clone) channel. 06610 * 3) The alertpipe needs to get poked for every frame that was already 06611 * on the new channel, since we are now using the alert pipe from the 06612 * old (clone) channel. 06613 */ 06614 { 06615 AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq; 06616 06617 AST_LIST_HEAD_INIT_NOLOCK(&tmp_readq); 06618 AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list); 06619 AST_LIST_APPEND_LIST(&original->readq, &clonechan->readq, frame_list); 06620 06621 while ((current = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) { 06622 AST_LIST_INSERT_TAIL(&original->readq, current, frame_list); 06623 if (original->alertpipe[1] > -1) { 06624 int poke = 0; 06625 06626 if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) { 06627 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 06628 } 06629 } 06630 } 06631 } 06632 06633 /* Swap the raw formats */ 06634 tmp_format = original->rawreadformat; 06635 original->rawreadformat = clonechan->rawreadformat; 06636 clonechan->rawreadformat = tmp_format; 06637 06638 tmp_format = original->rawwriteformat; 06639 original->rawwriteformat = clonechan->rawwriteformat; 06640 clonechan->rawwriteformat = tmp_format; 06641 06642 clonechan->_softhangup = AST_SOFTHANGUP_DEV; 06643 06644 /* And of course, so does our current state. Note we need not 06645 call ast_setstate since the event manager doesn't really consider 06646 these separate. We do this early so that the clone has the proper 06647 state of the original channel. */ 06648 origstate = original->_state; 06649 original->_state = clonechan->_state; 06650 clonechan->_state = origstate; 06651 06652 /* Mangle the name of the clone channel */ 06653 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); /* quick, hide the brains! */ 06654 __ast_change_name_nolink(clonechan, zombn); 06655 06656 /* Update the type. */ 06657 t_pvt = original->monitor; 06658 original->monitor = clonechan->monitor; 06659 clonechan->monitor = t_pvt; 06660 06661 /* Keep the same language. */ 06662 ast_string_field_set(original, language, clonechan->language); 06663 /* Copy the FD's other than the generator fd */ 06664 for (x = 0; x < AST_MAX_FDS; x++) { 06665 if (x != AST_GENERATOR_FD) 06666 ast_channel_set_fd(original, x, clonechan->fds[x]); 06667 } 06668 06669 ast_app_group_update(clonechan, original); 06670 06671 /* Move data stores over */ 06672 if (AST_LIST_FIRST(&clonechan->datastores)) { 06673 struct ast_datastore *ds; 06674 /* We use a safe traversal here because some fixup routines actually 06675 * remove the datastore from the list and free them. 06676 */ 06677 AST_LIST_TRAVERSE_SAFE_BEGIN(&clonechan->datastores, ds, entry) { 06678 if (ds->info->chan_fixup) 06679 ds->info->chan_fixup(ds->data, clonechan, original); 06680 } 06681 AST_LIST_TRAVERSE_SAFE_END; 06682 AST_LIST_APPEND_LIST(&original->datastores, &clonechan->datastores, entry); 06683 } 06684 06685 ast_autochan_new_channel(clonechan, original); 06686 06687 clone_variables(original, clonechan); 06688 /* Presense of ADSI capable CPE follows clone */ 06689 original->adsicpe = clonechan->adsicpe; 06690 /* Bridge remains the same */ 06691 /* CDR fields remain the same */ 06692 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 06693 /* Application and data remain the same */ 06694 /* Clone exception becomes real one, as with fdno */ 06695 ast_set_flag(original, ast_test_flag(clonechan, AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING)); 06696 original->fdno = clonechan->fdno; 06697 /* Schedule context remains the same */ 06698 /* Stream stuff stays the same */ 06699 /* Keep the original state. The fixup code will need to work with it most likely */ 06700 06701 /* 06702 * Just swap the whole structures, nevermind the allocations, 06703 * they'll work themselves out. 06704 */ 06705 exchange.dialed = original->dialed; 06706 original->dialed = clonechan->dialed; 06707 clonechan->dialed = exchange.dialed; 06708 06709 exchange.caller = original->caller; 06710 original->caller = clonechan->caller; 06711 clonechan->caller = exchange.caller; 06712 06713 exchange.connected = original->connected; 06714 original->connected = clonechan->connected; 06715 clonechan->connected = exchange.connected; 06716 06717 exchange.redirecting = original->redirecting; 06718 original->redirecting = clonechan->redirecting; 06719 clonechan->redirecting = exchange.redirecting; 06720 06721 report_new_callerid(original); 06722 06723 /* Restore original timing file descriptor */ 06724 ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd); 06725 06726 /* Our native formats are different now */ 06727 original->nativeformats = clonechan->nativeformats; 06728 06729 /* Context, extension, priority, app data, jump table, remain the same */ 06730 /* pvt switches. pbx stays the same, as does next */ 06731 06732 /* Set the write format */ 06733 ast_set_write_format(original, wformat); 06734 06735 /* Set the read format */ 06736 ast_set_read_format(original, rformat); 06737 06738 /* Copy the music class */ 06739 ast_string_field_set(original, musicclass, clonechan->musicclass); 06740 06741 /* copy over accuntcode and set peeraccount across the bridge */ 06742 ast_string_field_set(original, accountcode, S_OR(clonechan->accountcode, "")); 06743 if (original->_bridge) { 06744 /* XXX - should we try to lock original->_bridge here? */ 06745 ast_string_field_set(original->_bridge, peeraccount, S_OR(clonechan->accountcode, "")); 06746 ast_cel_report_event(original, AST_CEL_BRIDGE_UPDATE, NULL, NULL, NULL); 06747 } 06748 06749 ast_debug(1, "Putting channel %s in %s/%s formats\n", original->name, 06750 ast_getformatname(wformat), ast_getformatname(rformat)); 06751 06752 /* Fixup the original clonechan's physical side */ 06753 if (original->tech->fixup && original->tech->fixup(clonechan, original)) { 06754 ast_log(LOG_WARNING, "Channel type '%s' could not fixup channel %s, strange things may happen. (clonechan)\n", 06755 original->tech->type, original->name); 06756 } 06757 06758 /* Fixup the original original's physical side */ 06759 if (clonechan->tech->fixup && clonechan->tech->fixup(original, clonechan)) { 06760 ast_log(LOG_WARNING, "Channel type '%s' could not fixup channel %s, strange things may happen. (original)\n", 06761 clonechan->tech->type, clonechan->name); 06762 } 06763 06764 /* 06765 * Now, at this point, the "clone" channel is totally F'd up. 06766 * We mark it as a zombie so nothing tries to touch it. If it's 06767 * already been marked as a zombie, then we must free it (since 06768 * it already is considered invalid). 06769 * 06770 * This must be done before we unlock clonechan to prevent 06771 * setting up another masquerade on the clonechan. 06772 */ 06773 if (ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) { 06774 clone_was_zombie = 1; 06775 } else { 06776 ast_set_flag(clonechan, AST_FLAG_ZOMBIE); 06777 ast_queue_frame(clonechan, &ast_null_frame); 06778 } 06779 06780 /* clear the masquerade channels */ 06781 original->masq = NULL; 06782 clonechan->masqr = NULL; 06783 06784 /* 06785 * When we unlock original here, it can be immediately setup to 06786 * masquerade again or hungup. The new masquerade or hangup 06787 * will not actually happen until we release the channels 06788 * container lock. 06789 */ 06790 ast_channel_unlock(original); 06791 06792 /* Disconnect the original original's physical side */ 06793 if (clonechan->tech->hangup && clonechan->tech->hangup(clonechan)) { 06794 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n"); 06795 } else { 06796 /* 06797 * We just hung up the original original's physical side of the 06798 * channel. Set the new zombie to use the kill channel driver 06799 * for safety. 06800 */ 06801 clonechan->tech = &ast_kill_tech; 06802 } 06803 06804 ast_channel_unlock(clonechan); 06805 06806 /* 06807 * If an indication is currently playing, maintain it on the 06808 * channel that is taking the place of original. 06809 * 06810 * This is needed because the masquerade is swapping out the 06811 * internals of the channel, and the new channel private data 06812 * needs to be made aware of the current visible indication 06813 * (RINGING, CONGESTION, etc.) 06814 */ 06815 if (visible_indication) { 06816 ast_indicate(original, visible_indication); 06817 } 06818 06819 ast_channel_lock(original); 06820 06821 /* Signal any blocker */ 06822 if (ast_test_flag(original, AST_FLAG_BLOCKING)) { 06823 pthread_kill(original->blocker, SIGURG); 06824 } 06825 06826 ast_debug(1, "Done Masquerading %s (%d)\n", original->name, original->_state); 06827 06828 if ((bridged = ast_bridged_channel(original))) { 06829 ast_channel_ref(bridged); 06830 ast_channel_unlock(original); 06831 ast_indicate(bridged, AST_CONTROL_SRCCHANGE); 06832 ast_channel_unref(bridged); 06833 } else { 06834 ast_channel_unlock(original); 06835 } 06836 ast_indicate(original, AST_CONTROL_SRCCHANGE); 06837 06838 if (xfer_colp) { 06839 /* 06840 * After the masquerade, the original channel pointer actually 06841 * points to the new transferee channel and the bridged channel 06842 * is still the intended transfer target party. 06843 */ 06844 masquerade_colp_transfer(original, xfer_colp); 06845 } 06846 06847 if (xfer_ds) { 06848 ast_datastore_free(xfer_ds); 06849 } 06850 06851 if (clone_was_zombie) { 06852 ast_channel_lock(clonechan); 06853 ast_debug(1, "Destroying channel clone '%s'\n", clonechan->name); 06854 ast_manager_event(clonechan, EVENT_FLAG_CALL, "Hangup", 06855 "Channel: %s\r\n" 06856 "Uniqueid: %s\r\n" 06857 "Cause: %d\r\n" 06858 "Cause-txt: %s\r\n", 06859 clonechan->name, 06860 clonechan->uniqueid, 06861 clonechan->hangupcause, 06862 ast_cause2str(clonechan->hangupcause) 06863 ); 06864 ast_channel_unlock(clonechan); 06865 06866 /* 06867 * Drop the system reference to destroy the channel since it is 06868 * already unlinked. 06869 */ 06870 ast_channel_unref(clonechan); 06871 } else { 06872 ao2_link(channels, clonechan); 06873 } 06874 06875 ao2_link(channels, original); 06876 ao2_unlock(channels); 06877 06878 /* Release our held safety references. */ 06879 ast_channel_unref(original); 06880 ast_channel_unref(clonechan); 06881 06882 return 0; 06883 }
struct ast_channel* ast_dummy_channel_alloc | ( | void | ) |
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 1380 of file channel.c.
References __ao2_alloc_debug(), ao2_alloc, ast_channel_unref, ast_dummy_channel_destructor(), AST_LIST_HEAD_INIT_NOLOCK, and ast_string_field_init.
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(), custom_log(), make_email_file(), manager_log(), pbx_substitute_variables_helper_full(), rotate_file(), sendmail(), sendpage(), syslog_log(), and write_cdr().
01382 { 01383 struct ast_channel *tmp; 01384 struct varshead *headp; 01385 01386 #if defined(REF_DEBUG) 01387 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel", 01388 file, line, function, 1); 01389 #elif defined(__AST_DEBUG_MALLOC) 01390 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel", 01391 file, line, function, 0); 01392 #else 01393 tmp = ao2_alloc(sizeof(*tmp), ast_dummy_channel_destructor); 01394 #endif 01395 if (!tmp) { 01396 /* Dummy channel structure allocation failure. */ 01397 return NULL; 01398 } 01399 01400 if ((ast_string_field_init(tmp, 128))) { 01401 return ast_channel_unref(tmp); 01402 } 01403 01404 headp = &tmp->varshead; 01405 AST_LIST_HEAD_INIT_NOLOCK(headp); 01406 01407 return tmp; 01408 }
static void ast_dummy_channel_destructor | ( | void * | obj | ) | [static] |
Free a dummy channel structure.
Definition at line 2497 of file channel.c.
References ast_cdr_discard(), ast_datastore_free(), 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, chanlist::chan, ast_channel::connected, ast_channel::datastores, ast_channel::dialed, ast_datastore::entry, ast_channel::redirecting, and ast_channel::varshead.
Referenced by ast_dummy_channel_alloc().
02498 { 02499 struct ast_channel *chan = obj; 02500 struct ast_var_t *vardata; 02501 struct varshead *headp; 02502 struct ast_datastore *datastore; 02503 02504 /* Get rid of each of the data stores on the channel */ 02505 while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry))) { 02506 /* Free the data store */ 02507 ast_datastore_free(datastore); 02508 } 02509 02510 headp = &chan->varshead; 02511 02512 ast_party_dialed_free(&chan->dialed); 02513 ast_party_caller_free(&chan->caller); 02514 ast_party_connected_line_free(&chan->connected); 02515 ast_party_redirecting_free(&chan->redirecting); 02516 02517 /* loop over the variables list, freeing all data and deleting list items */ 02518 /* no need to lock the list, as the channel is already locked */ 02519 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) 02520 ast_var_delete(vardata); 02521 02522 if (chan->cdr) { 02523 ast_cdr_discard(chan->cdr); 02524 chan->cdr = NULL; 02525 } 02526 02527 ast_string_field_free_memory(chan); 02528 }
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 7037 of file channel.c.
References AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_RETRY, ast_clear_flag, AST_FEATURE_WARNING_ACTIVE, ast_jb_do_usecheck(), ast_jb_empty_and_reset(), ast_poll_channel_add(), ast_samp2tv(), ast_set_flag, ast_test_flag, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), config, f, ast_channel::nativeformats, and ast_channel::tech_pvt.
Referenced by ast_channel_bridge().
07040 { 07041 /* Copy voice back and forth between the two channels. */ 07042 struct ast_channel *cs[3]; 07043 struct ast_frame *f; 07044 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 07045 format_t o0nativeformats; 07046 format_t o1nativeformats; 07047 int watch_c0_dtmf; 07048 int watch_c1_dtmf; 07049 void *pvt0, *pvt1; 07050 /* Indicates whether a frame was queued into a jitterbuffer */ 07051 int frame_put_in_jb = 0; 07052 int jb_in_use; 07053 int to; 07054 07055 cs[0] = c0; 07056 cs[1] = c1; 07057 pvt0 = c0->tech_pvt; 07058 pvt1 = c1->tech_pvt; 07059 o0nativeformats = c0->nativeformats; 07060 o1nativeformats = c1->nativeformats; 07061 watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0; 07062 watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1; 07063 07064 /* Check the need of a jitterbuffer for each channel */ 07065 jb_in_use = ast_jb_do_usecheck(c0, c1); 07066 if (jb_in_use) 07067 ast_jb_empty_and_reset(c0, c1); 07068 07069 ast_poll_channel_add(c0, c1); 07070 07071 if (config->feature_timer > 0 && ast_tvzero(config->nexteventts)) { 07072 /* nexteventts is not set when the bridge is not scheduled to 07073 * break, so calculate when the bridge should possibly break 07074 * if a partial feature match timed out */ 07075 config->nexteventts = ast_tvadd(ast_tvnow(), ast_samp2tv(config->feature_timer, 1000)); 07076 } 07077 07078 for (;;) { 07079 struct ast_channel *who, *other; 07080 07081 if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) || 07082 (o0nativeformats != c0->nativeformats) || 07083 (o1nativeformats != c1->nativeformats)) { 07084 /* Check for Masquerade, codec changes, etc */ 07085 res = AST_BRIDGE_RETRY; 07086 break; 07087 } 07088 if (config->nexteventts.tv_sec) { 07089 to = ast_tvdiff_ms(config->nexteventts, ast_tvnow()); 07090 if (to <= 0) { 07091 if (config->timelimit && !config->feature_timer && !ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) { 07092 res = AST_BRIDGE_RETRY; 07093 /* generic bridge ending to play warning */ 07094 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE); 07095 } else if (config->feature_timer) { 07096 /* feature timer expired - make sure we do not play warning */ 07097 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE); 07098 res = AST_BRIDGE_RETRY; 07099 } else { 07100 res = AST_BRIDGE_COMPLETE; 07101 } 07102 break; 07103 } 07104 } else { 07105 /* If a feature has been started and the bridge is configured to 07106 * to not break, leave the channel bridge when the feature timer 07107 * time has elapsed so the DTMF will be sent to the other side. 07108 */ 07109 if (!ast_tvzero(config->nexteventts)) { 07110 int diff = ast_tvdiff_ms(config->nexteventts, ast_tvnow()); 07111 if (diff <= 0) { 07112 res = AST_BRIDGE_RETRY; 07113 break; 07114 } 07115 } 07116 to = -1; 07117 } 07118 /* Calculate the appropriate max sleep interval - in general, this is the time, 07119 left to the closest jb delivery moment */ 07120 if (jb_in_use) 07121 to = ast_jb_get_when_to_wakeup(c0, c1, to); 07122 who = ast_waitfor_n(cs, 2, &to); 07123 if (!who) { 07124 /* No frame received within the specified timeout - check if we have to deliver now */ 07125 if (jb_in_use) 07126 ast_jb_get_and_deliver(c0, c1); 07127 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 07128 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07129 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE); 07130 } 07131 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07132 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE); 07133 } 07134 c0->_bridge = c1; 07135 c1->_bridge = c0; 07136 } 07137 continue; 07138 } 07139 f = ast_read(who); 07140 if (!f) { 07141 *fo = NULL; 07142 *rc = who; 07143 ast_debug(1, "Didn't get a frame from channel: %s\n",who->name); 07144 break; 07145 } 07146 07147 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 07148 /* Try add the frame info the who's bridged channel jitterbuff */ 07149 if (jb_in_use) 07150 frame_put_in_jb = !ast_jb_put(other, f); 07151 07152 if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) { 07153 int bridge_exit = 0; 07154 07155 switch (f->subclass.integer) { 07156 case AST_CONTROL_AOC: 07157 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen); 07158 break; 07159 case AST_CONTROL_REDIRECTING: 07160 if (ast_channel_redirecting_macro(who, other, f, other == c0, 1)) { 07161 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen); 07162 } 07163 break; 07164 case AST_CONTROL_CONNECTED_LINE: 07165 if (ast_channel_connected_line_macro(who, other, f, other == c0, 1)) { 07166 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen); 07167 } 07168 break; 07169 case AST_CONTROL_HOLD: 07170 case AST_CONTROL_UNHOLD: 07171 case AST_CONTROL_VIDUPDATE: 07172 case AST_CONTROL_SRCUPDATE: 07173 case AST_CONTROL_SRCCHANGE: 07174 case AST_CONTROL_T38_PARAMETERS: 07175 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen); 07176 if (jb_in_use) { 07177 ast_jb_empty_and_reset(c0, c1); 07178 } 07179 break; 07180 default: 07181 *fo = f; 07182 *rc = who; 07183 bridge_exit = 1; 07184 ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass.integer, who->name); 07185 break; 07186 } 07187 if (bridge_exit) 07188 break; 07189 } 07190 if ((f->frametype == AST_FRAME_VOICE) || 07191 (f->frametype == AST_FRAME_DTMF_BEGIN) || 07192 (f->frametype == AST_FRAME_DTMF) || 07193 (f->frametype == AST_FRAME_VIDEO) || 07194 (f->frametype == AST_FRAME_IMAGE) || 07195 (f->frametype == AST_FRAME_HTML) || 07196 (f->frametype == AST_FRAME_MODEM) || 07197 (f->frametype == AST_FRAME_TEXT)) { 07198 /* monitored dtmf causes exit from bridge */ 07199 int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf; 07200 07201 if (monitored_source && 07202 (f->frametype == AST_FRAME_DTMF_END || 07203 f->frametype == AST_FRAME_DTMF_BEGIN)) { 07204 *fo = f; 07205 *rc = who; 07206 ast_debug(1, "Got DTMF %s on channel (%s)\n", 07207 f->frametype == AST_FRAME_DTMF_END ? "end" : "begin", 07208 who->name); 07209 07210 break; 07211 } 07212 /* Write immediately frames, not passed through jb */ 07213 if (!frame_put_in_jb) 07214 ast_write(other, f); 07215 07216 /* Check if we have to deliver now */ 07217 if (jb_in_use) 07218 ast_jb_get_and_deliver(c0, c1); 07219 } 07220 /* XXX do we want to pass on also frames not matched above ? */ 07221 ast_frfree(f); 07222 07223 #ifndef HAVE_EPOLL 07224 /* Swap who gets priority */ 07225 cs[2] = cs[0]; 07226 cs[0] = cs[1]; 07227 cs[1] = cs[2]; 07228 #endif 07229 } 07230 07231 ast_poll_channel_del(c0, c1); 07232 07233 return res; 07234 }
struct ast_channel_tech* ast_get_channel_tech | ( | const char * | name | ) |
Get a channel technology structure by name.
name | name of technology to find |
Definition at line 949 of file channel.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, chanlist::list, 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().
00950 { 00951 struct chanlist *chanls; 00952 const struct ast_channel_tech *ret = NULL; 00953 00954 AST_RWLIST_RDLOCK(&backends); 00955 00956 AST_RWLIST_TRAVERSE(&backends, chanls, list) { 00957 if (!strcasecmp(name, chanls->tech->type)) { 00958 ret = chanls->tech; 00959 break; 00960 } 00961 } 00962 00963 AST_RWLIST_UNLOCK(&backends); 00964 00965 return ret; 00966 }
ast_group_t ast_get_group | ( | const char * | s | ) |
Definition at line 7800 of file channel.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_ERROR, LOG_WARNING, and strsep().
Referenced by _parse(), build_device(), build_peer(), config_parse_variables(), func_channel_write_real(), and read_agent_config().
07801 { 07802 char *piece; 07803 char *c; 07804 int start=0, finish=0, x; 07805 ast_group_t group = 0; 07806 07807 if (ast_strlen_zero(s)) 07808 return 0; 07809 07810 c = ast_strdupa(s); 07811 07812 while ((piece = strsep(&c, ","))) { 07813 if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) { 07814 /* Range */ 07815 } else if (sscanf(piece, "%30d", &start)) { 07816 /* Just one */ 07817 finish = start; 07818 } else { 07819 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece); 07820 continue; 07821 } 07822 for (x = start; x <= finish; x++) { 07823 if ((x > 63) || (x < 0)) { 07824 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x); 07825 } else 07826 group |= ((ast_group_t) 1 << x); 07827 } 07828 } 07829 return group; 07830 }
int ast_hangup | ( | struct ast_channel * | chan | ) |
Hang up a channel.
This function performs a hard hangup on a channel. Unlike the soft-hangup, this function performs all stream stopping, etc, on the channel that needs to end. chan is no longer valid after this call.
chan | channel to hang up |
Definition at line 2771 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_lock, 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_set_flag, ast_test_flag, ast_channel::blocker, ast_channel::blockproc, ast_channel::caller, ast_channel::cdr, chanlist::chan, 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_channel::hangupsource, ast_party_connected_line::id, ast_party_caller::id, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_party_id::name, ast_channel::name, ast_party_id::number, pbx_builtin_getvar_helper(), ast_generator::release, S_COR, S_OR, ast_channel::sched, sched_context_destroy(), ast_party_name::str, ast_party_number::str, ast_channel::stream, ast_channel::tech, ast_channel::uniqueid, ast_party_name::valid, ast_party_number::valid, and ast_channel::vstream.
Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_request_and_dial(), __oh323_new(), action_bridge(), alsa_new(), analog_handle_init_event(), analog_ss_thread(), answer_exec_run(), app_exec(), ast_async_goto(), ast_call_forward(), ast_dial_destroy(), ast_dial_hangup(), ast_iax2_new(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run_app(), async_wait(), begin_dial_channel(), bridge_call_thread(), bridge_call_thread_launch(), bridge_channel_thread(), bridge_exec(), build_conf(), builtin_atxfer(), chanavail_exec(), check_availability(), check_compat(), check_goto_on_transfer(), clear_caller(), conf_run(), console_new(), dahdi_handle_event(), dahdi_new(), destroy_conference_bridge(), dial_exec_full(), dial_transfer(), do_forward(), do_hang(), do_idle_thread(), feature_attended_transfer(), feature_request_and_dial(), findmeexec(), generic_recall(), gtalk_new(), handle_call_forward(), handle_callforward_button(), handle_enbloc_call_message(), handle_frame(), handle_frame_ownerless(), handle_hd_hf(), handle_init_event(), handle_invite_replaces(), handle_offhook_message(), handle_request_invite(), handle_soft_key_event_message(), handle_stimulus_message(), handle_timeout_trip(), handle_transfer_button(), HandleCallOutgoing(), hangup_chan(), hangupcalls(), hanguptree(), iax2_request(), iax_park(), iax_park_thread(), jingle_new(), local_hangup(), manage_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(), play_sound_file(), pri_dchannel(), pri_ss_thread(), sip_park(), sip_park_thread(), sip_pickup_thread(), skinny_new(), skinny_ss(), unistim_new(), and wait_for_winner().
02772 { 02773 char extra_str[64]; /* used for cel logging below */ 02774 int was_zombie; 02775 02776 ast_autoservice_stop(chan); 02777 02778 ast_channel_lock(chan); 02779 02780 /* 02781 * Do the masquerade if someone is setup to masquerade into us. 02782 * 02783 * NOTE: We must hold the channel lock after testing for a 02784 * pending masquerade and setting the channel as a zombie to 02785 * prevent __ast_channel_masquerade() from setting up a 02786 * masquerade with a dead channel. 02787 */ 02788 while (chan->masq) { 02789 ast_channel_unlock(chan); 02790 ast_do_masquerade(chan); 02791 ast_channel_lock(chan); 02792 } 02793 02794 if (chan->masqr) { 02795 /* 02796 * This channel is one which will be masqueraded into something. 02797 * Mark it as a zombie already so ast_do_masquerade() will know 02798 * to free it later. 02799 */ 02800 ast_set_flag(chan, AST_FLAG_ZOMBIE); 02801 destroy_hooks(chan); 02802 ast_channel_unlock(chan); 02803 return 0; 02804 } 02805 02806 /* Mark as a zombie so a masquerade cannot be setup on this channel. */ 02807 if (!(was_zombie = ast_test_flag(chan, AST_FLAG_ZOMBIE))) { 02808 ast_set_flag(chan, AST_FLAG_ZOMBIE); 02809 } 02810 02811 ast_channel_unlock(chan); 02812 ao2_unlink(channels, chan); 02813 ast_channel_lock(chan); 02814 02815 destroy_hooks(chan); 02816 02817 free_translation(chan); 02818 /* Close audio stream */ 02819 if (chan->stream) { 02820 ast_closestream(chan->stream); 02821 chan->stream = NULL; 02822 } 02823 /* Close video stream */ 02824 if (chan->vstream) { 02825 ast_closestream(chan->vstream); 02826 chan->vstream = NULL; 02827 } 02828 if (chan->sched) { 02829 sched_context_destroy(chan->sched); 02830 chan->sched = NULL; 02831 } 02832 02833 if (chan->generatordata) { /* Clear any tone stuff remaining */ 02834 if (chan->generator && chan->generator->release) { 02835 chan->generator->release(chan, chan->generatordata); 02836 } 02837 } 02838 chan->generatordata = NULL; 02839 chan->generator = NULL; 02840 02841 snprintf(extra_str, sizeof(extra_str), "%d,%s,%s", chan->hangupcause, chan->hangupsource, S_OR(pbx_builtin_getvar_helper(chan, "DIALSTATUS"), "")); 02842 ast_cel_report_event(chan, AST_CEL_HANGUP, NULL, extra_str, NULL); 02843 02844 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 02845 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 02846 "is blocked by thread %ld in procedure %s! Expect a failure\n", 02847 (long) pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 02848 ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0); 02849 } 02850 if (!was_zombie) { 02851 ast_debug(1, "Hanging up channel '%s'\n", chan->name); 02852 02853 if (chan->tech->hangup) { 02854 chan->tech->hangup(chan); 02855 } 02856 } else { 02857 ast_debug(1, "Hanging up zombie '%s'\n", chan->name); 02858 } 02859 02860 ast_channel_unlock(chan); 02861 02862 ast_cc_offer(chan); 02863 ast_manager_event(chan, EVENT_FLAG_CALL, "Hangup", 02864 "Channel: %s\r\n" 02865 "Uniqueid: %s\r\n" 02866 "CallerIDNum: %s\r\n" 02867 "CallerIDName: %s\r\n" 02868 "ConnectedLineNum: %s\r\n" 02869 "ConnectedLineName: %s\r\n" 02870 "Cause: %d\r\n" 02871 "Cause-txt: %s\r\n", 02872 chan->name, 02873 chan->uniqueid, 02874 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<unknown>"), 02875 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"), 02876 S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, "<unknown>"), 02877 S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, "<unknown>"), 02878 chan->hangupcause, 02879 ast_cause2str(chan->hangupcause) 02880 ); 02881 02882 if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) && 02883 !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) && 02884 (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) { 02885 ast_channel_lock(chan); 02886 ast_cdr_end(chan->cdr); 02887 ast_cdr_detach(chan->cdr); 02888 chan->cdr = NULL; 02889 ast_channel_unlock(chan); 02890 } 02891 02892 ast_channel_unref(chan); 02893 02894 return 0; 02895 }
int ast_indicate | ( | struct ast_channel * | chan, | |
int | condition | |||
) |
Indicates condition of channel.
Indicate a condition such as AST_CONTROL_BUSY, AST_CONTROL_RINGING, or AST_CONTROL_CONGESTION on a channel
chan | channel to change the indication | |
condition | which condition to indicate on the channel |
Definition at line 4296 of file channel.c.
References ast_indicate_data(), and chanlist::chan.
Referenced by __ast_play_and_record(), agent_request(), alsa_call(), answer_trunk_chan(), ast_bridge_call(), ast_channel_bridge(), ast_do_masquerade(), ast_dtmf_stream(), ast_raw_answer(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), cli_console_answer(), conf_run(), console_call(), dial_exec_full(), do_forward(), feature_request_and_dial(), finishup(), 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(), rna(), say_periodic_announcement(), say_position(), send_waveform_to_channel(), skinny_ss(), sla_handle_hold_event(), sla_station_exec(), and sla_trunk_exec().
04297 { 04298 return ast_indicate_data(chan, condition, NULL, 0); 04299 }
int ast_indicate_data | ( | struct ast_channel * | chan, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) |
Indicates condition of channel, with payload.
Indicate a condition such as AST_CONTROL_HOLD with payload being music on hold class
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 4350 of file channel.c.
References ast_channel::_state, _XXX_AST_CONTROL_T38, ast_channel_lock, ast_channel_set_connected_line(), ast_channel_set_redirecting(), ast_channel_unlock, ast_check_hangup(), ast_connected_line_parse_data(), AST_CONTROL_ANSWER, AST_CONTROL_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_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(), chanlist::chan, ast_channel::connected, chanlist::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_channel::name, 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_handle_cc_control_frame(), ast_indicate(), disable_t38(), feature_request_and_dial(), generic_fax_exec(), handle_frame(), 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().
04352 { 04353 /* By using an enum, we'll get compiler warnings for values not handled 04354 * in switch statements. */ 04355 enum ast_control_frame_type condition = _condition; 04356 struct ast_tone_zone_sound *ts = NULL; 04357 int res; 04358 /* this frame is used by framehooks. if it is set, we must free it at the end of this function */ 04359 struct ast_frame *awesome_frame = NULL; 04360 04361 ast_channel_lock(chan); 04362 04363 /* Don't bother if the channel is about to go away, anyway. */ 04364 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 04365 res = -1; 04366 goto indicate_cleanup; 04367 } 04368 04369 if (!ast_framehook_list_is_empty(chan->framehooks)) { 04370 /* Do framehooks now, do it, go, go now */ 04371 struct ast_frame frame = { 04372 .frametype = AST_FRAME_CONTROL, 04373 .subclass.integer = condition, 04374 .data.ptr = (void *) data, /* this cast from const is only okay because we do the ast_frdup below */ 04375 .datalen = datalen 04376 }; 04377 04378 /* we have now committed to freeing this frame */ 04379 awesome_frame = ast_frdup(&frame); 04380 04381 /* who knows what we will get back! the anticipation is killing me. */ 04382 if (!(awesome_frame = ast_framehook_list_write_event(chan->framehooks, awesome_frame)) 04383 || awesome_frame->frametype != AST_FRAME_CONTROL) { 04384 04385 res = 0; 04386 goto indicate_cleanup; 04387 } 04388 04389 condition = awesome_frame->subclass.integer; 04390 data = awesome_frame->data.ptr; 04391 datalen = awesome_frame->datalen; 04392 } 04393 04394 switch (condition) { 04395 case AST_CONTROL_CONNECTED_LINE: 04396 { 04397 struct ast_party_connected_line connected; 04398 04399 ast_party_connected_line_set_init(&connected, &chan->connected); 04400 res = ast_connected_line_parse_data(data, datalen, &connected); 04401 if (!res) { 04402 ast_channel_set_connected_line(chan, &connected, NULL); 04403 } 04404 ast_party_connected_line_free(&connected); 04405 } 04406 break; 04407 04408 case AST_CONTROL_REDIRECTING: 04409 { 04410 struct ast_party_redirecting redirecting; 04411 04412 ast_party_redirecting_set_init(&redirecting, &chan->redirecting); 04413 res = ast_redirecting_parse_data(data, datalen, &redirecting); 04414 if (!res) { 04415 ast_channel_set_redirecting(chan, &redirecting, NULL); 04416 } 04417 ast_party_redirecting_free(&redirecting); 04418 } 04419 break; 04420 04421 default: 04422 break; 04423 } 04424 04425 if (is_visible_indication(condition)) { 04426 /* A new visible indication is requested. */ 04427 chan->visible_indication = condition; 04428 } else if (condition == AST_CONTROL_UNHOLD || _condition < 0) { 04429 /* Visible indication is cleared/stopped. */ 04430 chan->visible_indication = 0; 04431 } 04432 04433 if (chan->tech->indicate) { 04434 /* See if the channel driver can handle this condition. */ 04435 res = chan->tech->indicate(chan, condition, data, datalen); 04436 } else { 04437 res = -1; 04438 } 04439 04440 if (!res) { 04441 /* The channel driver successfully handled this indication */ 04442 res = 0; 04443 goto indicate_cleanup; 04444 } 04445 04446 /* The channel driver does not support this indication, let's fake 04447 * it by doing our own tone generation if applicable. */ 04448 04449 /*!\note If we compare the enumeration type, which does not have any 04450 * negative constants, the compiler may optimize this code away. 04451 * Therefore, we must perform an integer comparison here. */ 04452 if (_condition < 0) { 04453 /* Stop any tones that are playing */ 04454 ast_playtones_stop(chan); 04455 res = 0; 04456 goto indicate_cleanup; 04457 } 04458 04459 /* Handle conditions that we have tones for. */ 04460 switch (condition) { 04461 case _XXX_AST_CONTROL_T38: 04462 /* deprecated T.38 control frame */ 04463 res = -1; 04464 goto indicate_cleanup; 04465 case AST_CONTROL_T38_PARAMETERS: 04466 /* there is no way to provide 'default' behavior for these 04467 * control frames, so we need to return failure, but there 04468 * is also no value in the log message below being emitted 04469 * since failure to handle these frames is not an 'error' 04470 * so just return right now. in addition, we want to return 04471 * whatever value the channel driver returned, in case it 04472 * has some meaning.*/ 04473 goto indicate_cleanup; 04474 case AST_CONTROL_RINGING: 04475 ts = ast_get_indication_tone(chan->zone, "ring"); 04476 /* It is common practice for channel drivers to return -1 if trying 04477 * to indicate ringing on a channel which is up. The idea is to let the 04478 * core generate the ringing inband. However, we don't want the 04479 * warning message about not being able to handle the specific indication 04480 * to print nor do we want ast_indicate_data to return an "error" for this 04481 * condition 04482 */ 04483 if (chan->_state == AST_STATE_UP) { 04484 res = 0; 04485 } 04486 break; 04487 case AST_CONTROL_BUSY: 04488 ts = ast_get_indication_tone(chan->zone, "busy"); 04489 break; 04490 case AST_CONTROL_INCOMPLETE: 04491 case AST_CONTROL_CONGESTION: 04492 ts = ast_get_indication_tone(chan->zone, "congestion"); 04493 break; 04494 case AST_CONTROL_PROGRESS: 04495 case AST_CONTROL_PROCEEDING: 04496 case AST_CONTROL_VIDUPDATE: 04497 case AST_CONTROL_SRCUPDATE: 04498 case AST_CONTROL_SRCCHANGE: 04499 case AST_CONTROL_RADIO_KEY: 04500 case AST_CONTROL_RADIO_UNKEY: 04501 case AST_CONTROL_OPTION: 04502 case AST_CONTROL_WINK: 04503 case AST_CONTROL_FLASH: 04504 case AST_CONTROL_OFFHOOK: 04505 case AST_CONTROL_TAKEOFFHOOK: 04506 case AST_CONTROL_ANSWER: 04507 case AST_CONTROL_HANGUP: 04508 case AST_CONTROL_RING: 04509 case AST_CONTROL_HOLD: 04510 case AST_CONTROL_UNHOLD: 04511 case AST_CONTROL_TRANSFER: 04512 case AST_CONTROL_CONNECTED_LINE: 04513 case AST_CONTROL_REDIRECTING: 04514 case AST_CONTROL_CC: 04515 case AST_CONTROL_READ_ACTION: 04516 case AST_CONTROL_AOC: 04517 case AST_CONTROL_END_OF_Q: 04518 case AST_CONTROL_UPDATE_RTP_PEER: 04519 /* Nothing left to do for these. */ 04520 res = 0; 04521 break; 04522 } 04523 04524 if (ts) { 04525 /* We have a tone to play, yay. */ 04526 ast_debug(1, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition); 04527 res = ast_playtones_start(chan, 0, ts->data, 1); 04528 ts = ast_tone_zone_sound_unref(ts); 04529 } 04530 04531 if (res) { 04532 /* not handled */ 04533 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); 04534 } 04535 04536 indicate_cleanup: 04537 ast_channel_unlock(chan); 04538 if (awesome_frame) { 04539 ast_frfree(awesome_frame); 04540 } 04541 04542 return res; 04543 }
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 7836 of file channel.c.
References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.
Referenced by load_module().
07839 { 07840 ast_moh_start_ptr = start_ptr; 07841 ast_moh_stop_ptr = stop_ptr; 07842 ast_moh_cleanup_ptr = cleanup_ptr; 07843 }
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 4281 of file channel.c.
References ast_opt_internal_timing, chanlist::chan, and ast_channel::timingfd.
Referenced by add_sdp(), and ast_read_generator_actions().
04282 { 04283 return (ast_opt_internal_timing && chan->timingfd > -1); 04284 }
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 1790 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().
01791 { 01792 /* Do not add a default entry in this switch statement. Each new 01793 * frame type should be addressed directly as to whether it should 01794 * be queued up or not. 01795 */ 01796 switch (frame->frametype) { 01797 case AST_FRAME_CONTROL: 01798 case AST_FRAME_TEXT: 01799 case AST_FRAME_IMAGE: 01800 case AST_FRAME_HTML: 01801 return 1; 01802 01803 case AST_FRAME_DTMF_END: 01804 case AST_FRAME_DTMF_BEGIN: 01805 case AST_FRAME_VOICE: 01806 case AST_FRAME_VIDEO: 01807 case AST_FRAME_NULL: 01808 case AST_FRAME_IAX: 01809 case AST_FRAME_CNG: 01810 case AST_FRAME_MODEM: 01811 return 0; 01812 } 01813 return 0; 01814 }
void ast_moh_cleanup | ( | struct ast_channel * | chan | ) |
Definition at line 7870 of file channel.c.
References ast_moh_cleanup_ptr.
Referenced by ast_channel_destructor().
07871 { 07872 if (ast_moh_cleanup_ptr) 07873 ast_moh_cleanup_ptr(chan); 07874 }
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 7853 of file channel.c.
References ast_moh_start_ptr, and ast_verb.
Referenced by alsa_indicate(), app_exec(), conf_start_moh(), 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(), menu_callback(), 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(), sig_pri_indicate(), sip_indicate(), skinny_indicate(), start_moh_exec(), TransferCallStep1(), unistim_indicate(), and wait_moh_exec().
07854 { 07855 if (ast_moh_start_ptr) 07856 return ast_moh_start_ptr(chan, mclass, interpclass); 07857 07858 ast_verb(3, "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : (interpclass ? interpclass : "default")); 07859 07860 return 0; 07861 }
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 7864 of file channel.c.
References ast_moh_stop_ptr.
Referenced by alsa_indicate(), app_exec(), ast_quiet_chan(), conf_run(), 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(), menu_callback(), mgcp_indicate(), misdn_indication(), moh_handle_digit(), monitor_dial(), oh323_indicate(), oss_indicate(), phone_indicate(), play_moh_exec(), post_join_marked(), post_join_unmarked(), retrydial_exec(), say_periodic_announcement(), say_position(), sig_pri_indicate(), sip_indicate(), skinny_indicate(), stop_moh_exec(), unistim_hangup(), unistim_indicate(), and wait_moh_exec().
07865 { 07866 if (ast_moh_stop_ptr) 07867 ast_moh_stop_ptr(chan); 07868 }
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 2244 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_copy(), and ast_party_caller::id.
02245 { 02246 if (dest == src) { 02247 /* Don't copy to self */ 02248 return; 02249 } 02250 02251 ast_party_id_copy(&dest->id, &src->id); 02252 ast_party_id_copy(&dest->ani, &src->ani); 02253 dest->ani2 = src->ani2; 02254 }
void ast_party_caller_free | ( | struct ast_party_caller * | doomed | ) |
Destroy the caller party contents.
doomed | The caller party to destroy. |
Definition at line 2270 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().
02271 { 02272 ast_party_id_free(&doomed->id); 02273 ast_party_id_free(&doomed->ani); 02274 }
void ast_party_caller_init | ( | struct ast_party_caller * | init | ) |
Initialize the given caller structure.
init | Caller structure to initialize. |
Definition at line 2237 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(), sig_pri_set_caller_id(), and sla_ring_station().
02238 { 02239 ast_party_id_init(&init->id); 02240 ast_party_id_init(&init->ani); 02241 init->ani2 = 0; 02242 }
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 2263 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_set(), ast_party_caller::id, and update().
Referenced by ast_channel_set_caller(), ast_channel_set_caller_event(), and callerid_write().
02264 { 02265 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL); 02266 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL); 02267 dest->ani2 = src->ani2; 02268 }
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 2256 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(), ring_entry(), and sig_pri_handle_subcmds().
02257 { 02258 ast_party_id_set_init(&init->id, &guide->id); 02259 ast_party_id_set_init(&init->ani, &guide->ani); 02260 init->ani2 = guide->ani2; 02261 }
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 2313 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_channel::caller, chanlist::connected, ast_party_caller::id, ast_party_connected_line::id, and ast_party_connected_line::source.
02314 { 02315 connected->id = caller->id; 02316 connected->ani = caller->ani; 02317 connected->ani2 = caller->ani2; 02318 connected->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN; 02319 }
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 2284 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(), and party_connected_line_copy_transfer().
02285 { 02286 if (dest == src) { 02287 /* Don't copy to self */ 02288 return; 02289 } 02290 02291 ast_party_id_copy(&dest->id, &src->id); 02292 ast_party_id_copy(&dest->ani, &src->ani); 02293 dest->ani2 = src->ani2; 02294 dest->source = src->source; 02295 }
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 2321 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_connected_line_macro(), 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(), local_attended_transfer(), misdn_attempt_transfer(), parked_call_exec(), sig_pri_handle_subcmds(), socket_process(), wait_for_answer(), wait_for_winner(), and xfer_ds_destroy().
02322 { 02323 ast_party_id_free(&doomed->id); 02324 ast_party_id_free(&doomed->ani); 02325 }
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 2276 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_channel_connected_line_macro(), 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(), sig_pri_handle_subcmds(), sip_call(), socket_process(), and wait_for_answer().
02277 { 02278 ast_party_id_init(&init->id); 02279 ast_party_id_init(&init->ani); 02280 init->ani2 = 0; 02281 init->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN; 02282 }
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 2305 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_set(), ast_party_connected_line::id, ast_party_connected_line::source, and update().
Referenced by ast_channel_set_connected_line(), and wait_for_winner().
02306 { 02307 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL); 02308 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL); 02309 dest->ani2 = src->ani2; 02310 dest->source = src->source; 02311 }
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 2297 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(), and wait_for_winner().
02298 { 02299 ast_party_id_set_init(&init->id, &guide->id); 02300 ast_party_id_set_init(&init->ani, &guide->ani); 02301 init->ani2 = guide->ani2; 02302 init->source = guide->source; 02303 }
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 2195 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().
02196 { 02197 if (dest == src) { 02198 /* Don't copy to self */ 02199 return; 02200 } 02201 02202 ast_free(dest->number.str); 02203 dest->number.str = ast_strdup(src->number.str); 02204 dest->number.plan = src->number.plan; 02205 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress); 02206 dest->transit_network_select = src->transit_network_select; 02207 }
void ast_party_dialed_free | ( | struct ast_party_dialed * | doomed | ) |
Destroy the dialed party contents.
doomed | The dialed party to destroy. |
Definition at line 2230 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().
02231 { 02232 ast_free(doomed->number.str); 02233 doomed->number.str = NULL; 02234 ast_party_subaddress_free(&doomed->subaddress); 02235 }
void ast_party_dialed_init | ( | struct ast_party_dialed * | init | ) |
Initialize the given dialed structure.
init | Dialed structure to initialize. |
Definition at line 2187 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().
02188 { 02189 init->number.str = NULL; 02190 init->number.plan = 0;/* Unknown */ 02191 ast_party_subaddress_init(&init->subaddress); 02192 init->transit_network_select = 0; 02193 }
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 2217 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().
02218 { 02219 if (src->number.str && src->number.str != dest->number.str) { 02220 ast_free(dest->number.str); 02221 dest->number.str = ast_strdup(src->number.str); 02222 } 02223 dest->number.plan = src->number.plan; 02224 02225 ast_party_subaddress_set(&dest->subaddress, &src->subaddress); 02226 02227 dest->transit_network_select = src->transit_network_select; 02228 }
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 2209 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().
02210 { 02211 init->number.str = NULL; 02212 init->number.plan = guide->number.plan; 02213 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress); 02214 init->transit_network_select = guide->transit_network_select; 02215 }
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 2063 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().
02064 { 02065 if (dest == src) { 02066 /* Don't copy to self */ 02067 return; 02068 } 02069 02070 ast_party_name_copy(&dest->name, &src->name); 02071 ast_party_number_copy(&dest->number, &src->number); 02072 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress); 02073 02074 ast_free(dest->tag); 02075 dest->tag = ast_strdup(src->tag); 02076 }
void ast_party_id_free | ( | struct ast_party_id * | doomed | ) |
Destroy the party id contents.
doomed | The party id to destroy. |
Definition at line 2109 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(), parkandannounce_exec(), and sig_pri_mcid_event().
02110 { 02111 ast_party_name_free(&doomed->name); 02112 ast_party_number_free(&doomed->number); 02113 ast_party_subaddress_free(&doomed->subaddress); 02114 02115 ast_free(doomed->tag); 02116 doomed->tag = NULL; 02117 }
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 2055 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(), parkandannounce_exec(), and sig_pri_mcid_event().
02056 { 02057 ast_party_name_init(&init->name); 02058 ast_party_number_init(&init->number); 02059 ast_party_subaddress_init(&init->subaddress); 02060 init->tag = NULL; 02061 }
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 2119 of file channel.c.
References AST_PRES_ALLOWED, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_NUMBER_TYPE, AST_PRES_RESTRICTED, AST_PRES_RESTRICTION, AST_PRES_UNAVAILABLE, AST_PRES_USER_NUMBER_UNSCREENED, and id.
Referenced by add_rpid(), ast_str_retrieve_variable(), ast_var_channels_table(), callerpres_read(), iax2_call(), initreqprep(), my_set_callerid(), oh323_call(), party_id_build_data(), party_id_read(), redirecting_read(), report_new_callerid(), setup_env(), sig_pri_event_party_id(), sig_pri_handle_subcmds(), sip_call(), and socket_process().
02120 { 02121 int number_priority; 02122 int number_value; 02123 int number_screening; 02124 int name_priority; 02125 int name_value; 02126 02127 /* Determine name presentation priority. */ 02128 if (!id->name.valid) { 02129 name_value = AST_PRES_UNAVAILABLE; 02130 name_priority = 3; 02131 } else { 02132 name_value = id->name.presentation & AST_PRES_RESTRICTION; 02133 switch (name_value) { 02134 case AST_PRES_RESTRICTED: 02135 name_priority = 0; 02136 break; 02137 case AST_PRES_ALLOWED: 02138 name_priority = 1; 02139 break; 02140 case AST_PRES_UNAVAILABLE: 02141 name_priority = 2; 02142 break; 02143 default: 02144 name_value = AST_PRES_UNAVAILABLE; 02145 name_priority = 3; 02146 break; 02147 } 02148 } 02149 02150 /* Determine number presentation priority. */ 02151 if (!id->number.valid) { 02152 number_screening = AST_PRES_USER_NUMBER_UNSCREENED; 02153 number_value = AST_PRES_UNAVAILABLE; 02154 number_priority = 3; 02155 } else { 02156 number_screening = id->number.presentation & AST_PRES_NUMBER_TYPE; 02157 number_value = id->number.presentation & AST_PRES_RESTRICTION; 02158 switch (number_value) { 02159 case AST_PRES_RESTRICTED: 02160 number_priority = 0; 02161 break; 02162 case AST_PRES_ALLOWED: 02163 number_priority = 1; 02164 break; 02165 case AST_PRES_UNAVAILABLE: 02166 number_priority = 2; 02167 break; 02168 default: 02169 number_screening = AST_PRES_USER_NUMBER_UNSCREENED; 02170 number_value = AST_PRES_UNAVAILABLE; 02171 number_priority = 3; 02172 break; 02173 } 02174 } 02175 02176 /* Select the wining presentation value. */ 02177 if (name_priority < number_priority) { 02178 number_value = name_value; 02179 } 02180 if (number_value == AST_PRES_UNAVAILABLE) { 02181 return AST_PRES_NUMBER_NOT_AVAILABLE; 02182 } 02183 02184 return number_value | number_screening; 02185 }
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 2086 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_party_id::number, ast_party_id::subaddress, ast_party_id::tag, and update().
Referenced by ast_party_caller_set(), ast_party_connected_line_set(), and ast_party_redirecting_set().
02087 { 02088 if (dest == src) { 02089 /* Don't set to self */ 02090 return; 02091 } 02092 02093 if (!update || update->name) { 02094 ast_party_name_set(&dest->name, &src->name); 02095 } 02096 if (!update || update->number) { 02097 ast_party_number_set(&dest->number, &src->number); 02098 } 02099 if (!update || update->subaddress) { 02100 ast_party_subaddress_set(&dest->subaddress, &src->subaddress); 02101 } 02102 02103 if (src->tag && src->tag != dest->tag) { 02104 ast_free(dest->tag); 02105 dest->tag = ast_strdup(src->tag); 02106 } 02107 }
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 2078 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().
02079 { 02080 ast_party_name_set_init(&init->name, &guide->name); 02081 ast_party_number_set_init(&init->number, &guide->number); 02082 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress); 02083 init->tag = NULL; 02084 }
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 1904 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().
01905 { 01906 if (dest == src) { 01907 /* Don't copy to self */ 01908 return; 01909 } 01910 01911 ast_free(dest->str); 01912 dest->str = ast_strdup(src->str); 01913 dest->char_set = src->char_set; 01914 dest->presentation = src->presentation; 01915 dest->valid = src->valid; 01916 }
void ast_party_name_free | ( | struct ast_party_name * | doomed | ) |
Destroy the party name contents.
doomed | The party name to destroy. |
Definition at line 1943 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 1896 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().
01897 { 01898 init->str = NULL; 01899 init->char_set = AST_PARTY_CHAR_SET_ISO8859_1; 01900 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 01901 init->valid = 0; 01902 }
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 1926 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().
01927 { 01928 if (dest == src) { 01929 /* Don't set to self */ 01930 return; 01931 } 01932 01933 if (src->str && src->str != dest->str) { 01934 ast_free(dest->str); 01935 dest->str = ast_strdup(src->str); 01936 } 01937 01938 dest->char_set = src->char_set; 01939 dest->presentation = src->presentation; 01940 dest->valid = src->valid; 01941 }
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 1918 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().
01919 { 01920 init->str = NULL; 01921 init->char_set = guide->char_set; 01922 init->presentation = guide->presentation; 01923 init->valid = guide->valid; 01924 }
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.
dest | Destination party number | |
src | Source party number |
Definition at line 1957 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().
01958 { 01959 if (dest == src) { 01960 /* Don't copy to self */ 01961 return; 01962 } 01963 01964 ast_free(dest->str); 01965 dest->str = ast_strdup(src->str); 01966 dest->plan = src->plan; 01967 dest->presentation = src->presentation; 01968 dest->valid = src->valid; 01969 }
void ast_party_number_free | ( | struct ast_party_number * | doomed | ) |
Destroy the party number contents.
doomed | The party number to destroy. |
Definition at line 1996 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(), and skinny_newcall().
void ast_party_number_init | ( | struct ast_party_number * | init | ) |
Initialize the given number structure.
init | Number structure to initialize. |
Definition at line 1949 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(), and skinny_newcall().
01950 { 01951 init->str = NULL; 01952 init->plan = 0;/* Unknown */ 01953 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 01954 init->valid = 0; 01955 }
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.
dest | The number one wishes to update | |
src | The new number values to update the dest |
Definition at line 1979 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().
01980 { 01981 if (dest == src) { 01982 /* Don't set to self */ 01983 return; 01984 } 01985 01986 if (src->str && src->str != dest->str) { 01987 ast_free(dest->str); 01988 dest->str = ast_strdup(src->str); 01989 } 01990 01991 dest->plan = src->plan; 01992 dest->presentation = src->presentation; 01993 dest->valid = src->valid; 01994 }
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 1971 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().
01972 { 01973 init->str = NULL; 01974 init->plan = guide->plan; 01975 init->presentation = guide->presentation; 01976 init->valid = guide->valid; 01977 }
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 2335 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(), and ring_entry().
02336 { 02337 if (dest == src) { 02338 /* Don't copy to self */ 02339 return; 02340 } 02341 02342 ast_party_id_copy(&dest->from, &src->from); 02343 ast_party_id_copy(&dest->to, &src->to); 02344 dest->count = src->count; 02345 dest->reason = src->reason; 02346 }
void ast_party_redirecting_free | ( | struct ast_party_redirecting * | doomed | ) |
Destroy the redirecting information contents.
doomed | The redirecting information to destroy. |
Definition at line 2364 of file channel.c.
References ast_party_id_free(), ast_party_redirecting::from, and ast_party_redirecting::to.
Referenced by ast_channel_destructor(), ast_channel_redirecting_macro(), ast_dummy_channel_destructor(), ast_indicate_data(), call_forward_inherit(), do_forward(), handle_request_invite(), handle_response(), handle_response_invite(), redirecting_write(), and sig_pri_handle_subcmds().
02365 { 02366 ast_party_id_free(&doomed->from); 02367 ast_party_id_free(&doomed->to); 02368 }
void ast_party_redirecting_init | ( | struct ast_party_redirecting * | init | ) |
Initialize the given redirecting structure.
init | Redirecting structure to initialize. |
Definition at line 2327 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(), ast_channel_redirecting_macro(), call_forward_inherit(), do_forward(), handle_request_invite(), handle_response(), and handle_response_invite().
02328 { 02329 ast_party_id_init(&init->from); 02330 ast_party_id_init(&init->to); 02331 init->count = 0; 02332 init->reason = AST_REDIRECTING_REASON_UNKNOWN; 02333 }
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 2356 of file channel.c.
References ast_party_id_set(), ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, ast_party_redirecting::to, and update().
Referenced by ast_channel_set_redirecting().
02357 { 02358 ast_party_id_set(&dest->from, &src->from, update ? &update->from : NULL); 02359 ast_party_id_set(&dest->to, &src->to, update ? &update->to : NULL); 02360 dest->reason = src->reason; 02361 dest->count = src->count; 02362 }
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 2348 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(), redirecting_write(), and sig_pri_redirecting_convert().
02349 { 02350 ast_party_id_set_init(&init->from, &guide->from); 02351 ast_party_id_set_init(&init->to, &guide->to); 02352 init->count = guide->count; 02353 init->reason = guide->reason; 02354 }
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 2010 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().
02011 { 02012 if (dest == src) { 02013 /* Don't copy to self */ 02014 return; 02015 } 02016 02017 ast_free(dest->str); 02018 dest->str = ast_strdup(src->str); 02019 dest->type = src->type; 02020 dest->odd_even_indicator = src->odd_even_indicator; 02021 dest->valid = src->valid; 02022 }
void ast_party_subaddress_free | ( | struct ast_party_subaddress * | doomed | ) |
Destroy the party subaddress contents.
doomed | The party subaddress to destroy. |
Definition at line 2049 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 2002 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(), ast_party_id_init(), sig_pri_call(), and sig_pri_set_subaddress().
02003 { 02004 init->str = NULL; 02005 init->type = 0; 02006 init->odd_even_indicator = 0; 02007 init->valid = 0; 02008 }
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 2032 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(), ast_party_id_set(), and sig_pri_handle_subcmds().
02033 { 02034 if (dest == src) { 02035 /* Don't set to self */ 02036 return; 02037 } 02038 02039 if (src->str && src->str != dest->str) { 02040 ast_free(dest->str); 02041 dest->str = ast_strdup(src->str); 02042 } 02043 02044 dest->type = src->type; 02045 dest->odd_even_indicator = src->odd_even_indicator; 02046 dest->valid = src->valid; 02047 }
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 2024 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().
02025 { 02026 init->str = NULL; 02027 init->type = guide->type; 02028 init->odd_even_indicator = guide->odd_even_indicator; 02029 init->valid = guide->valid; 02030 }
int ast_plc_reload | ( | void | ) |
Reload genericplc configuration value from codecs.conf.
Implementation is in main/channel.c
Definition at line 7889 of file channel.c.
References 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, and var.
Referenced by ast_channels_init().
07890 { 07891 struct ast_variable *var; 07892 struct ast_flags config_flags = { 0 }; 07893 struct ast_config *cfg = ast_config_load("codecs.conf", config_flags); 07894 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) 07895 return 0; 07896 for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) { 07897 if (!strcasecmp(var->name, "genericplc")) { 07898 ast_set2_flag(&ast_options, ast_true(var->value), AST_OPT_FLAG_GENERIC_PLC); 07899 } 07900 } 07901 ast_config_destroy(cfg); 07902 return 0; 07903 }
void ast_poll_channel_add | ( | struct ast_channel * | chan0, | |
struct ast_channel * | chan1 | |||
) |
Add a channel to an optimized waitfor
Definition at line 2632 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().
02633 { 02634 #ifdef HAVE_EPOLL 02635 struct epoll_event ev; 02636 int i = 0; 02637 02638 if (chan0->epfd == -1) 02639 return; 02640 02641 /* Iterate through the file descriptors on chan1, adding them to chan0 */ 02642 for (i = 0; i < AST_MAX_FDS; i++) { 02643 if (chan1->fds[i] == -1) 02644 continue; 02645 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 02646 ev.data.ptr = chan1->epfd_data[i]; 02647 epoll_ctl(chan0->epfd, EPOLL_CTL_ADD, chan1->fds[i], &ev); 02648 } 02649 02650 #endif 02651 return; 02652 }
void ast_poll_channel_del | ( | struct ast_channel * | chan0, | |
struct ast_channel * | chan1 | |||
) |
Delete a channel from an optimized waitfor
Definition at line 2655 of file channel.c.
References AST_MAX_FDS, and ast_channel::fds.
Referenced by feature_request_and_dial(), and monitor_dial().
02656 { 02657 #ifdef HAVE_EPOLL 02658 struct epoll_event ev; 02659 int i = 0; 02660 02661 if (chan0->epfd == -1) 02662 return; 02663 02664 for (i = 0; i < AST_MAX_FDS; i++) { 02665 if (chan1->fds[i] == -1) 02666 continue; 02667 epoll_ctl(chan0->epfd, EPOLL_CTL_DEL, chan1->fds[i], &ev); 02668 } 02669 02670 #endif 02671 return; 02672 }
char* ast_print_group | ( | char * | buf, | |
int | buflen, | |||
ast_group_t | group | |||
) |
print call- and pickup groups into buffer
Definition at line 8037 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().
08038 { 08039 unsigned int i; 08040 int first = 1; 08041 char num[3]; 08042 08043 buf[0] = '\0'; 08044 08045 if (!group) /* Return empty string if no group */ 08046 return buf; 08047 08048 for (i = 0; i <= 63; i++) { /* Max group is 63 */ 08049 if (group & ((ast_group_t) 1 << i)) { 08050 if (!first) { 08051 strncat(buf, ", ", buflen - strlen(buf) - 1); 08052 } else { 08053 first = 0; 08054 } 08055 snprintf(num, sizeof(num), "%u", i); 08056 strncat(buf, num, buflen - strlen(buf) - 1); 08057 } 08058 } 08059 return buf; 08060 }
int ast_prod | ( | struct ast_channel * | chan | ) |
Send empty audio to prime a channel driver.
Definition at line 4669 of file channel.c.
References ast_channel::_state, ast_debug, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), AST_STATE_UP, ast_write(), chanlist::chan, ast_frame_subclass::codec, ast_frame::data, LOG_WARNING, ast_channel::name, ast_frame::ptr, ast_channel::rawwriteformat, ast_frame::src, and ast_frame::subclass.
Referenced by ast_activate_generator().
04670 { 04671 struct ast_frame a = { AST_FRAME_VOICE }; 04672 char nothing[128]; 04673 04674 /* Send an empty audio frame to get things moving */ 04675 if (chan->_state != AST_STATE_UP) { 04676 ast_debug(1, "Prodding channel '%s'\n", chan->name); 04677 a.subclass.codec = chan->rawwriteformat; 04678 a.data.ptr = nothing + AST_FRIENDLY_OFFSET; 04679 a.src = "ast_prod"; /* this better match check in ast_write */ 04680 if (ast_write(chan, &a)) 04681 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 04682 } 04683 return 0; 04684 }
int ast_queue_control | ( | struct ast_channel * | chan, | |
enum ast_control_frame_type | control | |||
) |
Queue a control frame with payload.
chan | channel to queue frame onto | |
control | type of control frame |
zero | on success | |
non-zero | on failure |
Definition at line 1573 of file channel.c.
References AST_FRAME_CONTROL, ast_queue_frame(), chanlist::chan, and f.
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_offhook_message(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_refer(), handle_soft_key_event_message(), handle_stimulus_message(), 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(), setup_rtp_connection(), skinny_call(), skinny_transfer(), skinny_unhold(), unistim_call(), and update_state().
01574 { 01575 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control }; 01576 return ast_queue_frame(chan, &f); 01577 }
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 1580 of file channel.c.
References AST_FRAME_CONTROL, ast_queue_frame(), chanlist::chan, and f.
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(), handle_request_notify(), handle_response_refer(), iax2_queue_control_data(), iax2_transfer(), interpret_t38_parameters(), local_attended_transfer(), masquerade_colp_transfer(), process_sdp(), sig_pri_aoc_d_from_pri(), sig_pri_aoc_e_from_pri(), sig_pri_aoc_s_from_pri(), sig_pri_send_aoce_termination_request(), sip_sipredirect(), and skinny_hold().
01582 { 01583 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control, .data.ptr = (void *) data, .datalen = datalen }; 01584 return ast_queue_frame(chan, &f); 01585 }
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 1530 of file channel.c.
References __ast_queue_frame(), and chanlist::chan.
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_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(), 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(), keypad_digit(), local_queue_frame(), mgcp_queue_frame(), oh323_simulate_dtmf_end(), oss_call(), pri_queue_frame(), process_sdp(), queue_dtmf_readq(), receive_digit(), receive_message(), sig_pri_dial_complete(), sig_pri_handle_hold(), sig_pri_handle_subcmds(), stream_monitor(), unistim_do_senddigit(), unistim_senddigit_end(), and wakeup_sub().
01531 { 01532 return __ast_queue_frame(chan, fin, 0, NULL); 01533 }
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 1535 of file channel.c.
References __ast_queue_frame(), and chanlist::chan.
Referenced by __ast_answer(), __ast_read(), ast_autoservice_stop(), ast_safe_sleep_conditional(), and feature_request_and_dial().
01536 { 01537 return __ast_queue_frame(chan, fin, 1, NULL); 01538 }
int ast_queue_hangup | ( | struct ast_channel * | chan | ) |
Queue a hangup frame.
Definition at line 1541 of file channel.c.
References ast_channel::_softhangup, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), AST_SOFTHANGUP_DEV, chanlist::chan, and f.
Referenced by bridge_queue_hangup(), cleanup_connection(), cli_console_hangup(), close_call(), gtalk_hangup_farend(), gtalk_is_answered(), handle_onhook_message(), handle_request_bye(), handle_soft_key_event_message(), iax2_destroy(), iax2_queue_hangup(), jingle_hangup_farend(), local_fixup(), local_hangup(), mgcp_queue_hangup(), and sip_queue_hangup_cause().
01542 { 01543 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP }; 01544 /* Yeah, let's not change a lock-critical value without locking */ 01545 if (!ast_channel_trylock(chan)) { 01546 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01547 ast_channel_unlock(chan); 01548 } 01549 return ast_queue_frame(chan, &f); 01550 }
int ast_queue_hangup_with_cause | ( | struct ast_channel * | chan, | |
int | cause | |||
) |
Queue a hangup frame with hangupcause set.
[in] | chan | channel to queue frame onto |
[in] | cause | the hangup cause |
Definition at line 1553 of file channel.c.
References ast_channel::_softhangup, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), AST_SOFTHANGUP_DEV, chanlist::chan, f, and ast_channel::hangupcause.
Referenced by __analog_handle_event(), __oh323_update_info(), __sip_autodestruct(), close_call(), close_client(), console_hangup(), dahdi_handle_event(), dahdi_r2_on_call_disconnect(), handle_request_bye(), handle_response(), handle_response_invite(), HandleCallOutgoing(), hangup_chan(), hangup_connection(), misdn_answer(), retrans_pkt(), sip_queue_hangup_cause(), and TransferCallStep1().
01554 { 01555 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP }; 01556 01557 if (cause >= 0) 01558 f.data.uint32 = cause; 01559 01560 /* Yeah, let's not change a lock-critical value without locking */ 01561 if (!ast_channel_trylock(chan)) { 01562 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01563 if (cause < 0) 01564 f.data.uint32 = chan->hangupcause; 01565 01566 ast_channel_unlock(chan); 01567 } 01568 01569 return ast_queue_frame(chan, &f); 01570 }
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 2897 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, chanlist::chan, and ast_channel::tech.
Referenced by __ast_answer(), and ast_bridge_call().
02898 { 02899 int res = 0; 02900 02901 ast_channel_lock(chan); 02902 02903 /* You can't answer an outbound call */ 02904 if (ast_test_flag(chan, AST_FLAG_OUTGOING)) { 02905 ast_channel_unlock(chan); 02906 return 0; 02907 } 02908 02909 /* Stop if we're a zombie or need a soft hangup */ 02910 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02911 ast_channel_unlock(chan); 02912 return -1; 02913 } 02914 02915 ast_channel_unlock(chan); 02916 02917 switch (chan->_state) { 02918 case AST_STATE_RINGING: 02919 case AST_STATE_RING: 02920 ast_channel_lock(chan); 02921 if (chan->tech->answer) { 02922 res = chan->tech->answer(chan); 02923 } 02924 ast_setstate(chan, AST_STATE_UP); 02925 if (cdr_answer) { 02926 ast_cdr_answer(chan->cdr); 02927 } 02928 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 02929 ast_channel_unlock(chan); 02930 break; 02931 case AST_STATE_UP: 02932 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 02933 /* Calling ast_cdr_answer when it it has previously been called 02934 * is essentially a no-op, so it is safe. 02935 */ 02936 if (cdr_answer) { 02937 ast_cdr_answer(chan->cdr); 02938 } 02939 break; 02940 default: 02941 break; 02942 } 02943 02944 ast_indicate(chan, -1); 02945 02946 return res; 02947 }
struct ast_frame* ast_read | ( | struct ast_channel * | chan | ) |
Reads a frame.
chan | channel to read a frame from |
Definition at line 4286 of file channel.c.
References __ast_read(), and chanlist::chan.
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_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_idle_thread(), do_waiting(), echo_exec(), eivr_comm(), feature_request_and_dial(), find_cache(), generic_fax_exec(), handle_recordfile(), handle_speechrecognize(), 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(), recordthread(), remote_bridge_loop(), run_agi(), send_tone_burst(), send_waveform_to_channel(), sendfax_t38_init(), sendurl_exec(), speech_background(), transmit_audio(), transmit_t38(), wait_for_hangup(), wait_for_winner(), waitforring_exec(), and waitstream_core().
04287 { 04288 return __ast_read(chan, 0); 04289 }
static void ast_read_generator_actions | ( | struct ast_channel * | chan, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 3644 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_deactivate_generator(), ast_debug, ast_format_rate(), AST_FRAME_CNG, ast_internal_timing_enabled(), ast_settimeout(), chanlist::chan, f, ast_generator::generate, ast_channel::generator, generator_force(), ast_channel::generatordata, ast_channel::timingfd, ast_channel::timingfunc, and ast_channel::writeformat.
Referenced by __ast_read().
03645 { 03646 if (chan->generator && chan->generator->generate && chan->generatordata && !ast_internal_timing_enabled(chan)) { 03647 void *tmp = chan->generatordata; 03648 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = chan->generator->generate; 03649 int res; 03650 int samples; 03651 03652 if (chan->timingfunc) { 03653 ast_debug(1, "Generator got voice, switching to phase locked mode\n"); 03654 ast_settimeout(chan, 0, NULL, NULL); 03655 } 03656 03657 chan->generatordata = NULL; /* reset, to let writes go through */ 03658 03659 if (f->subclass.codec != chan->writeformat) { 03660 float factor; 03661 factor = ((float) ast_format_rate(chan->writeformat)) / ((float) ast_format_rate(f->subclass.codec)); 03662 samples = (int) ( ((float) f->samples) * factor ); 03663 } else { 03664 samples = f->samples; 03665 } 03666 03667 /* This unlock is here based on two assumptions that hold true at this point in the 03668 * code. 1) this function is only called from within __ast_read() and 2) all generators 03669 * call ast_write() in their generate callback. 03670 * 03671 * The reason this is added is so that when ast_write is called, the lock that occurs 03672 * there will not recursively lock the channel. Doing this will cause intended deadlock 03673 * avoidance not to work in deeper functions 03674 */ 03675 ast_channel_unlock(chan); 03676 res = generate(chan, tmp, f->datalen, samples); 03677 ast_channel_lock(chan); 03678 chan->generatordata = tmp; 03679 if (res) { 03680 ast_debug(1, "Auto-deactivating generator\n"); 03681 ast_deactivate_generator(chan); 03682 } 03683 03684 } else if (f->frametype == AST_FRAME_CNG) { 03685 if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) { 03686 ast_debug(1, "Generator got CNG, switching to timed mode\n"); 03687 ast_settimeout(chan, 50, generator_force, chan); 03688 } 03689 } 03690 }
struct ast_frame* ast_read_noaudio | ( | struct ast_channel * | chan | ) |
Reads a frame, returning AST_FRAME_NULL frame if audio.
chan | channel to read a frame from |
Definition at line 4291 of file channel.c.
References __ast_read(), and chanlist::chan.
Referenced by ast_bridge_handle_trip(), and conf_run().
04292 { 04293 return __ast_read(chan, 1); 04294 }
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 5721 of file channel.c.
References ast_readstring_full().
Referenced by adsi_begin_download(), adsi_get_cpeinfo(), adsi_load_session(), ast_app_getdata(), dialout(), do_directory(), forward_message(), privacy_exec(), vm_authenticate(), vm_newuser(), and vm_options().
05722 { 05723 return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1); 05724 }
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 5726 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().
05727 { 05728 int pos = 0; /* index in the buffer where we accumulate digits */ 05729 int to = ftimeout; 05730 05731 struct ast_silence_generator *silgen = NULL; 05732 05733 /* Stop if we're a zombie or need a soft hangup */ 05734 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 05735 return -1; 05736 if (!len) 05737 return -1; 05738 for (;;) { 05739 int d; 05740 if (c->stream) { 05741 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 05742 ast_stopstream(c); 05743 if (!silgen && ast_opt_transmit_silence) 05744 silgen = ast_channel_start_silence_generator(c); 05745 usleep(1000); 05746 if (!d) 05747 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 05748 } else { 05749 if (!silgen && ast_opt_transmit_silence) 05750 silgen = ast_channel_start_silence_generator(c); 05751 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 05752 } 05753 if (d < 0) { 05754 ast_channel_stop_silence_generator(c, silgen); 05755 return AST_GETDATA_FAILED; 05756 } 05757 if (d == 0) { 05758 s[pos] = '\0'; 05759 ast_channel_stop_silence_generator(c, silgen); 05760 return AST_GETDATA_TIMEOUT; 05761 } 05762 if (d == 1) { 05763 s[pos] = '\0'; 05764 ast_channel_stop_silence_generator(c, silgen); 05765 return AST_GETDATA_INTERRUPTED; 05766 } 05767 if (strchr(enders, d) && (pos == 0)) { 05768 s[pos] = '\0'; 05769 ast_channel_stop_silence_generator(c, silgen); 05770 return AST_GETDATA_EMPTY_END_TERMINATED; 05771 } 05772 if (!strchr(enders, d)) { 05773 s[pos++] = d; 05774 } 05775 if (strchr(enders, d) || (pos >= len)) { 05776 s[pos] = '\0'; 05777 ast_channel_stop_silence_generator(c, silgen); 05778 return AST_GETDATA_COMPLETE; 05779 } 05780 to = timeout; 05781 } 05782 /* Never reached */ 05783 return 0; 05784 }
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 4545 of file channel.c.
References ast_free, ast_recvtext(), and chanlist::chan.
Referenced by handle_recvchar().
04546 { 04547 int c; 04548 char *buf = ast_recvtext(chan, timeout); 04549 if (buf == NULL) 04550 return -1; /* error or timeout */ 04551 c = *(unsigned char *)buf; 04552 ast_free(buf); 04553 return c; 04554 }
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 4556 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(), chanlist::chan, and f.
Referenced by ast_recvchar(), and handle_recvtext().
04557 { 04558 int res, done = 0; 04559 char *buf = NULL; 04560 04561 while (!done) { 04562 struct ast_frame *f; 04563 if (ast_check_hangup(chan)) 04564 break; 04565 res = ast_waitfor(chan, timeout); 04566 if (res <= 0) /* timeout or error */ 04567 break; 04568 timeout = res; /* update timeout */ 04569 f = ast_read(chan); 04570 if (f == NULL) 04571 break; /* no frame */ 04572 if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP) 04573 done = 1; /* force a break */ 04574 else if (f->frametype == AST_FRAME_TEXT) { /* what we want */ 04575 buf = ast_strndup((char *) f->data.ptr, f->datalen); /* dup and break */ 04576 done = 1; 04577 } 04578 ast_frfree(f); 04579 } 04580 return buf; 04581 }
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 8939 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_party_redirecting::from, LOG_WARNING, ast_party_id_ies::name, party_id_build_data(), ast_party_redirecting::reason, ast_party_name_ies::str, ast_party_redirecting::to, update(), and value.
Referenced by ast_channel_queue_redirecting_update(), ast_channel_update_redirecting(), and local_indicate().
08940 { 08941 int32_t value; 08942 size_t pos = 0; 08943 int res; 08944 08945 static const struct ast_party_id_ies from_ies = { 08946 .name.str = AST_REDIRECTING_FROM_NAME, 08947 .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET, 08948 .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION, 08949 .name.valid = AST_REDIRECTING_FROM_NAME_VALID, 08950 08951 .number.str = AST_REDIRECTING_FROM_NUMBER, 08952 .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN, 08953 .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION, 08954 .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID, 08955 08956 .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS, 08957 .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE, 08958 .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, 08959 .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID, 08960 08961 .tag = AST_REDIRECTING_FROM_TAG, 08962 .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION, 08963 }; 08964 static const struct ast_party_id_ies to_ies = { 08965 .name.str = AST_REDIRECTING_TO_NAME, 08966 .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET, 08967 .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION, 08968 .name.valid = AST_REDIRECTING_TO_NAME_VALID, 08969 08970 .number.str = AST_REDIRECTING_TO_NUMBER, 08971 .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN, 08972 .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION, 08973 .number.valid = AST_REDIRECTING_TO_NUMBER_VALID, 08974 08975 .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS, 08976 .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE, 08977 .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, 08978 .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID, 08979 08980 .tag = AST_REDIRECTING_TO_TAG, 08981 .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION, 08982 }; 08983 08984 /* Redirecting frame version */ 08985 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08986 ast_log(LOG_WARNING, "No space left for redirecting frame version\n"); 08987 return -1; 08988 } 08989 data[pos++] = AST_REDIRECTING_VERSION; 08990 data[pos++] = 1; 08991 data[pos++] = 2;/* Version 1 did not have a version ie */ 08992 08993 res = party_id_build_data(data + pos, datalen - pos, &redirecting->from, 08994 "redirecting-from", &from_ies, update ? &update->from : NULL); 08995 if (res < 0) { 08996 return -1; 08997 } 08998 pos += res; 08999 09000 res = party_id_build_data(data + pos, datalen - pos, &redirecting->to, 09001 "redirecting-to", &to_ies, update ? &update->to : NULL); 09002 if (res < 0) { 09003 return -1; 09004 } 09005 pos += res; 09006 09007 /* Redirecting reason */ 09008 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 09009 ast_log(LOG_WARNING, "No space left for redirecting reason\n"); 09010 return -1; 09011 } 09012 data[pos++] = AST_REDIRECTING_REASON; 09013 data[pos++] = sizeof(value); 09014 value = htonl(redirecting->reason); 09015 memcpy(data + pos, &value, sizeof(value)); 09016 pos += sizeof(value); 09017 09018 /* Redirecting count */ 09019 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 09020 ast_log(LOG_WARNING, "No space left for redirecting count\n"); 09021 return -1; 09022 } 09023 data[pos++] = AST_REDIRECTING_COUNT; 09024 data[pos++] = sizeof(value); 09025 value = htonl(redirecting->count); 09026 memcpy(data + pos, &value, sizeof(value)); 09027 pos += sizeof(value); 09028 09029 return pos; 09030 }
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 9032 of file channel.c.
References 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_DEBUG, 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().
09033 { 09034 size_t pos; 09035 unsigned char ie_len; 09036 unsigned char ie_id; 09037 int32_t value; 09038 int frame_version = 1; 09039 int from_combined_presentation = 0; 09040 int got_from_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 09041 int to_combined_presentation = 0; 09042 int got_to_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 09043 09044 for (pos = 0; pos < datalen; pos += ie_len) { 09045 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) { 09046 ast_log(LOG_WARNING, "Invalid redirecting update\n"); 09047 return -1; 09048 } 09049 ie_id = data[pos++]; 09050 ie_len = data[pos++]; 09051 if (datalen < pos + ie_len) { 09052 ast_log(LOG_WARNING, "Invalid redirecting update\n"); 09053 return -1; 09054 } 09055 09056 switch (ie_id) { 09057 /* Redirecting frame version */ 09058 case AST_REDIRECTING_VERSION: 09059 if (ie_len != 1) { 09060 ast_log(LOG_WARNING, "Invalid redirecting frame version (%u)\n", 09061 (unsigned) ie_len); 09062 break; 09063 } 09064 frame_version = data[pos]; 09065 break; 09066 /* Redirecting-from party id name */ 09067 case AST_REDIRECTING_FROM_NAME: 09068 ast_free(redirecting->from.name.str); 09069 redirecting->from.name.str = ast_malloc(ie_len + 1); 09070 if (redirecting->from.name.str) { 09071 memcpy(redirecting->from.name.str, data + pos, ie_len); 09072 redirecting->from.name.str[ie_len] = 0; 09073 } 09074 break; 09075 case AST_REDIRECTING_FROM_NAME_CHAR_SET: 09076 if (ie_len != 1) { 09077 ast_log(LOG_WARNING, "Invalid redirecting-from name char set (%u)\n", 09078 (unsigned) ie_len); 09079 break; 09080 } 09081 redirecting->from.name.char_set = data[pos]; 09082 break; 09083 case AST_REDIRECTING_FROM_NAME_PRESENTATION: 09084 if (ie_len != 1) { 09085 ast_log(LOG_WARNING, "Invalid redirecting-from name presentation (%u)\n", 09086 (unsigned) ie_len); 09087 break; 09088 } 09089 redirecting->from.name.presentation = data[pos]; 09090 break; 09091 case AST_REDIRECTING_FROM_NAME_VALID: 09092 if (ie_len != 1) { 09093 ast_log(LOG_WARNING, "Invalid redirecting-from name valid (%u)\n", 09094 (unsigned) ie_len); 09095 break; 09096 } 09097 redirecting->from.name.valid = data[pos]; 09098 break; 09099 /* Redirecting-from party id number */ 09100 case AST_REDIRECTING_FROM_NUMBER: 09101 ast_free(redirecting->from.number.str); 09102 redirecting->from.number.str = ast_malloc(ie_len + 1); 09103 if (redirecting->from.number.str) { 09104 memcpy(redirecting->from.number.str, data + pos, ie_len); 09105 redirecting->from.number.str[ie_len] = 0; 09106 } 09107 break; 09108 case AST_REDIRECTING_FROM_NUMBER_PLAN: 09109 if (ie_len != 1) { 09110 ast_log(LOG_WARNING, "Invalid redirecting-from numbering plan (%u)\n", 09111 (unsigned) ie_len); 09112 break; 09113 } 09114 redirecting->from.number.plan = data[pos]; 09115 break; 09116 case AST_REDIRECTING_FROM_NUMBER_PRESENTATION: 09117 if (ie_len != 1) { 09118 ast_log(LOG_WARNING, "Invalid redirecting-from number presentation (%u)\n", 09119 (unsigned) ie_len); 09120 break; 09121 } 09122 redirecting->from.number.presentation = data[pos]; 09123 break; 09124 case AST_REDIRECTING_FROM_NUMBER_VALID: 09125 if (ie_len != 1) { 09126 ast_log(LOG_WARNING, "Invalid redirecting-from number valid (%u)\n", 09127 (unsigned) ie_len); 09128 break; 09129 } 09130 redirecting->from.number.valid = data[pos]; 09131 break; 09132 /* Redirecting-from party id combined presentation */ 09133 case AST_REDIRECTING_FROM_ID_PRESENTATION: 09134 if (ie_len != 1) { 09135 ast_log(LOG_WARNING, "Invalid redirecting-from combined presentation (%u)\n", 09136 (unsigned) ie_len); 09137 break; 09138 } 09139 from_combined_presentation = data[pos]; 09140 got_from_combined_presentation = 1; 09141 break; 09142 /* Redirecting-from party id subaddress */ 09143 case AST_REDIRECTING_FROM_SUBADDRESS: 09144 ast_free(redirecting->from.subaddress.str); 09145 redirecting->from.subaddress.str = ast_malloc(ie_len + 1); 09146 if (redirecting->from.subaddress.str) { 09147 memcpy(redirecting->from.subaddress.str, data + pos, ie_len); 09148 redirecting->from.subaddress.str[ie_len] = 0; 09149 } 09150 break; 09151 case AST_REDIRECTING_FROM_SUBADDRESS_TYPE: 09152 if (ie_len != 1) { 09153 ast_log(LOG_WARNING, "Invalid redirecting-from type of subaddress (%u)\n", 09154 (unsigned) ie_len); 09155 break; 09156 } 09157 redirecting->from.subaddress.type = data[pos]; 09158 break; 09159 case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN: 09160 if (ie_len != 1) { 09161 ast_log(LOG_WARNING, 09162 "Invalid redirecting-from subaddress odd-even indicator (%u)\n", 09163 (unsigned) ie_len); 09164 break; 09165 } 09166 redirecting->from.subaddress.odd_even_indicator = data[pos]; 09167 break; 09168 case AST_REDIRECTING_FROM_SUBADDRESS_VALID: 09169 if (ie_len != 1) { 09170 ast_log(LOG_WARNING, "Invalid redirecting-from subaddress valid (%u)\n", 09171 (unsigned) ie_len); 09172 break; 09173 } 09174 redirecting->from.subaddress.valid = data[pos]; 09175 break; 09176 /* Redirecting-from party id tag */ 09177 case AST_REDIRECTING_FROM_TAG: 09178 ast_free(redirecting->from.tag); 09179 redirecting->from.tag = ast_malloc(ie_len + 1); 09180 if (redirecting->from.tag) { 09181 memcpy(redirecting->from.tag, data + pos, ie_len); 09182 redirecting->from.tag[ie_len] = 0; 09183 } 09184 break; 09185 /* Redirecting-to party id name */ 09186 case AST_REDIRECTING_TO_NAME: 09187 ast_free(redirecting->to.name.str); 09188 redirecting->to.name.str = ast_malloc(ie_len + 1); 09189 if (redirecting->to.name.str) { 09190 memcpy(redirecting->to.name.str, data + pos, ie_len); 09191 redirecting->to.name.str[ie_len] = 0; 09192 } 09193 break; 09194 case AST_REDIRECTING_TO_NAME_CHAR_SET: 09195 if (ie_len != 1) { 09196 ast_log(LOG_WARNING, "Invalid redirecting-to name char set (%u)\n", 09197 (unsigned) ie_len); 09198 break; 09199 } 09200 redirecting->to.name.char_set = data[pos]; 09201 break; 09202 case AST_REDIRECTING_TO_NAME_PRESENTATION: 09203 if (ie_len != 1) { 09204 ast_log(LOG_WARNING, "Invalid redirecting-to name presentation (%u)\n", 09205 (unsigned) ie_len); 09206 break; 09207 } 09208 redirecting->to.name.presentation = data[pos]; 09209 break; 09210 case AST_REDIRECTING_TO_NAME_VALID: 09211 if (ie_len != 1) { 09212 ast_log(LOG_WARNING, "Invalid redirecting-to name valid (%u)\n", 09213 (unsigned) ie_len); 09214 break; 09215 } 09216 redirecting->to.name.valid = data[pos]; 09217 break; 09218 /* Redirecting-to party id number */ 09219 case AST_REDIRECTING_TO_NUMBER: 09220 ast_free(redirecting->to.number.str); 09221 redirecting->to.number.str = ast_malloc(ie_len + 1); 09222 if (redirecting->to.number.str) { 09223 memcpy(redirecting->to.number.str, data + pos, ie_len); 09224 redirecting->to.number.str[ie_len] = 0; 09225 } 09226 break; 09227 case AST_REDIRECTING_TO_NUMBER_PLAN: 09228 if (ie_len != 1) { 09229 ast_log(LOG_WARNING, "Invalid redirecting-to numbering plan (%u)\n", 09230 (unsigned) ie_len); 09231 break; 09232 } 09233 redirecting->to.number.plan = data[pos]; 09234 break; 09235 case AST_REDIRECTING_TO_NUMBER_PRESENTATION: 09236 if (ie_len != 1) { 09237 ast_log(LOG_WARNING, "Invalid redirecting-to number presentation (%u)\n", 09238 (unsigned) ie_len); 09239 break; 09240 } 09241 redirecting->to.number.presentation = data[pos]; 09242 break; 09243 case AST_REDIRECTING_TO_NUMBER_VALID: 09244 if (ie_len != 1) { 09245 ast_log(LOG_WARNING, "Invalid redirecting-to number valid (%u)\n", 09246 (unsigned) ie_len); 09247 break; 09248 } 09249 redirecting->to.number.valid = data[pos]; 09250 break; 09251 /* Redirecting-to party id combined presentation */ 09252 case AST_REDIRECTING_TO_ID_PRESENTATION: 09253 if (ie_len != 1) { 09254 ast_log(LOG_WARNING, "Invalid redirecting-to combined presentation (%u)\n", 09255 (unsigned) ie_len); 09256 break; 09257 } 09258 to_combined_presentation = data[pos]; 09259 got_to_combined_presentation = 1; 09260 break; 09261 /* Redirecting-to party id subaddress */ 09262 case AST_REDIRECTING_TO_SUBADDRESS: 09263 ast_free(redirecting->to.subaddress.str); 09264 redirecting->to.subaddress.str = ast_malloc(ie_len + 1); 09265 if (redirecting->to.subaddress.str) { 09266 memcpy(redirecting->to.subaddress.str, data + pos, ie_len); 09267 redirecting->to.subaddress.str[ie_len] = 0; 09268 } 09269 break; 09270 case AST_REDIRECTING_TO_SUBADDRESS_TYPE: 09271 if (ie_len != 1) { 09272 ast_log(LOG_WARNING, "Invalid redirecting-to type of subaddress (%u)\n", 09273 (unsigned) ie_len); 09274 break; 09275 } 09276 redirecting->to.subaddress.type = data[pos]; 09277 break; 09278 case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN: 09279 if (ie_len != 1) { 09280 ast_log(LOG_WARNING, 09281 "Invalid redirecting-to subaddress odd-even indicator (%u)\n", 09282 (unsigned) ie_len); 09283 break; 09284 } 09285 redirecting->to.subaddress.odd_even_indicator = data[pos]; 09286 break; 09287 case AST_REDIRECTING_TO_SUBADDRESS_VALID: 09288 if (ie_len != 1) { 09289 ast_log(LOG_WARNING, "Invalid redirecting-to subaddress valid (%u)\n", 09290 (unsigned) ie_len); 09291 break; 09292 } 09293 redirecting->to.subaddress.valid = data[pos]; 09294 break; 09295 /* Redirecting-to party id tag */ 09296 case AST_REDIRECTING_TO_TAG: 09297 ast_free(redirecting->to.tag); 09298 redirecting->to.tag = ast_malloc(ie_len + 1); 09299 if (redirecting->to.tag) { 09300 memcpy(redirecting->to.tag, data + pos, ie_len); 09301 redirecting->to.tag[ie_len] = 0; 09302 } 09303 break; 09304 /* Redirecting reason */ 09305 case AST_REDIRECTING_REASON: 09306 if (ie_len != sizeof(value)) { 09307 ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n", 09308 (unsigned) ie_len); 09309 break; 09310 } 09311 memcpy(&value, data + pos, sizeof(value)); 09312 redirecting->reason = ntohl(value); 09313 break; 09314 /* Redirecting count */ 09315 case AST_REDIRECTING_COUNT: 09316 if (ie_len != sizeof(value)) { 09317 ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n", 09318 (unsigned) ie_len); 09319 break; 09320 } 09321 memcpy(&value, data + pos, sizeof(value)); 09322 redirecting->count = ntohl(value); 09323 break; 09324 /* Redirecting unknown element */ 09325 default: 09326 ast_log(LOG_DEBUG, "Unknown redirecting element: %u (%u)\n", 09327 (unsigned) ie_id, (unsigned) ie_len); 09328 break; 09329 } 09330 } 09331 09332 switch (frame_version) { 09333 case 1: 09334 /* 09335 * The other end is an earlier version that we need to adjust 09336 * for compatibility. 09337 */ 09338 redirecting->from.name.valid = 1; 09339 redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 09340 redirecting->from.number.valid = 1; 09341 if (got_from_combined_presentation) { 09342 redirecting->from.name.presentation = from_combined_presentation; 09343 redirecting->from.number.presentation = from_combined_presentation; 09344 } 09345 09346 redirecting->to.name.valid = 1; 09347 redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 09348 redirecting->to.number.valid = 1; 09349 if (got_to_combined_presentation) { 09350 redirecting->to.name.presentation = to_combined_presentation; 09351 redirecting->to.number.presentation = to_combined_presentation; 09352 } 09353 break; 09354 case 2: 09355 /* The other end is at the same level as we are. */ 09356 break; 09357 default: 09358 /* 09359 * The other end is newer than we are. 09360 * We need to assume that they are compatible with us. 09361 */ 09362 ast_log(LOG_DEBUG, "Redirecting frame has newer version: %u\n", 09363 (unsigned) frame_version); 09364 break; 09365 } 09366 09367 return 0; 09368 }
struct ast_channel* ast_request | ( | const char * | type, | |
format_t | format, | |||
const struct ast_channel * | requestor, | |||
void * | data, | |||
int * | status | |||
) |
Requests a channel.
type | type of channel to request | |
format | requested channel format (codec) | |
requestor | channel asking for data | |
data | data to pass to the channel requester (Should be treated as const char *) | |
status | status |
NULL | failure | |
non-NULL | channel on success |
Definition at line 5579 of file channel.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_NOSUCHDRIVER, AST_CAUSE_NOTDEFINED, ast_channel_release(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_translator_best_choice(), ast_channel_tech::capabilities, capabilities, chanlist::chan, chanlist::list, LOG_WARNING, ast_channel_tech::requester, set_security_requirements(), ast_channel::tech, and ast_channel_tech::type.
Referenced by __ast_request_and_dial(), ast_call_forward(), begin_dial_channel(), build_conf(), chanavail_exec(), conf_run(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), play_sound_file(), and ring_entry().
05580 { 05581 struct chanlist *chan; 05582 struct ast_channel *c; 05583 format_t capabilities; 05584 format_t fmt; 05585 int res; 05586 int foo; 05587 format_t videoformat = format & AST_FORMAT_VIDEO_MASK; 05588 format_t textformat = format & AST_FORMAT_TEXT_MASK; 05589 05590 if (!cause) 05591 cause = &foo; 05592 *cause = AST_CAUSE_NOTDEFINED; 05593 05594 if (AST_RWLIST_RDLOCK(&backends)) { 05595 ast_log(LOG_WARNING, "Unable to lock technology backend list\n"); 05596 return NULL; 05597 } 05598 05599 AST_RWLIST_TRAVERSE(&backends, chan, list) { 05600 if (strcasecmp(type, chan->tech->type)) 05601 continue; 05602 05603 capabilities = chan->tech->capabilities; 05604 fmt = format & AST_FORMAT_AUDIO_MASK; 05605 if (fmt) { 05606 /* We have audio - is it possible to connect the various calls to each other? 05607 (Avoid this check for calls without audio, like text+video calls) 05608 */ 05609 res = ast_translator_best_choice(&fmt, &capabilities); 05610 if (res < 0) { 05611 char tmp1[256], tmp2[256]; 05612 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %s) to %s\n", type, 05613 ast_getformatname_multiple(tmp1, sizeof(tmp1), chan->tech->capabilities), 05614 ast_getformatname_multiple(tmp2, sizeof(tmp2), format)); 05615 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05616 AST_RWLIST_UNLOCK(&backends); 05617 return NULL; 05618 } 05619 } 05620 AST_RWLIST_UNLOCK(&backends); 05621 if (!chan->tech->requester) 05622 return NULL; 05623 05624 if (!(c = chan->tech->requester(type, capabilities | videoformat | textformat, requestor, data, cause))) 05625 return NULL; 05626 05627 if (set_security_requirements(requestor, c)) { 05628 ast_log(LOG_WARNING, "Setting security requirements failed\n"); 05629 c = ast_channel_release(c); 05630 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05631 return NULL; 05632 } 05633 05634 /* no need to generate a Newchannel event here; it is done in the channel_alloc call */ 05635 return c; 05636 } 05637 05638 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 05639 *cause = AST_CAUSE_NOSUCHDRIVER; 05640 AST_RWLIST_UNLOCK(&backends); 05641 05642 return NULL; 05643 }
struct ast_channel* ast_request_and_dial | ( | const char * | type, | |
format_t | format, | |||
const struct ast_channel * | requestor, | |||
void * | data, | |||
int | timeout, | |||
int * | reason, | |||
const char * | cid_num, | |||
const char * | cid_name | |||
) |
Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.
type | type of channel to request | |
format | requested channel format | |
requestor | channel asking for data | |
data | data to pass to the channel requester | |
timeout | maximum amount of time to wait for an answer | |
reason | why unsuccessful (if unsuccessful) | |
cid_num | Caller-ID Number | |
cid_name | Caller-ID Name (ascii) |
Definition at line 5534 of file channel.c.
References __ast_request_and_dial().
Referenced by ast_pbx_outgoing_exten(), and generic_recall().
05535 { 05536 return __ast_request_and_dial(type, format, requestor, data, timeout, outstate, cidnum, cidname, NULL); 05537 }
int ast_safe_sleep | ( | struct ast_channel * | chan, | |
int | ms | |||
) |
Wait for a specified amount of time, looking for hangups.
chan | channel to wait for | |
ms | length of time in milliseconds to sleep |
Definition at line 1884 of file channel.c.
References ast_safe_sleep_conditional(), and chanlist::chan.
Referenced by __analog_ss_thread(), adsi_transmit_message_full(), alarmreceiver_exec(), analog_ss_thread(), ast_dtmf_stream(), ast_senddigit(), builtin_atxfer(), builtin_parkcall(), conf_run(), dahdi_send_callrerouting_facility_exec(), dictate_exec(), flash_exec(), handle_callforward_button(), login_exec(), mgcp_ss(), milliwatt_exec(), misdn_check_l2l1(), old_milliwatt_exec(), park_call_exec(), pbx_builtin_wait(), play_moh_exec(), playtone(), privacy_exec(), receive_ademco_contact_id(), skinny_ss(), testclient_exec(), testserver_exec(), wait_for_hangup(), wait_moh_exec(), waituntil_exec(), and zapateller_exec().
01885 { 01886 return ast_safe_sleep_conditional(chan, ms, NULL, NULL); 01887 }
int ast_safe_sleep_conditional | ( | struct ast_channel * | chan, | |
int | ms, | |||
int(*)(void *) | cond, | |||
void * | data | |||
) |
Wait for a specified amount of time, looking for hangups and a condition argument.
chan | channel to wait for | |
ms | length of time in milliseconds to sleep | |
cond | a function pointer for testing continue condition | |
data | argument to be passed to the condition test function |
Definition at line 1817 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(), chanlist::chan, f, and ast_channel::generatordata.
Referenced by ast_safe_sleep(), and login_exec().
01818 { 01819 struct ast_frame *f; 01820 struct ast_silence_generator *silgen = NULL; 01821 int res = 0; 01822 AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames; 01823 01824 AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames); 01825 01826 /* If no other generator is present, start silencegen while waiting */ 01827 if (ast_opt_transmit_silence && !chan->generatordata) { 01828 silgen = ast_channel_start_silence_generator(chan); 01829 } 01830 01831 while (ms > 0) { 01832 struct ast_frame *dup_f = NULL; 01833 if (cond && ((*cond)(data) == 0)) { 01834 break; 01835 } 01836 ms = ast_waitfor(chan, ms); 01837 if (ms < 0) { 01838 res = -1; 01839 break; 01840 } 01841 if (ms > 0) { 01842 f = ast_read(chan); 01843 if (!f) { 01844 res = -1; 01845 break; 01846 } 01847 01848 if (!ast_is_deferrable_frame(f)) { 01849 ast_frfree(f); 01850 continue; 01851 } 01852 01853 if ((dup_f = ast_frisolate(f))) { 01854 if (dup_f != f) { 01855 ast_frfree(f); 01856 } 01857 AST_LIST_INSERT_HEAD(&deferred_frames, dup_f, frame_list); 01858 } 01859 } 01860 } 01861 01862 /* stop silgen if present */ 01863 if (silgen) { 01864 ast_channel_stop_silence_generator(chan, silgen); 01865 } 01866 01867 /* We need to free all the deferred frames, but we only need to 01868 * queue the deferred frames if there was no error and no 01869 * hangup was received 01870 */ 01871 ast_channel_lock(chan); 01872 while ((f = AST_LIST_REMOVE_HEAD(&deferred_frames, frame_list))) { 01873 if (!res) { 01874 ast_queue_frame_head(chan, f); 01875 } 01876 ast_frfree(f); 01877 } 01878 ast_channel_unlock(chan); 01879 01880 return res; 01881 }
int ast_say_character_str | ( | struct ast_channel * | chan, | |
const char * | str, | |||
const char * | ints, | |||
const char * | lang | |||
) |
Definition at line 8199 of file channel.c.
References ast_say_character_str_full.
Referenced by common_exec(), pbx_builtin_saycharacters(), play_mailbox_owner(), and vmsayname_exec().
08201 { 08202 return ast_say_character_str_full(chan, str, ints, lang, -1, -1); 08203 }
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 8193 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().
08195 { 08196 return ast_say_digit_str_full(chan, str, ints, lang, -1, -1); 08197 }
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 8187 of file channel.c.
References ast_say_digits_full().
Referenced by common_exec(), conf_exec(), conf_run(), park_call_full(), and parkandannounce_exec().
08189 { 08190 return ast_say_digits_full(chan, num, ints, lang, -1, -1); 08191 }
int ast_say_digits_full | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | ints, | |||
const char * | lang, | |||
int | audiofd, | |||
int | ctrlfd | |||
) |
Definition at line 8211 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().
08213 { 08214 char buf[256]; 08215 08216 snprintf(buf, sizeof(buf), "%d", num); 08217 08218 return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd); 08219 }
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 8181 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().
08183 { 08184 return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1); 08185 }
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 8175 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(), say_and_wait(), say_position(), vm_intro_gr(), vm_intro_he(), vm_intro_multilang(), vm_intro_pt(), and vm_intro_pt_BR().
08177 { 08178 return ast_say_number_full(chan, num, ints, language, options, -1, -1); 08179 }
int ast_say_phonetic_str | ( | struct ast_channel * | chan, | |
const char * | str, | |||
const char * | ints, | |||
const char * | lang | |||
) |
Definition at line 8205 of file channel.c.
References ast_say_phonetic_str_full.
Referenced by pbx_builtin_sayphonetic().
08207 { 08208 return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1); 08209 }
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 4659 of file channel.c.
References AST_DEFAULT_EMULATE_DTMF_DURATION, ast_safe_sleep(), ast_senddigit_begin(), ast_senddigit_end(), chanlist::chan, ast_channel_tech::send_digit_begin, and ast_channel::tech.
Referenced by ast_dtmf_stream(), dial_exec_full(), and manager_play_dtmf().
04660 { 04661 if (chan->tech->send_digit_begin) { 04662 ast_senddigit_begin(chan, digit); 04663 ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 04664 } 04665 04666 return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 04667 }
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 4601 of file channel.c.
References ast_debug, ast_playtones_start(), chanlist::chan, ast_channel::name, ast_channel_tech::send_digit_begin, and ast_channel::tech.
Referenced by agent_digit_begin(), ast_senddigit(), and ast_write().
04602 { 04603 /* Device does not support DTMF tones, lets fake 04604 * it by doing our own generation. */ 04605 static const char * const dtmf_tones[] = { 04606 "941+1336", /* 0 */ 04607 "697+1209", /* 1 */ 04608 "697+1336", /* 2 */ 04609 "697+1477", /* 3 */ 04610 "770+1209", /* 4 */ 04611 "770+1336", /* 5 */ 04612 "770+1477", /* 6 */ 04613 "852+1209", /* 7 */ 04614 "852+1336", /* 8 */ 04615 "852+1477", /* 9 */ 04616 "697+1633", /* A */ 04617 "770+1633", /* B */ 04618 "852+1633", /* C */ 04619 "941+1633", /* D */ 04620 "941+1209", /* * */ 04621 "941+1477" /* # */ 04622 }; 04623 04624 if (!chan->tech->send_digit_begin) 04625 return 0; 04626 04627 if (!chan->tech->send_digit_begin(chan, digit)) 04628 return 0; 04629 04630 if (digit >= '0' && digit <='9') 04631 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0); 04632 else if (digit >= 'A' && digit <= 'D') 04633 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0); 04634 else if (digit == '*') 04635 ast_playtones_start(chan, 0, dtmf_tones[14], 0); 04636 else if (digit == '#') 04637 ast_playtones_start(chan, 0, dtmf_tones[15], 0); 04638 else { 04639 /* not handled */ 04640 ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name); 04641 } 04642 04643 return 0; 04644 }
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 4646 of file channel.c.
References ast_playtones_stop(), chanlist::chan, ast_channel::generator, ast_channel_tech::send_digit_end, and ast_channel::tech.
Referenced by agent_digit_end(), ast_senddigit(), and ast_write().
04647 { 04648 int res = -1; 04649 04650 if (chan->tech->send_digit_end) 04651 res = chan->tech->send_digit_end(chan, digit, duration); 04652 04653 if (res && chan->generator) 04654 ast_playtones_stop(chan); 04655 04656 return 0; 04657 }
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 4583 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_test_flag, chanlist::chan, CHECK_BLOCKING, ast_channel_tech::send_text, and ast_channel::tech.
Referenced by action_sendtext(), agent_sendtext(), handle_sendtext(), and sendtext_exec().
04584 { 04585 int res = 0; 04586 04587 ast_channel_lock(chan); 04588 /* Stop if we're a zombie or need a soft hangup */ 04589 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 04590 ast_channel_unlock(chan); 04591 return -1; 04592 } 04593 CHECK_BLOCKING(chan); 04594 if (chan->tech->send_text) 04595 res = chan->tech->send_text(chan, text); 04596 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04597 ast_channel_unlock(chan); 04598 return res; 04599 }
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 6885 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, chanlist::chan, 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(), __ast_request_and_dial(), analog_ss_thread(), cb_events(), get_pai(), get_rpid(), handle_setcallerid(), mgcp_ss(), ring_entry(), skinny_newcall(), and socket_process().
06886 { 06887 ast_channel_lock(chan); 06888 06889 if (cid_num) { 06890 chan->caller.id.number.valid = 1; 06891 ast_free(chan->caller.id.number.str); 06892 chan->caller.id.number.str = ast_strdup(cid_num); 06893 } 06894 if (cid_name) { 06895 chan->caller.id.name.valid = 1; 06896 ast_free(chan->caller.id.name.str); 06897 chan->caller.id.name.str = ast_strdup(cid_name); 06898 } 06899 if (cid_ani) { 06900 chan->caller.ani.number.valid = 1; 06901 ast_free(chan->caller.ani.number.str); 06902 chan->caller.ani.number.str = ast_strdup(cid_ani); 06903 } 06904 if (chan->cdr) { 06905 ast_cdr_setcid(chan->cdr, chan); 06906 } 06907 06908 report_new_callerid(chan); 06909 06910 ast_channel_unlock(chan); 06911 }
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 2736 of file channel.c.
References ast_bridged_channel(), ast_channel_lock, ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_string_field_set, ast_strlen_zero(), ast_channel::bridge, chanlist::chan, and ast_channel::hangupsource.
Referenced by __dahdi_exception(), analog_exception(), func_channel_write_real(), handle_hangup(), pbx_builtin_hangup(), set_hangup_source_and_cause(), and sip_queue_hangup_cause().
02737 { 02738 struct ast_channel *bridge; 02739 02740 ast_channel_lock(chan); 02741 if (force || ast_strlen_zero(chan->hangupsource)) { 02742 ast_string_field_set(chan, hangupsource, source); 02743 } 02744 bridge = ast_bridged_channel(chan); 02745 if (bridge) { 02746 ast_channel_ref(bridge); 02747 } 02748 ast_channel_unlock(chan); 02749 02750 if (bridge) { 02751 ast_channel_lock(bridge); 02752 if (force || ast_strlen_zero(bridge->hangupsource)) { 02753 ast_string_field_set(bridge, hangupsource, source); 02754 } 02755 ast_channel_unlock(bridge); 02756 ast_channel_unref(bridge); 02757 } 02758 }
static void ast_set_owners_and_peers | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 6313 of file channel.c.
References accountcode, ast_channel::accountcode, ast_log(), ast_string_field_set, ast_strlen_zero(), LOG_DEBUG, ast_channel::name, and ast_channel::peeraccount.
Referenced by ast_channel_bridge().
06315 { 06316 if (!ast_strlen_zero(chan1->accountcode) && ast_strlen_zero(chan2->peeraccount)) { 06317 ast_log(LOG_DEBUG, "setting peeraccount to %s for %s from data on channel %s\n", 06318 chan1->accountcode, chan2->name, chan1->name); 06319 ast_string_field_set(chan2, peeraccount, chan1->accountcode); 06320 } 06321 if (!ast_strlen_zero(chan2->accountcode) && ast_strlen_zero(chan1->peeraccount)) { 06322 ast_log(LOG_DEBUG, "setting peeraccount to %s for %s from data on channel %s\n", 06323 chan2->accountcode, chan1->name, chan2->name); 06324 ast_string_field_set(chan1, peeraccount, chan2->accountcode); 06325 } 06326 if (!ast_strlen_zero(chan1->peeraccount) && ast_strlen_zero(chan2->accountcode)) { 06327 ast_log(LOG_DEBUG, "setting accountcode to %s for %s from data on channel %s\n", 06328 chan1->peeraccount, chan2->name, chan1->name); 06329 ast_string_field_set(chan2, accountcode, chan1->peeraccount); 06330 } 06331 if (!ast_strlen_zero(chan2->peeraccount) && ast_strlen_zero(chan1->accountcode)) { 06332 ast_log(LOG_DEBUG, "setting accountcode to %s for %s from data on channel %s\n", 06333 chan2->peeraccount, chan1->name, chan2->name); 06334 ast_string_field_set(chan1, accountcode, chan2->peeraccount); 06335 } 06336 if (0 != strcmp(chan1->accountcode, chan2->peeraccount)) { 06337 ast_log(LOG_DEBUG, "changing peeraccount from %s to %s on %s to match channel %s\n", 06338 chan2->peeraccount, chan1->peeraccount, chan2->name, chan1->name); 06339 ast_string_field_set(chan2, peeraccount, chan1->accountcode); 06340 } 06341 if (0 != strcmp(chan2->accountcode, chan1->peeraccount)) { 06342 ast_log(LOG_DEBUG, "changing peeraccount from %s to %s on %s to match channel %s\n", 06343 chan1->peeraccount, chan2->peeraccount, chan1->name, chan2->name); 06344 ast_string_field_set(chan1, peeraccount, chan2->accountcode); 06345 } 06346 }
int ast_set_read_format | ( | struct ast_channel * | chan, | |
format_t | format | |||
) |
Sets read format on channel chan Set read format for channel to whichever component of "format" is best.
chan | channel to change | |
format | format to change to |
Definition at line 5186 of file channel.c.
References chanlist::chan, ast_channel::rawreadformat, ast_channel::readformat, ast_channel::readtrans, and set_format().
Referenced by __ast_play_and_record(), __oh323_update_info(), adsi_transmit_message_full(), agent_call(), alarmreceiver_exec(), ast_channel_make_compatible_helper(), ast_do_masquerade(), background_detect_exec(), bridge_channel_join(), bridge_make_compatible(), build_conf(), conf_run(), dictate_exec(), do_waiting(), eagi_exec(), echo_exec(), generic_fax_exec(), gtalk_rtp_read(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), jack_exec(), jingle_rtp_read(), login_exec(), measurenoise(), mgcp_rtp_read(), oh323_rtp_read(), old_milliwatt_exec(), process_sdp(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), speech_background(), transmit_audio(), and unistim_rtp_read().
05187 { 05188 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat, 05189 &chan->readtrans, 0); 05190 }
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 8062 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().
08063 { 08064 struct ast_variable *cur; 08065 08066 for (cur = vars; cur; cur = cur->next) 08067 pbx_builtin_setvar_helper(chan, cur->name, cur->value); 08068 }
int ast_set_write_format | ( | struct ast_channel * | chan, | |
format_t | format | |||
) |
Sets write format on channel chan Set write format for channel to whichever component of "format" is best.
chan | channel to change | |
format | new format for writing |
Definition at line 5192 of file channel.c.
References chanlist::chan, ast_channel::rawwriteformat, set_format(), ast_channel::writeformat, and ast_channel::writetrans.
Referenced by __oh323_update_info(), adsi_transmit_message_full(), agent_call(), alarmreceiver_exec(), ast_channel_make_compatible_helper(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_do_masquerade(), ast_openstream_full(), ast_stopstream(), ast_write(), bridge_channel_join(), bridge_make_compatible(), build_conf(), chanspy_exec(), conf_run(), dahdiscan_exec(), echo_exec(), extenspy_exec(), generic_fax_exec(), gtalk_rtp_read(), jack_exec(), jingle_rtp_read(), linear_alloc(), linear_release(), login_exec(), mgcp_rtp_read(), moh_alloc(), moh_files_release(), moh_release(), mp3_exec(), NBScat_exec(), oh323_rtp_read(), old_milliwatt_exec(), playtones_alloc(), playtones_release(), process_sdp(), send_waveform_to_channel(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), tonepair_alloc(), tonepair_release(), transmit_audio(), and unistim_rtp_read().
05193 { 05194 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat, 05195 &chan->writetrans, 1); 05196 }
int ast_setstate | ( | struct ast_channel * | chan, | |
enum ast_channel_state | state | |||
) |
Change the state of a channel.
Definition at line 6953 of file channel.c.
References ast_channel::_state, AST_CHANNEL_NAME, ast_copy_string(), AST_DEVICE_UNKNOWN, ast_devstate_changed_literal(), ast_manager_event, ast_state2str(), ast_channel::caller, chanlist::chan, ast_channel::connected, EVENT_FLAG_CALL, ast_party_connected_line::id, ast_party_caller::id, ast_party_id::name, ast_channel::name, name, ast_party_id::number, S_COR, ast_party_name::str, ast_party_number::str, ast_channel::uniqueid, 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_offhook_message(), handle_request_invite(), handle_response_invite(), handle_soft_key_event_message(), handle_stimulus_message(), iax2_call(), jingle_call(), jingle_newcall(), local_queue_frame(), mgcp_answer(), mgcp_call(), mgcp_ss(), misdn_call(), misdn_indication(), 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(), pri_ss_thread(), release_chan(), release_chan_early(), sig_pri_answer(), sig_pri_call(), sig_pri_indicate(), sip_answer(), skinny_answer(), skinny_call(), skinny_newcall(), unistim_answer(), unistim_call(), unistim_new(), unistim_ss(), and update_state().
06954 { 06955 int oldstate = chan->_state; 06956 char name[AST_CHANNEL_NAME], *dashptr; 06957 06958 if (oldstate == state) 06959 return 0; 06960 06961 ast_copy_string(name, chan->name, sizeof(name)); 06962 if ((dashptr = strrchr(name, '-'))) { 06963 *dashptr = '\0'; 06964 } 06965 06966 chan->_state = state; 06967 06968 /* We have to pass AST_DEVICE_UNKNOWN here because it is entirely possible that the channel driver 06969 * for this channel is using the callback method for device state. If we pass in an actual state here 06970 * we override what they are saying the state is and things go amuck. */ 06971 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, name); 06972 06973 /* setstate used to conditionally report Newchannel; this is no more */ 06974 ast_manager_event(chan, EVENT_FLAG_CALL, "Newstate", 06975 "Channel: %s\r\n" 06976 "ChannelState: %d\r\n" 06977 "ChannelStateDesc: %s\r\n" 06978 "CallerIDNum: %s\r\n" 06979 "CallerIDName: %s\r\n" 06980 "ConnectedLineNum: %s\r\n" 06981 "ConnectedLineName: %s\r\n" 06982 "Uniqueid: %s\r\n", 06983 chan->name, chan->_state, ast_state2str(chan->_state), 06984 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""), 06985 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""), 06986 S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, ""), 06987 S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, ""), 06988 chan->uniqueid); 06989 06990 return 0; 06991 }
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 3502 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_debug, ast_timer_get_max_rate(), ast_timer_set_rate(), AST_TIMING_FD, ast_channel::fdno, 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().
03503 { 03504 int res; 03505 unsigned int real_rate = rate, max_rate; 03506 03507 ast_channel_lock(c); 03508 03509 if (c->timingfd == -1) { 03510 ast_channel_unlock(c); 03511 return -1; 03512 } 03513 03514 if (!func) { 03515 rate = 0; 03516 data = NULL; 03517 } 03518 03519 if (rate && rate > (max_rate = ast_timer_get_max_rate(c->timer))) { 03520 real_rate = max_rate; 03521 } 03522 03523 ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate); 03524 03525 res = ast_timer_set_rate(c->timer, real_rate); 03526 03527 c->timingfunc = func; 03528 c->timingdata = data; 03529 03530 if (func == NULL && rate == 0 && c->fdno == AST_TIMING_FD) { 03531 /* Clearing the timing func and setting the rate to 0 03532 * means that we don't want to be reading from the timingfd 03533 * any more. Setting c->fdno to -1 means we won't have any 03534 * errant reads from the timingfd, meaning we won't potentially 03535 * miss any important frames. 03536 */ 03537 c->fdno = -1; 03538 } 03539 03540 ast_channel_unlock(c); 03541 03542 return res; 03543 }
int ast_shutting_down | ( | void | ) |
Returns non-zero if Asterisk is being shut down.
Definition at line 854 of file channel.c.
Referenced by handle_request_options().
00855 { 00856 return shutting_down; 00857 }
int ast_softhangup | ( | struct ast_channel * | chan, | |
int | reason | |||
) |
Softly hangup up a channel.
chan | channel to be soft-hung-up | |
reason | an AST_SOFTHANGUP_* reason code |
Definition at line 2713 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_softhangup_nolock(), and chanlist::chan.
Referenced by __analog_handle_event(), __ast_module_user_hangup_all(), __unload_module(), agent_hangup(), agent_logoff(), agent_read(), ast_bridge_call(), ast_channel_softhangup_cb(), ast_dial_join(), cc_generic_agent_stop_ringing(), conf_free(), dahdi_handle_event(), handle_hangup(), handle_softhangup(), login_exec(), manager_park(), mgcp_pktcgate_remove(), read_agent_config(), sla_handle_hold_event(), softhangup_exec(), start_spying(), startmon(), and unload_module().
02714 { 02715 int res; 02716 02717 ast_channel_lock(chan); 02718 res = ast_softhangup_nolock(chan, cause); 02719 ast_channel_unlock(chan); 02720 02721 return res; 02722 }
int ast_softhangup_nolock | ( | struct ast_channel * | chan, | |
int | reason | |||
) |
Softly hangup up a channel (no channel lock).
chan | channel to be soft-hung-up | |
reason | an AST_SOFTHANGUP_* reason code |
Definition at line 2700 of file channel.c.
References ast_channel::_softhangup, ast_debug, AST_FLAG_BLOCKING, ast_null_frame, ast_queue_frame(), ast_test_flag, ast_channel::blocker, chanlist::chan, and ast_channel::name.
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(), sig_pri_indicate(), sig_pri_send_aoce_termination_request(), sip_indicate(), and skinny_indicate().
02701 { 02702 ast_debug(1, "Soft-Hanging up channel '%s'\n", chan->name); 02703 /* Inform channel driver that we need to be hung up, if it cares */ 02704 chan->_softhangup |= cause; 02705 ast_queue_frame(chan, &ast_null_frame); 02706 /* Interrupt any poll call or such */ 02707 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) 02708 pthread_kill(chan->blocker, SIGURG); 02709 return 0; 02710 }
const char* ast_state2str | ( | enum ast_channel_state | state | ) |
Gives the string form of a given channel state.
Definition at line 996 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(), 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().
00997 { 00998 char *buf; 00999 01000 switch (state) { 01001 case AST_STATE_DOWN: 01002 return "Down"; 01003 case AST_STATE_RESERVED: 01004 return "Rsrvd"; 01005 case AST_STATE_OFFHOOK: 01006 return "OffHook"; 01007 case AST_STATE_DIALING: 01008 return "Dialing"; 01009 case AST_STATE_RING: 01010 return "Ring"; 01011 case AST_STATE_RINGING: 01012 return "Ringing"; 01013 case AST_STATE_UP: 01014 return "Up"; 01015 case AST_STATE_BUSY: 01016 return "Busy"; 01017 case AST_STATE_DIALING_OFFHOOK: 01018 return "Dialing Offhook"; 01019 case AST_STATE_PRERING: 01020 return "Pre-ring"; 01021 default: 01022 if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE))) 01023 return "Unknown"; 01024 snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state); 01025 return buf; 01026 } 01027 }
int ast_str2cause | ( | const char * | name | ) |
Convert the string form of a cause code to a number.
name | string form of the cause |
Definition at line 982 of file channel.c.
References ARRAY_LEN, and causes.
Referenced by pbx_builtin_hangup().
00983 { 00984 int x; 00985 00986 for (x = 0; x < ARRAY_LEN(causes); x++) 00987 if (!strncasecmp(causes[x].name, name, strlen(causes[x].name))) 00988 return causes[x].cause; 00989 00990 return -1; 00991 }
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 7782 of file channel.c.
References ast_frfree, ast_read(), ast_tonepair_start(), ast_waitfor(), f, and ast_channel::generatordata.
Referenced by zapateller_exec().
07783 { 07784 int res; 07785 07786 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 07787 return res; 07788 07789 /* Give us some wiggle room */ 07790 while (chan->generatordata && ast_waitfor(chan, 100) >= 0) { 07791 struct ast_frame *f = ast_read(chan); 07792 if (f) 07793 ast_frfree(f); 07794 else 07795 return -1; 07796 } 07797 return 0; 07798 }
int ast_tonepair_start | ( | struct ast_channel * | chan, | |
int | freq1, | |||
int | freq2, | |||
int | duration, | |||
int | vol | |||
) |
Start a tone going
Definition at line 7764 of file channel.c.
References ast_activate_generator(), tonepair_def::duration, tonepair_def::freq1, tonepair_def::freq2, tonepair, and tonepair_def::vol.
Referenced by ast_tonepair(), pbx_builtin_waitexten(), play_dialtone(), and sendnoise().
07765 { 07766 struct tonepair_def d = { 0, }; 07767 07768 d.freq1 = freq1; 07769 d.freq2 = freq2; 07770 d.duration = duration; 07771 d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */ 07772 if (ast_activate_generator(chan, &tonepair, &d)) 07773 return -1; 07774 return 0; 07775 }
void ast_tonepair_stop | ( | struct ast_channel * | chan | ) |
Stop a tone from playing
Definition at line 7777 of file channel.c.
References ast_deactivate_generator().
Referenced by sendnoise().
07778 { 07779 ast_deactivate_generator(chan); 07780 }
int ast_transfer | ( | struct ast_channel * | chan, | |
char * | dest | |||
) |
Transfer a channel (if supported).
Called by:
Definition at line 5672 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(), chanlist::chan, ast_channel::tech, and ast_channel_tech::transfer.
Referenced by transfer_exec().
05673 { 05674 int res = -1; 05675 05676 /* Stop if we're a zombie or need a soft hangup */ 05677 ast_channel_lock(chan); 05678 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 05679 if (chan->tech->transfer) { 05680 res = chan->tech->transfer(chan, dest); 05681 if (!res) 05682 res = 1; 05683 } else 05684 res = 0; 05685 } 05686 ast_channel_unlock(chan); 05687 05688 if (res <= 0) { 05689 return res; 05690 } 05691 05692 for (;;) { 05693 struct ast_frame *fr; 05694 05695 res = ast_waitfor(chan, -1); 05696 05697 if (res < 0 || !(fr = ast_read(chan))) { 05698 res = -1; 05699 break; 05700 } 05701 05702 if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_TRANSFER) { 05703 enum ast_control_transfer *message = fr->data.ptr; 05704 05705 if (*message == AST_TRANSFER_SUCCESS) { 05706 res = 1; 05707 } else { 05708 res = -1; 05709 } 05710 05711 ast_frfree(fr); 05712 break; 05713 } 05714 05715 ast_frfree(fr); 05716 } 05717 05718 return res; 05719 }
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 1030 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(), oh323_call(), sig_pri_call(), and sig_pri_new_ast_channel().
01031 { 01032 switch (transfercapability) { 01033 case AST_TRANS_CAP_SPEECH: 01034 return "SPEECH"; 01035 case AST_TRANS_CAP_DIGITAL: 01036 return "DIGITAL"; 01037 case AST_TRANS_CAP_RESTRICTED_DIGITAL: 01038 return "RESTRICTED_DIGITAL"; 01039 case AST_TRANS_CAP_3_1K_AUDIO: 01040 return "3K1AUDIO"; 01041 case AST_TRANS_CAP_DIGITAL_W_TONES: 01042 return "DIGITAL_W_TONES"; 01043 case AST_TRANS_CAP_VIDEO: 01044 return "VIDEO"; 01045 default: 01046 return "UNKNOWN"; 01047 } 01048 }
int ast_undestroyed_channels | ( | void | ) |
Definition at line 842 of file channel.c.
References ast_atomic_fetchadd_int().
Referenced by can_safely_quit().
00843 { 00844 return ast_atomic_fetchadd_int(&chancount, 0); 00845 }
void ast_uninstall_music_functions | ( | void | ) |
Definition at line 7845 of file channel.c.
References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.
Referenced by unload_module().
07846 { 07847 ast_moh_start_ptr = NULL; 07848 ast_moh_stop_ptr = NULL; 07849 ast_moh_cleanup_ptr = NULL; 07850 }
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 3486 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_idle_thread(), do_waiting(), echo_exec(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), jack_exec(), launch_asyncagi(), measurenoise(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), receivefax_t38_init(), 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().
03487 { 03488 int oldms = ms; /* -1 if no timeout */ 03489 03490 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms); 03491 if ((ms < 0) && (oldms < 0)) 03492 ms = 0; 03493 return ms; 03494 }
struct ast_channel* ast_waitfor_n | ( | struct ast_channel ** | chan, | |
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.
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 3481 of file channel.c.
References ast_waitfor_nandfds().
Referenced by ast_udptl_bridge(), autoservice_run(), dahdi_bridge(), dial_exec_full(), feature_request_and_dial(), generic_thread_loop(), misdn_bridge(), monitor_dial(), remote_bridge_loop(), wait_for_answer(), and wait_for_winner().
03482 { 03483 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 03484 }
int ast_waitfor_n_fd | ( | int * | fds, | |
int | n, | |||
int * | ms, | |||
int * | exception | |||
) |
Waits for input on an fd.
Definition at line 3125 of file channel.c.
References ast_waitfor_nandfds().
Referenced by dundi_lookup_internal(), dundi_precache_internal(), and softmix_bridge_thread().
03126 { 03127 int winner = -1; 03128 ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms); 03129 return winner; 03130 }
struct ast_channel* ast_waitfor_nandfds | ( | struct ast_channel ** | chan, | |
int | n, | |||
int * | fds, | |||
int | nfds, | |||
int * | exception, | |||
int * | outfd, | |||
int * | ms | |||
) |
Waits for activity on a group of channels.
chan | an array of pointers to channels | |
n | number of channels that are to be waited upon | |
fds | an array of fds to wait upon | |
nfds | the number of fds to wait upon | |
exception | exception flag | |
outfd | fd that had activity on it | |
ms | how long the wait was |
Definition at line 3137 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_MAX_FDS, ast_poll, ast_set_flag, AST_SOFTHANGUP_TIMEOUT, ast_tvcmp(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chanlist::chan, CHECK_BLOCKING, and errno.
Referenced by ast_waitfor(), ast_waitfor_n(), ast_waitfor_n_fd(), ast_waitfordigit_full(), conf_run(), eivr_comm(), find_cache(), generic_fax_exec(), multiplexed_thread_function(), run_agi(), and waitstream_core().
03140 { 03141 struct timeval start = { 0 , 0 }; 03142 struct pollfd *pfds = NULL; 03143 int res; 03144 long rms; 03145 int x, y, max; 03146 int sz; 03147 struct timeval now = { 0, 0 }; 03148 struct timeval whentohangup = { 0, 0 }, diff; 03149 struct ast_channel *winner = NULL; 03150 struct fdmap { 03151 int chan; 03152 int fdno; 03153 } *fdmap = NULL; 03154 03155 if (outfd) 03156 *outfd = -99999; 03157 if (exception) 03158 *exception = 0; 03159 03160 if ((sz = n * AST_MAX_FDS + nfds)) { 03161 pfds = alloca(sizeof(*pfds) * sz); 03162 fdmap = alloca(sizeof(*fdmap) * sz); 03163 } else { 03164 /* nothing to allocate and no FDs to check */ 03165 return NULL; 03166 } 03167 03168 /* Perform any pending masquerades */ 03169 for (x = 0; x < n; x++) { 03170 while (c[x]->masq) { 03171 ast_do_masquerade(c[x]); 03172 } 03173 03174 ast_channel_lock(c[x]); 03175 if (!ast_tvzero(c[x]->whentohangup)) { 03176 if (ast_tvzero(whentohangup)) 03177 now = ast_tvnow(); 03178 diff = ast_tvsub(c[x]->whentohangup, now); 03179 if (diff.tv_sec < 0 || ast_tvzero(diff)) { 03180 /* Should already be hungup */ 03181 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 03182 ast_channel_unlock(c[x]); 03183 return c[x]; 03184 } 03185 if (ast_tvzero(whentohangup) || ast_tvcmp(diff, whentohangup) < 0) 03186 whentohangup = diff; 03187 } 03188 ast_channel_unlock(c[x]); 03189 } 03190 /* Wait full interval */ 03191 rms = *ms; 03192 /* INT_MAX, not LONG_MAX, because it matters on 64-bit */ 03193 if (!ast_tvzero(whentohangup) && whentohangup.tv_sec < INT_MAX / 1000) { 03194 rms = whentohangup.tv_sec * 1000 + whentohangup.tv_usec / 1000; /* timeout in milliseconds */ 03195 if (*ms >= 0 && *ms < rms) { /* original *ms still smaller */ 03196 rms = *ms; 03197 } 03198 } else if (!ast_tvzero(whentohangup) && rms < 0) { 03199 /* Tiny corner case... call would need to last >24 days */ 03200 rms = INT_MAX; 03201 } 03202 /* 03203 * Build the pollfd array, putting the channels' fds first, 03204 * followed by individual fds. Order is important because 03205 * individual fd's must have priority over channel fds. 03206 */ 03207 max = 0; 03208 for (x = 0; x < n; x++) { 03209 for (y = 0; y < AST_MAX_FDS; y++) { 03210 fdmap[max].fdno = y; /* fd y is linked to this pfds */ 03211 fdmap[max].chan = x; /* channel x is linked to this pfds */ 03212 max += ast_add_fd(&pfds[max], c[x]->fds[y]); 03213 } 03214 CHECK_BLOCKING(c[x]); 03215 } 03216 /* Add the individual fds */ 03217 for (x = 0; x < nfds; x++) { 03218 fdmap[max].chan = -1; 03219 max += ast_add_fd(&pfds[max], fds[x]); 03220 } 03221 03222 if (*ms > 0) 03223 start = ast_tvnow(); 03224 03225 if (sizeof(int) == 4) { /* XXX fix timeout > 600000 on linux x86-32 */ 03226 do { 03227 int kbrms = rms; 03228 if (kbrms > 600000) 03229 kbrms = 600000; 03230 res = ast_poll(pfds, max, kbrms); 03231 if (!res) 03232 rms -= kbrms; 03233 } while (!res && (rms > 0)); 03234 } else { 03235 res = ast_poll(pfds, max, rms); 03236 } 03237 for (x = 0; x < n; x++) 03238 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 03239 if (res < 0) { /* Simulate a timeout if we were interrupted */ 03240 if (errno != EINTR) 03241 *ms = -1; 03242 return NULL; 03243 } 03244 if (!ast_tvzero(whentohangup)) { /* if we have a timeout, check who expired */ 03245 now = ast_tvnow(); 03246 for (x = 0; x < n; x++) { 03247 if (!ast_tvzero(c[x]->whentohangup) && ast_tvcmp(c[x]->whentohangup, now) <= 0) { 03248 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 03249 if (winner == NULL) 03250 winner = c[x]; 03251 } 03252 } 03253 } 03254 if (res == 0) { /* no fd ready, reset timeout and done */ 03255 *ms = 0; /* XXX use 0 since we may not have an exact timeout. */ 03256 return winner; 03257 } 03258 /* 03259 * Then check if any channel or fd has a pending event. 03260 * Remember to check channels first and fds last, as they 03261 * must have priority on setting 'winner' 03262 */ 03263 for (x = 0; x < max; x++) { 03264 res = pfds[x].revents; 03265 if (res == 0) 03266 continue; 03267 if (fdmap[x].chan >= 0) { /* this is a channel */ 03268 winner = c[fdmap[x].chan]; /* override previous winners */ 03269 if (res & POLLPRI) 03270 ast_set_flag(winner, AST_FLAG_EXCEPTION); 03271 else 03272 ast_clear_flag(winner, AST_FLAG_EXCEPTION); 03273 winner->fdno = fdmap[x].fdno; 03274 } else { /* this is an fd */ 03275 if (outfd) 03276 *outfd = pfds[x].fd; 03277 if (exception) 03278 *exception = (res & POLLPRI) ? -1 : 0; 03279 winner = NULL; 03280 } 03281 } 03282 if (*ms > 0) { 03283 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 03284 if (*ms < 0) 03285 *ms = 0; 03286 } 03287 return winner; 03288 }
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 3497 of file channel.c.
References ast_waitfordigit_full().
Referenced by __analog_ss_thread(), _while_exec(), adsi_get_cpeid(), adsi_get_cpeinfo(), adsi_print(), adsi_read_encoded_dtmf(), adsi_transmit_message_full(), advanced_options(), analog_my_getsigstr(), analog_ss_thread(), 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(), pri_ss_thread(), 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(), and wait_a_bit().
03498 { 03499 return ast_waitfordigit_full(c, ms, -1, -1); 03500 }
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 3545 of file channel.c.
References ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, 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(), errno, f, and LOG_WARNING.
Referenced by ast_readstring_full(), ast_waitfordigit(), handle_getoption(), and handle_waitfordigit().
03546 { 03547 /* Stop if we're a zombie or need a soft hangup */ 03548 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 03549 return -1; 03550 03551 /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */ 03552 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY); 03553 03554 /* Wait for a digit, no more than ms milliseconds total. */ 03555 03556 while (ms) { 03557 struct ast_channel *rchan; 03558 int outfd=-1; 03559 03560 errno = 0; 03561 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 03562 03563 if (!rchan && outfd < 0 && ms) { 03564 if (errno == 0 || errno == EINTR) 03565 continue; 03566 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 03567 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03568 return -1; 03569 } else if (outfd > -1) { 03570 /* The FD we were watching has something waiting */ 03571 ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n"); 03572 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03573 return 1; 03574 } else if (rchan) { 03575 int res; 03576 struct ast_frame *f = ast_read(c); 03577 if (!f) 03578 return -1; 03579 03580 switch (f->frametype) { 03581 case AST_FRAME_DTMF_BEGIN: 03582 break; 03583 case AST_FRAME_DTMF_END: 03584 res = f->subclass.integer; 03585 ast_frfree(f); 03586 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03587 return res; 03588 case AST_FRAME_CONTROL: 03589 switch (f->subclass.integer) { 03590 case AST_CONTROL_HANGUP: 03591 ast_frfree(f); 03592 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03593 return -1; 03594 case AST_CONTROL_RINGING: 03595 case AST_CONTROL_ANSWER: 03596 case AST_CONTROL_SRCUPDATE: 03597 case AST_CONTROL_SRCCHANGE: 03598 case AST_CONTROL_CONNECTED_LINE: 03599 case AST_CONTROL_REDIRECTING: 03600 case AST_CONTROL_UPDATE_RTP_PEER: 03601 case AST_CONTROL_HOLD: 03602 case AST_CONTROL_UNHOLD: 03603 case -1: 03604 /* Unimportant */ 03605 break; 03606 default: 03607 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass.integer); 03608 break; 03609 } 03610 break; 03611 case AST_FRAME_VOICE: 03612 /* Write audio if appropriate */ 03613 if (audiofd > -1) { 03614 if (write(audiofd, f->data.ptr, f->datalen) < 0) { 03615 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 03616 } 03617 } 03618 default: 03619 /* Ignore */ 03620 break; 03621 } 03622 ast_frfree(f); 03623 } 03624 } 03625 03626 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03627 03628 return 0; /* Time is up */ 03629 }
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 4801 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_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_AUDIO_MASK, 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(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_translate(), ast_writestream(), ast_channel::audiohooks, calc_monitor_jump(), chanlist::chan, CHECK_BLOCKING, ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, DEBUGCHAN_FLAG, f, ast_filestream::fmt, ast_format::format, ast_channel::fout, FRAMECOUNT_INC, ast_channel::framehooks, ast_frame::frametype, ast_channel::generatordata, 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::name, 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_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(), gen_generate(), generic_fax_exec(), handle_jack_audio(), jb_get_and_deliver(), linear_generator(), milliwatt_generate(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), multiplexed_bridge_write(), NBScat_exec(), remote_bridge_loop(), send_tone_burst(), send_waveform_to_channel(), silence_generator_generate(), simple_bridge_write(), softmix_bridge_poke(), softmix_bridge_write(), spy_generate(), and t38_tx_packet_handler().
04802 { 04803 int res = -1; 04804 struct ast_frame *f = NULL; 04805 int count = 0; 04806 04807 /*Deadlock avoidance*/ 04808 while(ast_channel_trylock(chan)) { 04809 /*cannot goto done since the channel is not locked*/ 04810 if(count++ > 10) { 04811 ast_debug(1, "Deadlock avoided for write to channel '%s'\n", chan->name); 04812 return 0; 04813 } 04814 usleep(1); 04815 } 04816 /* Stop if we're a zombie or need a soft hangup */ 04817 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 04818 goto done; 04819 04820 /* Handle any pending masquerades */ 04821 while (chan->masq) { 04822 ast_channel_unlock(chan); 04823 ast_do_masquerade(chan); 04824 ast_channel_lock(chan); 04825 } 04826 if (chan->masqr) { 04827 res = 0; /* XXX explain, why 0 ? */ 04828 goto done; 04829 } 04830 04831 /* Perform the framehook write event here. After the frame enters the framehook list 04832 * there is no telling what will happen, how awesome is that!!! */ 04833 if (!(fr = ast_framehook_list_write_event(chan->framehooks, fr))) { 04834 res = 0; 04835 goto done; 04836 } 04837 04838 if (chan->generatordata && (!fr->src || strcasecmp(fr->src, "ast_prod"))) { 04839 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) { 04840 ast_deactivate_generator(chan); 04841 } else { 04842 if (fr->frametype == AST_FRAME_DTMF_END) { 04843 /* There is a generator running while we're in the middle of a digit. 04844 * It's probably inband DTMF, so go ahead and pass it so it can 04845 * stop the generator */ 04846 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04847 ast_channel_unlock(chan); 04848 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len); 04849 ast_channel_lock(chan); 04850 CHECK_BLOCKING(chan); 04851 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_UNHOLD) { 04852 /* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */ 04853 res = (chan->tech->indicate == NULL) ? 0 : 04854 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen); 04855 } 04856 res = 0; /* XXX explain, why 0 ? */ 04857 goto done; 04858 } 04859 } 04860 /* High bit prints debugging */ 04861 if (chan->fout & DEBUGCHAN_FLAG) 04862 ast_frame_dump(chan->name, fr, ">>"); 04863 CHECK_BLOCKING(chan); 04864 switch (fr->frametype) { 04865 case AST_FRAME_CONTROL: 04866 res = (chan->tech->indicate == NULL) ? 0 : 04867 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen); 04868 break; 04869 case AST_FRAME_DTMF_BEGIN: 04870 if (chan->audiohooks) { 04871 struct ast_frame *old_frame = fr; 04872 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 04873 if (old_frame != fr) 04874 f = fr; 04875 } 04876 send_dtmf_event(chan, "Sent", fr->subclass.integer, "Yes", "No"); 04877 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04878 ast_channel_unlock(chan); 04879 res = ast_senddigit_begin(chan, fr->subclass.integer); 04880 ast_channel_lock(chan); 04881 CHECK_BLOCKING(chan); 04882 break; 04883 case AST_FRAME_DTMF_END: 04884 if (chan->audiohooks) { 04885 struct ast_frame *new_frame = fr; 04886 04887 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 04888 if (new_frame != fr) { 04889 ast_frfree(new_frame); 04890 } 04891 } 04892 send_dtmf_event(chan, "Sent", fr->subclass.integer, "No", "Yes"); 04893 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04894 ast_channel_unlock(chan); 04895 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len); 04896 ast_channel_lock(chan); 04897 CHECK_BLOCKING(chan); 04898 break; 04899 case AST_FRAME_TEXT: 04900 if (fr->subclass.integer == AST_FORMAT_T140) { 04901 res = (chan->tech->write_text == NULL) ? 0 : 04902 chan->tech->write_text(chan, fr); 04903 } else { 04904 res = (chan->tech->send_text == NULL) ? 0 : 04905 chan->tech->send_text(chan, (char *) fr->data.ptr); 04906 } 04907 break; 04908 case AST_FRAME_HTML: 04909 res = (chan->tech->send_html == NULL) ? 0 : 04910 chan->tech->send_html(chan, fr->subclass.integer, (char *) fr->data.ptr, fr->datalen); 04911 break; 04912 case AST_FRAME_VIDEO: 04913 /* XXX Handle translation of video codecs one day XXX */ 04914 res = (chan->tech->write_video == NULL) ? 0 : 04915 chan->tech->write_video(chan, fr); 04916 break; 04917 case AST_FRAME_MODEM: 04918 res = (chan->tech->write == NULL) ? 0 : 04919 chan->tech->write(chan, fr); 04920 break; 04921 case AST_FRAME_VOICE: 04922 if (chan->tech->write == NULL) 04923 break; /*! \todo XXX should return 0 maybe ? */ 04924 04925 if (ast_opt_generic_plc && fr->subclass.codec == AST_FORMAT_SLINEAR) { 04926 apply_plc(chan, fr); 04927 } 04928 04929 /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */ 04930 if (fr->subclass.codec == chan->rawwriteformat) { 04931 f = fr; 04932 } else { 04933 if ((!(fr->subclass.codec & chan->nativeformats)) && (chan->writeformat != fr->subclass.codec)) { 04934 char nf[512]; 04935 04936 /* 04937 * XXX Something is not right. We are not compatible with this 04938 * frame. Bad things can happen. Problems range from no audio, 04939 * one-way audio, to unexplained line hangups. As a last resort 04940 * try to adjust the format. Ideally, we do not want to do this 04941 * because it indicates a deeper problem. For now, we log these 04942 * events to reduce user impact and help identify the problem 04943 * areas. 04944 */ 04945 ast_log(LOG_WARNING, "Codec mismatch on channel %s setting write format to %s from %s native formats %s\n", 04946 chan->name, ast_getformatname(fr->subclass.codec), ast_getformatname(chan->writeformat), 04947 ast_getformatname_multiple(nf, sizeof(nf), chan->nativeformats & AST_FORMAT_AUDIO_MASK)); 04948 ast_set_write_format(chan, fr->subclass.codec); 04949 } 04950 04951 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr; 04952 } 04953 04954 if (!f) { 04955 res = 0; 04956 break; 04957 } 04958 04959 if (chan->audiohooks) { 04960 struct ast_frame *prev = NULL, *new_frame, *cur, *dup; 04961 int freeoldlist = 0; 04962 04963 if (f != fr) { 04964 freeoldlist = 1; 04965 } 04966 04967 /* Since ast_audiohook_write may return a new frame, and the cur frame is 04968 * an item in a list of frames, create a new list adding each cur frame back to it 04969 * regardless if the cur frame changes or not. */ 04970 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 04971 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, cur); 04972 04973 /* if this frame is different than cur, preserve the end of the list, 04974 * free the old frames, and set cur to be the new frame */ 04975 if (new_frame != cur) { 04976 04977 /* doing an ast_frisolate here seems silly, but we are not guaranteed the new_frame 04978 * isn't part of local storage, meaning if ast_audiohook_write is called multiple 04979 * times it may override the previous frame we got from it unless we dup it */ 04980 if ((dup = ast_frisolate(new_frame))) { 04981 AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list); 04982 if (freeoldlist) { 04983 AST_LIST_NEXT(cur, frame_list) = NULL; 04984 ast_frfree(cur); 04985 } 04986 if (new_frame != dup) { 04987 ast_frfree(new_frame); 04988 } 04989 cur = dup; 04990 } 04991 } 04992 04993 /* now, regardless if cur is new or not, add it to the new list, 04994 * if the new list has not started, cur will become the first item. */ 04995 if (prev) { 04996 AST_LIST_NEXT(prev, frame_list) = cur; 04997 } else { 04998 f = cur; /* set f to be the beginning of our new list */ 04999 } 05000 prev = cur; 05001 } 05002 } 05003 05004 /* If Monitor is running on this channel, then we have to write frames out there too */ 05005 /* the translator on chan->writetrans may have returned multiple frames 05006 from the single frame we passed in; if so, feed each one of them to the 05007 monitor */ 05008 if (chan->monitor && chan->monitor->write_stream) { 05009 struct ast_frame *cur; 05010 05011 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 05012 /* XXX must explain this code */ 05013 #ifndef MONITOR_CONSTANT_DELAY 05014 int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples; 05015 if (jump >= 0) { 05016 jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 05017 if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1) 05018 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 05019 chan->outsmpl += (chan->insmpl - chan->outsmpl) + cur->samples; 05020 } else { 05021 chan->outsmpl += cur->samples; 05022 } 05023 #else 05024 int jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 05025 if (jump - MONITOR_DELAY >= 0) { 05026 if (ast_seekstream(chan->monitor->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1) 05027 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 05028 chan->outsmpl += chan->insmpl - chan->outsmpl; 05029 } else { 05030 chan->outsmpl += cur->samples; 05031 } 05032 #endif 05033 if (chan->monitor->state == AST_MONITOR_RUNNING) { 05034 if (ast_writestream(chan->monitor->write_stream, cur) < 0) 05035 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 05036 } 05037 } 05038 } 05039 05040 /* the translator on chan->writetrans may have returned multiple frames 05041 from the single frame we passed in; if so, feed each one of them to the 05042 channel, freeing each one after it has been written */ 05043 if ((f != fr) && AST_LIST_NEXT(f, frame_list)) { 05044 struct ast_frame *cur, *next; 05045 unsigned int skip = 0; 05046 05047 for (cur = f, next = AST_LIST_NEXT(cur, frame_list); 05048 cur; 05049 cur = next, next = cur ? AST_LIST_NEXT(cur, frame_list) : NULL) { 05050 if (!skip) { 05051 if ((res = chan->tech->write(chan, cur)) < 0) { 05052 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05053 skip = 1; 05054 } else if (next) { 05055 /* don't do this for the last frame in the list, 05056 as the code outside the loop will do it once 05057 */ 05058 chan->fout = FRAMECOUNT_INC(chan->fout); 05059 } 05060 } 05061 ast_frfree(cur); 05062 } 05063 05064 /* reset f so the code below doesn't attempt to free it */ 05065 f = NULL; 05066 } else { 05067 res = chan->tech->write(chan, f); 05068 } 05069 break; 05070 case AST_FRAME_NULL: 05071 case AST_FRAME_IAX: 05072 /* Ignore these */ 05073 res = 0; 05074 break; 05075 default: 05076 /* At this point, fr is the incoming frame and f is NULL. Channels do 05077 * not expect to get NULL as a frame pointer and will segfault. Hence, 05078 * we output the original frame passed in. */ 05079 res = chan->tech->write(chan, fr); 05080 break; 05081 } 05082 05083 if (f && f != fr) 05084 ast_frfree(f); 05085 ast_clear_flag(chan, AST_FLAG_BLOCKING); 05086 05087 /* Consider a write failure to force a soft hangup */ 05088 if (res < 0) { 05089 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05090 } else { 05091 chan->fout = FRAMECOUNT_INC(chan->fout); 05092 } 05093 done: 05094 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) { 05095 /* The list gets recreated if audiohooks are added again later */ 05096 ast_audiohook_detach_list(chan->audiohooks); 05097 chan->audiohooks = NULL; 05098 } 05099 ast_channel_unlock(chan); 05100 return res; 05101 }
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 4686 of file channel.c.
References ast_write(), chanlist::chan, ast_channel::tech, and ast_channel_tech::write_video.
04687 { 04688 int res; 04689 if (!chan->tech->write_video) 04690 return 0; 04691 res = ast_write(chan, fr); 04692 if (!res) 04693 res = 1; 04694 return res; 04695 }
static void bridge_play_sounds | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1 | |||
) | [static] |
Definition at line 7309 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().
07310 { 07311 const char *s, *sound; 07312 07313 /* See if we need to play an audio file to any side of the bridge */ 07314 07315 ast_channel_lock(c0); 07316 if ((s = pbx_builtin_getvar_helper(c0, "BRIDGE_PLAY_SOUND"))) { 07317 sound = ast_strdupa(s); 07318 ast_channel_unlock(c0); 07319 bridge_playfile(c0, c1, sound, 0); 07320 pbx_builtin_setvar_helper(c0, "BRIDGE_PLAY_SOUND", NULL); 07321 } else { 07322 ast_channel_unlock(c0); 07323 } 07324 07325 ast_channel_lock(c1); 07326 if ((s = pbx_builtin_getvar_helper(c1, "BRIDGE_PLAY_SOUND"))) { 07327 sound = ast_strdupa(s); 07328 ast_channel_unlock(c1); 07329 bridge_playfile(c1, c0, sound, 0); 07330 pbx_builtin_setvar_helper(c1, "BRIDGE_PLAY_SOUND", NULL); 07331 } else { 07332 ast_channel_unlock(c1); 07333 } 07334 }
static void bridge_playfile | ( | struct ast_channel * | chan, | |
struct ast_channel * | peer, | |||
const char * | sound, | |||
int | remain | |||
) | [static] |
Definition at line 7003 of file channel.c.
References ast_autoservice_start(), ast_autoservice_stop(), AST_DIGIT_ANY, ast_say_number(), ast_stream_and_wait(), and chanlist::chan.
Referenced by ast_channel_bridge(), and bridge_play_sounds().
07004 { 07005 int min = 0, sec = 0, check; 07006 07007 check = ast_autoservice_start(peer); 07008 if (check) 07009 return; 07010 07011 if (remain > 0) { 07012 if (remain / 60 > 1) { 07013 min = remain / 60; 07014 sec = remain % 60; 07015 } else { 07016 sec = remain; 07017 } 07018 } 07019 07020 if (!strcmp(sound,"timeleft")) { /* Queue support */ 07021 ast_stream_and_wait(chan, "vm-youhave", ""); 07022 if (min) { 07023 ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, NULL); 07024 ast_stream_and_wait(chan, "queue-minutes", ""); 07025 } 07026 if (sec) { 07027 ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, NULL); 07028 ast_stream_and_wait(chan, "queue-seconds", ""); 07029 } 07030 } else { 07031 ast_stream_and_wait(chan, sound, ""); 07032 } 07033 07034 ast_autoservice_stop(peer); 07035 }
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 3737 of file channel.c.
Referenced by __ast_read(), and ast_write().
03738 { 03739 int diff = sample_rate - seek_rate; 03740 03741 if (diff > 0) { 03742 samples = samples / (float) (sample_rate / seek_rate); 03743 } else if (diff < 0) { 03744 samples = samples * (float) (seek_rate / sample_rate); 03745 } 03746 03747 return samples; 03748 }
static void call_forward_inherit | ( | struct ast_channel * | new_chan, | |
struct ast_channel * | parent, | |||
struct ast_channel * | orig | |||
) | [static] |
Definition at line 5244 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().
05245 { 05246 if (!ast_test_flag(parent, AST_FLAG_ZOMBIE) && !ast_check_hangup(parent)) { 05247 struct ast_party_redirecting redirecting; 05248 05249 /* 05250 * The parent is not a ZOMBIE or hungup so update it with the 05251 * original channel's redirecting information. 05252 */ 05253 ast_party_redirecting_init(&redirecting); 05254 ast_channel_lock(orig); 05255 ast_party_redirecting_copy(&redirecting, &orig->redirecting); 05256 ast_channel_unlock(orig); 05257 if (ast_channel_redirecting_macro(orig, parent, &redirecting, 1, 0)) { 05258 ast_channel_update_redirecting(parent, &redirecting, NULL); 05259 } 05260 ast_party_redirecting_free(&redirecting); 05261 } 05262 05263 /* Safely inherit variables and datastores from the parent channel. */ 05264 ast_channel_lock_both(parent, new_chan); 05265 ast_channel_inherit_variables(parent, new_chan); 05266 ast_channel_datastore_inherit(parent, new_chan); 05267 ast_channel_unlock(new_chan); 05268 ast_channel_unlock(parent); 05269 }
static void* channel_cc_params_copy | ( | void * | data | ) | [static] |
Definition at line 9486 of file channel.c.
References ast_cc_config_params_init, and ast_cc_copy_config_params().
09487 { 09488 const struct ast_cc_config_params *src = data; 09489 struct ast_cc_config_params *dest = ast_cc_config_params_init(); 09490 if (!dest) { 09491 return NULL; 09492 } 09493 ast_cc_copy_config_params(dest, src); 09494 return dest; 09495 }
static void channel_cc_params_destroy | ( | void * | data | ) | [static] |
Definition at line 9497 of file channel.c.
References ast_cc_config_params_destroy().
09498 { 09499 struct ast_cc_config_params *cc_params = data; 09500 ast_cc_config_params_destroy(cc_params); 09501 }
static void channel_data_add_flags | ( | struct ast_data * | tree, | |
struct ast_channel * | chan | |||
) | [static] |
Definition at line 272 of file channel.c.
References ast_data_add_bool(), AST_FLAG_ANSWERED_ELSEWHERE, AST_FLAG_BLOCKING, AST_FLAG_BRIDGE_HANGUP_DONT, AST_FLAG_BRIDGE_HANGUP_RUN, AST_FLAG_DEFER_DTMF, AST_FLAG_DISABLE_WORKAROUNDS, AST_FLAG_EMULATE_DTMF, AST_FLAG_END_DTMF_ONLY, AST_FLAG_EXCEPTION, AST_FLAG_IN_AUTOLOOP, AST_FLAG_IN_DTMF, AST_FLAG_MASQ_NOSTREAM, AST_FLAG_MOH, AST_FLAG_NBRIDGE, AST_FLAG_OUTGOING, AST_FLAG_SPYING, AST_FLAG_WRITE_INT, AST_FLAG_ZOMBIE, ast_test_flag, and chanlist::chan.
Referenced by ast_channel_data_add_structure().
00274 { 00275 ast_data_add_bool(tree, "DEFER_DTMF", ast_test_flag(chan, AST_FLAG_DEFER_DTMF)); 00276 ast_data_add_bool(tree, "WRITE_INT", ast_test_flag(chan, AST_FLAG_WRITE_INT)); 00277 ast_data_add_bool(tree, "BLOCKING", ast_test_flag(chan, AST_FLAG_BLOCKING)); 00278 ast_data_add_bool(tree, "ZOMBIE", ast_test_flag(chan, AST_FLAG_ZOMBIE)); 00279 ast_data_add_bool(tree, "EXCEPTION", ast_test_flag(chan, AST_FLAG_EXCEPTION)); 00280 ast_data_add_bool(tree, "MOH", ast_test_flag(chan, AST_FLAG_MOH)); 00281 ast_data_add_bool(tree, "SPYING", ast_test_flag(chan, AST_FLAG_SPYING)); 00282 ast_data_add_bool(tree, "NBRIDGE", ast_test_flag(chan, AST_FLAG_NBRIDGE)); 00283 ast_data_add_bool(tree, "IN_AUTOLOOP", ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)); 00284 ast_data_add_bool(tree, "OUTGOING", ast_test_flag(chan, AST_FLAG_OUTGOING)); 00285 ast_data_add_bool(tree, "IN_DTMF", ast_test_flag(chan, AST_FLAG_IN_DTMF)); 00286 ast_data_add_bool(tree, "EMULATE_DTMF", ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)); 00287 ast_data_add_bool(tree, "END_DTMF_ONLY", ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)); 00288 ast_data_add_bool(tree, "ANSWERED_ELSEWHERE", ast_test_flag(chan, AST_FLAG_ANSWERED_ELSEWHERE)); 00289 ast_data_add_bool(tree, "MASQ_NOSTREAM", ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM)); 00290 ast_data_add_bool(tree, "BRIDGE_HANGUP_RUN", ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN)); 00291 ast_data_add_bool(tree, "BRIDGE_HANGUP_DONT", ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT)); 00292 ast_data_add_bool(tree, "DISABLE_WORKAROUNDS", ast_test_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS)); 00293 }
static struct ast_channel_iterator* channel_iterator_search | ( | const char * | name, | |
size_t | name_len, | |||
const char * | exten, | |||
const char * | context | |||
) | [static] |
Definition at line 1629 of file channel.c.
References ao2_find, ast_calloc, ast_copy_string(), ast_free, ast_strlen_zero(), channels, ast_channel::context, ast_channel::exten, ast_channel::name, OBJ_MULTIPLE, and OBJ_POINTER.
Referenced by ast_channel_iterator_by_exten_new(), and ast_channel_iterator_by_name_new().
01632 { 01633 struct ast_channel_iterator *i; 01634 struct ast_channel tmp_chan = { 01635 .name = name, 01636 /* This is sort of a hack. Basically, we're using an arbitrary field 01637 * in ast_channel to pass the name_len for a prefix match. If this 01638 * gets changed, then the compare callback must be changed, too. */ 01639 .rings = name_len, 01640 }; 01641 01642 if (!(i = ast_calloc(1, sizeof(*i)))) { 01643 return NULL; 01644 } 01645 01646 if (exten) { 01647 ast_copy_string(tmp_chan.exten, exten, sizeof(tmp_chan.exten)); 01648 } 01649 01650 if (context) { 01651 ast_copy_string(tmp_chan.context, context, sizeof(tmp_chan.context)); 01652 } 01653 01654 if (!(i->active_iterator = ao2_find(channels, &tmp_chan, 01655 OBJ_MULTIPLE | ((!ast_strlen_zero(name) && (name_len == 0)) ? OBJ_POINTER : 0)))) { 01656 ast_free(i); 01657 return NULL; 01658 } 01659 01660 return i; 01661 }
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 8150 of file channel.c.
References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.
08151 { 08152 switch (reason) { 08153 case CHANNEL_MODULE_LOAD: 08154 return "LOAD (Channel module load)"; 08155 08156 case CHANNEL_MODULE_RELOAD: 08157 return "RELOAD (Channel module reload)"; 08158 08159 case CHANNEL_CLI_RELOAD: 08160 return "CLIRELOAD (Channel module reload by CLI command)"; 08161 08162 default: 08163 return "MANAGERRELOAD (Channel module reload by manager)"; 08164 } 08165 };
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 6174 of file channel.c.
References AST_LIST_APPEND_LIST, 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().
06175 { 06176 struct ast_var_t *current, *newvar; 06177 /* Append variables from clone channel into original channel */ 06178 /* XXX Is this always correct? We have to in order to keep MACROS working XXX */ 06179 AST_LIST_APPEND_LIST(&original->varshead, &clonechan->varshead, entries); 06180 06181 /* then, dup the varshead list into the clone */ 06182 06183 AST_LIST_TRAVERSE(&original->varshead, current, entries) { 06184 newvar = ast_var_assign(current->name, current->value); 06185 if (newvar) 06186 AST_LIST_INSERT_TAIL(&clonechan->varshead, newvar, entries); 06187 } 06188 }
static char* complete_channeltypes | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 527 of file channel.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, chanlist::list, 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().
00528 { 00529 struct chanlist *cl; 00530 int which = 0; 00531 int wordlen; 00532 char *ret = NULL; 00533 00534 if (a->pos != 3) 00535 return NULL; 00536 00537 wordlen = strlen(a->word); 00538 00539 AST_RWLIST_RDLOCK(&backends); 00540 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00541 if (!strncasecmp(a->word, cl->tech->type, wordlen) && ++which > a->n) { 00542 ret = ast_strdup(cl->tech->type); 00543 break; 00544 } 00545 } 00546 AST_RWLIST_UNLOCK(&backends); 00547 00548 return ret; 00549 }
static int data_channels_provider_handler | ( | const struct ast_data_search * | search, | |
struct ast_data * | root | |||
) | [static] |
Definition at line 7909 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_unlock, ast_channel_unref, ast_data_add_node(), ast_data_remove_node(), ast_data_search_match(), ast_log(), and LOG_ERROR.
07911 { 07912 struct ast_channel *c; 07913 struct ast_channel_iterator *iter = NULL; 07914 struct ast_data *data_channel; 07915 07916 for (iter = ast_channel_iterator_all_new(); 07917 iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) { 07918 ast_channel_lock(c); 07919 07920 data_channel = ast_data_add_node(root, "channel"); 07921 if (!data_channel) { 07922 ast_channel_unlock(c); 07923 continue; 07924 } 07925 07926 if (ast_channel_data_add_structure(data_channel, c, 1) < 0) { 07927 ast_log(LOG_ERROR, "Unable to add channel structure for channel: %s\n", c->name); 07928 } 07929 07930 ast_channel_unlock(c); 07931 07932 if (!ast_data_search_match(search, data_channel)) { 07933 ast_data_remove_node(root, data_channel); 07934 } 07935 } 07936 if (iter) { 07937 ast_channel_iterator_destroy(iter); 07938 } 07939 07940 return 0; 07941 }
static int data_channeltypes_provider_handler | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 7947 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.
07949 { 07950 struct chanlist *cl; 07951 struct ast_data *data_type; 07952 07953 AST_RWLIST_RDLOCK(&backends); 07954 AST_RWLIST_TRAVERSE(&backends, cl, list) { 07955 data_type = ast_data_add_node(data_root, "type"); 07956 if (!data_type) { 07957 continue; 07958 } 07959 ast_data_add_str(data_type, "name", cl->tech->type); 07960 ast_data_add_str(data_type, "description", cl->tech->description); 07961 ast_data_add_bool(data_type, "devicestate", cl->tech->devicestate ? 1 : 0); 07962 ast_data_add_bool(data_type, "indications", cl->tech->indicate ? 1 : 0); 07963 ast_data_add_bool(data_type, "transfer", cl->tech->transfer ? 1 : 0); 07964 ast_data_add_bool(data_type, "send_digit_begin", cl->tech->send_digit_begin ? 1 : 0); 07965 ast_data_add_bool(data_type, "send_digit_end", cl->tech->send_digit_end ? 1 : 0); 07966 ast_data_add_bool(data_type, "call", cl->tech->call ? 1 : 0); 07967 ast_data_add_bool(data_type, "hangup", cl->tech->hangup ? 1 : 0); 07968 ast_data_add_bool(data_type, "answer", cl->tech->answer ? 1 : 0); 07969 ast_data_add_bool(data_type, "read", cl->tech->read ? 1 : 0); 07970 ast_data_add_bool(data_type, "write", cl->tech->write ? 1 : 0); 07971 ast_data_add_bool(data_type, "send_text", cl->tech->send_text ? 1 : 0); 07972 ast_data_add_bool(data_type, "send_image", cl->tech->send_image ? 1 : 0); 07973 ast_data_add_bool(data_type, "send_html", cl->tech->send_html ? 1 : 0); 07974 ast_data_add_bool(data_type, "exception", cl->tech->exception ? 1 : 0); 07975 ast_data_add_bool(data_type, "bridge", cl->tech->bridge ? 1 : 0); 07976 ast_data_add_bool(data_type, "early_bridge", cl->tech->early_bridge ? 1 : 0); 07977 ast_data_add_bool(data_type, "fixup", cl->tech->fixup ? 1 : 0); 07978 ast_data_add_bool(data_type, "setoption", cl->tech->setoption ? 1 : 0); 07979 ast_data_add_bool(data_type, "queryoption", cl->tech->queryoption ? 1 : 0); 07980 ast_data_add_bool(data_type, "write_video", cl->tech->write_video ? 1 : 0); 07981 ast_data_add_bool(data_type, "write_text", cl->tech->write_text ? 1 : 0); 07982 ast_data_add_bool(data_type, "bridged_channel", cl->tech->bridged_channel ? 1 : 0); 07983 ast_data_add_bool(data_type, "func_channel_read", cl->tech->func_channel_read ? 1 : 0); 07984 ast_data_add_bool(data_type, "func_channel_write", cl->tech->func_channel_write ? 1 : 0); 07985 ast_data_add_bool(data_type, "get_base_channel", cl->tech->get_base_channel ? 1 : 0); 07986 ast_data_add_bool(data_type, "set_base_channel", cl->tech->set_base_channel ? 1 : 0); 07987 ast_data_add_bool(data_type, "get_pvt_uniqueid", cl->tech->get_pvt_uniqueid ? 1 : 0); 07988 ast_data_add_bool(data_type, "cc_callback", cl->tech->cc_callback ? 1 : 0); 07989 07990 ast_data_add_codecs(data_type, "capabilities", cl->tech->capabilities); 07991 07992 if (!ast_data_search_match(search, data_type)) { 07993 ast_data_remove_node(data_root, data_type); 07994 } 07995 } 07996 AST_RWLIST_UNLOCK(&backends); 07997 07998 return 0; 07999 }
static void destroy_hooks | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 2760 of file channel.c.
References ast_audiohook_detach_list(), ast_framehook_list_destroy(), ast_channel::audiohooks, and chanlist::chan.
Referenced by ast_hangup().
02761 { 02762 if (chan->audiohooks) { 02763 ast_audiohook_detach_list(chan->audiohooks); 02764 chan->audiohooks = NULL; 02765 } 02766 02767 ast_framehook_list_destroy(chan); 02768 }
static void free_translation | ( | struct ast_channel * | clonechan | ) | [static] |
Definition at line 2724 of file channel.c.
References ast_translator_free_path(), ast_channel::nativeformats, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readtrans, and ast_channel::writetrans.
Referenced by ast_do_masquerade(), and ast_hangup().
02725 { 02726 if (clonechan->writetrans) 02727 ast_translator_free_path(clonechan->writetrans); 02728 if (clonechan->readtrans) 02729 ast_translator_free_path(clonechan->readtrans); 02730 clonechan->writetrans = NULL; 02731 clonechan->readtrans = NULL; 02732 clonechan->rawwriteformat = clonechan->nativeformats; 02733 clonechan->rawreadformat = clonechan->nativeformats; 02734 }
static int generator_force | ( | const void * | data | ) | [static] |
Definition at line 3070 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_deactivate_generator(), ast_debug, AST_FORMAT_AUDIO_MASK, ast_format_rate(), and chanlist::chan.
Referenced by ast_activate_generator(), and ast_read_generator_actions().
03071 { 03072 /* Called if generator doesn't have data */ 03073 void *tmp; 03074 int res; 03075 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL; 03076 struct ast_channel *chan = (struct ast_channel *)data; 03077 03078 ast_channel_lock(chan); 03079 tmp = chan->generatordata; 03080 chan->generatordata = NULL; 03081 if (chan->generator) 03082 generate = chan->generator->generate; 03083 ast_channel_unlock(chan); 03084 03085 if (!tmp || !generate) 03086 return 0; 03087 03088 res = generate(chan, tmp, 0, ast_format_rate(chan->writeformat & AST_FORMAT_AUDIO_MASK) / 50); 03089 03090 chan->generatordata = tmp; 03091 03092 if (res) { 03093 ast_debug(1, "Auto-deactivating generator\n"); 03094 ast_deactivate_generator(chan); 03095 } 03096 03097 return 0; 03098 }
static void handle_cause | ( | int | cause, | |
int * | outstate | |||
) | [static] |
Definition at line 5221 of file channel.c.
References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CONTROL_BUSY, and AST_CONTROL_CONGESTION.
05222 { 05223 if (outstate) { 05224 /* compute error and return */ 05225 if (cause == AST_CAUSE_BUSY) 05226 *outstate = AST_CONTROL_BUSY; 05227 else if (cause == AST_CAUSE_CONGESTION) 05228 *outstate = AST_CONTROL_CONGESTION; 05229 else 05230 *outstate = 0; 05231 } 05232 }
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 552 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, chanlist::list, 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.
00553 { 00554 struct chanlist *cl = NULL; 00555 char buf[512]; 00556 00557 switch (cmd) { 00558 case CLI_INIT: 00559 e->command = "core show channeltype"; 00560 e->usage = 00561 "Usage: core show channeltype <name>\n" 00562 " Show details about the specified channel type, <name>.\n"; 00563 return NULL; 00564 case CLI_GENERATE: 00565 return complete_channeltypes(a); 00566 } 00567 00568 if (a->argc != 4) 00569 return CLI_SHOWUSAGE; 00570 00571 AST_RWLIST_RDLOCK(&backends); 00572 00573 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00574 if (!strncasecmp(cl->tech->type, a->argv[3], strlen(cl->tech->type))) 00575 break; 00576 } 00577 00578 00579 if (!cl) { 00580 ast_cli(a->fd, "\n%s is not a registered channel driver.\n", a->argv[3]); 00581 AST_RWLIST_UNLOCK(&backends); 00582 return CLI_FAILURE; 00583 } 00584 00585 ast_cli(a->fd, 00586 "-- Info about channel driver: %s --\n" 00587 " Device State: %s\n" 00588 " Indication: %s\n" 00589 " Transfer : %s\n" 00590 " Capabilities: %s\n" 00591 " Digit Begin: %s\n" 00592 " Digit End: %s\n" 00593 " Send HTML : %s\n" 00594 " Image Support: %s\n" 00595 " Text Support: %s\n", 00596 cl->tech->type, 00597 (cl->tech->devicestate) ? "yes" : "no", 00598 (cl->tech->indicate) ? "yes" : "no", 00599 (cl->tech->transfer) ? "yes" : "no", 00600 ast_getformatname_multiple(buf, sizeof(buf), (cl->tech->capabilities) ? cl->tech->capabilities : -1), 00601 (cl->tech->send_digit_begin) ? "yes" : "no", 00602 (cl->tech->send_digit_end) ? "yes" : "no", 00603 (cl->tech->send_html) ? "yes" : "no", 00604 (cl->tech->send_image) ? "yes" : "no", 00605 (cl->tech->send_text) ? "yes" : "no" 00606 00607 ); 00608 00609 AST_RWLIST_UNLOCK(&backends); 00610 00611 return CLI_SUCCESS; 00612 }
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 486 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::list, chanlist::tech, ast_channel_tech::transfer, ast_channel_tech::type, and ast_cli_entry::usage.
00487 { 00488 #define FORMAT "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\n" 00489 struct chanlist *cl; 00490 int count_chan = 0; 00491 00492 switch (cmd) { 00493 case CLI_INIT: 00494 e->command = "core show channeltypes"; 00495 e->usage = 00496 "Usage: core show channeltypes\n" 00497 " Lists available channel types registered in your\n" 00498 " Asterisk server.\n"; 00499 return NULL; 00500 case CLI_GENERATE: 00501 return NULL; 00502 } 00503 00504 if (a->argc != 3) 00505 return CLI_SHOWUSAGE; 00506 00507 ast_cli(a->fd, FORMAT, "Type", "Description", "Devicestate", "Indications", "Transfer"); 00508 ast_cli(a->fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------"); 00509 00510 AST_RWLIST_RDLOCK(&backends); 00511 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00512 ast_cli(a->fd, FORMAT, cl->tech->type, cl->tech->description, 00513 (cl->tech->devicestate) ? "yes" : "no", 00514 (cl->tech->indicate) ? "yes" : "no", 00515 (cl->tech->transfer) ? "yes" : "no"); 00516 count_chan++; 00517 } 00518 AST_RWLIST_UNLOCK(&backends); 00519 00520 ast_cli(a->fd, "----------\n%d channel drivers registered.\n", count_chan); 00521 00522 return CLI_SUCCESS; 00523 00524 #undef FORMAT 00525 }
static int attribute_const is_visible_indication | ( | enum ast_control_frame_type | condition | ) | [static] |
Definition at line 4301 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_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().
04302 { 04303 /* Don't include a default case here so that we get compiler warnings 04304 * when a new type is added. */ 04305 04306 switch (condition) { 04307 case AST_CONTROL_PROGRESS: 04308 case AST_CONTROL_PROCEEDING: 04309 case AST_CONTROL_VIDUPDATE: 04310 case AST_CONTROL_SRCUPDATE: 04311 case AST_CONTROL_SRCCHANGE: 04312 case AST_CONTROL_RADIO_KEY: 04313 case AST_CONTROL_RADIO_UNKEY: 04314 case AST_CONTROL_OPTION: 04315 case AST_CONTROL_WINK: 04316 case AST_CONTROL_FLASH: 04317 case AST_CONTROL_OFFHOOK: 04318 case AST_CONTROL_TAKEOFFHOOK: 04319 case AST_CONTROL_ANSWER: 04320 case AST_CONTROL_HANGUP: 04321 case AST_CONTROL_CONNECTED_LINE: 04322 case AST_CONTROL_REDIRECTING: 04323 case AST_CONTROL_TRANSFER: 04324 case AST_CONTROL_T38_PARAMETERS: 04325 case _XXX_AST_CONTROL_T38: 04326 case AST_CONTROL_CC: 04327 case AST_CONTROL_READ_ACTION: 04328 case AST_CONTROL_AOC: 04329 case AST_CONTROL_END_OF_Q: 04330 case AST_CONTROL_UPDATE_RTP_PEER: 04331 break; 04332 04333 case AST_CONTROL_INCOMPLETE: 04334 case AST_CONTROL_CONGESTION: 04335 case AST_CONTROL_BUSY: 04336 case AST_CONTROL_RINGING: 04337 case AST_CONTROL_RING: 04338 case AST_CONTROL_HOLD: 04339 /* You can hear these */ 04340 return 1; 04341 04342 case AST_CONTROL_UNHOLD: 04343 /* This is a special case. You stop hearing this. */ 04344 break; 04345 } 04346 04347 return 0; 04348 }
static struct ast_frame* kill_exception | ( | struct ast_channel * | chan | ) | [static] |
static int kill_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
static int kill_hangup | ( | struct ast_channel * | chan | ) | [static] |
static struct ast_frame* kill_read | ( | struct ast_channel * | chan | ) | [static] |
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 7252 of file channel.c.
References ast_manager_event_multichan, ast_channel::caller, EVENT_FLAG_CALL, ast_party_caller::id, ast_channel::name, ast_party_id::number, S_COR, ast_party_number::str, ast_channel::uniqueid, and ast_party_number::valid.
Referenced by ast_channel_bridge().
07253 { 07254 struct ast_channel *chans[2] = { c0, c1 }; 07255 ast_manager_event_multichan(EVENT_FLAG_CALL, "Bridge", 2, chans, 07256 "Bridgestate: %s\r\n" 07257 "Bridgetype: %s\r\n" 07258 "Channel1: %s\r\n" 07259 "Channel2: %s\r\n" 07260 "Uniqueid1: %s\r\n" 07261 "Uniqueid2: %s\r\n" 07262 "CallerID1: %s\r\n" 07263 "CallerID2: %s\r\n", 07264 onoff ? "Link" : "Unlink", 07265 type == 1 ? "core" : "native", 07266 c0->name, c1->name, 07267 c0->uniqueid, c1->uniqueid, 07268 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, ""), 07269 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "")); 07270 }
static void masquerade_colp_transfer | ( | struct ast_channel * | transferee, | |
struct xfer_masquerade_ds * | colp | |||
) | [static] |
Definition at line 6381 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().
06382 { 06383 struct ast_control_read_action_payload *frame_payload; 06384 int payload_size; 06385 int frame_size; 06386 unsigned char connected_line_data[1024]; 06387 06388 /* Release any hold on the target. */ 06389 if (colp->target_held) { 06390 ast_queue_control(transferee, AST_CONTROL_UNHOLD); 06391 } 06392 06393 /* 06394 * Since transferee may not actually be bridged to another channel, 06395 * there is no way for us to queue a frame so that its connected 06396 * line status will be updated. Instead, we use the somewhat 06397 * hackish approach of using a special control frame type that 06398 * instructs ast_read() to perform a specific action. In this 06399 * case, the frame we queue tells ast_read() to call the 06400 * connected line interception macro configured for transferee. 06401 */ 06402 payload_size = ast_connected_line_build_data(connected_line_data, 06403 sizeof(connected_line_data), &colp->target_id, NULL); 06404 if (payload_size != -1) { 06405 frame_size = payload_size + sizeof(*frame_payload); 06406 frame_payload = alloca(frame_size); 06407 frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO; 06408 frame_payload->payload_size = payload_size; 06409 memcpy(frame_payload->payload, connected_line_data, payload_size); 06410 ast_queue_control_data(transferee, AST_CONTROL_READ_ACTION, frame_payload, 06411 frame_size); 06412 } 06413 /* 06414 * In addition to queueing the read action frame so that the 06415 * connected line info on transferee will be updated, we also are 06416 * going to queue a plain old connected line update on transferee to 06417 * update the target. 06418 */ 06419 ast_channel_queue_connected_line_update(transferee, &colp->transferee_id, NULL); 06420 }
static const char* oldest_linkedid | ( | const char * | a, | |
const char * | b | |||
) | [static] |
Definition at line 6203 of file channel.c.
References ast_strlen_zero().
Referenced by ast_channel_set_linkgroup().
06204 { 06205 const char *satime, *saseq; 06206 const char *sbtime, *sbseq; 06207 const char *dash; 06208 06209 unsigned int atime, aseq, btime, bseq; 06210 06211 if (ast_strlen_zero(a)) 06212 return b; 06213 06214 if (ast_strlen_zero(b)) 06215 return a; 06216 06217 satime = a; 06218 sbtime = b; 06219 06220 /* jump over the system name */ 06221 if ((dash = strrchr(satime, '-'))) { 06222 satime = dash+1; 06223 } 06224 if ((dash = strrchr(sbtime, '-'))) { 06225 sbtime = dash+1; 06226 } 06227 06228 /* the sequence comes after the '.' */ 06229 saseq = strchr(satime, '.'); 06230 sbseq = strchr(sbtime, '.'); 06231 if (!saseq || !sbseq) 06232 return NULL; 06233 saseq++; 06234 sbseq++; 06235 06236 /* convert it all to integers */ 06237 atime = atoi(satime); /* note that atoi is ignoring the '.' after the time string */ 06238 btime = atoi(sbtime); /* note that atoi is ignoring the '.' after the time string */ 06239 aseq = atoi(saseq); 06240 bseq = atoi(sbseq); 06241 06242 /* and finally compare */ 06243 if (atime == btime) { 06244 return (aseq < bseq) ? a : b; 06245 } 06246 else { 06247 return (atime < btime) ? a : b; 06248 } 06249 }
static void party_connected_line_copy_transfer | ( | struct ast_party_connected_line * | dest, | |
const struct ast_party_connected_line * | src | |||
) | [static] |
Definition at line 6009 of file channel.c.
References AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, ast_party_connected_line_copy(), chanlist::connected, and ast_party_connected_line::source.
Referenced by ast_channel_transfer_masquerade().
06010 { 06011 struct ast_party_connected_line connected; 06012 06013 connected = *((struct ast_party_connected_line *) src); 06014 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; 06015 06016 /* Make sure empty strings will be erased. */ 06017 if (!connected.id.name.str) { 06018 connected.id.name.str = ""; 06019 } 06020 if (!connected.id.number.str) { 06021 connected.id.number.str = ""; 06022 } 06023 if (!connected.id.subaddress.str) { 06024 connected.id.subaddress.str = ""; 06025 } 06026 if (!connected.id.tag) { 06027 connected.id.tag = ""; 06028 } 06029 06030 ast_party_connected_line_copy(dest, &connected); 06031 }
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 8500 of file channel.c.
References ast_log(), ast_party_id_presentation(), ast_party_id_ies::combined_presentation, id, LOG_WARNING, ast_party_id_ies::name, ast_party_id_ies::number, party_name_build_data(), party_number_build_data(), party_subaddress_build_data(), ast_party_id_ies::subaddress, ast_party_id_ies::tag, and update().
Referenced by ast_connected_line_build_data(), and ast_redirecting_build_data().
08503 { 08504 size_t length; 08505 size_t pos = 0; 08506 int res; 08507 08508 /* 08509 * The size of integer values must be fixed in case the frame is 08510 * shipped to another machine. 08511 */ 08512 08513 if (!update || update->name) { 08514 res = party_name_build_data(data + pos, datalen - pos, &id->name, label, 08515 &ies->name); 08516 if (res < 0) { 08517 return -1; 08518 } 08519 pos += res; 08520 } 08521 08522 if (!update || update->number) { 08523 res = party_number_build_data(data + pos, datalen - pos, &id->number, label, 08524 &ies->number); 08525 if (res < 0) { 08526 return -1; 08527 } 08528 pos += res; 08529 } 08530 08531 if (!update || update->subaddress) { 08532 res = party_subaddress_build_data(data + pos, datalen - pos, &id->subaddress, 08533 label, &ies->subaddress); 08534 if (res < 0) { 08535 return -1; 08536 } 08537 pos += res; 08538 } 08539 08540 /* *************** Party id user tag **************************** */ 08541 if (id->tag) { 08542 length = strlen(id->tag); 08543 if (datalen < pos + (sizeof(data[0]) * 2) + length) { 08544 ast_log(LOG_WARNING, "No space left for %s tag\n", label); 08545 return -1; 08546 } 08547 data[pos++] = ies->tag; 08548 data[pos++] = length; 08549 memcpy(data + pos, id->tag, length); 08550 pos += length; 08551 } 08552 08553 /* *************** Party id combined presentation *************** */ 08554 if (!update || update->number) { 08555 int presentation; 08556 08557 if (!update || update->name) { 08558 presentation = ast_party_id_presentation(id); 08559 } else { 08560 /* 08561 * We must compromise because not all the information is available 08562 * to determine a combined presentation value. 08563 * We will only send the number presentation instead. 08564 */ 08565 presentation = id->number.presentation; 08566 } 08567 08568 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08569 ast_log(LOG_WARNING, "No space left for %s combined presentation\n", label); 08570 return -1; 08571 } 08572 data[pos++] = ies->combined_presentation; 08573 data[pos++] = 1; 08574 data[pos++] = presentation; 08575 } 08576 08577 return pos; 08578 }
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 8274 of file channel.c.
References ast_log(), ast_party_name_ies::char_set, LOG_WARNING, name, ast_party_name_ies::presentation, ast_party_name_ies::str, and ast_party_name_ies::valid.
Referenced by party_id_build_data().
08275 { 08276 size_t length; 08277 size_t pos = 0; 08278 08279 /* 08280 * The size of integer values must be fixed in case the frame is 08281 * shipped to another machine. 08282 */ 08283 if (name->str) { 08284 length = strlen(name->str); 08285 if (datalen < pos + (sizeof(data[0]) * 2) + length) { 08286 ast_log(LOG_WARNING, "No space left for %s name\n", label); 08287 return -1; 08288 } 08289 data[pos++] = ies->str; 08290 data[pos++] = length; 08291 memcpy(data + pos, name->str, length); 08292 pos += length; 08293 } 08294 08295 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08296 ast_log(LOG_WARNING, "No space left for %s name char set\n", label); 08297 return -1; 08298 } 08299 data[pos++] = ies->char_set; 08300 data[pos++] = 1; 08301 data[pos++] = name->char_set; 08302 08303 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08304 ast_log(LOG_WARNING, "No space left for %s name presentation\n", label); 08305 return -1; 08306 } 08307 data[pos++] = ies->presentation; 08308 data[pos++] = 1; 08309 data[pos++] = name->presentation; 08310 08311 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08312 ast_log(LOG_WARNING, "No space left for %s name valid\n", label); 08313 return -1; 08314 } 08315 data[pos++] = ies->valid; 08316 data[pos++] = 1; 08317 data[pos++] = name->valid; 08318 08319 return pos; 08320 }
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 8348 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().
08349 { 08350 size_t length; 08351 size_t pos = 0; 08352 08353 /* 08354 * The size of integer values must be fixed in case the frame is 08355 * shipped to another machine. 08356 */ 08357 if (number->str) { 08358 length = strlen(number->str); 08359 if (datalen < pos + (sizeof(data[0]) * 2) + length) { 08360 ast_log(LOG_WARNING, "No space left for %s number\n", label); 08361 return -1; 08362 } 08363 data[pos++] = ies->str; 08364 data[pos++] = length; 08365 memcpy(data + pos, number->str, length); 08366 pos += length; 08367 } 08368 08369 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08370 ast_log(LOG_WARNING, "No space left for %s numbering plan\n", label); 08371 return -1; 08372 } 08373 data[pos++] = ies->plan; 08374 data[pos++] = 1; 08375 data[pos++] = number->plan; 08376 08377 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08378 ast_log(LOG_WARNING, "No space left for %s number presentation\n", label); 08379 return -1; 08380 } 08381 data[pos++] = ies->presentation; 08382 data[pos++] = 1; 08383 data[pos++] = number->presentation; 08384 08385 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08386 ast_log(LOG_WARNING, "No space left for %s number valid\n", label); 08387 return -1; 08388 } 08389 data[pos++] = ies->valid; 08390 data[pos++] = 1; 08391 data[pos++] = number->valid; 08392 08393 return pos; 08394 }
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 8422 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().
08423 { 08424 size_t length; 08425 size_t pos = 0; 08426 08427 /* 08428 * The size of integer values must be fixed in case the frame is 08429 * shipped to another machine. 08430 */ 08431 if (subaddress->str) { 08432 length = strlen(subaddress->str); 08433 if (datalen < pos + (sizeof(data[0]) * 2) + length) { 08434 ast_log(LOG_WARNING, "No space left for %s subaddress\n", label); 08435 return -1; 08436 } 08437 data[pos++] = ies->str; 08438 data[pos++] = length; 08439 memcpy(data + pos, subaddress->str, length); 08440 pos += length; 08441 } 08442 08443 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08444 ast_log(LOG_WARNING, "No space left for %s type of subaddress\n", label); 08445 return -1; 08446 } 08447 data[pos++] = ies->type; 08448 data[pos++] = 1; 08449 data[pos++] = subaddress->type; 08450 08451 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08452 ast_log(LOG_WARNING, 08453 "No space left for %s subaddress odd-even indicator\n", label); 08454 return -1; 08455 } 08456 data[pos++] = ies->odd_even_indicator; 08457 data[pos++] = 1; 08458 data[pos++] = subaddress->odd_even_indicator; 08459 08460 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08461 ast_log(LOG_WARNING, "No space left for %s subaddress valid\n", label); 08462 return -1; 08463 } 08464 data[pos++] = ies->valid; 08465 data[pos++] = 1; 08466 data[pos++] = subaddress->valid; 08467 08468 return pos; 08469 }
static void plc_ds_destroy | ( | void * | data | ) | [static] |
Definition at line 4710 of file channel.c.
References ast_free, and plc_ds::samples_buf.
04711 { 04712 struct plc_ds *plc = data; 04713 ast_free(plc->samples_buf); 04714 ast_free(plc); 04715 }
static void queue_dtmf_readq | ( | struct ast_channel * | chan, | |
struct ast_frame * | f | |||
) | [inline, static] |
Definition at line 3692 of file channel.c.
References AST_FRAME_DTMF_END, ast_queue_frame(), chanlist::chan, ast_channel::dtmff, f, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::len, and ast_frame::subclass.
Referenced by __ast_read().
03693 { 03694 struct ast_frame *fr = &chan->dtmff; 03695 03696 fr->frametype = AST_FRAME_DTMF_END; 03697 fr->subclass.integer = f->subclass.integer; 03698 fr->len = f->len; 03699 03700 /* The only time this function will be called is for a frame that just came 03701 * out of the channel driver. So, we want to stick it on the tail of the 03702 * readq. */ 03703 03704 ast_queue_frame(chan, fr); 03705 }
static void report_new_callerid | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6351 of file channel.c.
References ast_describe_caller_presentation(), ast_manager_event, ast_party_id_presentation(), ast_channel::caller, chanlist::chan, EVENT_FLAG_CALL, ast_party_caller::id, ast_party_id::name, ast_channel::name, ast_party_id::number, S_COR, ast_party_name::str, ast_party_number::str, ast_channel::uniqueid, ast_party_name::valid, and ast_party_number::valid.
Referenced by ast_channel_set_caller_event(), ast_do_masquerade(), and ast_set_callerid().
06352 { 06353 int pres; 06354 06355 pres = ast_party_id_presentation(&chan->caller.id); 06356 ast_manager_event(chan, EVENT_FLAG_CALL, "NewCallerid", 06357 "Channel: %s\r\n" 06358 "CallerIDNum: %s\r\n" 06359 "CallerIDName: %s\r\n" 06360 "Uniqueid: %s\r\n" 06361 "CID-CallingPres: %d (%s)\r\n", 06362 chan->name, 06363 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""), 06364 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""), 06365 chan->uniqueid, 06366 pres, 06367 ast_describe_caller_presentation(pres) 06368 ); 06369 }
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 3631 of file channel.c.
References ast_manager_event, chanlist::chan, EVENT_FLAG_DTMF, ast_channel::name, and ast_channel::uniqueid.
Referenced by __ast_read(), and ast_write().
03632 { 03633 ast_manager_event(chan, EVENT_FLAG_DTMF, 03634 "DTMF", 03635 "Channel: %s\r\n" 03636 "Uniqueid: %s\r\n" 03637 "Digit: %c\r\n" 03638 "Direction: %s\r\n" 03639 "Begin: %s\r\n" 03640 "End: %s\r\n", 03641 chan->name, chan->uniqueid, digit, direction, begin, end); 03642 }
static int set_format | ( | struct ast_channel * | chan, | |
format_t | fmt, | |||
format_t * | rawformat, | |||
format_t * | format, | |||
struct ast_trans_pvt ** | trans, | |||
const int | direction | |||
) | [static] |
Definition at line 5103 of file channel.c.
References ast_best_codec(), ast_channel_lock, ast_channel_setoption(), ast_channel_unlock, ast_debug, AST_FORMAT_AUDIO_MASK, 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(), chanlist::chan, LOG_WARNING, ast_channel::name, and ast_channel::nativeformats.
Referenced by ast_set_read_format(), and ast_set_write_format().
05105 { 05106 format_t native, native_fmt = ast_best_codec(fmt); 05107 int res; 05108 char from[200], to[200]; 05109 05110 /* Make sure we only consider audio */ 05111 fmt &= AST_FORMAT_AUDIO_MASK; 05112 05113 native = chan->nativeformats; 05114 05115 if (!fmt || !native) /* No audio requested */ 05116 return 0; /* Let's try a call without any sounds (video, text) */ 05117 05118 /* See if the underlying channel driver is capable of performing transcoding for us */ 05119 if (!ast_channel_setoption(chan, direction ? AST_OPTION_FORMAT_WRITE : AST_OPTION_FORMAT_READ, &native_fmt, sizeof(int*), 0)) { 05120 ast_debug(1, "Channel driver natively set channel %s to %s format %s\n", chan->name, 05121 direction ? "write" : "read", ast_getformatname(native_fmt)); 05122 chan->nativeformats = *rawformat = *format = native_fmt; 05123 if (*trans) { 05124 ast_translator_free_path(*trans); 05125 } 05126 *trans = NULL; 05127 return 0; 05128 } 05129 05130 /* Find a translation path from the native format to one of the desired formats */ 05131 if (!direction) 05132 /* reading */ 05133 res = ast_translator_best_choice(&fmt, &native); 05134 else 05135 /* writing */ 05136 res = ast_translator_best_choice(&native, &fmt); 05137 05138 if (res < 0) { 05139 ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n", 05140 ast_getformatname_multiple(from, sizeof(from), native), 05141 ast_getformatname_multiple(to, sizeof(to), fmt)); 05142 return -1; 05143 } 05144 05145 /* Now we have a good choice for both. */ 05146 ast_channel_lock(chan); 05147 05148 if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) { 05149 /* the channel is already in these formats, so nothing to do */ 05150 ast_channel_unlock(chan); 05151 return 0; 05152 } 05153 05154 *rawformat = native; 05155 /* User perspective is fmt */ 05156 *format = fmt; 05157 /* Free any read translation we have right now */ 05158 if (*trans) { 05159 ast_translator_free_path(*trans); 05160 *trans = NULL; 05161 } 05162 /* Build a translation path from the raw format to the desired format */ 05163 if (*format == *rawformat) { 05164 /* 05165 * If we were able to swap the native format to the format that 05166 * has been requested, then there is no need to try to build 05167 * a translation path. 05168 */ 05169 res = 0; 05170 } else { 05171 if (!direction) { 05172 /* reading */ 05173 *trans = ast_translator_build_path(*format, *rawformat); 05174 } else { 05175 /* writing */ 05176 *trans = ast_translator_build_path(*rawformat, *format); 05177 } 05178 res = *trans ? 0 : -1; 05179 } 05180 ast_channel_unlock(chan); 05181 ast_debug(1, "Set channel %s to %s format %s\n", chan->name, 05182 direction ? "write" : "read", ast_getformatname(fmt)); 05183 return res; 05184 }
static int set_security_requirements | ( | const struct ast_channel * | requestor, | |
struct ast_channel * | out | |||
) | [static] |
Definition at line 5539 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().
05540 { 05541 int ops[2][2] = { 05542 {AST_OPTION_SECURE_SIGNALING, 0}, 05543 {AST_OPTION_SECURE_MEDIA, 0}, 05544 }; 05545 int i; 05546 struct ast_channel *r = (struct ast_channel *) requestor; /* UGLY */ 05547 struct ast_datastore *ds; 05548 05549 if (!requestor || !out) { 05550 return 0; 05551 } 05552 05553 ast_channel_lock(r); 05554 if ((ds = ast_channel_datastore_find(r, &secure_call_info, NULL))) { 05555 struct ast_secure_call_store *encrypt = ds->data; 05556 ops[0][1] = encrypt->signaling; 05557 ops[1][1] = encrypt->media; 05558 } else { 05559 ast_channel_unlock(r); 05560 return 0; 05561 } 05562 ast_channel_unlock(r); 05563 05564 for (i = 0; i < 2; i++) { 05565 if (ops[i][1]) { 05566 if (ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0)) { 05567 /* We require a security feature, but the channel won't provide it */ 05568 return -1; 05569 } 05570 } else { 05571 /* We don't care if we can't clear the option on a channel that doesn't support it */ 05572 ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0); 05573 } 05574 } 05575 05576 return 0; 05577 }
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 3710 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(), chanlist::chan, and ast_channel::dtmf_tv.
Referenced by __ast_read().
03711 { 03712 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)) { 03713 /* We're in the middle of emulating a digit, or DTMF has been 03714 * explicitly deferred. Skip this digit, then. */ 03715 return 1; 03716 } 03717 03718 if (!ast_tvzero(chan->dtmf_tv) && 03719 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) { 03720 /* We're not in the middle of a digit, but it hasn't been long enough 03721 * since the last digit, so we'll have to skip DTMF for now. */ 03722 return 1; 03723 } 03724 03725 return 0; 03726 }
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 8081 of file channel.c.
References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_write(), and ast_frame::frametype.
08082 { 08083 short buf[samples]; 08084 struct ast_frame frame = { 08085 .frametype = AST_FRAME_VOICE, 08086 .subclass.codec = AST_FORMAT_SLINEAR, 08087 .data.ptr = buf, 08088 .samples = samples, 08089 .datalen = sizeof(buf), 08090 }; 08091 08092 memset(buf, 0, sizeof(buf)); 08093 08094 if (ast_write(chan, &frame)) 08095 return -1; 08096 08097 return 0; 08098 }
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 7682 of file channel.c.
References ast_calloc, AST_FLAG_WRITE_INT, AST_FORMAT_SLINEAR, ast_log(), ast_set_flag, ast_set_write_format(), chanlist::chan, cos, tonepair_def::duration, tonepair_def::freq1, tonepair_def::freq2, LOG_WARNING, M_PI, ast_channel::name, tonepair_release(), tonepair_def::vol, and ast_channel::writeformat.
07683 { 07684 struct tonepair_state *ts; 07685 struct tonepair_def *td = params; 07686 07687 if (!(ts = ast_calloc(1, sizeof(*ts)))) 07688 return NULL; 07689 ts->origwfmt = chan->writeformat; 07690 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) { 07691 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name); 07692 tonepair_release(NULL, ts); 07693 ts = NULL; 07694 } else { 07695 ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0; 07696 ts->v1_1 = 0; 07697 ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol; 07698 ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol; 07699 ts->v2_1 = 0; 07700 ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0; 07701 ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol; 07702 ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol; 07703 ts->duration = td->duration; 07704 ts->modulate = 0; 07705 } 07706 /* Let interrupts interrupt :) */ 07707 ast_set_flag(chan, AST_FLAG_WRITE_INT); 07708 return ts; 07709 }
static int tonepair_generator | ( | struct ast_channel * | chan, | |
void * | data, | |||
int | len, | |||
int | samples | |||
) | [static] |
Definition at line 7711 of file channel.c.
References ast_log(), tonepair_state::data, tonepair_state::f, tonepair_state::fac1, tonepair_state::fac2, LOG_WARNING, tonepair_state::modulate, 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.
07712 { 07713 struct tonepair_state *ts = data; 07714 int x; 07715 07716 /* we need to prepare a frame with 16 * timelen samples as we're 07717 * generating SLIN audio 07718 */ 07719 len = samples * 2; 07720 07721 if (len > sizeof(ts->data) / 2 - 1) { 07722 ast_log(LOG_WARNING, "Can't generate that much data!\n"); 07723 return -1; 07724 } 07725 memset(&ts->f, 0, sizeof(ts->f)); 07726 for (x=0;x<len/2;x++) { 07727 ts->v1_1 = ts->v2_1; 07728 ts->v2_1 = ts->v3_1; 07729 ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1; 07730 07731 ts->v1_2 = ts->v2_2; 07732 ts->v2_2 = ts->v3_2; 07733 ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2; 07734 if (ts->modulate) { 07735 int p; 07736 p = ts->v3_2 - 32768; 07737 if (p < 0) p = -p; 07738 p = ((p * 9) / 10) + 1; 07739 ts->data[x] = (ts->v3_1 * p) >> 15; 07740 } else 07741 ts->data[x] = ts->v3_1 + ts->v3_2; 07742 } 07743 ts->f.frametype = AST_FRAME_VOICE; 07744 ts->f.subclass.codec = AST_FORMAT_SLINEAR; 07745 ts->f.datalen = len; 07746 ts->f.samples = samples; 07747 ts->f.offset = AST_FRIENDLY_OFFSET; 07748 ts->f.data.ptr = ts->data; 07749 ast_write(chan, &ts->f); 07750 ts->pos += x; 07751 if (ts->duration > 0) { 07752 if (ts->pos >= ts->duration * 8) 07753 return -1; 07754 } 07755 return 0; 07756 }
static void tonepair_release | ( | struct ast_channel * | chan, | |
void * | params | |||
) | [static] |
Definition at line 7673 of file channel.c.
References ast_free, ast_set_write_format(), chanlist::chan, and tonepair_state::origwfmt.
Referenced by tonepair_alloc().
07674 { 07675 struct tonepair_state *ts = params; 07676 07677 if (chan) 07678 ast_set_write_format(chan, ts->origwfmt); 07679 ast_free(ts); 07680 }
static void update_bridge_vars | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1 | |||
) | [static] |
Definition at line 7272 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_strdupa, ast_strlen_zero(), ast_channel_tech::get_pvt_uniqueid, ast_channel::name, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and ast_channel::tech.
Referenced by ast_channel_bridge().
07273 { 07274 const char *c0_name; 07275 const char *c1_name; 07276 const char *c0_pvtid = NULL; 07277 const char *c1_pvtid = NULL; 07278 07279 ast_channel_lock(c1); 07280 c1_name = ast_strdupa(c1->name); 07281 if (c1->tech->get_pvt_uniqueid) { 07282 c1_pvtid = ast_strdupa(c1->tech->get_pvt_uniqueid(c1)); 07283 } 07284 ast_channel_unlock(c1); 07285 07286 ast_channel_lock(c0); 07287 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER"))) { 07288 pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1_name); 07289 } 07290 if (c1_pvtid) { 07291 pbx_builtin_setvar_helper(c0, "BRIDGEPVTCALLID", c1_pvtid); 07292 } 07293 c0_name = ast_strdupa(c0->name); 07294 if (c0->tech->get_pvt_uniqueid) { 07295 c0_pvtid = ast_strdupa(c0->tech->get_pvt_uniqueid(c0)); 07296 } 07297 ast_channel_unlock(c0); 07298 07299 ast_channel_lock(c1); 07300 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER"))) { 07301 pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0_name); 07302 } 07303 if (c0_pvtid) { 07304 pbx_builtin_setvar_helper(c1, "BRIDGEPVTCALLID", c0_pvtid); 07305 } 07306 ast_channel_unlock(c1); 07307 }
static void xfer_ds_destroy | ( | void * | data | ) | [static] |
Definition at line 6054 of file channel.c.
References ast_free, ast_party_connected_line_free(), xfer_masquerade_ds::target_id, and xfer_masquerade_ds::transferee_id.
06055 { 06056 struct xfer_masquerade_ds *ds = data; 06057 06058 ast_party_connected_line_free(&ds->target_id); 06059 ast_party_connected_line_free(&ds->transferee_id); 06060 ast_free(ds); 06061 }
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 658 of file channel.c.
Referenced by ast_do_masquerade().
void(*) ast_moh_cleanup_ptr(struct ast_channel *) = NULL [static] |
Definition at line 7834 of file channel.c.
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] |
Definition at line 7832 of file channel.c.
Referenced by ast_install_music_functions(), ast_moh_start(), and ast_uninstall_music_functions().
void(*) ast_moh_stop_ptr(struct ast_channel *) = NULL [static] |
Definition at line 7833 of file channel.c.
Referenced by ast_install_music_functions(), ast_moh_stop(), and ast_uninstall_music_functions().
int cause |
Definition at line 202 of file channel.c.
Referenced by __ast_read(), __ast_request_and_dial(), action_hangup(), ast_call_forward(), cb_events(), 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(), play_sound_file(), sig_pri_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().
const struct ast_datastore_info cc_channel_datastore_info [static] |
Initial value:
{ .type = "Call Completion", .duplicate = channel_cc_params_copy, .destroy = channel_cc_params_destroy, }
Definition at line 9503 of file channel.c.
Referenced by ast_channel_cc_params_init(), and ast_channel_get_cc_config_params().
int chancount [static] |
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), }
Definition at line 8019 of file channel.c.
Referenced by ast_channels_init().
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:
{ { .handler = handle_cli_core_show_channeltypes , .summary = "List available channel types" ,__VA_ARGS__ }, { .handler = handle_cli_core_show_channeltype , .summary = "Give more details on that channel type" ,__VA_ARGS__ } }
Definition at line 614 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 102 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 1109 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, }
Definition at line 4717 of file channel.c.
Referenced by apply_plc().
int shutting_down [static] |
struct ast_generator silence_generator [static] |
Initial value:
{ .alloc = silence_generator_alloc, .release = silence_generator_release, .generate = silence_generator_generate, }
Definition at line 8100 of file channel.c.
Referenced by ast_channel_start_silence_generator().
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, }
Definition at line 7758 of file channel.c.
Referenced by ast_tonepair_start().
const struct ast_datastore_info xfer_ds_info [static] |
Initial value:
{ .type = "xfer_colp", .destroy = xfer_ds_destroy, }
Definition at line 6063 of file channel.c.
Referenced by ast_channel_transfer_masquerade(), and ast_do_masquerade().