#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/sha1.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) |
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 struct ast_datastore_info *info, const char *uid) |
Create a channel data store object. | |
ast_datastore * | ast_channel_datastore_find (struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid) |
Find a datastore on a channel. | |
int | ast_channel_datastore_free (struct ast_datastore *datastore) |
Free a channel data store object. | |
int | ast_channel_datastore_inherit (struct ast_channel *from, struct ast_channel *to) |
Inherit datastores from a parent to a child. | |
int | ast_channel_datastore_remove (struct ast_channel *chan, struct ast_datastore *datastore) |
Remove a datastore from a channel. | |
int | ast_channel_defer_dtmf (struct ast_channel *chan) |
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. | |
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 * | 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 | free_translation (struct ast_channel *clonechan) |
static int | generator_force (const void *data) |
static void | handle_cause (int cause, int *outstate) |
static char * | handle_cli_core_show_channeltype (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show details about a channel driver - CLI command. | |
static char * | handle_cli_core_show_channeltypes (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show channel types - CLI command. | |
static int attribute_const | is_visible_indication (enum ast_control_frame_type condition) |
static void | manager_bridge_event (int onoff, int type, struct ast_channel *c0, struct ast_channel *c1) |
Send manager event for bridge link and unlink events. | |
static void | 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 | |
static void(*) | ast_moh_cleanup_ptr (struct ast_channel *) = NULL |
static int(*) | ast_moh_start_ptr (struct ast_channel *, const char *, const char *) = NULL |
static void(*) | ast_moh_stop_ptr (struct ast_channel *) = NULL |
struct { | |
int cause | |
const char * desc | |
const char * name | |
} | causes [] |
map AST_CAUSE's to readable string representations | |
static struct ast_datastore_info | cc_channel_datastore_info |
static struct ast_data_entry | channel_providers [] |
static struct ao2_container * | channels |
All active channels on the system. | |
static struct ast_data_handler | channels_provider |
static struct ast_data_handler | channeltypes_provider |
static struct ast_cli_entry | cli_channel [] |
unsigned long | global_fin |
unsigned long | global_fout |
static struct ast_channel_tech | null_tech |
static struct ast_datastore_info | plc_ds_info |
static int | shutting_down |
Prevent new channel allocation if shutting down. | |
static struct ast_generator | silence_generator |
static struct ast_threadstorage | state2str_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_state2str_threadbuf , .custom_init = NULL , } |
static struct ast_generator | tonepair |
static int | uniqueint |
static struct ast_datastore_info | xfer_ds_info |
Definition in file channel.c.
#define AST_DEFAULT_EMULATE_DTMF_DURATION 100 |
Default amount of time to use when emulating a digit as a begin and end 100ms
Definition at line 105 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 108 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 112 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 8248 of file channel.c.
08248 { 08249 AST_CONNECTED_LINE_NUMBER, 08250 AST_CONNECTED_LINE_NAME, 08251 AST_CONNECTED_LINE_NUMBER_PLAN, 08252 AST_CONNECTED_LINE_ID_PRESENTATION,/* Combined number and name presentation. */ 08253 AST_CONNECTED_LINE_SOURCE, 08254 AST_CONNECTED_LINE_SUBADDRESS, 08255 AST_CONNECTED_LINE_SUBADDRESS_TYPE, 08256 AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, 08257 AST_CONNECTED_LINE_SUBADDRESS_VALID, 08258 AST_CONNECTED_LINE_TAG, 08259 AST_CONNECTED_LINE_VERSION, 08260 AST_CONNECTED_LINE_NAME_VALID, 08261 AST_CONNECTED_LINE_NAME_CHAR_SET, 08262 AST_CONNECTED_LINE_NAME_PRESENTATION, 08263 AST_CONNECTED_LINE_NUMBER_VALID, 08264 AST_CONNECTED_LINE_NUMBER_PRESENTATION, 08265 };
anonymous enum |
Element identifiers for redirecting indication frame data.
Definition at line 8569 of file channel.c.
08569 { 08570 AST_REDIRECTING_FROM_NUMBER, 08571 AST_REDIRECTING_FROM_NAME, 08572 AST_REDIRECTING_FROM_NUMBER_PLAN, 08573 AST_REDIRECTING_FROM_ID_PRESENTATION, 08574 AST_REDIRECTING_TO_NUMBER, 08575 AST_REDIRECTING_TO_NAME, 08576 AST_REDIRECTING_TO_NUMBER_PLAN, 08577 AST_REDIRECTING_TO_ID_PRESENTATION, 08578 AST_REDIRECTING_REASON, 08579 AST_REDIRECTING_COUNT, 08580 AST_REDIRECTING_FROM_SUBADDRESS, 08581 AST_REDIRECTING_FROM_SUBADDRESS_TYPE, 08582 AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, 08583 AST_REDIRECTING_FROM_SUBADDRESS_VALID, 08584 AST_REDIRECTING_TO_SUBADDRESS, 08585 AST_REDIRECTING_TO_SUBADDRESS_TYPE, 08586 AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, 08587 AST_REDIRECTING_TO_SUBADDRESS_VALID, 08588 AST_REDIRECTING_FROM_TAG, 08589 AST_REDIRECTING_TO_TAG, 08590 AST_REDIRECTING_VERSION, 08591 AST_REDIRECTING_FROM_NAME_VALID, 08592 AST_REDIRECTING_FROM_NAME_CHAR_SET, 08593 AST_REDIRECTING_FROM_NAME_PRESENTATION, 08594 AST_REDIRECTING_FROM_NUMBER_VALID, 08595 AST_REDIRECTING_FROM_NUMBER_PRESENTATION, 08596 AST_REDIRECTING_TO_NAME_VALID, 08597 AST_REDIRECTING_TO_NAME_CHAR_SET, 08598 AST_REDIRECTING_TO_NAME_PRESENTATION, 08599 AST_REDIRECTING_TO_NUMBER_VALID, 08600 AST_REDIRECTING_TO_NUMBER_PRESENTATION, 08601 };
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 2825 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(), dial_exec_full(), pbx_builtin_answer(), and pbx_builtin_incomplete().
02826 { 02827 int res = 0; 02828 enum ast_channel_state old_state; 02829 02830 old_state = chan->_state; 02831 if ((res = ast_raw_answer(chan, cdr_answer))) { 02832 return res; 02833 } 02834 02835 switch (old_state) { 02836 case AST_STATE_RINGING: 02837 case AST_STATE_RING: 02838 /* wait for media to start flowing, but don't wait any longer 02839 * than 'delay' or 500 milliseconds, whichever is longer 02840 */ 02841 do { 02842 AST_LIST_HEAD_NOLOCK(, ast_frame) frames; 02843 struct ast_frame *cur, *new; 02844 int ms = MAX(delay, 500); 02845 unsigned int done = 0; 02846 02847 AST_LIST_HEAD_INIT_NOLOCK(&frames); 02848 02849 for (;;) { 02850 ms = ast_waitfor(chan, ms); 02851 if (ms < 0) { 02852 ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", chan->name, strerror(errno)); 02853 res = -1; 02854 break; 02855 } 02856 if (ms == 0) { 02857 ast_debug(2, "Didn't receive a media frame from %s within %d ms of answering. Continuing anyway\n", chan->name, MAX(delay, 500)); 02858 break; 02859 } 02860 cur = ast_read(chan); 02861 if (!cur || ((cur->frametype == AST_FRAME_CONTROL) && 02862 (cur->subclass.integer == AST_CONTROL_HANGUP))) { 02863 if (cur) { 02864 ast_frfree(cur); 02865 } 02866 res = -1; 02867 ast_debug(2, "Hangup of channel %s detected in answer routine\n", chan->name); 02868 break; 02869 } 02870 02871 if ((new = ast_frisolate(cur)) != cur) { 02872 ast_frfree(cur); 02873 } 02874 02875 AST_LIST_INSERT_HEAD(&frames, new, frame_list); 02876 02877 /* if a specific delay period was requested, continue 02878 * until that delay has passed. don't stop just because 02879 * incoming media has arrived. 02880 */ 02881 if (delay) { 02882 continue; 02883 } 02884 02885 switch (new->frametype) { 02886 /* all of these frametypes qualify as 'media' */ 02887 case AST_FRAME_VOICE: 02888 case AST_FRAME_VIDEO: 02889 case AST_FRAME_TEXT: 02890 case AST_FRAME_DTMF_BEGIN: 02891 case AST_FRAME_DTMF_END: 02892 case AST_FRAME_IMAGE: 02893 case AST_FRAME_HTML: 02894 case AST_FRAME_MODEM: 02895 done = 1; 02896 break; 02897 case AST_FRAME_CONTROL: 02898 case AST_FRAME_IAX: 02899 case AST_FRAME_NULL: 02900 case AST_FRAME_CNG: 02901 break; 02902 } 02903 02904 if (done) { 02905 break; 02906 } 02907 } 02908 02909 if (res == 0) { 02910 ast_channel_lock(chan); 02911 while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list))) { 02912 ast_queue_frame_head(chan, cur); 02913 ast_frfree(cur); 02914 } 02915 ast_channel_unlock(chan); 02916 } 02917 } while (0); 02918 break; 02919 default: 02920 break; 02921 } 02922 02923 return res; 02924 }
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 5850 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().
05851 { 05852 ast_manager_event(chan, EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid); 05853 ast_string_field_set(chan, name, newname); 05854 }
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 |
Definition at line 1295 of file channel.c.
References __ast_channel_alloc_ap().
01301 { 01302 va_list ap1, ap2; 01303 struct ast_channel *result; 01304 01305 va_start(ap1, name_fmt); 01306 va_start(ap2, name_fmt); 01307 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context, 01308 linkedid, amaflag, file, line, function, name_fmt, ap1, ap2); 01309 va_end(ap1); 01310 va_end(ap2); 01311 01312 return result; 01313 }
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 1060 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().
01064 { 01065 struct ast_channel *tmp; 01066 int x; 01067 int flags; 01068 struct varshead *headp; 01069 char *tech = "", *tech2 = NULL; 01070 01071 /* If shutting down, don't allocate any new channels */ 01072 if (shutting_down) { 01073 ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n"); 01074 return NULL; 01075 } 01076 01077 #if defined(REF_DEBUG) 01078 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_channel_destructor, "", file, line, 01079 function, 1); 01080 #elif defined(__AST_DEBUG_MALLOC) 01081 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_channel_destructor, "", file, line, 01082 function, 0); 01083 #else 01084 tmp = ao2_alloc(sizeof(*tmp), ast_channel_destructor); 01085 #endif 01086 if (!tmp) { 01087 /* Channel structure allocation failure. */ 01088 return NULL; 01089 } 01090 01091 /* 01092 * Init file descriptors to unopened state so 01093 * the destructor can know not to close them. 01094 */ 01095 tmp->timingfd = -1; 01096 for (x = 0; x < ARRAY_LEN(tmp->alertpipe); ++x) { 01097 tmp->alertpipe[x] = -1; 01098 } 01099 for (x = 0; x < ARRAY_LEN(tmp->fds); ++x) { 01100 tmp->fds[x] = -1; 01101 } 01102 #ifdef HAVE_EPOLL 01103 tmp->epfd = epoll_create(25); 01104 #endif 01105 01106 if (!(tmp->sched = sched_context_create())) { 01107 ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n"); 01108 return ast_channel_unref(tmp); 01109 } 01110 01111 ast_party_dialed_init(&tmp->dialed); 01112 ast_party_caller_init(&tmp->caller); 01113 ast_party_connected_line_init(&tmp->connected); 01114 ast_party_redirecting_init(&tmp->redirecting); 01115 01116 if (cid_name) { 01117 tmp->caller.id.name.valid = 1; 01118 tmp->caller.id.name.str = ast_strdup(cid_name); 01119 if (!tmp->caller.id.name.str) { 01120 return ast_channel_unref(tmp); 01121 } 01122 } 01123 if (cid_num) { 01124 tmp->caller.id.number.valid = 1; 01125 tmp->caller.id.number.str = ast_strdup(cid_num); 01126 if (!tmp->caller.id.number.str) { 01127 return ast_channel_unref(tmp); 01128 } 01129 } 01130 01131 if ((tmp->timer = ast_timer_open())) { 01132 if (strcmp(ast_timer_get_name(tmp->timer), "timerfd")) { 01133 needqueue = 0; 01134 } 01135 tmp->timingfd = ast_timer_fd(tmp->timer); 01136 } 01137 01138 if (needqueue) { 01139 if (pipe(tmp->alertpipe)) { 01140 ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe! Try increasing max file descriptors with ulimit -n\n"); 01141 return ast_channel_unref(tmp); 01142 } else { 01143 flags = fcntl(tmp->alertpipe[0], F_GETFL); 01144 if (fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) { 01145 ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno)); 01146 return ast_channel_unref(tmp); 01147 } 01148 flags = fcntl(tmp->alertpipe[1], F_GETFL); 01149 if (fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK) < 0) { 01150 ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno)); 01151 return ast_channel_unref(tmp); 01152 } 01153 } 01154 } 01155 01156 /* 01157 * This is the last place the channel constructor can fail. 01158 * 01159 * The destructor takes advantage of this fact to ensure that the 01160 * AST_CEL_CHANNEL_END is not posted if we have not posted the 01161 * AST_CEL_CHANNEL_START yet. 01162 */ 01163 if ((ast_string_field_init(tmp, 128))) { 01164 return ast_channel_unref(tmp); 01165 } 01166 01167 /* Always watch the alertpipe */ 01168 ast_channel_set_fd(tmp, AST_ALERT_FD, tmp->alertpipe[0]); 01169 /* And timing pipe */ 01170 ast_channel_set_fd(tmp, AST_TIMING_FD, tmp->timingfd); 01171 01172 /* Initial state */ 01173 tmp->_state = state; 01174 01175 tmp->streamid = -1; 01176 01177 tmp->fin = global_fin; 01178 tmp->fout = global_fout; 01179 01180 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) { 01181 ast_string_field_build(tmp, uniqueid, "%li.%d", (long) time(NULL), 01182 ast_atomic_fetchadd_int(&uniqueint, 1)); 01183 } else { 01184 ast_string_field_build(tmp, uniqueid, "%s-%li.%d", ast_config_AST_SYSTEM_NAME, 01185 (long) time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1)); 01186 } 01187 01188 if (!ast_strlen_zero(linkedid)) { 01189 ast_string_field_set(tmp, linkedid, linkedid); 01190 } else { 01191 ast_string_field_set(tmp, linkedid, tmp->uniqueid); 01192 } 01193 01194 if (!ast_strlen_zero(name_fmt)) { 01195 char *slash, *slash2; 01196 /* Almost every channel is calling this function, and setting the name via the ast_string_field_build() call. 01197 * And they all use slightly different formats for their name string. 01198 * This means, to set the name here, we have to accept variable args, and call the string_field_build from here. 01199 * This means, that the stringfields must have a routine that takes the va_lists directly, and 01200 * uses them to build the string, instead of forming the va_lists internally from the vararg ... list. 01201 * This new function was written so this can be accomplished. 01202 */ 01203 ast_string_field_build_va(tmp, name, name_fmt, ap1, ap2); 01204 tech = ast_strdupa(tmp->name); 01205 if ((slash = strchr(tech, '/'))) { 01206 if ((slash2 = strchr(slash + 1, '/'))) { 01207 tech2 = slash + 1; 01208 *slash2 = '\0'; 01209 } 01210 *slash = '\0'; 01211 } 01212 } else { 01213 /* 01214 * Start the string with '-' so it becomes an empty string 01215 * in the destructor. 01216 */ 01217 ast_string_field_set(tmp, name, "-**Unknown**"); 01218 } 01219 01220 /* Reminder for the future: under what conditions do we NOT want to track cdrs on channels? */ 01221 01222 /* These 4 variables need to be set up for the cdr_init() to work right */ 01223 if (amaflag) 01224 tmp->amaflags = amaflag; 01225 else 01226 tmp->amaflags = ast_default_amaflags; 01227 01228 if (!ast_strlen_zero(acctcode)) 01229 ast_string_field_set(tmp, accountcode, acctcode); 01230 else 01231 ast_string_field_set(tmp, accountcode, ast_default_accountcode); 01232 01233 if (!ast_strlen_zero(context)) 01234 ast_copy_string(tmp->context, context, sizeof(tmp->context)); 01235 else 01236 strcpy(tmp->context, "default"); 01237 01238 if (!ast_strlen_zero(exten)) 01239 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); 01240 else 01241 strcpy(tmp->exten, "s"); 01242 01243 tmp->priority = 1; 01244 01245 tmp->cdr = ast_cdr_alloc(); 01246 ast_cdr_init(tmp->cdr, tmp); 01247 ast_cdr_start(tmp->cdr); 01248 01249 ast_cel_report_event(tmp, AST_CEL_CHANNEL_START, NULL, NULL, NULL); 01250 01251 headp = &tmp->varshead; 01252 AST_LIST_HEAD_INIT_NOLOCK(headp); 01253 01254 AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores); 01255 01256 AST_LIST_HEAD_INIT_NOLOCK(&tmp->autochans); 01257 01258 ast_string_field_set(tmp, language, defaultlanguage); 01259 01260 tmp->tech = &null_tech; 01261 01262 ao2_link(channels, tmp); 01263 01264 /* 01265 * And now, since the channel structure is built, and has its name, let's 01266 * call the manager event generator with this Newchannel event. This is the 01267 * proper and correct place to make this call, but you sure do have to pass 01268 * a lot of data into this func to do it here! 01269 */ 01270 if (ast_get_channel_tech(tech) || (tech2 && ast_get_channel_tech(tech2))) { 01271 ast_manager_event(tmp, EVENT_FLAG_CALL, "Newchannel", 01272 "Channel: %s\r\n" 01273 "ChannelState: %d\r\n" 01274 "ChannelStateDesc: %s\r\n" 01275 "CallerIDNum: %s\r\n" 01276 "CallerIDName: %s\r\n" 01277 "AccountCode: %s\r\n" 01278 "Exten: %s\r\n" 01279 "Context: %s\r\n" 01280 "Uniqueid: %s\r\n", 01281 tmp->name, 01282 state, 01283 ast_state2str(state), 01284 S_OR(cid_num, ""), 01285 S_OR(cid_name, ""), 01286 tmp->accountcode, 01287 S_OR(exten, ""), 01288 S_OR(context, ""), 01289 tmp->uniqueid); 01290 } 01291 01292 return tmp; 01293 }
static int __ast_channel_masquerade | ( | struct ast_channel * | original, | |
struct ast_channel * | clonechan, | |||
struct ast_datastore * | xfer_ds | |||
) | [static] |
Definition at line 5647 of file channel.c.
References ast_channel::_bridge, ast_bridged_channel(), ast_channel_datastore_add(), ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_log(), ast_null_frame, ast_queue_frame(), ast_channel_tech::get_base_channel, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::name, and ast_channel::tech.
Referenced by ast_channel_masquerade(), and ast_channel_transfer_masquerade().
05648 { 05649 int res = -1; 05650 struct ast_channel *final_orig, *final_clone, *base; 05651 05652 retrymasq: 05653 final_orig = original; 05654 final_clone = clonechan; 05655 05656 ast_channel_lock(original); 05657 while (ast_channel_trylock(clonechan)) { 05658 ast_channel_unlock(original); 05659 usleep(1); 05660 ast_channel_lock(original); 05661 } 05662 05663 /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent) 05664 and if so, we don't really want to masquerade it, but its proxy */ 05665 if (original->_bridge && (original->_bridge != ast_bridged_channel(original)) && (original->_bridge->_bridge != original)) 05666 final_orig = original->_bridge; 05667 05668 if (clonechan->_bridge && (clonechan->_bridge != ast_bridged_channel(clonechan)) && (clonechan->_bridge->_bridge != clonechan)) 05669 final_clone = clonechan->_bridge; 05670 05671 if (final_clone->tech->get_base_channel && (base = final_clone->tech->get_base_channel(final_clone))) { 05672 final_clone = base; 05673 } 05674 05675 if ((final_orig != original) || (final_clone != clonechan)) { 05676 /* Lots and lots of deadlock avoidance. The main one we're competing with 05677 * is ast_write(), which locks channels recursively, when working with a 05678 * proxy channel. */ 05679 if (ast_channel_trylock(final_orig)) { 05680 ast_channel_unlock(clonechan); 05681 ast_channel_unlock(original); 05682 goto retrymasq; 05683 } 05684 if (ast_channel_trylock(final_clone)) { 05685 ast_channel_unlock(final_orig); 05686 ast_channel_unlock(clonechan); 05687 ast_channel_unlock(original); 05688 goto retrymasq; 05689 } 05690 ast_channel_unlock(clonechan); 05691 ast_channel_unlock(original); 05692 original = final_orig; 05693 clonechan = final_clone; 05694 } 05695 05696 if (original == clonechan) { 05697 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name); 05698 ast_channel_unlock(clonechan); 05699 ast_channel_unlock(original); 05700 return -1; 05701 } 05702 05703 ast_debug(1, "Planning to masquerade channel %s into the structure of %s\n", 05704 clonechan->name, original->name); 05705 05706 if (!original->masqr && !original->masq && !clonechan->masq && !clonechan->masqr) { 05707 original->masq = clonechan; 05708 clonechan->masqr = original; 05709 if (xfer_ds) { 05710 ast_channel_datastore_add(original, xfer_ds); 05711 } 05712 ast_queue_frame(original, &ast_null_frame); 05713 ast_queue_frame(clonechan, &ast_null_frame); 05714 ast_debug(1, "Done planning to masquerade channel %s into the structure of %s\n", clonechan->name, original->name); 05715 res = 0; 05716 } else if (original->masq) { 05717 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 05718 original->masq->name, original->name); 05719 } else if (original->masqr) { 05720 /* not yet as a previously planned masq hasn't yet happened */ 05721 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 05722 original->name, original->masqr->name); 05723 } else if (clonechan->masq) { 05724 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 05725 clonechan->masq->name, clonechan->name); 05726 } else { /* (clonechan->masqr) */ 05727 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 05728 clonechan->name, clonechan->masqr->name); 05729 } 05730 05731 ast_channel_unlock(clonechan); 05732 ast_channel_unlock(original); 05733 05734 return res; 05735 }
static int __ast_queue_frame | ( | struct ast_channel * | chan, | |
struct ast_frame * | fin, | |||
int | head, | |||
struct ast_frame * | after | |||
) | [static] |
Definition at line 1350 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().
01351 { 01352 struct ast_frame *f; 01353 struct ast_frame *cur; 01354 int blah = 1; 01355 unsigned int new_frames = 0; 01356 unsigned int new_voice_frames = 0; 01357 unsigned int queued_frames = 0; 01358 unsigned int queued_voice_frames = 0; 01359 AST_LIST_HEAD_NOLOCK(, ast_frame) frames; 01360 01361 ast_channel_lock(chan); 01362 01363 /* 01364 * Check the last frame on the queue if we are queuing the new 01365 * frames after it. 01366 */ 01367 cur = AST_LIST_LAST(&chan->readq); 01368 if (cur && cur->frametype == AST_FRAME_CONTROL && !head && (!after || after == cur)) { 01369 switch (cur->subclass.integer) { 01370 case AST_CONTROL_END_OF_Q: 01371 if (fin->frametype == AST_FRAME_CONTROL 01372 && fin->subclass.integer == AST_CONTROL_HANGUP) { 01373 /* 01374 * Destroy the end-of-Q marker frame so we can queue the hangup 01375 * frame in its place. 01376 */ 01377 AST_LIST_REMOVE(&chan->readq, cur, frame_list); 01378 ast_frfree(cur); 01379 01380 /* 01381 * This has degenerated to a normal queue append anyway. Since 01382 * we just destroyed the last frame in the queue we must make 01383 * sure that "after" is NULL or bad things will happen. 01384 */ 01385 after = NULL; 01386 break; 01387 } 01388 /* Fall through */ 01389 case AST_CONTROL_HANGUP: 01390 /* Don't queue anything. */ 01391 ast_channel_unlock(chan); 01392 return 0; 01393 default: 01394 break; 01395 } 01396 } 01397 01398 /* Build copies of all the new frames and count them */ 01399 AST_LIST_HEAD_INIT_NOLOCK(&frames); 01400 for (cur = fin; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 01401 if (!(f = ast_frdup(cur))) { 01402 if (AST_LIST_FIRST(&frames)) { 01403 ast_frfree(AST_LIST_FIRST(&frames)); 01404 } 01405 ast_channel_unlock(chan); 01406 return -1; 01407 } 01408 01409 AST_LIST_INSERT_TAIL(&frames, f, frame_list); 01410 new_frames++; 01411 if (f->frametype == AST_FRAME_VOICE) { 01412 new_voice_frames++; 01413 } 01414 } 01415 01416 /* Count how many frames exist on the queue */ 01417 AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) { 01418 queued_frames++; 01419 if (cur->frametype == AST_FRAME_VOICE) { 01420 queued_voice_frames++; 01421 } 01422 } 01423 01424 if ((queued_frames + new_frames > 128 || queued_voice_frames + new_voice_frames > 96)) { 01425 int count = 0; 01426 ast_log(LOG_WARNING, "Exceptionally long %squeue length queuing to %s\n", queued_frames + new_frames > 128 ? "" : "voice ", chan->name); 01427 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, cur, frame_list) { 01428 /* Save the most recent frame */ 01429 if (!AST_LIST_NEXT(cur, frame_list)) { 01430 break; 01431 } else if (cur->frametype == AST_FRAME_VOICE || cur->frametype == AST_FRAME_VIDEO || cur->frametype == AST_FRAME_NULL) { 01432 if (++count > 64) { 01433 break; 01434 } 01435 AST_LIST_REMOVE_CURRENT(frame_list); 01436 ast_frfree(cur); 01437 } 01438 } 01439 AST_LIST_TRAVERSE_SAFE_END; 01440 } 01441 01442 if (after) { 01443 AST_LIST_INSERT_LIST_AFTER(&chan->readq, &frames, after, frame_list); 01444 } else { 01445 if (head) { 01446 AST_LIST_APPEND_LIST(&frames, &chan->readq, frame_list); 01447 AST_LIST_HEAD_INIT_NOLOCK(&chan->readq); 01448 } 01449 AST_LIST_APPEND_LIST(&chan->readq, &frames, frame_list); 01450 } 01451 01452 if (chan->alertpipe[1] > -1) { 01453 if (write(chan->alertpipe[1], &blah, new_frames * sizeof(blah)) != (new_frames * sizeof(blah))) { 01454 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s (qlen = %d): %s!\n", 01455 chan->name, queued_frames, strerror(errno)); 01456 } 01457 } else if (chan->timingfd > -1) { 01458 ast_timer_enable_continuous(chan->timer); 01459 } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 01460 pthread_kill(chan->blocker, SIGURG); 01461 } 01462 01463 ast_channel_unlock(chan); 01464 01465 return 0; 01466 }
static struct ast_frame* __ast_read | ( | struct ast_channel * | chan, | |
int | dropaudio | |||
) | [static] |
Definition at line 3616 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().
03617 { 03618 struct ast_frame *f = NULL; /* the return value */ 03619 int blah; 03620 int prestate; 03621 int cause = 0; 03622 03623 /* this function is very long so make sure there is only one return 03624 * point at the end (there are only two exceptions to this). 03625 */ 03626 03627 if (chan->masq) { 03628 if (ast_do_masquerade(chan)) 03629 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 03630 else 03631 f = &ast_null_frame; 03632 return f; 03633 } 03634 03635 /* if here, no masq has happened, lock the channel and proceed */ 03636 ast_channel_lock(chan); 03637 03638 /* Stop if we're a zombie or need a soft hangup */ 03639 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 03640 if (chan->generator) 03641 ast_deactivate_generator(chan); 03642 03643 /* 03644 * It is possible for chan->_softhangup to be set and there 03645 * still be control frames that need to be read. Instead of 03646 * just going to 'done' in the case of ast_check_hangup(), we 03647 * need to queue the end-of-Q frame so that it can mark the end 03648 * of the read queue. If there are frames to be read, 03649 * ast_queue_control() will be called repeatedly, but will only 03650 * queue the first end-of-Q frame. 03651 */ 03652 if (chan->_softhangup) { 03653 ast_queue_control(chan, AST_CONTROL_END_OF_Q); 03654 } else { 03655 goto done; 03656 } 03657 } 03658 03659 #ifdef AST_DEVMODE 03660 /* 03661 * The ast_waitfor() code records which of the channel's file descriptors reported that 03662 * data is available. In theory, ast_read() should only be called after ast_waitfor() 03663 * reports that a channel has data available for reading. However, there still may be 03664 * some edge cases throughout the code where ast_read() is called improperly. This can 03665 * potentially cause problems, so if this is a developer build, make a lot of noise if 03666 * this happens so that it can be addressed. 03667 */ 03668 if (chan->fdno == -1) { 03669 ast_log(LOG_ERROR, 03670 "ast_read() on chan '%s' called with no recorded file descriptor.\n", 03671 chan->name); 03672 } 03673 #endif 03674 03675 prestate = chan->_state; 03676 03677 /* Read and ignore anything on the alertpipe, but read only 03678 one sizeof(blah) per frame that we send from it */ 03679 if (chan->alertpipe[0] > -1) { 03680 int flags = fcntl(chan->alertpipe[0], F_GETFL); 03681 /* For some odd reason, the alertpipe occasionally loses nonblocking status, 03682 * which immediately causes a deadlock scenario. Detect and prevent this. */ 03683 if ((flags & O_NONBLOCK) == 0) { 03684 ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", chan->name); 03685 if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) { 03686 ast_log(LOG_WARNING, "Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno)); 03687 f = &ast_null_frame; 03688 goto done; 03689 } 03690 } 03691 if (read(chan->alertpipe[0], &blah, sizeof(blah)) < 0) { 03692 if (errno != EINTR && errno != EAGAIN) 03693 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 03694 } 03695 } 03696 03697 if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD) { 03698 enum ast_timer_event res; 03699 03700 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 03701 03702 res = ast_timer_get_event(chan->timer); 03703 03704 switch (res) { 03705 case AST_TIMING_EVENT_EXPIRED: 03706 ast_timer_ack(chan->timer, 1); 03707 03708 if (chan->timingfunc) { 03709 /* save a copy of func/data before unlocking the channel */ 03710 int (*func)(const void *) = chan->timingfunc; 03711 void *data = chan->timingdata; 03712 chan->fdno = -1; 03713 ast_channel_unlock(chan); 03714 func(data); 03715 } else { 03716 ast_timer_set_rate(chan->timer, 0); 03717 chan->fdno = -1; 03718 ast_channel_unlock(chan); 03719 } 03720 03721 /* cannot 'goto done' because the channel is already unlocked */ 03722 return &ast_null_frame; 03723 03724 case AST_TIMING_EVENT_CONTINUOUS: 03725 if (AST_LIST_EMPTY(&chan->readq) || 03726 !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) { 03727 ast_timer_disable_continuous(chan->timer); 03728 } 03729 break; 03730 } 03731 03732 } else if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) { 03733 /* if the AST_GENERATOR_FD is set, call the generator with args 03734 * set to -1 so it can do whatever it needs to. 03735 */ 03736 void *tmp = chan->generatordata; 03737 chan->generatordata = NULL; /* reset to let ast_write get through */ 03738 chan->generator->generate(chan, tmp, -1, -1); 03739 chan->generatordata = tmp; 03740 f = &ast_null_frame; 03741 chan->fdno = -1; 03742 goto done; 03743 } 03744 03745 /* Check for pending read queue */ 03746 if (!AST_LIST_EMPTY(&chan->readq)) { 03747 int skip_dtmf = should_skip_dtmf(chan); 03748 03749 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, f, frame_list) { 03750 /* We have to be picky about which frame we pull off of the readq because 03751 * there are cases where we want to leave DTMF frames on the queue until 03752 * some later time. */ 03753 03754 if ( (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && skip_dtmf) { 03755 continue; 03756 } 03757 03758 AST_LIST_REMOVE_CURRENT(frame_list); 03759 break; 03760 } 03761 AST_LIST_TRAVERSE_SAFE_END; 03762 03763 if (!f) { 03764 /* There were no acceptable frames on the readq. */ 03765 f = &ast_null_frame; 03766 if (chan->alertpipe[0] > -1) { 03767 int poke = 0; 03768 /* Restore the state of the alertpipe since we aren't ready for any 03769 * of the frames in the readq. */ 03770 if (write(chan->alertpipe[1], &poke, sizeof(poke)) != sizeof(poke)) { 03771 ast_log(LOG_ERROR, "Failed to write to alertpipe: %s\n", strerror(errno)); 03772 } 03773 } 03774 } 03775 03776 /* Interpret hangup and end-of-Q frames to return NULL */ 03777 /* XXX why not the same for frames from the channel ? */ 03778 if (f->frametype == AST_FRAME_CONTROL) { 03779 switch (f->subclass.integer) { 03780 case AST_CONTROL_HANGUP: 03781 chan->_softhangup |= AST_SOFTHANGUP_DEV; 03782 cause = f->data.uint32; 03783 /* Fall through */ 03784 case AST_CONTROL_END_OF_Q: 03785 ast_frfree(f); 03786 f = NULL; 03787 break; 03788 default: 03789 break; 03790 } 03791 } 03792 } else { 03793 chan->blocker = pthread_self(); 03794 if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) { 03795 if (chan->tech->exception) 03796 f = chan->tech->exception(chan); 03797 else { 03798 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name); 03799 f = &ast_null_frame; 03800 } 03801 /* Clear the exception flag */ 03802 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 03803 } else if (chan->tech->read) 03804 f = chan->tech->read(chan); 03805 else 03806 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name); 03807 } 03808 03809 /* 03810 * Reset the recorded file descriptor that triggered this read so that we can 03811 * easily detect when ast_read() is called without properly using ast_waitfor(). 03812 */ 03813 chan->fdno = -1; 03814 03815 /* Perform the framehook read event here. After the frame enters the framehook list 03816 * there is no telling what will happen, <insert mad scientist laugh here>!!! */ 03817 f = ast_framehook_list_read_event(chan->framehooks, f); 03818 03819 if (f) { 03820 struct ast_frame *readq_tail = AST_LIST_LAST(&chan->readq); 03821 struct ast_control_read_action_payload *read_action_payload; 03822 struct ast_party_connected_line connected; 03823 03824 /* if the channel driver returned more than one frame, stuff the excess 03825 into the readq for the next ast_read call 03826 */ 03827 if (AST_LIST_NEXT(f, frame_list)) { 03828 ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list)); 03829 ast_frfree(AST_LIST_NEXT(f, frame_list)); 03830 AST_LIST_NEXT(f, frame_list) = NULL; 03831 } 03832 03833 switch (f->frametype) { 03834 case AST_FRAME_CONTROL: 03835 if (f->subclass.integer == AST_CONTROL_ANSWER) { 03836 if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) { 03837 ast_debug(1, "Ignoring answer on an inbound call!\n"); 03838 ast_frfree(f); 03839 f = &ast_null_frame; 03840 } else if (prestate == AST_STATE_UP && ast_bridged_channel(chan)) { 03841 ast_debug(1, "Dropping duplicate answer!\n"); 03842 ast_frfree(f); 03843 f = &ast_null_frame; 03844 } else { 03845 /* Answer the CDR */ 03846 ast_setstate(chan, AST_STATE_UP); 03847 /* removed a call to ast_cdr_answer(chan->cdr) from here. */ 03848 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 03849 } 03850 } else if (f->subclass.integer == AST_CONTROL_READ_ACTION) { 03851 read_action_payload = f->data.ptr; 03852 switch (read_action_payload->action) { 03853 case AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO: 03854 ast_party_connected_line_init(&connected); 03855 ast_party_connected_line_copy(&connected, &chan->connected); 03856 if (ast_connected_line_parse_data(read_action_payload->payload, 03857 read_action_payload->payload_size, &connected)) { 03858 ast_party_connected_line_free(&connected); 03859 break; 03860 } 03861 if (ast_channel_connected_line_macro(NULL, chan, &connected, 1, 0)) { 03862 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, 03863 read_action_payload->payload, 03864 read_action_payload->payload_size); 03865 } 03866 ast_party_connected_line_free(&connected); 03867 break; 03868 } 03869 ast_frfree(f); 03870 f = &ast_null_frame; 03871 } 03872 break; 03873 case AST_FRAME_DTMF_END: 03874 send_dtmf_event(chan, "Received", f->subclass.integer, "No", "Yes"); 03875 ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass.integer, chan->name, f->len); 03876 /* Queue it up if DTMF is deferred, or if DTMF emulation is forced. */ 03877 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) || ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) { 03878 queue_dtmf_readq(chan, f); 03879 ast_frfree(f); 03880 f = &ast_null_frame; 03881 } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) { 03882 if (!ast_tvzero(chan->dtmf_tv) && 03883 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) { 03884 /* If it hasn't been long enough, defer this digit */ 03885 queue_dtmf_readq(chan, f); 03886 ast_frfree(f); 03887 f = &ast_null_frame; 03888 } else { 03889 /* There was no begin, turn this into a begin and send the end later */ 03890 f->frametype = AST_FRAME_DTMF_BEGIN; 03891 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF); 03892 chan->emulate_dtmf_digit = f->subclass.integer; 03893 chan->dtmf_tv = ast_tvnow(); 03894 if (f->len) { 03895 if (f->len > AST_MIN_DTMF_DURATION) 03896 chan->emulate_dtmf_duration = f->len; 03897 else 03898 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION; 03899 } else 03900 chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION; 03901 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); 03902 } 03903 if (chan->audiohooks) { 03904 struct ast_frame *old_frame = f; 03905 /*! 03906 * \todo XXX It is possible to write a digit to the audiohook twice 03907 * if the digit was originally read while the channel was in autoservice. */ 03908 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 03909 if (old_frame != f) 03910 ast_frfree(old_frame); 03911 } 03912 } else { 03913 struct timeval now = ast_tvnow(); 03914 if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) { 03915 ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass.integer, chan->name); 03916 ast_clear_flag(chan, AST_FLAG_IN_DTMF); 03917 if (!f->len) 03918 f->len = ast_tvdiff_ms(now, chan->dtmf_tv); 03919 03920 /* detect tones that were received on 03921 * the wire with durations shorter than 03922 * AST_MIN_DTMF_DURATION and set f->len 03923 * to the actual duration of the DTMF 03924 * frames on the wire. This will cause 03925 * dtmf emulation to be triggered later 03926 * on. 03927 */ 03928 if (ast_tvdiff_ms(now, chan->dtmf_tv) < AST_MIN_DTMF_DURATION) { 03929 f->len = ast_tvdiff_ms(now, chan->dtmf_tv); 03930 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); 03931 } 03932 } else if (!f->len) { 03933 ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass.integer, chan->name); 03934 f->len = AST_MIN_DTMF_DURATION; 03935 } 03936 if (f->len < AST_MIN_DTMF_DURATION && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) { 03937 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); 03938 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF); 03939 chan->emulate_dtmf_digit = f->subclass.integer; 03940 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len; 03941 ast_frfree(f); 03942 f = &ast_null_frame; 03943 } else { 03944 ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass.integer, chan->name); 03945 if (f->len < AST_MIN_DTMF_DURATION) { 03946 f->len = AST_MIN_DTMF_DURATION; 03947 } 03948 chan->dtmf_tv = now; 03949 } 03950 if (chan->audiohooks) { 03951 struct ast_frame *old_frame = f; 03952 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 03953 if (old_frame != f) 03954 ast_frfree(old_frame); 03955 } 03956 } 03957 break; 03958 case AST_FRAME_DTMF_BEGIN: 03959 send_dtmf_event(chan, "Received", f->subclass.integer, "Yes", "No"); 03960 ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass.integer, chan->name); 03961 if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) || 03962 (!ast_tvzero(chan->dtmf_tv) && 03963 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) { 03964 ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass.integer, chan->name); 03965 ast_frfree(f); 03966 f = &ast_null_frame; 03967 } else { 03968 ast_set_flag(chan, AST_FLAG_IN_DTMF); 03969 chan->dtmf_tv = ast_tvnow(); 03970 ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass.integer, chan->name); 03971 } 03972 break; 03973 case AST_FRAME_NULL: 03974 /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration 03975 * is reached , because we want to make sure we pass at least one 03976 * voice frame through before starting the next digit, to ensure a gap 03977 * between DTMF digits. */ 03978 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) { 03979 struct timeval now = ast_tvnow(); 03980 if (!chan->emulate_dtmf_duration) { 03981 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF); 03982 chan->emulate_dtmf_digit = 0; 03983 } else if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) { 03984 chan->emulate_dtmf_duration = 0; 03985 ast_frfree(f); 03986 f = &chan->dtmff; 03987 f->frametype = AST_FRAME_DTMF_END; 03988 f->subclass.integer = chan->emulate_dtmf_digit; 03989 f->len = ast_tvdiff_ms(now, chan->dtmf_tv); 03990 chan->dtmf_tv = now; 03991 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF); 03992 chan->emulate_dtmf_digit = 0; 03993 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, chan->name); 03994 if (chan->audiohooks) { 03995 struct ast_frame *old_frame = f; 03996 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 03997 if (old_frame != f) { 03998 ast_frfree(old_frame); 03999 } 04000 } 04001 } 04002 } 04003 break; 04004 case AST_FRAME_VOICE: 04005 /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration 04006 * is reached , because we want to make sure we pass at least one 04007 * voice frame through before starting the next digit, to ensure a gap 04008 * between DTMF digits. */ 04009 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) { 04010 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF); 04011 chan->emulate_dtmf_digit = 0; 04012 } 04013 04014 if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) { 04015 if (dropaudio) 04016 ast_read_generator_actions(chan, f); 04017 ast_frfree(f); 04018 f = &ast_null_frame; 04019 } 04020 04021 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_IN_DTMF)) { 04022 struct timeval now = ast_tvnow(); 04023 if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) { 04024 chan->emulate_dtmf_duration = 0; 04025 ast_frfree(f); 04026 f = &chan->dtmff; 04027 f->frametype = AST_FRAME_DTMF_END; 04028 f->subclass.integer = chan->emulate_dtmf_digit; 04029 f->len = ast_tvdiff_ms(now, chan->dtmf_tv); 04030 chan->dtmf_tv = now; 04031 if (chan->audiohooks) { 04032 struct ast_frame *old_frame = f; 04033 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 04034 if (old_frame != f) 04035 ast_frfree(old_frame); 04036 } 04037 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, chan->name); 04038 } else { 04039 /* Drop voice frames while we're still in the middle of the digit */ 04040 ast_frfree(f); 04041 f = &ast_null_frame; 04042 } 04043 } else if ((f->frametype == AST_FRAME_VOICE) && !(f->subclass.codec & chan->nativeformats)) { 04044 /* This frame is not one of the current native formats -- drop it on the floor */ 04045 char to[200]; 04046 ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n", 04047 chan->name, ast_getformatname(f->subclass.codec), ast_getformatname_multiple(to, sizeof(to), chan->nativeformats)); 04048 ast_frfree(f); 04049 f = &ast_null_frame; 04050 } else if ((f->frametype == AST_FRAME_VOICE)) { 04051 /* Send frame to audiohooks if present */ 04052 if (chan->audiohooks) { 04053 struct ast_frame *old_frame = f; 04054 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 04055 if (old_frame != f) 04056 ast_frfree(old_frame); 04057 } 04058 if (chan->monitor && chan->monitor->read_stream ) { 04059 /* XXX what does this do ? */ 04060 #ifndef MONITOR_CONSTANT_DELAY 04061 int jump = chan->outsmpl - chan->insmpl - 4 * f->samples; 04062 if (jump >= 0) { 04063 jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 04064 if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1) 04065 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 04066 chan->insmpl += (chan->outsmpl - chan->insmpl) + f->samples; 04067 } else 04068 chan->insmpl+= f->samples; 04069 #else 04070 int jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 04071 if (jump - MONITOR_DELAY >= 0) { 04072 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1) 04073 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 04074 chan->insmpl += chan->outsmpl - chan->insmpl; 04075 } else 04076 chan->insmpl += f->samples; 04077 #endif 04078 if (chan->monitor->state == AST_MONITOR_RUNNING) { 04079 if (ast_writestream(chan->monitor->read_stream, f) < 0) 04080 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n"); 04081 } 04082 } 04083 04084 if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL) { 04085 f = &ast_null_frame; 04086 } 04087 04088 /* it is possible for the translation process on chan->readtrans to have 04089 produced multiple frames from the single input frame we passed it; if 04090 this happens, queue the additional frames *before* the frames we may 04091 have queued earlier. if the readq was empty, put them at the head of 04092 the queue, and if it was not, put them just after the frame that was 04093 at the end of the queue. 04094 */ 04095 if (AST_LIST_NEXT(f, frame_list)) { 04096 if (!readq_tail) { 04097 ast_queue_frame_head(chan, AST_LIST_NEXT(f, frame_list)); 04098 } else { 04099 __ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list), 0, readq_tail); 04100 } 04101 ast_frfree(AST_LIST_NEXT(f, frame_list)); 04102 AST_LIST_NEXT(f, frame_list) = NULL; 04103 } 04104 04105 /* Run generator sitting on the line if timing device not available 04106 * and synchronous generation of outgoing frames is necessary */ 04107 ast_read_generator_actions(chan, f); 04108 } 04109 break; 04110 default: 04111 /* Just pass it on! */ 04112 break; 04113 } 04114 } else { 04115 /* Make sure we always return NULL in the future */ 04116 if (!chan->_softhangup) { 04117 chan->_softhangup |= AST_SOFTHANGUP_DEV; 04118 } 04119 if (cause) 04120 chan->hangupcause = cause; 04121 if (chan->generator) 04122 ast_deactivate_generator(chan); 04123 /* We no longer End the CDR here */ 04124 } 04125 04126 /* High bit prints debugging */ 04127 if (chan->fin & DEBUGCHAN_FLAG) 04128 ast_frame_dump(chan->name, f, "<<"); 04129 chan->fin = FRAMECOUNT_INC(chan->fin); 04130 04131 done: 04132 if (chan->music_state && chan->generator && chan->generator->digit && f && f->frametype == AST_FRAME_DTMF_END) 04133 chan->generator->digit(chan, f->subclass.integer); 04134 04135 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) { 04136 /* The list gets recreated if audiohooks are added again later */ 04137 ast_audiohook_detach_list(chan->audiohooks); 04138 chan->audiohooks = NULL; 04139 } 04140 ast_channel_unlock(chan); 04141 return f; 04142 }
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 5151 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_set_connected_line(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_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().
05152 { 05153 int dummy_outstate; 05154 int cause = 0; 05155 struct ast_channel *chan; 05156 int res = 0; 05157 int last_subclass = 0; 05158 struct ast_party_connected_line connected; 05159 05160 if (outstate) 05161 *outstate = 0; 05162 else 05163 outstate = &dummy_outstate; /* make outstate always a valid pointer */ 05164 05165 chan = ast_request(type, format, requestor, data, &cause); 05166 if (!chan) { 05167 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 05168 handle_cause(cause, outstate); 05169 return NULL; 05170 } 05171 05172 if (oh) { 05173 if (oh->vars) 05174 ast_set_variables(chan, oh->vars); 05175 /* XXX why is this necessary, for the parent_channel perhaps ? */ 05176 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) 05177 ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num); 05178 if (oh->parent_channel) { 05179 ast_channel_inherit_variables(oh->parent_channel, chan); 05180 ast_channel_datastore_inherit(oh->parent_channel, chan); 05181 } 05182 if (oh->account) 05183 ast_cdr_setaccount(chan, oh->account); 05184 } 05185 05186 ast_set_callerid(chan, cid_num, cid_name, cid_num); 05187 ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED); 05188 ast_party_connected_line_set_init(&connected, &chan->connected); 05189 if (cid_num) { 05190 connected.id.number.valid = 1; 05191 connected.id.number.str = (char *) cid_num; 05192 connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 05193 } 05194 if (cid_name) { 05195 connected.id.name.valid = 1; 05196 connected.id.name.str = (char *) cid_name; 05197 connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 05198 } 05199 ast_channel_set_connected_line(chan, &connected, NULL); 05200 05201 if (ast_call(chan, data, 0)) { /* ast_call failed... */ 05202 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data); 05203 } else { 05204 res = 1; /* mark success in case chan->_state is already AST_STATE_UP */ 05205 while (timeout && chan->_state != AST_STATE_UP) { 05206 struct ast_frame *f; 05207 res = ast_waitfor(chan, timeout); 05208 if (res == 0) { /* timeout, treat it like ringing */ 05209 *outstate = AST_CONTROL_RINGING; 05210 break; 05211 } 05212 if (res < 0) /* error or done */ 05213 break; 05214 if (timeout > -1) 05215 timeout = res; 05216 if (!ast_strlen_zero(chan->call_forward)) { 05217 if (!(chan = ast_call_forward(NULL, chan, NULL, format, oh, outstate))) { 05218 return NULL; 05219 } 05220 continue; 05221 } 05222 05223 f = ast_read(chan); 05224 if (!f) { 05225 *outstate = AST_CONTROL_HANGUP; 05226 res = 0; 05227 break; 05228 } 05229 if (f->frametype == AST_FRAME_CONTROL) { 05230 switch (f->subclass.integer) { 05231 case AST_CONTROL_RINGING: /* record but keep going */ 05232 *outstate = f->subclass.integer; 05233 break; 05234 05235 case AST_CONTROL_BUSY: 05236 ast_cdr_busy(chan->cdr); 05237 *outstate = f->subclass.integer; 05238 timeout = 0; 05239 break; 05240 05241 case AST_CONTROL_CONGESTION: 05242 ast_cdr_failed(chan->cdr); 05243 *outstate = f->subclass.integer; 05244 timeout = 0; 05245 break; 05246 05247 case AST_CONTROL_ANSWER: 05248 ast_cdr_answer(chan->cdr); 05249 *outstate = f->subclass.integer; 05250 timeout = 0; /* trick to force exit from the while() */ 05251 break; 05252 05253 /* Ignore these */ 05254 case AST_CONTROL_PROGRESS: 05255 case AST_CONTROL_PROCEEDING: 05256 case AST_CONTROL_HOLD: 05257 case AST_CONTROL_UNHOLD: 05258 case AST_CONTROL_VIDUPDATE: 05259 case AST_CONTROL_SRCUPDATE: 05260 case AST_CONTROL_SRCCHANGE: 05261 case AST_CONTROL_CONNECTED_LINE: 05262 case AST_CONTROL_REDIRECTING: 05263 case AST_CONTROL_CC: 05264 case -1: /* Ignore -- just stopping indications */ 05265 break; 05266 05267 default: 05268 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass.integer); 05269 } 05270 last_subclass = f->subclass.integer; 05271 } 05272 ast_frfree(f); 05273 } 05274 } 05275 05276 /* Final fixups */ 05277 if (oh) { 05278 if (!ast_strlen_zero(oh->context)) 05279 ast_copy_string(chan->context, oh->context, sizeof(chan->context)); 05280 if (!ast_strlen_zero(oh->exten)) 05281 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten)); 05282 if (oh->priority) 05283 chan->priority = oh->priority; 05284 } 05285 if (chan->_state == AST_STATE_UP) 05286 *outstate = AST_CONTROL_ANSWER; 05287 05288 if (res <= 0) { 05289 if ( AST_CONTROL_RINGING == last_subclass ) 05290 chan->hangupcause = AST_CAUSE_NO_ANSWER; 05291 if (!chan->cdr && (chan->cdr = ast_cdr_alloc())) 05292 ast_cdr_init(chan->cdr, chan); 05293 if (chan->cdr) { 05294 char tmp[256]; 05295 snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data); 05296 ast_cdr_setapp(chan->cdr,"Dial",tmp); 05297 ast_cdr_update(chan); 05298 ast_cdr_start(chan->cdr); 05299 ast_cdr_end(chan->cdr); 05300 /* If the cause wasn't handled properly */ 05301 if (ast_cdr_disposition(chan->cdr,chan->hangupcause)) 05302 ast_cdr_failed(chan->cdr); 05303 } 05304 ast_hangup(chan); 05305 chan = NULL; 05306 } 05307 return chan; 05308 }
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 4574 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().
04575 { 04576 int num_new_samples = frame->samples; 04577 struct plc_ds *plc = datastore->data; 04578 04579 /* As a general note, let me explain the somewhat odd calculations used when taking 04580 * the frame offset into account here. According to documentation in frame.h, the frame's 04581 * offset field indicates the number of bytes that the audio is offset. The plc->samples_buf 04582 * is not an array of bytes, but rather an array of 16-bit integers since it holds SLIN 04583 * samples. So I had two choices to make here with the offset. 04584 * 04585 * 1. Make the offset AST_FRIENDLY_OFFSET bytes. The main downside for this is that 04586 * I can't just add AST_FRIENDLY_OFFSET to the plc->samples_buf and have the pointer 04587 * arithmetic come out right. I would have to do some odd casting or division for this to 04588 * work as I wanted. 04589 * 2. Make the offset AST_FRIENDLY_OFFSET * 2 bytes. This allows the pointer arithmetic 04590 * to work out better with the plc->samples_buf. The downside here is that the buffer's 04591 * allocation contains an extra 64 bytes of unused space. 04592 * 04593 * I decided to go with option 2. This is why in the calloc statement and the statement that 04594 * sets the frame's offset, AST_FRIENDLY_OFFSET is multiplied by 2. 04595 */ 04596 04597 /* If this audio frame has no samples to fill in, ignore it */ 04598 if (!num_new_samples) { 04599 return; 04600 } 04601 04602 /* First, we need to be sure that our buffer is large enough to accomodate 04603 * the samples we need to fill in. This will likely only occur on the first 04604 * frame we write. 04605 */ 04606 if (plc->num_samples < num_new_samples) { 04607 ast_free(plc->samples_buf); 04608 plc->samples_buf = ast_calloc(1, (num_new_samples * sizeof(*plc->samples_buf)) + (AST_FRIENDLY_OFFSET * 2)); 04609 if (!plc->samples_buf) { 04610 ast_channel_datastore_remove(chan, datastore); 04611 ast_datastore_free(datastore); 04612 return; 04613 } 04614 plc->num_samples = num_new_samples; 04615 } 04616 04617 if (frame->datalen == 0) { 04618 plc_fillin(&plc->plc_state, plc->samples_buf + AST_FRIENDLY_OFFSET, frame->samples); 04619 frame->data.ptr = plc->samples_buf + AST_FRIENDLY_OFFSET; 04620 frame->datalen = num_new_samples * 2; 04621 frame->offset = AST_FRIENDLY_OFFSET * 2; 04622 } else { 04623 plc_rx(&plc->plc_state, frame->data.ptr, frame->samples); 04624 } 04625 }
static void apply_plc | ( | struct ast_channel * | chan, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 4627 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().
04628 { 04629 struct ast_datastore *datastore; 04630 struct plc_ds *plc; 04631 04632 datastore = ast_channel_datastore_find(chan, &plc_ds_info, NULL); 04633 if (datastore) { 04634 plc = datastore->data; 04635 adjust_frame_for_plc(chan, frame, datastore); 04636 return; 04637 } 04638 04639 datastore = ast_datastore_alloc(&plc_ds_info, NULL); 04640 if (!datastore) { 04641 return; 04642 } 04643 plc = ast_calloc(1, sizeof(*plc)); 04644 if (!plc) { 04645 ast_datastore_free(datastore); 04646 return; 04647 } 04648 datastore->data = plc; 04649 ast_channel_datastore_add(chan, datastore); 04650 adjust_frame_for_plc(chan, frame, datastore); 04651 }
int ast_activate_generator | ( | struct ast_channel * | chan, | |
struct ast_generator * | gen, | |||
void * | params | |||
) |
Activate a given generator
Definition at line 2976 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().
02977 { 02978 int res = 0; 02979 02980 ast_channel_lock(chan); 02981 if (chan->generatordata) { 02982 if (chan->generator && chan->generator->release) 02983 chan->generator->release(chan, chan->generatordata); 02984 chan->generatordata = NULL; 02985 } 02986 if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) { 02987 res = -1; 02988 } 02989 if (!res) { 02990 ast_settimeout(chan, 50, generator_force, chan); 02991 chan->generator = gen; 02992 } 02993 ast_channel_unlock(chan); 02994 02995 ast_prod(chan); 02996 02997 return res; 02998 }
int ast_active_channels | ( | void | ) |
returns number of active/allocated channels
Definition at line 783 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 quit_handler().
00784 { 00785 return channels ? ao2_container_count(channels) : 0; 00786 }
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 2926 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_pickup_call(), auth_exec(), background_detect_exec(), bridge_exec(), 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(), park_exec_full(), parkcall_helper(), pbx_builtin_background(), pickup_do(), playback_exec(), privacy_exec(), read_exec(), readexten_exec(), receivefax_exec(), rpt_exec(), sayunixtime_exec(), send_waveform_to_channel(), sendfax_exec(), setup_privacy_args(), skel_exec(), sla_station_exec(), speech_background(), testclient_exec(), testserver_exec(), transmit(), vm_exec(), vm_execmain(), waitfor_exec(), and zapateller_exec().
02927 { 02928 return __ast_answer(chan, 0, 1); 02929 }
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 773 of file channel.c.
References ao2_callback, ast_channel_softhangup_cb(), channels, OBJ_MULTIPLE, and OBJ_NODATA.
Referenced by quit_handler().
00774 { 00775 shutting_down = 1; 00776 00777 if (hangup) { 00778 ao2_callback(channels, OBJ_NODATA | OBJ_MULTIPLE, ast_channel_softhangup_cb, NULL); 00779 } 00780 }
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 992 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().
00993 { 00994 /* This just our opinion, expressed in code. We are asked to choose 00995 the best codec to use, given no information */ 00996 int x; 00997 static const format_t prefs[] = 00998 { 00999 /*! Okay, ulaw is used by all telephony equipment, so start with it */ 01000 AST_FORMAT_ULAW, 01001 /*! Unless of course, you're a silly European, so then prefer ALAW */ 01002 AST_FORMAT_ALAW, 01003 AST_FORMAT_G719, 01004 AST_FORMAT_SIREN14, 01005 AST_FORMAT_SIREN7, 01006 AST_FORMAT_TESTLAW, 01007 /*! G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority */ 01008 AST_FORMAT_G722, 01009 /*! Okay, well, signed linear is easy to translate into other stuff */ 01010 AST_FORMAT_SLINEAR16, 01011 AST_FORMAT_SLINEAR, 01012 /*! G.726 is standard ADPCM, in RFC3551 packing order */ 01013 AST_FORMAT_G726, 01014 /*! G.726 is standard ADPCM, in AAL2 packing order */ 01015 AST_FORMAT_G726_AAL2, 01016 /*! ADPCM has great sound quality and is still pretty easy to translate */ 01017 AST_FORMAT_ADPCM, 01018 /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to 01019 translate and sounds pretty good */ 01020 AST_FORMAT_GSM, 01021 /*! iLBC is not too bad */ 01022 AST_FORMAT_ILBC, 01023 /*! Speex is free, but computationally more expensive than GSM */ 01024 AST_FORMAT_SPEEX16, 01025 AST_FORMAT_SPEEX, 01026 /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough 01027 to use it */ 01028 AST_FORMAT_LPC10, 01029 /*! G.729a is faster than 723 and slightly less expensive */ 01030 AST_FORMAT_G729A, 01031 /*! Down to G.723.1 which is proprietary but at least designed for voice */ 01032 AST_FORMAT_G723_1, 01033 }; 01034 char buf[512]; 01035 01036 /* Strip out video */ 01037 fmts &= AST_FORMAT_AUDIO_MASK; 01038 01039 /* Find the first preferred codec in the format given */ 01040 for (x = 0; x < ARRAY_LEN(prefs); x++) { 01041 if (fmts & prefs[x]) 01042 return prefs[x]; 01043 } 01044 01045 ast_log(LOG_WARNING, "Don't know any of %s formats\n", ast_getformatname_multiple(buf, sizeof(buf), fmts)); 01046 01047 return 0; 01048 }
struct ast_channel* ast_bridged_channel | ( | struct ast_channel * | chan | ) |
Find bridged channel.
chan | Current channel |
Definition at line 6674 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(), sig_pri_attempt_transfer(), sig_pri_handle_hold(), sip_hangup(), sip_set_rtp_peer(), skinny_transfer(), socket_process(), start_spying(), startmon(), TransferCallStep1(), and unistim_hangup().
06675 { 06676 struct ast_channel *bridged; 06677 bridged = chan->_bridge; 06678 if (bridged && bridged->tech->bridged_channel) 06679 bridged = bridged->tech->bridged_channel(chan, bridged); 06680 return bridged; 06681 }
int ast_call | ( | struct ast_channel * | chan, | |
char * | addr, | |||
int | timeout | |||
) |
Make a call.
chan | which channel to make the call on | |
addr | destination of the call | |
timeout | time to wait on for connect |
Definition at line 5421 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(), attempt_reconnect(), begin_dial_channel(), connect_link(), dial_exec_full(), dial_transfer(), do_forward(), do_idle_thread(), feature_request_and_dial(), findmeexec(), play_sound_file(), ring_entry(), and rpt().
05422 { 05423 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 05424 If the remote end does not answer within the timeout, then do NOT hang up, but 05425 return anyway. */ 05426 int res = -1; 05427 /* Stop if we're a zombie or need a soft hangup */ 05428 ast_channel_lock(chan); 05429 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 05430 if (chan->cdr) { 05431 ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED); 05432 } 05433 if (chan->tech->call) 05434 res = chan->tech->call(chan, addr, timeout); 05435 ast_set_flag(chan, AST_FLAG_OUTGOING); 05436 } 05437 ast_channel_unlock(chan); 05438 return res; 05439 }
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 5070 of file channel.c.
References outgoing_helper::account, ast_channel::accountcode, accountcode, ast_call(), AST_CDR_FLAG_ORIGINATED, ast_cdr_setaccount(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_set_redirecting(), ast_channel_trylock, ast_channel_unlock, ast_channel_update_redirecting(), ast_copy_flags, ast_copy_string(), ast_hangup(), ast_log(), ast_party_caller_copy(), ast_party_connected_line_copy(), ast_request(), ast_set_callerid(), ast_set_variables(), ast_string_field_set, ast_strlen_zero(), ast_channel::call_forward, ast_channel::caller, cause, ast_channel::cdr, CHANNEL_DEADLOCK_AVOIDANCE, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_channel::connected, ast_channel::context, handle_cause(), LOG_NOTICE, outgoing_helper::parent_channel, pbx_builtin_getvar_helper(), ast_channel::redirecting, S_OR, type, and outgoing_helper::vars.
Referenced by __ast_request_and_dial(), and feature_request_and_dial().
05071 { 05072 char tmpchan[256]; 05073 struct ast_channel *new = NULL; 05074 struct ast_party_redirecting *apr = &orig->redirecting; 05075 char *data, *type; 05076 int cause = 0; 05077 int res; 05078 05079 /* gather data and request the new forward channel */ 05080 ast_copy_string(tmpchan, orig->call_forward, sizeof(tmpchan)); 05081 if ((data = strchr(tmpchan, '/'))) { 05082 *data++ = '\0'; 05083 type = tmpchan; 05084 } else { 05085 const char *forward_context; 05086 ast_channel_lock(orig); 05087 forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT"); 05088 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", orig->call_forward, S_OR(forward_context, orig->context)); 05089 ast_channel_unlock(orig); 05090 data = tmpchan; 05091 type = "Local"; 05092 } 05093 if (!(new = ast_request(type, format, orig, data, &cause))) { 05094 ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause); 05095 handle_cause(cause, outstate); 05096 ast_hangup(orig); 05097 return NULL; 05098 } 05099 05100 ast_channel_set_redirecting(new, apr, NULL); 05101 05102 /* Copy/inherit important information into new channel */ 05103 if (oh) { 05104 if (oh->vars) { 05105 ast_set_variables(new, oh->vars); 05106 } 05107 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) { 05108 ast_set_callerid(new, oh->cid_num, oh->cid_name, oh->cid_num); 05109 } 05110 if (oh->parent_channel) { 05111 ast_channel_update_redirecting(oh->parent_channel, apr, NULL); 05112 ast_channel_inherit_variables(oh->parent_channel, new); 05113 ast_channel_datastore_inherit(oh->parent_channel, new); 05114 } 05115 if (oh->account) { 05116 ast_cdr_setaccount(new, oh->account); 05117 } 05118 } else if (caller) { /* no outgoing helper so use caller if avaliable */ 05119 ast_channel_update_redirecting(caller, apr, NULL); 05120 ast_channel_inherit_variables(caller, new); 05121 ast_channel_datastore_inherit(caller, new); 05122 } 05123 05124 ast_channel_lock(orig); 05125 while (ast_channel_trylock(new)) { 05126 CHANNEL_DEADLOCK_AVOIDANCE(orig); 05127 } 05128 ast_copy_flags(new->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED); 05129 ast_string_field_set(new, accountcode, orig->accountcode); 05130 ast_party_caller_copy(&new->caller, &orig->caller); 05131 ast_party_connected_line_copy(&new->connected, &orig->connected); 05132 ast_channel_unlock(new); 05133 ast_channel_unlock(orig); 05134 05135 /* call new channel */ 05136 res = ast_call(new, data, 0); 05137 if (timeout) { 05138 *timeout = res; 05139 } 05140 if (res) { 05141 ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data); 05142 ast_hangup(orig); 05143 ast_hangup(new); 05144 return NULL; 05145 } 05146 ast_hangup(orig); 05147 05148 return new; 05149 }
void ast_cancel_shutdown | ( | void | ) |
Cancel a shutdown in progress.
Cancels an existing shutdown and returns to normal operation
Definition at line 789 of file channel.c.
Referenced by handle_abort_shutdown().
00790 { 00791 shutting_down = 0; 00792 }
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 910 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().
00911 { 00912 int x; 00913 00914 for (x = 0; x < ARRAY_LEN(causes); x++) { 00915 if (causes[x].cause == cause) 00916 return causes[x].desc; 00917 } 00918 00919 return "Unknown"; 00920 }
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 5856 of file channel.c.
References __ast_change_name_nolink(), ao2_link, ao2_unlink, ast_channel_lock, ast_channel_unlock, chanlist::chan, and channels.
Referenced by update_name().
05857 { 05858 /* We must re-link, as the hash value will change here. */ 05859 ao2_unlink(channels, chan); 05860 ast_channel_lock(chan); 05861 __ast_change_name_nolink(chan, newname); 05862 ast_channel_unlock(chan); 05863 ao2_link(channels, chan); 05864 }
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 9256 of file channel.c.
References __ast_channel_alloc_ap().
09261 { 09262 va_list ap1, ap2; 09263 struct ast_channel *result; 09264 09265 09266 va_start(ap1, name_fmt); 09267 va_start(ap2, name_fmt); 09268 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context, 09269 linkedid, amaflag, __FILE__, __LINE__, __FUNCTION__, name_fmt, ap1, ap2); 09270 va_end(ap1); 09271 va_end(ap2); 09272 09273 return result; 09274 }
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 7017 of file channel.c.
References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_RETRY, ast_channel_make_compatible(), ast_check_hangup(), ast_check_hangup_locked(), ast_clear_flag, AST_CONTROL_SRCUPDATE, ast_debug, AST_FEATURE_PLAY_WARNING, AST_FEATURE_WARNING_ACTIVE, AST_FLAG_END_DTMF_ONLY, AST_FLAG_NBRIDGE, AST_FLAG_ZOMBIE, ast_generic_bridge(), ast_indicate(), ast_log(), ast_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::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().
07019 { 07020 struct ast_channel *chans[2] = { c0, c1 }; 07021 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 07022 format_t o0nativeformats; 07023 format_t o1nativeformats; 07024 long time_left_ms=0; 07025 char caller_warning = 0; 07026 char callee_warning = 0; 07027 07028 if (c0->_bridge) { 07029 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 07030 c0->name, c0->_bridge->name); 07031 return -1; 07032 } 07033 if (c1->_bridge) { 07034 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 07035 c1->name, c1->_bridge->name); 07036 return -1; 07037 } 07038 07039 /* Stop if we're a zombie or need a soft hangup */ 07040 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 07041 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 07042 return -1; 07043 07044 *fo = NULL; 07045 07046 if (ast_tvzero(config->start_time)) { 07047 config->start_time = ast_tvnow(); 07048 if (config->start_sound) { 07049 if (caller_warning) { 07050 bridge_playfile(c0, c1, config->start_sound, config->timelimit / 1000); 07051 } 07052 if (callee_warning) { 07053 bridge_playfile(c1, c0, config->start_sound, config->timelimit / 1000); 07054 } 07055 } 07056 } 07057 07058 /* Keep track of bridge */ 07059 c0->_bridge = c1; 07060 c1->_bridge = c0; 07061 07062 ast_set_owners_and_peers(c0, c1); 07063 07064 o0nativeformats = c0->nativeformats; 07065 o1nativeformats = c1->nativeformats; 07066 07067 if (config->feature_timer && !ast_tvzero(config->nexteventts)) { 07068 config->nexteventts = ast_tvadd(config->feature_start_time, ast_samp2tv(config->feature_timer, 1000)); 07069 } else if (config->timelimit) { 07070 time_left_ms = config->timelimit - ast_tvdiff_ms(ast_tvnow(), config->start_time); 07071 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING); 07072 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING); 07073 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 07074 if ((caller_warning || callee_warning) && config->play_warning) { 07075 long next_warn = config->play_warning; 07076 if (time_left_ms < config->play_warning) { 07077 /* At least one warning was played, which means we are returning after feature */ 07078 long warns_passed = (config->play_warning - time_left_ms) / config->warning_freq; 07079 /* It is 'warns_passed * warning_freq' NOT '(warns_passed + 1) * warning_freq', 07080 because nexteventts will be updated once again in the 'if (!to)' block */ 07081 next_warn = config->play_warning - warns_passed * config->warning_freq; 07082 } 07083 config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(next_warn, 1000)); 07084 } 07085 } else { 07086 config->nexteventts.tv_sec = 0; 07087 config->nexteventts.tv_usec = 0; 07088 } 07089 07090 if (!c0->tech->send_digit_begin) 07091 ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY); 07092 if (!c1->tech->send_digit_begin) 07093 ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY); 07094 manager_bridge_event(1, 1, c0, c1); 07095 07096 /* Before we enter in and bridge these two together tell them both the source of audio has changed */ 07097 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 07098 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 07099 07100 for (/* ever */;;) { 07101 struct timeval now = { 0, }; 07102 int to; 07103 07104 to = -1; 07105 07106 if (!ast_tvzero(config->nexteventts)) { 07107 now = ast_tvnow(); 07108 to = ast_tvdiff_ms(config->nexteventts, now); 07109 if (to <= 0) { 07110 if (!config->timelimit) { 07111 res = AST_BRIDGE_COMPLETE; 07112 break; 07113 } 07114 to = 0; 07115 } 07116 } 07117 07118 if (config->timelimit) { 07119 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time); 07120 if (time_left_ms < to) 07121 to = time_left_ms; 07122 07123 if (time_left_ms <= 0) { 07124 if (caller_warning && config->end_sound) 07125 bridge_playfile(c0, c1, config->end_sound, 0); 07126 if (callee_warning && config->end_sound) 07127 bridge_playfile(c1, c0, config->end_sound, 0); 07128 *fo = NULL; 07129 res = 0; 07130 break; 07131 } 07132 07133 if (!to) { 07134 if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) { 07135 int t = (time_left_ms + 500) / 1000; /* round to nearest second */ 07136 if (caller_warning) 07137 bridge_playfile(c0, c1, config->warning_sound, t); 07138 if (callee_warning) 07139 bridge_playfile(c1, c0, config->warning_sound, t); 07140 } 07141 07142 if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) { 07143 config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000)); 07144 } else { 07145 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 07146 } 07147 } 07148 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE); 07149 } 07150 07151 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 07152 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07153 c0->_softhangup &= ~AST_SOFTHANGUP_UNBRIDGE; 07154 } 07155 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07156 c1->_softhangup &= ~AST_SOFTHANGUP_UNBRIDGE; 07157 } 07158 c0->_bridge = c1; 07159 c1->_bridge = c0; 07160 ast_debug(1, "Unbridge signal received. Ending native bridge.\n"); 07161 continue; 07162 } 07163 07164 /* Stop if we're a zombie or need a soft hangup */ 07165 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 07166 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) { 07167 *fo = NULL; 07168 res = 0; 07169 ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n", 07170 c0->name, c1->name, 07171 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No", 07172 ast_check_hangup(c0) ? "Yes" : "No", 07173 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No", 07174 ast_check_hangup(c1) ? "Yes" : "No"); 07175 break; 07176 } 07177 07178 update_bridge_vars(c0, c1); 07179 07180 bridge_play_sounds(c0, c1); 07181 07182 if (c0->tech->bridge && 07183 /* if < 1 ms remains use generic bridging for accurate timing */ 07184 (!config->timelimit || to > 1000 || to == 0) && 07185 (c0->tech->bridge == c1->tech->bridge) && 07186 !c0->monitor && !c1->monitor && 07187 !c0->audiohooks && !c1->audiohooks && 07188 !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) { 07189 int timeoutms = to - 1000 > 0 ? to - 1000 : to; 07190 /* Looks like they share a bridge method and nothing else is in the way */ 07191 ast_set_flag(c0, AST_FLAG_NBRIDGE); 07192 ast_set_flag(c1, AST_FLAG_NBRIDGE); 07193 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, timeoutms)) == AST_BRIDGE_COMPLETE) { 07194 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans, 07195 "Channel1: %s\r\n" 07196 "Channel2: %s\r\n" 07197 "Uniqueid1: %s\r\n" 07198 "Uniqueid2: %s\r\n" 07199 "CallerID1: %s\r\n" 07200 "CallerID2: %s\r\n", 07201 c0->name, c1->name, 07202 c0->uniqueid, c1->uniqueid, 07203 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"), 07204 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>")); 07205 07206 ast_debug(1, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name); 07207 07208 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 07209 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 07210 07211 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 07212 continue; 07213 } 07214 07215 c0->_bridge = NULL; 07216 c1->_bridge = NULL; 07217 return res; 07218 } else { 07219 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 07220 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 07221 } 07222 switch (res) { 07223 case AST_BRIDGE_RETRY: 07224 if (config->play_warning) { 07225 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE); 07226 } 07227 continue; 07228 default: 07229 ast_verb(3, "Native bridging %s and %s ended\n", c0->name, c1->name); 07230 /* fallthrough */ 07231 case AST_BRIDGE_FAILED_NOWARN: 07232 break; 07233 } 07234 } 07235 07236 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) || 07237 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) && 07238 !(c0->generator || c1->generator)) { 07239 if (ast_channel_make_compatible(c0, c1)) { 07240 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 07241 manager_bridge_event(0, 1, c0, c1); 07242 return AST_BRIDGE_FAILED; 07243 } 07244 o0nativeformats = c0->nativeformats; 07245 o1nativeformats = c1->nativeformats; 07246 } 07247 07248 update_bridge_vars(c0, c1); 07249 07250 res = ast_generic_bridge(c0, c1, config, fo, rc); 07251 if (res != AST_BRIDGE_RETRY) { 07252 break; 07253 } else if (config->feature_timer) { 07254 /* feature timer expired but has not been updated, sending to ast_bridge_call to do so */ 07255 break; 07256 } 07257 } 07258 07259 ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY); 07260 ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY); 07261 07262 /* Now that we have broken the bridge the source will change yet again */ 07263 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 07264 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 07265 07266 c0->_bridge = NULL; 07267 c1->_bridge = NULL; 07268 07269 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans, 07270 "Channel1: %s\r\n" 07271 "Channel2: %s\r\n" 07272 "Uniqueid1: %s\r\n" 07273 "Uniqueid2: %s\r\n" 07274 "CallerID1: %s\r\n" 07275 "CallerID2: %s\r\n", 07276 c0->name, c1->name, 07277 c0->uniqueid, c1->uniqueid, 07278 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"), 07279 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>")); 07280 ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name); 07281 07282 return res; 07283 }
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 1544 of file channel.c.
References ao2_callback_data, and channels.
Referenced by ast_cel_check_retire_linkedid(), ast_pickup_call(), handle_core_set_debug_channel(), my_ast_get_channel_by_name_locked(), pickup_by_mark(), pickup_by_part(), and state_notify_build_xml().
01546 { 01547 return ao2_callback_data(channels, ao2_flags, cb_fn, arg, data); 01548 }
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 9162 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().
09164 { 09165 struct ast_cc_config_params *cc_params; 09166 struct ast_datastore *cc_datastore; 09167 09168 if (!(cc_params = ast_cc_config_params_init())) { 09169 return -1; 09170 } 09171 09172 if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL))) { 09173 ast_cc_config_params_destroy(cc_params); 09174 return -1; 09175 } 09176 09177 if (base_params) { 09178 ast_cc_copy_config_params(cc_params, base_params); 09179 } 09180 cc_datastore->data = cc_params; 09181 ast_channel_datastore_add(chan, cc_datastore); 09182 return 0; 09183 }
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 5995 of file channel.c.
References ast_cel_check_retire_linkedid(), ast_string_field_set, ast_strlen_zero(), chanlist::chan, and ast_channel::linkedid.
Referenced by ast_channel_set_linkgroup().
05996 { 05997 /* if the linkedid for this channel is being changed from something, check... */ 05998 if (!ast_strlen_zero(chan->linkedid) && 0 != strcmp(chan->linkedid, linkedid)) { 05999 ast_cel_check_retire_linkedid(chan); 06000 } 06001 06002 ast_string_field_set(chan, linkedid, linkedid); 06003 }
static int ast_channel_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1630 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.
01631 { 01632 struct ast_channel *chan = obj, *cmp_args = arg; 01633 size_t name_len; 01634 int ret = CMP_MATCH; 01635 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 uses of ao2_find() must be changed, too. */ 01639 name_len = cmp_args->rings; 01640 01641 ast_channel_lock(chan); 01642 01643 if (!ast_strlen_zero(cmp_args->name)) { /* match by name */ 01644 if ((!name_len && strcasecmp(chan->name, cmp_args->name)) || 01645 (name_len && strncasecmp(chan->name, cmp_args->name, name_len))) { 01646 ret = 0; /* name match failed */ 01647 } 01648 } else if (!ast_strlen_zero(cmp_args->exten)) { 01649 if (cmp_args->context && strcasecmp(chan->context, cmp_args->context) && 01650 strcasecmp(chan->macrocontext, cmp_args->context)) { 01651 ret = 0; /* context match failed */ 01652 } 01653 if (ret && strcasecmp(chan->exten, cmp_args->exten) && 01654 strcasecmp(chan->macroexten, cmp_args->exten)) { 01655 ret = 0; /* exten match failed */ 01656 } 01657 } else if (!ast_strlen_zero(cmp_args->uniqueid)) { 01658 if ((!name_len && strcasecmp(chan->uniqueid, cmp_args->uniqueid)) || 01659 (name_len && strncasecmp(chan->uniqueid, cmp_args->uniqueid, name_len))) { 01660 ret = 0; /* uniqueid match failed */ 01661 } 01662 } else { 01663 ret = 0; 01664 } 01665 01666 ast_channel_unlock(chan); 01667 01668 return ret; 01669 }
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 830 of file channel.c.
References ast_channel_cmpwhentohangup_tv(), and chanlist::chan.
00831 { 00832 struct timeval when = { offset, }; 00833 return ast_channel_cmpwhentohangup_tv(chan, when); 00834 }
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 815 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().
00816 { 00817 struct timeval whentohangup; 00818 00819 if (ast_tvzero(chan->whentohangup)) 00820 return ast_tvzero(offset) ? 0 : -1; 00821 00822 if (ast_tvzero(offset)) 00823 return 1; 00824 00825 whentohangup = ast_tvadd(offset, ast_tvnow()); 00826 00827 return ast_tvdiff_ms(whentohangup, chan->whentohangup); 00828 }
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 9060 of file channel.c.
References ast_app_run_macro(), ast_channel_lock, ast_channel_unlock, ast_channel_update_connected_line(), ast_connected_line_parse_data(), ast_party_connected_line_copy(), ast_strdupa, ast_strlen_zero(), connected, ast_channel::connected, ast_frame::data, ast_frame::datalen, pbx_builtin_getvar_helper(), ast_frame::ptr, and S_OR.
Referenced by __ast_read(), ast_bridge_call(), ast_pickup_call(), atxfer_fail_cleanup(), builtin_atxfer(), builtin_blindtransfer(), feature_request_and_dial(), handle_frame(), pickup_do(), remote_bridge_loop(), and wait_for_answer().
09061 { 09062 const char *macro; 09063 const char *macro_args; 09064 int retval; 09065 09066 ast_channel_lock(macro_chan); 09067 macro = pbx_builtin_getvar_helper(macro_chan, is_caller 09068 ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO"); 09069 macro = ast_strdupa(S_OR(macro, "")); 09070 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller 09071 ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS"); 09072 macro_args = ast_strdupa(S_OR(macro_args, "")); 09073 09074 if (ast_strlen_zero(macro)) { 09075 ast_channel_unlock(macro_chan); 09076 return -1; 09077 } 09078 09079 if (is_frame) { 09080 const struct ast_frame *frame = connected_info; 09081 09082 ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->connected); 09083 } else { 09084 const struct ast_party_connected_line *connected = connected_info; 09085 09086 ast_party_connected_line_copy(¯o_chan->connected, connected); 09087 } 09088 ast_channel_unlock(macro_chan); 09089 09090 if (!(retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args))) { 09091 ast_channel_lock(macro_chan); 09092 ast_channel_update_connected_line(macro_chan, ¯o_chan->connected, NULL); 09093 ast_channel_unlock(macro_chan); 09094 } 09095 09096 return retval; 09097 }
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 343 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().
00345 { 00346 struct ast_channel *bc; 00347 struct ast_data *data_bridged; 00348 struct ast_data *data_cdr; 00349 struct ast_data *data_flags; 00350 struct ast_data *data_zones; 00351 struct ast_data *enum_node; 00352 struct ast_data *data_softhangup; 00353 #if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */ 00354 struct ast_data *data_callerid; 00355 char value_str[100]; 00356 #endif 00357 00358 if (!tree) { 00359 return -1; 00360 } 00361 00362 ast_data_add_structure(ast_channel, tree, chan); 00363 00364 if (add_bridged) { 00365 bc = ast_bridged_channel(chan); 00366 if (bc) { 00367 data_bridged = ast_data_add_node(tree, "bridged"); 00368 if (!data_bridged) { 00369 return -1; 00370 } 00371 ast_channel_data_add_structure(data_bridged, bc, 0); 00372 } 00373 } 00374 00375 ast_data_add_codecs(tree, "oldwriteformat", chan->oldwriteformat); 00376 ast_data_add_codecs(tree, "nativeformats", chan->nativeformats); 00377 ast_data_add_codecs(tree, "readformat", chan->readformat); 00378 ast_data_add_codecs(tree, "writeformat", chan->writeformat); 00379 ast_data_add_codecs(tree, "rawreadformat", chan->rawreadformat); 00380 ast_data_add_codecs(tree, "rawwriteformat", chan->rawwriteformat); 00381 00382 /* state */ 00383 enum_node = ast_data_add_node(tree, "state"); 00384 if (!enum_node) { 00385 return -1; 00386 } 00387 ast_data_add_str(enum_node, "text", ast_state2str(chan->_state)); 00388 ast_data_add_int(enum_node, "value", chan->_state); 00389 00390 /* hangupcause */ 00391 enum_node = ast_data_add_node(tree, "hangupcause"); 00392 if (!enum_node) { 00393 return -1; 00394 } 00395 ast_data_add_str(enum_node, "text", ast_cause2str(chan->hangupcause)); 00396 ast_data_add_int(enum_node, "value", chan->hangupcause); 00397 00398 /* amaflags */ 00399 enum_node = ast_data_add_node(tree, "amaflags"); 00400 if (!enum_node) { 00401 return -1; 00402 } 00403 ast_data_add_str(enum_node, "text", ast_cdr_flags2str(chan->amaflags)); 00404 ast_data_add_int(enum_node, "value", chan->amaflags); 00405 00406 /* transfercapability */ 00407 enum_node = ast_data_add_node(tree, "transfercapability"); 00408 if (!enum_node) { 00409 return -1; 00410 } 00411 ast_data_add_str(enum_node, "text", ast_transfercapability2str(chan->transfercapability)); 00412 ast_data_add_int(enum_node, "value", chan->transfercapability); 00413 00414 /* _softphangup */ 00415 data_softhangup = ast_data_add_node(tree, "softhangup"); 00416 if (!data_softhangup) { 00417 return -1; 00418 } 00419 ast_data_add_bool(data_softhangup, "dev", chan->_softhangup & AST_SOFTHANGUP_DEV); 00420 ast_data_add_bool(data_softhangup, "asyncgoto", chan->_softhangup & AST_SOFTHANGUP_ASYNCGOTO); 00421 ast_data_add_bool(data_softhangup, "shutdown", chan->_softhangup & AST_SOFTHANGUP_SHUTDOWN); 00422 ast_data_add_bool(data_softhangup, "timeout", chan->_softhangup & AST_SOFTHANGUP_TIMEOUT); 00423 ast_data_add_bool(data_softhangup, "appunload", chan->_softhangup & AST_SOFTHANGUP_APPUNLOAD); 00424 ast_data_add_bool(data_softhangup, "explicit", chan->_softhangup & AST_SOFTHANGUP_EXPLICIT); 00425 ast_data_add_bool(data_softhangup, "unbridge", chan->_softhangup & AST_SOFTHANGUP_UNBRIDGE); 00426 00427 /* channel flags */ 00428 data_flags = ast_data_add_node(tree, "flags"); 00429 if (!data_flags) { 00430 return -1; 00431 } 00432 channel_data_add_flags(data_flags, chan); 00433 00434 ast_data_add_uint(tree, "timetohangup", chan->whentohangup.tv_sec); 00435 00436 #if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */ 00437 /* callerid */ 00438 data_callerid = ast_data_add_node(tree, "callerid"); 00439 if (!data_callerid) { 00440 return -1; 00441 } 00442 ast_data_add_structure(ast_callerid, data_callerid, &(chan->cid)); 00443 /* insert the callerid ton */ 00444 enum_node = ast_data_add_node(data_callerid, "cid_ton"); 00445 if (!enum_node) { 00446 return -1; 00447 } 00448 ast_data_add_int(enum_node, "value", chan->cid.cid_ton); 00449 snprintf(value_str, sizeof(value_str), "TON: %s/Plan: %s", 00450 party_number_ton2str(chan->cid.cid_ton), 00451 party_number_plan2str(chan->cid.cid_ton)); 00452 ast_data_add_str(enum_node, "text", value_str); 00453 #endif 00454 00455 /* tone zone */ 00456 if (chan->zone) { 00457 data_zones = ast_data_add_node(tree, "zone"); 00458 if (!data_zones) { 00459 return -1; 00460 } 00461 ast_tone_zone_data_add_structure(data_zones, chan->zone); 00462 } 00463 00464 /* insert cdr */ 00465 data_cdr = ast_data_add_node(tree, "cdr"); 00466 if (!data_cdr) { 00467 return -1; 00468 } 00469 00470 ast_cdr_data_add_structure(data_cdr, chan->cdr, 1); 00471 00472 return 0; 00473 }
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 475 of file channel.c.
References ast_data_search_cmp_structure, and chanlist::chan.
00477 { 00478 return ast_data_search_cmp_structure(tree, ast_channel, chan, structure_name); 00479 }
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 2484 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_datastores(), add_to_agi(), apply_plc(), ast_channel_cc_params_init(), 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(), pbx_builtin_raise_exception(), pitchshift_helper(), 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().
02485 { 02486 int res = 0; 02487 02488 AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry); 02489 02490 return res; 02491 }
struct ast_datastore* ast_channel_datastore_alloc | ( | const struct ast_datastore_info * | info, | |
const char * | uid | |||
) |
Create a channel data store object.
Definition at line 2457 of file channel.c.
References ast_datastore_alloc, and ast_datastore::info.
02458 { 02459 return ast_datastore_alloc(info, uid); 02460 }
struct ast_datastore* ast_channel_datastore_find | ( | struct ast_channel * | chan, | |
const struct ast_datastore_info * | info, | |||
const char * | uid | |||
) |
Find a datastore on a channel.
The datastore returned from this function must not be used if the reference to the channel is released.
pointer | to the datastore if found | |
NULL | if not found |
Definition at line 2498 of file channel.c.
References AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, chanlist::chan, ast_channel::datastores, ast_datastore::entry, ast_datastore::info, and ast_datastore::uid.
Referenced by _macro_exec(), acf_curl_helper(), acf_curlopt_helper(), acf_curlopt_write(), acf_exception_read(), acf_fetch(), acf_iaxvar_read(), acf_iaxvar_write(), add_agi_cmd(), add_features_datastores(), add_to_agi(), apply_plc(), ast_cc_agent_set_interfaces_chanvar(), ast_cc_call_init(), ast_cc_completed(), ast_cc_extension_monitor_add_dialstring(), ast_cc_get_current_core_id(), ast_cc_is_recall(), ast_cc_offer(), ast_channel_get_cc_config_params(), ast_do_masquerade(), ast_handle_cc_control_frame(), ast_ignore_cc(), ast_odbc_retrieve_transaction_obj(), ast_set_cc_interfaces_chanvar(), attended_transfer_occurred(), audiohook_volume_callback(), audiohook_volume_get(), builtin_atxfer(), calendar_event_read(), calendar_query_exec(), calendar_query_result_exec(), cc_build_payload(), dial_exec_full(), disable_jack_hook(), dundi_result_read(), enable_jack_hook(), enum_result_read(), exec_odbcfinish(), find_details(), find_speech(), find_transaction(), frame_trace_helper(), func_channel_read(), func_channel_write_real(), func_inheritance_write(), func_mute_write(), get_agi_cmd(), get_lock(), gosub_exec(), handle_gosub(), iax2_call(), jack_hook_callback(), local_read(), local_write(), lock_fixup(), lua_get_state(), manage_parkinglot(), manager_mutestream(), mark_transaction_active(), mute_callback(), park_exec_full(), pbx_builtin_raise_exception(), pitchshift_cb(), pitchshift_helper(), pop_exec(), queue_transfer_fixup(), release_transaction(), return_exec(), set_security_requirements(), shared_read(), shared_write(), smdi_msg_read(), speech_background(), speech_destroy(), speex_callback(), speex_read(), speex_write(), srv_query_read(), srv_result_read(), stop_mixmonitor_exec(), try_calling(), unlock_read(), volume_callback(), and volume_write().
02499 { 02500 struct ast_datastore *datastore = NULL; 02501 02502 if (info == NULL) 02503 return NULL; 02504 02505 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) { 02506 if (datastore->info != info) { 02507 continue; 02508 } 02509 02510 if (uid == NULL) { 02511 /* matched by type only */ 02512 break; 02513 } 02514 02515 if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) { 02516 /* Matched by type AND uid */ 02517 break; 02518 } 02519 } 02520 AST_LIST_TRAVERSE_SAFE_END; 02521 02522 return datastore; 02523 }
int ast_channel_datastore_free | ( | struct ast_datastore * | datastore | ) |
Free a channel data store object.
Definition at line 2462 of file channel.c.
References ast_datastore_free().
02463 { 02464 return ast_datastore_free(datastore); 02465 }
int ast_channel_datastore_inherit | ( | struct ast_channel * | from, | |
struct ast_channel * | to | |||
) |
Inherit datastores from a parent to a child.
Definition at line 2467 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(), ast_call_forward(), begin_dial_channel(), dial_exec_full(), do_forward(), findmeexec(), local_call(), and ring_entry().
02468 { 02469 struct ast_datastore *datastore = NULL, *datastore2; 02470 02471 AST_LIST_TRAVERSE(&from->datastores, datastore, entry) { 02472 if (datastore->inheritance > 0) { 02473 datastore2 = ast_datastore_alloc(datastore->info, datastore->uid); 02474 if (datastore2) { 02475 datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL; 02476 datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1; 02477 AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry); 02478 } 02479 } 02480 } 02481 return 0; 02482 }
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 2493 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(), 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().
02494 { 02495 return AST_LIST_REMOVE(&chan->datastores, datastore, entry) ? 0 : -1; 02496 }
int ast_channel_defer_dtmf | ( | struct ast_channel * | chan | ) |
Defers DTMF so that you only read things like hangups and audio.
Definition at line 1526 of file channel.c.
References AST_FLAG_DEFER_DTMF, ast_set_flag, ast_test_flag, and chanlist::chan.
Referenced by find_cache().
01527 { 01528 int pre = 0; 01529 01530 if (chan) { 01531 pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF); 01532 ast_set_flag(chan, AST_FLAG_DEFER_DTMF); 01533 } 01534 return pre; 01535 }
static void ast_channel_destructor | ( | void * | obj | ) | [static] |
Free a channel structure.
Definition at line 2306 of file channel.c.
References ast_channel::alertpipe, ast_app_group_discard(), ast_cdr_discard(), AST_CEL_CHANNEL_END, ast_cel_check_retire_linkedid(), ast_cel_report_event(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_unlock, ast_copy_string(), ast_datastore_free(), AST_DEVICE_UNKNOWN, ast_devstate_changed_literal(), ast_free, ast_frfree, ast_jb_destroy(), AST_LIST_REMOVE_HEAD, ast_log(), AST_MAX_FDS, ast_moh_cleanup(), ast_party_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().
02307 { 02308 struct ast_channel *chan = obj; 02309 int fd; 02310 #ifdef HAVE_EPOLL 02311 int i; 02312 #endif 02313 struct ast_var_t *vardata; 02314 struct ast_frame *f; 02315 struct varshead *headp; 02316 struct ast_datastore *datastore; 02317 char device_name[AST_CHANNEL_NAME]; 02318 02319 if (chan->name) { 02320 /* The string fields were initialized. */ 02321 ast_cel_report_event(chan, AST_CEL_CHANNEL_END, NULL, NULL, NULL); 02322 ast_cel_check_retire_linkedid(chan); 02323 } 02324 02325 /* Get rid of each of the data stores on the channel */ 02326 ast_channel_lock(chan); 02327 while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry))) 02328 /* Free the data store */ 02329 ast_datastore_free(datastore); 02330 ast_channel_unlock(chan); 02331 02332 /* Lock and unlock the channel just to be sure nobody has it locked still 02333 due to a reference that was stored in a datastore. (i.e. app_chanspy) */ 02334 ast_channel_lock(chan); 02335 ast_channel_unlock(chan); 02336 02337 if (chan->tech_pvt) { 02338 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name); 02339 ast_free(chan->tech_pvt); 02340 } 02341 02342 if (chan->sched) 02343 sched_context_destroy(chan->sched); 02344 02345 if (chan->name) { 02346 char *dashptr; 02347 02348 /* The string fields were initialized. */ 02349 ast_copy_string(device_name, chan->name, sizeof(device_name)); 02350 if ((dashptr = strrchr(device_name, '-'))) { 02351 *dashptr = '\0'; 02352 } 02353 } else { 02354 device_name[0] = '\0'; 02355 } 02356 02357 /* Stop monitoring */ 02358 if (chan->monitor) 02359 chan->monitor->stop( chan, 0 ); 02360 02361 /* If there is native format music-on-hold state, free it */ 02362 if (chan->music_state) 02363 ast_moh_cleanup(chan); 02364 02365 /* Free translators */ 02366 if (chan->readtrans) 02367 ast_translator_free_path(chan->readtrans); 02368 if (chan->writetrans) 02369 ast_translator_free_path(chan->writetrans); 02370 if (chan->pbx) 02371 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name); 02372 02373 ast_party_dialed_free(&chan->dialed); 02374 ast_party_caller_free(&chan->caller); 02375 ast_party_connected_line_free(&chan->connected); 02376 ast_party_redirecting_free(&chan->redirecting); 02377 02378 /* Close pipes if appropriate */ 02379 if ((fd = chan->alertpipe[0]) > -1) 02380 close(fd); 02381 if ((fd = chan->alertpipe[1]) > -1) 02382 close(fd); 02383 if (chan->timer) { 02384 ast_timer_close(chan->timer); 02385 } 02386 #ifdef HAVE_EPOLL 02387 for (i = 0; i < AST_MAX_FDS; i++) { 02388 if (chan->epfd_data[i]) 02389 free(chan->epfd_data[i]); 02390 } 02391 close(chan->epfd); 02392 #endif 02393 while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list))) 02394 ast_frfree(f); 02395 02396 /* loop over the variables list, freeing all data and deleting list items */ 02397 /* no need to lock the list, as the channel is already locked */ 02398 headp = &chan->varshead; 02399 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) 02400 ast_var_delete(vardata); 02401 02402 ast_app_group_discard(chan); 02403 02404 /* Destroy the jitterbuffer */ 02405 ast_jb_destroy(chan); 02406 02407 if (chan->cdr) { 02408 ast_cdr_discard(chan->cdr); 02409 chan->cdr = NULL; 02410 } 02411 02412 if (chan->zone) { 02413 chan->zone = ast_tone_zone_unref(chan->zone); 02414 } 02415 02416 ast_string_field_free_memory(chan); 02417 02418 if (device_name[0]) { 02419 /* 02420 * We have a device name to notify of a new state. 02421 * 02422 * Queue an unknown state, because, while we know that this particular 02423 * instance is dead, we don't know the state of all other possible 02424 * instances. 02425 */ 02426 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name); 02427 } 02428 }
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 6917 of file channel.c.
References ast_channel_tech::early_bridge, and ast_channel::tech.
Referenced by dial_exec_full().
06918 { 06919 /* Make sure we can early bridge, if not error out */ 06920 if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge))) 06921 return -1; 06922 06923 return c0->tech->early_bridge(c0, c1); 06924 }
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 1723 of file channel.c.
References ast_channel_get_full().
01724 { 01725 return ast_channel_get_full(NULL, 0, exten, context); 01726 }
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 1713 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().
01714 { 01715 return ast_channel_get_full(name, 0, NULL, NULL); 01716 }
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 1718 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().
01719 { 01720 return ast_channel_get_full(name, name_len, NULL, NULL); 01721 }
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 9224 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().
09225 { 09226 int len = size; 09227 char *slash; 09228 09229 if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE, agent_type, &len, 0)) { 09230 return 0; 09231 } 09232 09233 ast_copy_string(agent_type, chan->name, size); 09234 if ((slash = strchr(agent_type, '/'))) { 09235 *slash = '\0'; 09236 } 09237 return 0; 09238 }
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 9185 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(), and sig_pri_cc_generic_check().
09186 { 09187 struct ast_datastore *cc_datastore; 09188 09189 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) { 09190 /* If we can't find the datastore, it almost definitely means that the channel type being 09191 * used has not had its driver modified to parse CC config parameters. The best action 09192 * to take here is to create the parameters on the spot with the defaults set. 09193 */ 09194 if (ast_channel_cc_params_init(chan, NULL)) { 09195 return NULL; 09196 } 09197 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) { 09198 /* Should be impossible */ 09199 return NULL; 09200 } 09201 } 09202 09203 ast_assert(cc_datastore->data != NULL); 09204 return cc_datastore->data; 09205 }
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 9207 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_generic_check(), sip_call(), and sip_handle_cc().
09208 { 09209 int len = name_buffer_length; 09210 char *dash; 09211 if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME, device_name, &len, 0)) { 09212 return 0; 09213 } 09214 09215 /* Dang. Do it the old-fashioned way */ 09216 ast_copy_string(device_name, chan->name, name_buffer_length); 09217 if ((dash = strrchr(device_name, '-'))) { 09218 *dash = '\0'; 09219 } 09220 09221 return 0; 09222 }
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 1671 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().
01673 { 01674 struct ast_channel tmp_chan = { 01675 .name = name, 01676 /* This is sort of a hack. Basically, we're using an arbitrary field 01677 * in ast_channel to pass the name_len for a prefix match. If this 01678 * gets changed, then the compare callback must be changed, too. */ 01679 .rings = name_len, 01680 }; 01681 struct ast_channel *chan; 01682 01683 if (exten) { 01684 ast_copy_string(tmp_chan.exten, exten, sizeof(tmp_chan.exten)); 01685 } 01686 01687 if (context) { 01688 ast_copy_string(tmp_chan.context, context, sizeof(tmp_chan.context)); 01689 } 01690 01691 if ((chan = ao2_find(channels, &tmp_chan, 01692 (!ast_strlen_zero(name) && (name_len == 0)) ? OBJ_POINTER : 0))) { 01693 return chan; 01694 } 01695 01696 if (!name) { 01697 return NULL; 01698 } 01699 01700 /* If name was specified, but the result was NULL, 01701 * try a search on uniqueid, instead. */ 01702 01703 { 01704 struct ast_channel tmp_chan2 = { 01705 .uniqueid = name, 01706 .rings = name_len, 01707 }; 01708 01709 return ao2_find(channels, &tmp_chan2, 0); 01710 } 01711 }
static int ast_channel_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 7540 of file channel.c.
References ast_str_case_hash(), ast_strlen_zero(), and ast_channel::name.
07541 { 07542 const struct ast_channel *chan = obj; 07543 07544 /* If the name isn't set, return 0 so that the ao2_find() search will 07545 * start in the first bucket. */ 07546 if (ast_strlen_zero(chan->name)) { 07547 return 0; 07548 } 07549 07550 return ast_str_case_hash(chan->name); 07551 }
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 5866 of file channel.c.
References ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_var_assign(), ast_var_full_name(), ast_var_name(), ast_var_value(), ast_var_t::entries, and ast_channel::varshead.
Referenced by __ast_request_and_dial(), ast_call_forward(), begin_dial_channel(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), and ring_entry().
05867 { 05868 struct ast_var_t *current, *newvar; 05869 const char *varname; 05870 05871 AST_LIST_TRAVERSE(&parent->varshead, current, entries) { 05872 int vartype = 0; 05873 05874 varname = ast_var_full_name(current); 05875 if (!varname) 05876 continue; 05877 05878 if (varname[0] == '_') { 05879 vartype = 1; 05880 if (varname[1] == '_') 05881 vartype = 2; 05882 } 05883 05884 switch (vartype) { 05885 case 1: 05886 newvar = ast_var_assign(&varname[1], ast_var_value(current)); 05887 if (newvar) { 05888 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 05889 ast_debug(1, "Copying soft-transferable variable %s.\n", ast_var_name(newvar)); 05890 } 05891 break; 05892 case 2: 05893 newvar = ast_var_assign(varname, ast_var_value(current)); 05894 if (newvar) { 05895 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 05896 ast_debug(1, "Copying hard-transferable variable %s.\n", ast_var_name(newvar)); 05897 } 05898 break; 05899 default: 05900 ast_debug(1, "Not copying variable %s.\n", ast_var_name(current)); 05901 break; 05902 } 05903 } 05904 }
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 1611 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().
01612 { 01613 struct ast_channel_iterator *i; 01614 01615 if (!(i = ast_calloc(1, sizeof(*i)))) { 01616 return NULL; 01617 } 01618 01619 i->simple_iterator = ao2_iterator_init(channels, 0); 01620 i->active_iterator = &i->simple_iterator; 01621 01622 return i; 01623 }
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 1601 of file channel.c.
References channel_iterator_search().
Referenced by common_exec(), and pickup_by_exten().
01602 { 01603 return channel_iterator_search(NULL, 0, exten, context); 01604 }
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 1606 of file channel.c.
References channel_iterator_search().
Referenced by ast_complete_channels(), common_exec(), and softhangup_exec().
01607 { 01608 return channel_iterator_search(name, name_len, NULL, NULL); 01609 }
struct ast_channel_iterator* ast_channel_iterator_destroy | ( | struct ast_channel_iterator * | i | ) |
Destroy a channel iterator.
Definition at line 1559 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().
01560 { 01561 ao2_iterator_destroy(i->active_iterator); 01562 ast_free(i); 01563 01564 return NULL; 01565 }
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 1625 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().
01626 { 01627 return ao2_iterator_next(i->active_iterator); 01628 }
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 5630 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(), park_exec_full(), simple_bridge_join(), and wait_for_answer().
05631 { 05632 /* Some callers do not check return code, and we must try to set all call legs correctly */ 05633 int rc = 0; 05634 05635 /* Set up translation from the chan to the peer */ 05636 rc = ast_channel_make_compatible_helper(chan, peer); 05637 05638 if (rc < 0) 05639 return rc; 05640 05641 /* Set up translation from the peer to the chan */ 05642 rc = ast_channel_make_compatible_helper(peer, chan); 05643 05644 return rc; 05645 }
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 5580 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().
05581 { 05582 format_t src, dst; 05583 int use_slin; 05584 05585 /* See if the channel driver can natively make these two channels compatible */ 05586 if (from->tech->bridge && from->tech->bridge == to->tech->bridge && 05587 !ast_channel_setoption(from, AST_OPTION_MAKE_COMPATIBLE, to, sizeof(struct ast_channel *), 0)) { 05588 return 0; 05589 } 05590 05591 if (from->readformat == to->writeformat && from->writeformat == to->readformat) { 05592 /* Already compatible! Moving on ... */ 05593 return 0; 05594 } 05595 05596 /* Set up translation from the 'from' channel to the 'to' channel */ 05597 src = from->nativeformats; 05598 dst = to->nativeformats; 05599 05600 /* If there's no audio in this call, don't bother with trying to find a translation path */ 05601 if ((src & AST_FORMAT_AUDIO_MASK) == 0 || (dst & AST_FORMAT_AUDIO_MASK) == 0) 05602 return 0; 05603 05604 if (ast_translator_best_choice(&dst, &src) < 0) { 05605 ast_log(LOG_WARNING, "No path to translate from %s to %s\n", from->name, to->name); 05606 return -1; 05607 } 05608 05609 /* if the best path is not 'pass through', then 05610 * transcoding is needed; if desired, force transcode path 05611 * to use SLINEAR between channels, but only if there is 05612 * no direct conversion available. If generic PLC is 05613 * desired, then transcoding via SLINEAR is a requirement 05614 */ 05615 use_slin = (src == AST_FORMAT_SLINEAR || dst == AST_FORMAT_SLINEAR); 05616 if ((src != dst) && (ast_opt_generic_plc || ast_opt_transcode_via_slin) && 05617 (ast_translate_path_steps(dst, src) != 1 || use_slin)) 05618 dst = AST_FORMAT_SLINEAR; 05619 if (ast_set_read_format(from, dst) < 0) { 05620 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %s\n", from->name, ast_getformatname(dst)); 05621 return -1; 05622 } 05623 if (ast_set_write_format(to, dst) < 0) { 05624 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %s\n", to->name, ast_getformatname(dst)); 05625 return -1; 05626 } 05627 return 0; 05628 }
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 5737 of file channel.c.
References __ast_channel_masquerade().
Referenced by ast_async_goto(), ast_pickup_call(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), masq_park_call(), pickup_do(), sip_park(), and skinny_transfer().
05738 { 05739 return __ast_channel_masquerade(original, clone, NULL); 05740 }
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 7299 of file channel.c.
References 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().
07300 { 07301 if (!chan->tech->queryoption) { 07302 errno = ENOSYS; 07303 return -1; 07304 } 07305 07306 if (block) 07307 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 07308 07309 return chan->tech->queryoption(chan, option, data, datalen); 07310 }
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 8540 of file channel.c.
References ast_connected_line_build_data(), AST_CONTROL_CONNECTED_LINE, ast_queue_control_data(), connected, and update().
Referenced by ast_pickup_call(), handle_request_invite(), handle_request_update(), handle_response_invite(), local_attended_transfer(), masquerade_colp_transfer(), misdn_queue_connected_line_update(), pickup_do(), and sig_pri_handle_subcmds().
08541 { 08542 unsigned char data[1024]; /* This should be large enough */ 08543 size_t datalen; 08544 08545 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update); 08546 if (datalen == (size_t) -1) { 08547 return; 08548 } 08549 08550 ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen); 08551 }
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 9047 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().
09048 { 09049 unsigned char data[1024]; /* This should be large enough */ 09050 size_t datalen; 09051 09052 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update); 09053 if (datalen == (size_t) -1) { 09054 return; 09055 } 09056 09057 ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen); 09058 }
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 5034 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().
05035 { 05036 switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */ 05037 { 05038 case 0: 05039 return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)"; 05040 case AST_CONTROL_HANGUP: 05041 return "Hangup"; 05042 case AST_CONTROL_RING: 05043 return "Local Ring"; 05044 case AST_CONTROL_RINGING: 05045 return "Remote end Ringing"; 05046 case AST_CONTROL_ANSWER: 05047 return "Remote end has Answered"; 05048 case AST_CONTROL_BUSY: 05049 return "Remote end is Busy"; 05050 case AST_CONTROL_CONGESTION: 05051 return "Congestion (circuits busy)"; 05052 default: 05053 return "Unknown Reason!!"; 05054 } 05055 }
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 9099 of file channel.c.
References ast_app_run_macro(), ast_channel_lock, ast_channel_unlock, ast_channel_update_redirecting(), ast_party_redirecting_copy(), ast_redirecting_parse_data(), ast_strdupa, ast_strlen_zero(), ast_frame::data, ast_frame::datalen, pbx_builtin_getvar_helper(), ast_frame::ptr, ast_channel::redirecting, and S_OR.
Referenced by ast_bridge_call(), do_forward(), feature_request_and_dial(), handle_frame(), and remote_bridge_loop().
09100 { 09101 const char *macro; 09102 const char *macro_args; 09103 int retval; 09104 09105 ast_channel_lock(macro_chan); 09106 macro = pbx_builtin_getvar_helper(macro_chan, is_caller 09107 ? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO"); 09108 macro = ast_strdupa(S_OR(macro, "")); 09109 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller 09110 ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS"); 09111 macro_args = ast_strdupa(S_OR(macro_args, "")); 09112 09113 if (ast_strlen_zero(macro)) { 09114 ast_channel_unlock(macro_chan); 09115 return -1; 09116 } 09117 09118 if (is_frame) { 09119 const struct ast_frame *frame = redirecting_info; 09120 09121 ast_redirecting_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->redirecting); 09122 } else { 09123 const struct ast_party_redirecting *redirecting = redirecting_info; 09124 09125 ast_party_redirecting_copy(¯o_chan->redirecting, redirecting); 09126 } 09127 ast_channel_unlock(macro_chan); 09128 09129 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args); 09130 if (!retval) { 09131 ast_channel_lock(macro_chan); 09132 ast_channel_update_redirecting(macro_chan, ¯o_chan->redirecting, NULL); 09133 ast_channel_unlock(macro_chan); 09134 } 09135 09136 return retval; 09137 }
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 837 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().
00838 { 00839 struct chanlist *chan; 00840 00841 AST_RWLIST_WRLOCK(&backends); 00842 00843 AST_RWLIST_TRAVERSE(&backends, chan, list) { 00844 if (!strcasecmp(tech->type, chan->tech->type)) { 00845 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type); 00846 AST_RWLIST_UNLOCK(&backends); 00847 return -1; 00848 } 00849 } 00850 00851 if (!(chan = ast_calloc(1, sizeof(*chan)))) { 00852 AST_RWLIST_UNLOCK(&backends); 00853 return -1; 00854 } 00855 chan->tech = tech; 00856 AST_RWLIST_INSERT_HEAD(&backends, chan, list); 00857 00858 ast_debug(1, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description); 00859 00860 ast_verb(2, "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description); 00861 00862 AST_RWLIST_UNLOCK(&backends); 00863 00864 return 0; 00865 }
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 1827 of file channel.c.
References ao2_unlink, ast_channel_unref, chanlist::chan, and channels.
Referenced by acf_odbc_read(), acf_odbc_write(), action_getvar(), agent_cleanup(), agent_new(), ast_add_extension2_lockopt(), ast_cel_fabricate_channel_from_event(), ast_do_masquerade(), ast_hangup(), ast_iax2_new(), ast_pbx_outgoing_cdr_failed(), ast_request(), ast_str_substitute_variables_full(), bridge_request(), custom_log(), do_notify(), gtalk_newcall(), local_new(), local_request(), make_email_file(), manager_log(), pbx_substitute_variables_helper_full(), rotate_file(), sendmail(), sendpage(), syslog_log(), and write_cdr().
01828 { 01829 /* Safe, even if already unlinked. */ 01830 ao2_unlink(channels, chan); 01831 return ast_channel_unref(chan); 01832 }
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 5567 of file channel.c.
References chanlist::chan, ast_channel_tech::send_html, and ast_channel::tech.
Referenced by agent_sendhtml(), and ast_channel_sendurl().
05568 { 05569 if (chan->tech->send_html) 05570 return chan->tech->send_html(chan, subclass, data, datalen); 05571 return -1; 05572 }
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 5574 of file channel.c.
References ast_channel_sendhtml(), AST_HTML_URL, and chanlist::chan.
Referenced by dial_exec_full(), and sendurl_exec().
05575 { 05576 return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1); 05577 }
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 6600 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_party_caller_set(), ast_channel::caller, chanlist::chan, and update().
06601 { 06602 if (&chan->caller == caller) { 06603 /* Don't set to self */ 06604 return; 06605 } 06606 06607 ast_channel_lock(chan); 06608 ast_party_caller_set(&chan->caller, caller, update); 06609 ast_channel_unlock(chan); 06610 }
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 6612 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(), misdn_update_caller_id(), ring_entry(), and sig_pri_handle_subcmds().
06613 { 06614 struct ast_party_caller pre_set; 06615 06616 if (&chan->caller == caller) { 06617 /* Don't set to self */ 06618 return; 06619 } 06620 06621 ast_channel_lock(chan); 06622 pre_set = chan->caller; 06623 ast_party_caller_set(&chan->caller, caller, update); 06624 if (S_COR(pre_set.id.number.valid, pre_set.id.number.str, NULL) 06625 != S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL) 06626 || S_COR(pre_set.id.name.valid, pre_set.id.name.str, NULL) 06627 != S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL)) { 06628 /* The caller id name or number changed. */ 06629 report_new_callerid(chan); 06630 } 06631 if (chan->cdr) { 06632 ast_cdr_setcid(chan->cdr, chan); 06633 } 06634 ast_channel_unlock(chan); 06635 }
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 7900 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().
07901 { 07902 if (&chan->connected == connected) { 07903 /* Don't set to self */ 07904 return; 07905 } 07906 07907 ast_channel_lock(chan); 07908 ast_party_connected_line_set(&chan->connected, connected, update); 07909 ast_channel_unlock(chan); 07910 }
void ast_channel_set_fd | ( | struct ast_channel * | chan, | |
int | which, | |||
int | fd | |||
) |
Set the file descriptor on the channel
Definition at line 2526 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(), jingle_new(), mgcp_new(), misdn_new(), my_swap_subchannels(), nbs_new(), oss_new(), phone_new(), setformat(), sip_new(), skinny_new(), start_rtp(), and swap_subs().
02527 { 02528 #ifdef HAVE_EPOLL 02529 struct epoll_event ev; 02530 struct ast_epoll_data *aed = NULL; 02531 02532 if (chan->fds[which] > -1) { 02533 epoll_ctl(chan->epfd, EPOLL_CTL_DEL, chan->fds[which], &ev); 02534 aed = chan->epfd_data[which]; 02535 } 02536 02537 /* If this new fd is valid, add it to the epoll */ 02538 if (fd > -1) { 02539 if (!aed && (!(aed = ast_calloc(1, sizeof(*aed))))) 02540 return; 02541 02542 chan->epfd_data[which] = aed; 02543 aed->chan = chan; 02544 aed->which = which; 02545 02546 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 02547 ev.data.ptr = aed; 02548 epoll_ctl(chan->epfd, EPOLL_CTL_ADD, fd, &ev); 02549 } else if (aed) { 02550 /* We don't have to keep around this epoll data structure now */ 02551 free(aed); 02552 chan->epfd_data[which] = NULL; 02553 } 02554 #endif 02555 chan->fds[which] = fd; 02556 return; 02557 }
void ast_channel_set_linkgroup | ( | struct ast_channel * | chan, | |
struct ast_channel * | peer | |||
) |
propagate the linked id between chan and peer
Definition at line 6010 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().
06011 { 06012 const char* linkedid=NULL; 06013 struct ast_channel *bridged; 06014 06015 linkedid = oldest_linkedid(chan->linkedid, peer->linkedid); 06016 linkedid = oldest_linkedid(linkedid, chan->uniqueid); 06017 linkedid = oldest_linkedid(linkedid, peer->uniqueid); 06018 if (chan->_bridge) { 06019 bridged = ast_bridged_channel(chan); 06020 if (bridged != peer) { 06021 linkedid = oldest_linkedid(linkedid, bridged->linkedid); 06022 linkedid = oldest_linkedid(linkedid, bridged->uniqueid); 06023 } 06024 } 06025 if (peer->_bridge) { 06026 bridged = ast_bridged_channel(peer); 06027 if (bridged != chan) { 06028 linkedid = oldest_linkedid(linkedid, bridged->linkedid); 06029 linkedid = oldest_linkedid(linkedid, bridged->uniqueid); 06030 } 06031 } 06032 06033 /* just in case setting a stringfield to itself causes problems */ 06034 linkedid = ast_strdupa(linkedid); 06035 06036 ast_channel_change_linkedid(chan, linkedid); 06037 ast_channel_change_linkedid(peer, linkedid); 06038 if (chan->_bridge) { 06039 bridged = ast_bridged_channel(chan); 06040 if (bridged != peer) { 06041 ast_channel_change_linkedid(bridged, linkedid); 06042 } 06043 } 06044 if (peer->_bridge) { 06045 bridged = ast_bridged_channel(peer); 06046 if (bridged != chan) { 06047 ast_channel_change_linkedid(bridged, linkedid); 06048 } 06049 } 06050 }
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 8553 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_party_redirecting_set(), ast_channel::redirecting, and update().
Referenced by ast_call_forward(), ast_indicate_data(), do_forward(), handle_request_invite(), handle_response(), misdn_copy_redirecting_to_ast(), redirecting_write(), and sig_pri_handle_subcmds().
08554 { 08555 if (&chan->redirecting == redirecting) { 08556 /* Don't set to self */ 08557 return; 08558 } 08559 08560 ast_channel_lock(chan); 08561 ast_party_redirecting_set(&chan->redirecting, redirecting, update); 08562 ast_channel_unlock(chan); 08563 }
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 7286 of file channel.c.
References 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(), rpt(), rpt_exec(), set_format(), set_listen_volume(), set_security_requirements(), set_talk_volume(), sndfax_exec(), and vm_forwardoptions().
07287 { 07288 if (!chan->tech->setoption) { 07289 errno = ENOSYS; 07290 return -1; 07291 } 07292 07293 if (block) 07294 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 07295 07296 return chan->tech->setoption(chan, option, data, datalen); 07297 }
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 808 of file channel.c.
References ast_channel_setwhentohangup_tv(), and chanlist::chan.
00809 { 00810 struct timeval when = { offset, }; 00811 ast_channel_setwhentohangup_tv(chan, when); 00812 }
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 801 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(), and timeout_write().
00802 { 00803 chan->whentohangup = ast_tvzero(offset) ? offset : ast_tvadd(offset, ast_tvnow()); 00804 ast_queue_frame(chan, &ast_null_frame); 00805 return; 00806 }
static int ast_channel_softhangup_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 764 of file channel.c.
References ast_softhangup(), AST_SOFTHANGUP_SHUTDOWN, and chanlist::chan.
Referenced by ast_begin_shutdown().
00765 { 00766 struct ast_channel *chan = obj; 00767 00768 ast_softhangup(chan, AST_SOFTHANGUP_SHUTDOWN); 00769 00770 return 0; 00771 }
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 7774 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_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), TransferCallStep1(), waitfor_exec(), and waitforring_exec().
07775 { 07776 struct ast_silence_generator *state; 07777 07778 if (!(state = ast_calloc(1, sizeof(*state)))) { 07779 return NULL; 07780 } 07781 07782 state->old_write_format = chan->writeformat; 07783 07784 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) { 07785 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n"); 07786 ast_free(state); 07787 return NULL; 07788 } 07789 07790 ast_activate_generator(chan, &silence_generator, state); 07791 07792 ast_debug(1, "Started silence generator on '%s'\n", chan->name); 07793 07794 return state; 07795 }
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 7797 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_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), HandleCallOutgoing(), key_dial_page(), unistim_hangup(), waitfor_exec(), and waitforring_exec().
07798 { 07799 if (!state) 07800 return; 07801 07802 ast_deactivate_generator(chan); 07803 07804 ast_debug(1, "Stopped silence generator on '%s'\n", chan->name); 07805 07806 if (ast_set_write_format(chan, state->old_write_format) < 0) 07807 ast_log(LOG_ERROR, "Could not return write format to its original state\n"); 07808 07809 ast_free(state); 07810 }
int ast_channel_supports_html | ( | struct ast_channel * | channel | ) |
Checks for HTML support on a channel.
Definition at line 5562 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 5811 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().
05818 { 05819 struct ast_datastore *xfer_ds; 05820 struct xfer_masquerade_ds *xfer_colp; 05821 int res; 05822 05823 xfer_ds = ast_datastore_alloc(&xfer_ds_info, NULL); 05824 if (!xfer_ds) { 05825 return -1; 05826 } 05827 05828 xfer_colp = ast_calloc(1, sizeof(*xfer_colp)); 05829 if (!xfer_colp) { 05830 ast_datastore_free(xfer_ds); 05831 return -1; 05832 } 05833 party_connected_line_copy_transfer(&xfer_colp->target_id, target_id); 05834 xfer_colp->target_held = target_held; 05835 party_connected_line_copy_transfer(&xfer_colp->transferee_id, transferee_id); 05836 xfer_colp->transferee_held = transferee_held; 05837 xfer_ds->data = xfer_colp; 05838 05839 res = __ast_channel_masquerade(target_chan, transferee_chan, xfer_ds); 05840 if (res) { 05841 ast_datastore_free(xfer_ds); 05842 } 05843 return res; 05844 }
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 1538 of file channel.c.
References ast_clear_flag, AST_FLAG_DEFER_DTMF, and chanlist::chan.
Referenced by find_cache(), and rpt_call().
01539 { 01540 if (chan) 01541 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF); 01542 }
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 868 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().
00869 { 00870 struct chanlist *chan; 00871 00872 ast_debug(1, "Unregistering channel type '%s'\n", tech->type); 00873 00874 AST_RWLIST_WRLOCK(&backends); 00875 00876 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) { 00877 if (chan->tech == tech) { 00878 AST_LIST_REMOVE_CURRENT(list); 00879 ast_free(chan); 00880 ast_verb(2, "Unregistered channel type '%s'\n", tech->type); 00881 break; 00882 } 00883 } 00884 AST_LIST_TRAVERSE_SAFE_END; 00885 00886 AST_RWLIST_UNLOCK(&backends); 00887 }
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 8527 of file channel.c.
References ast_connected_line_build_data(), AST_CONTROL_CONNECTED_LINE, ast_indicate_data(), connected, and update().
Referenced by ast_channel_connected_line_macro(), ast_pickup_call(), atxfer_fail_cleanup(), builtin_atxfer(), builtin_blindtransfer(), connectedline_write(), pickup_do(), and wait_for_answer().
08528 { 08529 unsigned char data[1024]; /* This should be large enough */ 08530 size_t datalen; 08531 08532 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update); 08533 if (datalen == (size_t) -1) { 08534 return; 08535 } 08536 08537 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen); 08538 }
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 9034 of file channel.c.
References AST_CONTROL_REDIRECTING, ast_indicate_data(), ast_redirecting_build_data(), and update().
Referenced by ast_call_forward(), ast_channel_redirecting_macro(), do_forward(), and redirecting_write().
09035 { 09036 unsigned char data[1024]; /* This should be large enough */ 09037 size_t datalen; 09038 09039 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update); 09040 if (datalen == (size_t) -1) { 09041 return; 09042 } 09043 09044 ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen); 09045 }
void ast_channels_init | ( | void | ) |
Provided by channel.c
Definition at line 7688 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().
07689 { 07690 channels = ao2_container_alloc(NUM_CHANNEL_BUCKETS, 07691 ast_channel_hash_cb, ast_channel_cmp_cb); 07692 07693 ast_cli_register_multiple(cli_channel, ARRAY_LEN(cli_channel)); 07694 07695 ast_data_register_multiple_core(channel_providers, ARRAY_LEN(channel_providers)); 07696 07697 ast_plc_reload(); 07698 }
struct ast_variable* ast_channeltype_list | ( | void | ) |
return an ast_variable list of channeltypes
Definition at line 248 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().
00249 { 00250 struct chanlist *cl; 00251 struct ast_variable *var = NULL, *prev = NULL; 00252 00253 AST_RWLIST_RDLOCK(&backends); 00254 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00255 if (prev) { 00256 if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description, ""))) 00257 prev = prev->next; 00258 } else { 00259 var = ast_variable_new(cl->tech->type, cl->tech->description, ""); 00260 prev = var; 00261 } 00262 } 00263 AST_RWLIST_UNLOCK(&backends); 00264 00265 return var; 00266 }
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 742 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(), 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_exec(), read_exec(), readexten_exec(), remote_bridge_loop(), rpt(), and run_ras().
00743 { 00744 if (chan->_softhangup) /* yes if soft hangup flag set */ 00745 return 1; 00746 if (ast_tvzero(chan->whentohangup)) /* no if no hangup scheduled */ 00747 return 0; 00748 if (ast_tvdiff_ms(chan->whentohangup, ast_tvnow()) > 0) /* no if hangup time has not come yet. */ 00749 return 0; 00750 ast_debug(4, "Hangup time has come: %" PRIi64 "\n", ast_tvdiff_ms(chan->whentohangup, ast_tvnow())); 00751 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */ 00752 return 1; 00753 }
int ast_check_hangup_locked | ( | struct ast_channel * | chan | ) |
Definition at line 755 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().
00756 { 00757 int res; 00758 ast_channel_lock(chan); 00759 res = ast_check_hangup(chan); 00760 ast_channel_unlock(chan); 00761 return res; 00762 }
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 8267 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().
08268 { 08269 int32_t value; 08270 size_t pos = 0; 08271 int res; 08272 08273 static const struct ast_party_id_ies ies = { 08274 .name.str = AST_CONNECTED_LINE_NAME, 08275 .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET, 08276 .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION, 08277 .name.valid = AST_CONNECTED_LINE_NAME_VALID, 08278 08279 .number.str = AST_CONNECTED_LINE_NUMBER, 08280 .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN, 08281 .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION, 08282 .number.valid = AST_CONNECTED_LINE_NUMBER_VALID, 08283 08284 .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS, 08285 .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE, 08286 .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, 08287 .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID, 08288 08289 .tag = AST_CONNECTED_LINE_TAG, 08290 .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION, 08291 }; 08292 08293 /* 08294 * The size of integer values must be fixed in case the frame is 08295 * shipped to another machine. 08296 */ 08297 08298 /* Connected line frame version */ 08299 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08300 ast_log(LOG_WARNING, "No space left for connected line frame version\n"); 08301 return -1; 08302 } 08303 data[pos++] = AST_CONNECTED_LINE_VERSION; 08304 data[pos++] = 1; 08305 data[pos++] = 2;/* Version 1 did not have a version ie */ 08306 08307 res = party_id_build_data(data + pos, datalen - pos, &connected->id, 08308 "connected line", &ies, update ? &update->id : NULL); 08309 if (res < 0) { 08310 return -1; 08311 } 08312 pos += res; 08313 08314 /* Connected line source */ 08315 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 08316 ast_log(LOG_WARNING, "No space left for connected line source\n"); 08317 return -1; 08318 } 08319 data[pos++] = AST_CONNECTED_LINE_SOURCE; 08320 data[pos++] = sizeof(value); 08321 value = htonl(connected->source); 08322 memcpy(data + pos, &value, sizeof(value)); 08323 pos += sizeof(value); 08324 08325 return pos; 08326 }
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 7885 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 begin_dial_channel(), builtin_atxfer(), dial_exec_full(), feature_request_and_dial(), local_call(), pickup_do(), ring_entry(), and wait_for_answer().
07886 { 07887 ast_party_id_copy(&dest->id, &src->id); 07888 ast_party_id_copy(&dest->ani, &src->ani); 07889 dest->ani2 = src->ani2; 07890 }
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 7892 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().
07893 { 07894 ast_party_id_copy(&dest->id, &src->id); 07895 ast_party_id_copy(&dest->ani, &src->ani); 07896 07897 dest->ani2 = src->ani2; 07898 }
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 8328 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(), and socket_process().
08329 { 08330 size_t pos; 08331 unsigned char ie_len; 08332 unsigned char ie_id; 08333 int32_t value; 08334 int frame_version = 1; 08335 int combined_presentation = 0; 08336 int got_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 08337 08338 for (pos = 0; pos < datalen; pos += ie_len) { 08339 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) { 08340 ast_log(LOG_WARNING, "Invalid connected line update\n"); 08341 return -1; 08342 } 08343 ie_id = data[pos++]; 08344 ie_len = data[pos++]; 08345 if (datalen < pos + ie_len) { 08346 ast_log(LOG_WARNING, "Invalid connected line update\n"); 08347 return -1; 08348 } 08349 08350 switch (ie_id) { 08351 /* Connected line party frame version */ 08352 case AST_CONNECTED_LINE_VERSION: 08353 if (ie_len != 1) { 08354 ast_log(LOG_WARNING, "Invalid connected line frame version (%u)\n", 08355 (unsigned) ie_len); 08356 break; 08357 } 08358 frame_version = data[pos]; 08359 break; 08360 /* Connected line party id name */ 08361 case AST_CONNECTED_LINE_NAME: 08362 ast_free(connected->id.name.str); 08363 connected->id.name.str = ast_malloc(ie_len + 1); 08364 if (connected->id.name.str) { 08365 memcpy(connected->id.name.str, data + pos, ie_len); 08366 connected->id.name.str[ie_len] = 0; 08367 } 08368 break; 08369 case AST_CONNECTED_LINE_NAME_CHAR_SET: 08370 if (ie_len != 1) { 08371 ast_log(LOG_WARNING, "Invalid connected line name char set (%u)\n", 08372 (unsigned) ie_len); 08373 break; 08374 } 08375 connected->id.name.char_set = data[pos]; 08376 break; 08377 case AST_CONNECTED_LINE_NAME_PRESENTATION: 08378 if (ie_len != 1) { 08379 ast_log(LOG_WARNING, "Invalid connected line name presentation (%u)\n", 08380 (unsigned) ie_len); 08381 break; 08382 } 08383 connected->id.name.presentation = data[pos]; 08384 break; 08385 case AST_CONNECTED_LINE_NAME_VALID: 08386 if (ie_len != 1) { 08387 ast_log(LOG_WARNING, "Invalid connected line name valid (%u)\n", 08388 (unsigned) ie_len); 08389 break; 08390 } 08391 connected->id.name.valid = data[pos]; 08392 break; 08393 /* Connected line party id number */ 08394 case AST_CONNECTED_LINE_NUMBER: 08395 ast_free(connected->id.number.str); 08396 connected->id.number.str = ast_malloc(ie_len + 1); 08397 if (connected->id.number.str) { 08398 memcpy(connected->id.number.str, data + pos, ie_len); 08399 connected->id.number.str[ie_len] = 0; 08400 } 08401 break; 08402 case AST_CONNECTED_LINE_NUMBER_PLAN: 08403 if (ie_len != 1) { 08404 ast_log(LOG_WARNING, "Invalid connected line numbering plan (%u)\n", 08405 (unsigned) ie_len); 08406 break; 08407 } 08408 connected->id.number.plan = data[pos]; 08409 break; 08410 case AST_CONNECTED_LINE_NUMBER_PRESENTATION: 08411 if (ie_len != 1) { 08412 ast_log(LOG_WARNING, "Invalid connected line number presentation (%u)\n", 08413 (unsigned) ie_len); 08414 break; 08415 } 08416 connected->id.number.presentation = data[pos]; 08417 break; 08418 case AST_CONNECTED_LINE_NUMBER_VALID: 08419 if (ie_len != 1) { 08420 ast_log(LOG_WARNING, "Invalid connected line number valid (%u)\n", 08421 (unsigned) ie_len); 08422 break; 08423 } 08424 connected->id.number.valid = data[pos]; 08425 break; 08426 /* Connected line party id combined presentation */ 08427 case AST_CONNECTED_LINE_ID_PRESENTATION: 08428 if (ie_len != 1) { 08429 ast_log(LOG_WARNING, "Invalid connected line combined presentation (%u)\n", 08430 (unsigned) ie_len); 08431 break; 08432 } 08433 combined_presentation = data[pos]; 08434 got_combined_presentation = 1; 08435 break; 08436 /* Connected line party id subaddress */ 08437 case AST_CONNECTED_LINE_SUBADDRESS: 08438 ast_free(connected->id.subaddress.str); 08439 connected->id.subaddress.str = ast_malloc(ie_len + 1); 08440 if (connected->id.subaddress.str) { 08441 memcpy(connected->id.subaddress.str, data + pos, ie_len); 08442 connected->id.subaddress.str[ie_len] = 0; 08443 } 08444 break; 08445 case AST_CONNECTED_LINE_SUBADDRESS_TYPE: 08446 if (ie_len != 1) { 08447 ast_log(LOG_WARNING, "Invalid connected line type of subaddress (%u)\n", 08448 (unsigned) ie_len); 08449 break; 08450 } 08451 connected->id.subaddress.type = data[pos]; 08452 break; 08453 case AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN: 08454 if (ie_len != 1) { 08455 ast_log(LOG_WARNING, 08456 "Invalid connected line subaddress odd-even indicator (%u)\n", 08457 (unsigned) ie_len); 08458 break; 08459 } 08460 connected->id.subaddress.odd_even_indicator = data[pos]; 08461 break; 08462 case AST_CONNECTED_LINE_SUBADDRESS_VALID: 08463 if (ie_len != 1) { 08464 ast_log(LOG_WARNING, "Invalid connected line subaddress valid (%u)\n", 08465 (unsigned) ie_len); 08466 break; 08467 } 08468 connected->id.subaddress.valid = data[pos]; 08469 break; 08470 /* Connected line party tag */ 08471 case AST_CONNECTED_LINE_TAG: 08472 ast_free(connected->id.tag); 08473 connected->id.tag = ast_malloc(ie_len + 1); 08474 if (connected->id.tag) { 08475 memcpy(connected->id.tag, data + pos, ie_len); 08476 connected->id.tag[ie_len] = 0; 08477 } 08478 break; 08479 /* Connected line party source */ 08480 case AST_CONNECTED_LINE_SOURCE: 08481 if (ie_len != sizeof(value)) { 08482 ast_log(LOG_WARNING, "Invalid connected line source (%u)\n", 08483 (unsigned) ie_len); 08484 break; 08485 } 08486 memcpy(&value, data + pos, sizeof(value)); 08487 connected->source = ntohl(value); 08488 break; 08489 /* Connected line party unknown element */ 08490 default: 08491 ast_log(LOG_DEBUG, "Unknown connected line element: %u (%u)\n", 08492 (unsigned) ie_id, (unsigned) ie_len); 08493 break; 08494 } 08495 } 08496 08497 switch (frame_version) { 08498 case 1: 08499 /* 08500 * The other end is an earlier version that we need to adjust 08501 * for compatibility. 08502 */ 08503 connected->id.name.valid = 1; 08504 connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 08505 connected->id.number.valid = 1; 08506 if (got_combined_presentation) { 08507 connected->id.name.presentation = combined_presentation; 08508 connected->id.number.presentation = combined_presentation; 08509 } 08510 break; 08511 case 2: 08512 /* The other end is at the same level as we are. */ 08513 break; 08514 default: 08515 /* 08516 * The other end is newer than we are. 08517 * We need to assume that they are compatible with us. 08518 */ 08519 ast_log(LOG_DEBUG, "Connected line frame has newer version: %u\n", 08520 (unsigned) frame_version); 08521 break; 08522 } 08523 08524 return 0; 08525 }
AST_DATA_STRUCTURE | ( | ast_channel | , | |
DATA_EXPORT_CHANNEL | ||||
) |
void ast_deactivate_generator | ( | struct ast_channel * | chan | ) |
Deactivate an active generator
Definition at line 2931 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().
02932 { 02933 ast_channel_lock(chan); 02934 if (chan->generatordata) { 02935 if (chan->generator && chan->generator->release) 02936 chan->generator->release(chan, chan->generatordata); 02937 chan->generatordata = NULL; 02938 chan->generator = NULL; 02939 ast_channel_set_fd(chan, AST_GENERATOR_FD, -1); 02940 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 02941 ast_settimeout(chan, 0, NULL, NULL); 02942 } 02943 ast_channel_unlock(chan); 02944 }
int ast_do_masquerade | ( | struct ast_channel * | original | ) |
Start masquerading a channel.
Definition at line 6169 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_NAME, ast_channel_release(), ast_channel_set_fd(), ast_channel_set_linkgroup(), ast_channel_trylock, ast_channel_unlock, AST_CONTROL_SRCCHANGE, AST_CONTROL_UNHOLD, ast_copy_string(), ast_datastore_free(), ast_debug, AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, AST_GENERATOR_FD, ast_getformatname(), ast_indicate(), AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_HEAD_NOLOCK, AST_LIST_HEAD_SET_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_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, CHANNEL_DEADLOCK_AVOIDANCE, 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_channel_tech::hangup, 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_hangup(), ast_waitfor_nandfds(), ast_write(), builtin_atxfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), local_attended_transfer(), sip_park(), and sip_park_thread().
06170 { 06171 format_t x; 06172 int i; 06173 int res=0; 06174 int origstate; 06175 int visible_indication; 06176 struct ast_frame *current; 06177 const struct ast_channel_tech *t; 06178 void *t_pvt; 06179 union { 06180 struct ast_party_dialed dialed; 06181 struct ast_party_caller caller; 06182 struct ast_party_connected_line connected; 06183 struct ast_party_redirecting redirecting; 06184 } exchange; 06185 struct ast_channel *clonechan, *chans[2]; 06186 struct ast_channel *bridged; 06187 struct ast_cdr *cdr; 06188 struct ast_datastore *xfer_ds; 06189 struct xfer_masquerade_ds *xfer_colp; 06190 format_t rformat = original->readformat; 06191 format_t wformat = original->writeformat; 06192 char newn[AST_CHANNEL_NAME]; 06193 char orig[AST_CHANNEL_NAME]; 06194 char masqn[AST_CHANNEL_NAME]; 06195 char zombn[AST_CHANNEL_NAME]; 06196 06197 /* XXX This operation is a bit odd. We're essentially putting the guts of 06198 * the clone channel into the original channel. Start by killing off the 06199 * original channel's backend. While the features are nice, which is the 06200 * reason we're keeping it, it's still awesomely weird. XXX */ 06201 06202 /* The reasoning for the channels ao2_container lock here is complex. 06203 * 06204 * In order to check for a race condition, the original channel must 06205 * be locked. If it is determined that the masquerade should proceed 06206 * the original channel can absolutely not be unlocked until the end 06207 * of the function. Since after determining the masquerade should 06208 * continue requires the channels to be unlinked from the ao2_container, 06209 * the container lock must be held first to achieve proper locking order. 06210 */ 06211 ao2_lock(channels); 06212 06213 /* lock the original channel to determine if the masquerade is require or not */ 06214 ast_channel_lock(original); 06215 06216 /* This checks to see if the masquerade has already happened or not. There is a 06217 * race condition that exists for this function. Since all pvt and channel locks 06218 * must be let go before calling do_masquerade, it is possible that it could be 06219 * called multiple times for the same channel. This check verifies whether 06220 * or not the masquerade has already been completed by another thread */ 06221 if (!original->masq) { 06222 ast_channel_unlock(original); 06223 ao2_unlock(channels); 06224 return 0; /* masq already completed by another thread, or never needed to be done to begin with */ 06225 } 06226 06227 /* now that we have verified no race condition exists, set the clone channel */ 06228 clonechan = original->masq; 06229 06230 /* since this function already holds the global container lock, unlocking original 06231 * for deadlock avoidance will not result in any sort of masquerade race condition. 06232 * If masq is called by a different thread while this happens, it will be stuck waiting 06233 * until we unlock the container. */ 06234 while (ast_channel_trylock(clonechan)) { 06235 CHANNEL_DEADLOCK_AVOIDANCE(original); 06236 } 06237 06238 /* Get any transfer masquerade connected line exchange data. */ 06239 xfer_ds = ast_channel_datastore_find(original, &xfer_ds_info, NULL); 06240 if (xfer_ds) { 06241 ast_channel_datastore_remove(original, xfer_ds); 06242 xfer_colp = xfer_ds->data; 06243 } else { 06244 xfer_colp = NULL; 06245 } 06246 06247 /* 06248 * Release any hold on the transferee channel before proceeding 06249 * with the masquerade. 06250 */ 06251 if (xfer_colp && xfer_colp->transferee_held) { 06252 ast_indicate(clonechan, AST_CONTROL_UNHOLD); 06253 } 06254 06255 /* clear the masquerade channels */ 06256 original->masq = NULL; 06257 clonechan->masqr = NULL; 06258 06259 /* unlink from channels container as name (which is the hash value) will change */ 06260 ao2_unlink(channels, original); 06261 ao2_unlink(channels, clonechan); 06262 06263 ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", 06264 clonechan->name, clonechan->_state, original->name, original->_state); 06265 06266 /* 06267 * Stop any visible indiction on the original channel so we can 06268 * transfer it to the clonechan taking the original's place. 06269 */ 06270 visible_indication = original->visible_indication; 06271 ast_indicate(original, -1); 06272 06273 chans[0] = clonechan; 06274 chans[1] = original; 06275 ast_manager_event_multichan(EVENT_FLAG_CALL, "Masquerade", 2, chans, 06276 "Clone: %s\r\n" 06277 "CloneState: %s\r\n" 06278 "Original: %s\r\n" 06279 "OriginalState: %s\r\n", 06280 clonechan->name, ast_state2str(clonechan->_state), original->name, ast_state2str(original->_state)); 06281 06282 /* Having remembered the original read/write formats, we turn off any translation on either 06283 one */ 06284 free_translation(clonechan); 06285 free_translation(original); 06286 06287 /* Save the original name */ 06288 ast_copy_string(orig, original->name, sizeof(orig)); 06289 /* Save the new name */ 06290 ast_copy_string(newn, clonechan->name, sizeof(newn)); 06291 /* Create the masq name */ 06292 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn); 06293 06294 /* Mangle the name of the clone channel */ 06295 __ast_change_name_nolink(clonechan, masqn); 06296 06297 /* Copy the name from the clone channel */ 06298 __ast_change_name_nolink(original, newn); 06299 06300 /* share linked id's */ 06301 ast_channel_set_linkgroup(original, clonechan); 06302 06303 /* Swap the technologies */ 06304 t = original->tech; 06305 original->tech = clonechan->tech; 06306 clonechan->tech = t; 06307 06308 /* Swap the cdrs */ 06309 cdr = original->cdr; 06310 original->cdr = clonechan->cdr; 06311 clonechan->cdr = cdr; 06312 06313 t_pvt = original->tech_pvt; 06314 original->tech_pvt = clonechan->tech_pvt; 06315 clonechan->tech_pvt = t_pvt; 06316 06317 /* Swap the alertpipes */ 06318 for (i = 0; i < 2; i++) { 06319 x = original->alertpipe[i]; 06320 original->alertpipe[i] = clonechan->alertpipe[i]; 06321 clonechan->alertpipe[i] = x; 06322 } 06323 06324 /* 06325 * Swap the readq's. The end result should be this: 06326 * 06327 * 1) All frames should be on the new (original) channel. 06328 * 2) Any frames that were already on the new channel before this 06329 * masquerade need to be at the end of the readq, after all of the 06330 * frames on the old (clone) channel. 06331 * 3) The alertpipe needs to get poked for every frame that was already 06332 * on the new channel, since we are now using the alert pipe from the 06333 * old (clone) channel. 06334 */ 06335 { 06336 AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq; 06337 AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL); 06338 06339 AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list); 06340 AST_LIST_APPEND_LIST(&original->readq, &clonechan->readq, frame_list); 06341 06342 while ((current = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) { 06343 AST_LIST_INSERT_TAIL(&original->readq, current, frame_list); 06344 if (original->alertpipe[1] > -1) { 06345 int poke = 0; 06346 06347 if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) { 06348 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 06349 } 06350 } 06351 } 06352 } 06353 06354 /* Swap the raw formats */ 06355 x = original->rawreadformat; 06356 original->rawreadformat = clonechan->rawreadformat; 06357 clonechan->rawreadformat = x; 06358 x = original->rawwriteformat; 06359 original->rawwriteformat = clonechan->rawwriteformat; 06360 clonechan->rawwriteformat = x; 06361 06362 clonechan->_softhangup = AST_SOFTHANGUP_DEV; 06363 06364 /* And of course, so does our current state. Note we need not 06365 call ast_setstate since the event manager doesn't really consider 06366 these separate. We do this early so that the clone has the proper 06367 state of the original channel. */ 06368 origstate = original->_state; 06369 original->_state = clonechan->_state; 06370 clonechan->_state = origstate; 06371 06372 if (clonechan->tech->fixup && clonechan->tech->fixup(original, clonechan)) { 06373 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clonechan->name); 06374 } 06375 06376 /* Start by disconnecting the original's physical side */ 06377 if (clonechan->tech->hangup && clonechan->tech->hangup(clonechan)) { 06378 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n"); 06379 res = -1; 06380 goto done; 06381 } 06382 06383 /* Mangle the name of the clone channel */ 06384 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); /* quick, hide the brains! */ 06385 __ast_change_name_nolink(clonechan, zombn); 06386 06387 /* Update the type. */ 06388 t_pvt = original->monitor; 06389 original->monitor = clonechan->monitor; 06390 clonechan->monitor = t_pvt; 06391 06392 /* Keep the same language. */ 06393 ast_string_field_set(original, language, clonechan->language); 06394 /* Copy the FD's other than the generator fd */ 06395 for (x = 0; x < AST_MAX_FDS; x++) { 06396 if (x != AST_GENERATOR_FD) 06397 ast_channel_set_fd(original, x, clonechan->fds[x]); 06398 } 06399 06400 ast_app_group_update(clonechan, original); 06401 06402 /* Move data stores over */ 06403 if (AST_LIST_FIRST(&clonechan->datastores)) { 06404 struct ast_datastore *ds; 06405 /* We use a safe traversal here because some fixup routines actually 06406 * remove the datastore from the list and free them. 06407 */ 06408 AST_LIST_TRAVERSE_SAFE_BEGIN(&clonechan->datastores, ds, entry) { 06409 if (ds->info->chan_fixup) 06410 ds->info->chan_fixup(ds->data, clonechan, original); 06411 } 06412 AST_LIST_TRAVERSE_SAFE_END; 06413 AST_LIST_APPEND_LIST(&original->datastores, &clonechan->datastores, entry); 06414 } 06415 06416 ast_autochan_new_channel(clonechan, original); 06417 06418 clone_variables(original, clonechan); 06419 /* Presense of ADSI capable CPE follows clone */ 06420 original->adsicpe = clonechan->adsicpe; 06421 /* Bridge remains the same */ 06422 /* CDR fields remain the same */ 06423 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 06424 /* Application and data remain the same */ 06425 /* Clone exception becomes real one, as with fdno */ 06426 ast_set_flag(original, ast_test_flag(clonechan, AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING)); 06427 original->fdno = clonechan->fdno; 06428 /* Schedule context remains the same */ 06429 /* Stream stuff stays the same */ 06430 /* Keep the original state. The fixup code will need to work with it most likely */ 06431 06432 /* 06433 * Just swap the whole structures, nevermind the allocations, 06434 * they'll work themselves out. 06435 */ 06436 exchange.dialed = original->dialed; 06437 original->dialed = clonechan->dialed; 06438 clonechan->dialed = exchange.dialed; 06439 06440 exchange.caller = original->caller; 06441 original->caller = clonechan->caller; 06442 clonechan->caller = exchange.caller; 06443 06444 exchange.connected = original->connected; 06445 original->connected = clonechan->connected; 06446 clonechan->connected = exchange.connected; 06447 06448 exchange.redirecting = original->redirecting; 06449 original->redirecting = clonechan->redirecting; 06450 clonechan->redirecting = exchange.redirecting; 06451 06452 report_new_callerid(original); 06453 06454 /* Restore original timing file descriptor */ 06455 ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd); 06456 06457 /* Our native formats are different now */ 06458 original->nativeformats = clonechan->nativeformats; 06459 06460 /* Context, extension, priority, app data, jump table, remain the same */ 06461 /* pvt switches. pbx stays the same, as does next */ 06462 06463 /* Set the write format */ 06464 ast_set_write_format(original, wformat); 06465 06466 /* Set the read format */ 06467 ast_set_read_format(original, rformat); 06468 06469 /* Copy the music class */ 06470 ast_string_field_set(original, musicclass, clonechan->musicclass); 06471 06472 /* copy over accuntcode and set peeraccount across the bridge */ 06473 ast_string_field_set(original, accountcode, S_OR(clonechan->accountcode, "")); 06474 if (original->_bridge) { 06475 /* XXX - should we try to lock original->_bridge here? */ 06476 ast_string_field_set(original->_bridge, peeraccount, S_OR(clonechan->accountcode, "")); 06477 ast_cel_report_event(original, AST_CEL_BRIDGE_UPDATE, NULL, NULL, NULL); 06478 } 06479 06480 ast_debug(1, "Putting channel %s in %s/%s formats\n", original->name, 06481 ast_getformatname(wformat), ast_getformatname(rformat)); 06482 06483 /* Okay. Last thing is to let the channel driver know about all this mess, so he 06484 can fix up everything as best as possible */ 06485 if (original->tech->fixup) { 06486 if (original->tech->fixup(clonechan, original)) { 06487 ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n", 06488 original->tech->type, original->name); 06489 res = -1; 06490 goto done; 06491 } 06492 } else 06493 ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)! Bad things may happen.\n", 06494 original->tech->type, original->name); 06495 06496 /* 06497 * If an indication is currently playing, maintain it on the channel 06498 * that is taking the place of original 06499 * 06500 * This is needed because the masquerade is swapping out in the internals 06501 * of this channel, and the new channel private data needs to be made 06502 * aware of the current visible indication (RINGING, CONGESTION, etc.) 06503 */ 06504 if (visible_indication) { 06505 ast_indicate(original, visible_indication); 06506 } 06507 06508 /* Now, at this point, the "clone" channel is totally F'd up. We mark it as 06509 a zombie so nothing tries to touch it. If it's already been marked as a 06510 zombie, then free it now (since it already is considered invalid). */ 06511 if (ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) { 06512 ast_debug(1, "Destroying channel clone '%s'\n", clonechan->name); 06513 ast_channel_unlock(clonechan); 06514 ast_manager_event(clonechan, EVENT_FLAG_CALL, "Hangup", 06515 "Channel: %s\r\n" 06516 "Uniqueid: %s\r\n" 06517 "Cause: %d\r\n" 06518 "Cause-txt: %s\r\n", 06519 clonechan->name, 06520 clonechan->uniqueid, 06521 clonechan->hangupcause, 06522 ast_cause2str(clonechan->hangupcause) 06523 ); 06524 clonechan = ast_channel_release(clonechan); 06525 } else { 06526 ast_debug(1, "Released clone lock on '%s'\n", clonechan->name); 06527 ast_set_flag(clonechan, AST_FLAG_ZOMBIE); 06528 ast_queue_frame(clonechan, &ast_null_frame); 06529 } 06530 06531 /* Signal any blocker */ 06532 if (ast_test_flag(original, AST_FLAG_BLOCKING)) 06533 pthread_kill(original->blocker, SIGURG); 06534 ast_debug(1, "Done Masquerading %s (%d)\n", original->name, original->_state); 06535 06536 if ((bridged = ast_bridged_channel(original))) { 06537 ast_channel_lock(bridged); 06538 ast_indicate(bridged, AST_CONTROL_SRCCHANGE); 06539 ast_channel_unlock(bridged); 06540 } 06541 ast_indicate(original, AST_CONTROL_SRCCHANGE); 06542 06543 if (xfer_colp) { 06544 /* 06545 * After the masquerade, the original channel pointer actually 06546 * points to the new transferee channel and the bridged channel 06547 * is still the intended transfer target party. 06548 */ 06549 masquerade_colp_transfer(original, xfer_colp); 06550 } 06551 06552 done: 06553 if (xfer_ds) { 06554 ast_datastore_free(xfer_ds); 06555 } 06556 /* it is possible for the clone channel to disappear during this */ 06557 if (clonechan) { 06558 ast_channel_unlock(original); 06559 ast_channel_unlock(clonechan); 06560 ao2_link(channels, clonechan); 06561 ao2_link(channels, original); 06562 } else { 06563 ast_channel_unlock(original); 06564 ao2_link(channels, original); 06565 } 06566 06567 ao2_unlock(channels); 06568 06569 return res; 06570 }
struct ast_channel* ast_dummy_channel_alloc | ( | void | ) |
Create a fake channel structure.
NULL | failure | |
non-NULL | successfully allocated channel |
Definition at line 1320 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().
01322 { 01323 struct ast_channel *tmp; 01324 struct varshead *headp; 01325 01326 #if defined(REF_DEBUG) 01327 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel", 01328 file, line, function, 1); 01329 #elif defined(__AST_DEBUG_MALLOC) 01330 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel", 01331 file, line, function, 0); 01332 #else 01333 tmp = ao2_alloc(sizeof(*tmp), ast_dummy_channel_destructor); 01334 #endif 01335 if (!tmp) { 01336 /* Dummy channel structure allocation failure. */ 01337 return NULL; 01338 } 01339 01340 if ((ast_string_field_init(tmp, 128))) { 01341 return ast_channel_unref(tmp); 01342 } 01343 01344 headp = &tmp->varshead; 01345 AST_LIST_HEAD_INIT_NOLOCK(headp); 01346 01347 return tmp; 01348 }
static void ast_dummy_channel_destructor | ( | void * | obj | ) | [static] |
Free a dummy channel structure.
Definition at line 2431 of file channel.c.
References ast_cdr_discard(), AST_LIST_REMOVE_HEAD, ast_party_caller_free(), ast_party_connected_line_free(), ast_party_dialed_free(), ast_party_redirecting_free(), ast_string_field_free_memory, ast_var_delete(), ast_channel::caller, ast_channel::cdr, chanlist::chan, ast_channel::connected, ast_channel::dialed, ast_channel::redirecting, and ast_channel::varshead.
Referenced by ast_dummy_channel_alloc().
02432 { 02433 struct ast_channel *chan = obj; 02434 struct ast_var_t *vardata; 02435 struct varshead *headp; 02436 02437 headp = &chan->varshead; 02438 02439 ast_party_dialed_free(&chan->dialed); 02440 ast_party_caller_free(&chan->caller); 02441 ast_party_connected_line_free(&chan->connected); 02442 ast_party_redirecting_free(&chan->redirecting); 02443 02444 /* loop over the variables list, freeing all data and deleting list items */ 02445 /* no need to lock the list, as the channel is already locked */ 02446 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) 02447 ast_var_delete(vardata); 02448 02449 if (chan->cdr) { 02450 ast_cdr_discard(chan->cdr); 02451 chan->cdr = NULL; 02452 } 02453 02454 ast_string_field_free_memory(chan); 02455 }
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 6717 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().
06720 { 06721 /* Copy voice back and forth between the two channels. */ 06722 struct ast_channel *cs[3]; 06723 struct ast_frame *f; 06724 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 06725 format_t o0nativeformats; 06726 format_t o1nativeformats; 06727 int watch_c0_dtmf; 06728 int watch_c1_dtmf; 06729 void *pvt0, *pvt1; 06730 /* Indicates whether a frame was queued into a jitterbuffer */ 06731 int frame_put_in_jb = 0; 06732 int jb_in_use; 06733 int to; 06734 06735 cs[0] = c0; 06736 cs[1] = c1; 06737 pvt0 = c0->tech_pvt; 06738 pvt1 = c1->tech_pvt; 06739 o0nativeformats = c0->nativeformats; 06740 o1nativeformats = c1->nativeformats; 06741 watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0; 06742 watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1; 06743 06744 /* Check the need of a jitterbuffer for each channel */ 06745 jb_in_use = ast_jb_do_usecheck(c0, c1); 06746 if (jb_in_use) 06747 ast_jb_empty_and_reset(c0, c1); 06748 06749 ast_poll_channel_add(c0, c1); 06750 06751 if (config->feature_timer > 0 && ast_tvzero(config->nexteventts)) { 06752 /* nexteventts is not set when the bridge is not scheduled to 06753 * break, so calculate when the bridge should possibly break 06754 * if a partial feature match timed out */ 06755 config->nexteventts = ast_tvadd(ast_tvnow(), ast_samp2tv(config->feature_timer, 1000)); 06756 } 06757 06758 for (;;) { 06759 struct ast_channel *who, *other; 06760 06761 if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) || 06762 (o0nativeformats != c0->nativeformats) || 06763 (o1nativeformats != c1->nativeformats)) { 06764 /* Check for Masquerade, codec changes, etc */ 06765 res = AST_BRIDGE_RETRY; 06766 break; 06767 } 06768 if (config->nexteventts.tv_sec) { 06769 to = ast_tvdiff_ms(config->nexteventts, ast_tvnow()); 06770 if (to <= 0) { 06771 if (config->timelimit && !config->feature_timer && !ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) { 06772 res = AST_BRIDGE_RETRY; 06773 /* generic bridge ending to play warning */ 06774 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE); 06775 } else if (config->feature_timer) { 06776 /* feature timer expired - make sure we do not play warning */ 06777 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE); 06778 res = AST_BRIDGE_RETRY; 06779 } else { 06780 res = AST_BRIDGE_COMPLETE; 06781 } 06782 break; 06783 } 06784 } else { 06785 /* If a feature has been started and the bridge is configured to 06786 * to not break, leave the channel bridge when the feature timer 06787 * time has elapsed so the DTMF will be sent to the other side. 06788 */ 06789 if (!ast_tvzero(config->nexteventts)) { 06790 int diff = ast_tvdiff_ms(config->nexteventts, ast_tvnow()); 06791 if (diff <= 0) { 06792 res = AST_BRIDGE_RETRY; 06793 break; 06794 } 06795 } 06796 to = -1; 06797 } 06798 /* Calculate the appropriate max sleep interval - in general, this is the time, 06799 left to the closest jb delivery moment */ 06800 if (jb_in_use) 06801 to = ast_jb_get_when_to_wakeup(c0, c1, to); 06802 who = ast_waitfor_n(cs, 2, &to); 06803 if (!who) { 06804 /* No frame received within the specified timeout - check if we have to deliver now */ 06805 if (jb_in_use) 06806 ast_jb_get_and_deliver(c0, c1); 06807 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 06808 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 06809 c0->_softhangup &= ~AST_SOFTHANGUP_UNBRIDGE; 06810 } 06811 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 06812 c1->_softhangup &= ~AST_SOFTHANGUP_UNBRIDGE; 06813 } 06814 c0->_bridge = c1; 06815 c1->_bridge = c0; 06816 } 06817 continue; 06818 } 06819 f = ast_read(who); 06820 if (!f) { 06821 *fo = NULL; 06822 *rc = who; 06823 ast_debug(1, "Didn't get a frame from channel: %s\n",who->name); 06824 break; 06825 } 06826 06827 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 06828 /* Try add the frame info the who's bridged channel jitterbuff */ 06829 if (jb_in_use) 06830 frame_put_in_jb = !ast_jb_put(other, f); 06831 06832 if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) { 06833 int bridge_exit = 0; 06834 06835 switch (f->subclass.integer) { 06836 case AST_CONTROL_AOC: 06837 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen); 06838 break; 06839 case AST_CONTROL_REDIRECTING: 06840 if (ast_channel_redirecting_macro(who, other, f, other == c0, 1)) { 06841 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen); 06842 } 06843 break; 06844 case AST_CONTROL_CONNECTED_LINE: 06845 if (ast_channel_connected_line_macro(who, other, f, other == c0, 1)) { 06846 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen); 06847 } 06848 break; 06849 case AST_CONTROL_HOLD: 06850 case AST_CONTROL_UNHOLD: 06851 case AST_CONTROL_VIDUPDATE: 06852 case AST_CONTROL_SRCUPDATE: 06853 case AST_CONTROL_SRCCHANGE: 06854 case AST_CONTROL_T38_PARAMETERS: 06855 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen); 06856 if (jb_in_use) { 06857 ast_jb_empty_and_reset(c0, c1); 06858 } 06859 break; 06860 default: 06861 *fo = f; 06862 *rc = who; 06863 bridge_exit = 1; 06864 ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass.integer, who->name); 06865 break; 06866 } 06867 if (bridge_exit) 06868 break; 06869 } 06870 if ((f->frametype == AST_FRAME_VOICE) || 06871 (f->frametype == AST_FRAME_DTMF_BEGIN) || 06872 (f->frametype == AST_FRAME_DTMF) || 06873 (f->frametype == AST_FRAME_VIDEO) || 06874 (f->frametype == AST_FRAME_IMAGE) || 06875 (f->frametype == AST_FRAME_HTML) || 06876 (f->frametype == AST_FRAME_MODEM) || 06877 (f->frametype == AST_FRAME_TEXT)) { 06878 /* monitored dtmf causes exit from bridge */ 06879 int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf; 06880 06881 if (monitored_source && 06882 (f->frametype == AST_FRAME_DTMF_END || 06883 f->frametype == AST_FRAME_DTMF_BEGIN)) { 06884 *fo = f; 06885 *rc = who; 06886 ast_debug(1, "Got DTMF %s on channel (%s)\n", 06887 f->frametype == AST_FRAME_DTMF_END ? "end" : "begin", 06888 who->name); 06889 06890 break; 06891 } 06892 /* Write immediately frames, not passed through jb */ 06893 if (!frame_put_in_jb) 06894 ast_write(other, f); 06895 06896 /* Check if we have to deliver now */ 06897 if (jb_in_use) 06898 ast_jb_get_and_deliver(c0, c1); 06899 } 06900 /* XXX do we want to pass on also frames not matched above ? */ 06901 ast_frfree(f); 06902 06903 #ifndef HAVE_EPOLL 06904 /* Swap who gets priority */ 06905 cs[2] = cs[0]; 06906 cs[0] = cs[1]; 06907 cs[1] = cs[2]; 06908 #endif 06909 } 06910 06911 ast_poll_channel_del(c0, c1); 06912 06913 return res; 06914 }
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 890 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().
00891 { 00892 struct chanlist *chanls; 00893 const struct ast_channel_tech *ret = NULL; 00894 00895 AST_RWLIST_RDLOCK(&backends); 00896 00897 AST_RWLIST_TRAVERSE(&backends, chanls, list) { 00898 if (!strcasecmp(name, chanls->tech->type)) { 00899 ret = chanls->tech; 00900 break; 00901 } 00902 } 00903 00904 AST_RWLIST_UNLOCK(&backends); 00905 00906 return ret; 00907 }
ast_group_t ast_get_group | ( | const char * | s | ) |
Definition at line 7464 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().
07465 { 07466 char *piece; 07467 char *c; 07468 int start=0, finish=0, x; 07469 ast_group_t group = 0; 07470 07471 if (ast_strlen_zero(s)) 07472 return 0; 07473 07474 c = ast_strdupa(s); 07475 07476 while ((piece = strsep(&c, ","))) { 07477 if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) { 07478 /* Range */ 07479 } else if (sscanf(piece, "%30d", &start)) { 07480 /* Just one */ 07481 finish = start; 07482 } else { 07483 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece); 07484 continue; 07485 } 07486 for (x = start; x <= finish; x++) { 07487 if ((x > 63) || (x < 0)) { 07488 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x); 07489 } else 07490 group |= ((ast_group_t) 1 << x); 07491 } 07492 } 07493 return group; 07494 }
int ast_hangup | ( | struct ast_channel * | chan | ) |
Hang up a channel.
chan | channel to hang up |
Definition at line 2658 of file channel.c.
References ao2_unlink, ast_assert, ast_audiohook_detach_list(), 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_release(), ast_channel_unlock, ast_closestream(), ast_debug, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_framehook_list_destroy(), ast_log(), ast_manager_event, ast_set_flag, ast_test_flag, ast_channel::audiohooks, ast_channel::blocker, ast_channel::blockproc, ast_channel::caller, ast_channel::cdr, chanlist::chan, channels, 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_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_channel_thread(), bridge_exec(), build_conf(), builtin_atxfer(), chanavail_exec(), check_compat(), check_goto_on_transfer(), clear_caller(), conf_run(), connect_link(), 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_parkinglot(), mgcp_new(), mgcp_ss(), monitor_dial(), mwi_thread(), my_distinctive_ring(), my_handle_notify_message(), nbs_new(), oss_new(), park_exec_full(), parkandannounce_exec(), phone_new(), play_sound_file(), pri_dchannel(), pri_ss_thread(), rpt(), rpt_call(), rpt_tele_thread(), sip_new(), sip_park(), sip_park_thread(), skinny_new(), skinny_ss(), ss7_start_call(), unistim_new(), usbradio_new(), and wait_for_winner().
02659 { 02660 int res = 0; 02661 char extra_str[64]; /* used for cel logging below */ 02662 02663 /* Don't actually hang up a channel that will masquerade as someone else, or 02664 if someone is going to masquerade as us */ 02665 ast_channel_lock(chan); 02666 02667 if (chan->audiohooks) { 02668 ast_audiohook_detach_list(chan->audiohooks); 02669 chan->audiohooks = NULL; 02670 } 02671 02672 ast_framehook_list_destroy(chan); 02673 02674 ast_autoservice_stop(chan); 02675 02676 if (chan->masq) { 02677 ast_channel_unlock(chan); 02678 if (ast_do_masquerade(chan)) { 02679 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 02680 } 02681 ast_channel_lock(chan); 02682 } 02683 02684 if (chan->masq) { 02685 ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name); 02686 ast_channel_unlock(chan); 02687 return 0; 02688 } 02689 /* If this channel is one which will be masqueraded into something, 02690 mark it as a zombie already, so we know to free it later */ 02691 if (chan->masqr) { 02692 ast_set_flag(chan, AST_FLAG_ZOMBIE); 02693 ast_channel_unlock(chan); 02694 return 0; 02695 } 02696 ast_channel_unlock(chan); 02697 02698 ao2_unlink(channels, chan); 02699 02700 ast_channel_lock(chan); 02701 free_translation(chan); 02702 /* Close audio stream */ 02703 if (chan->stream) { 02704 ast_closestream(chan->stream); 02705 chan->stream = NULL; 02706 } 02707 /* Close video stream */ 02708 if (chan->vstream) { 02709 ast_closestream(chan->vstream); 02710 chan->vstream = NULL; 02711 } 02712 if (chan->sched) { 02713 sched_context_destroy(chan->sched); 02714 chan->sched = NULL; 02715 } 02716 02717 if (chan->generatordata) /* Clear any tone stuff remaining */ 02718 if (chan->generator && chan->generator->release) 02719 chan->generator->release(chan, chan->generatordata); 02720 chan->generatordata = NULL; 02721 chan->generator = NULL; 02722 02723 snprintf(extra_str, sizeof(extra_str), "%d,%s,%s", chan->hangupcause, chan->hangupsource, S_OR(pbx_builtin_getvar_helper(chan, "DIALSTATUS"), "")); 02724 ast_cel_report_event(chan, AST_CEL_HANGUP, NULL, extra_str, NULL); 02725 02726 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 02727 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 02728 "is blocked by thread %ld in procedure %s! Expect a failure\n", 02729 (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 02730 ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0); 02731 } 02732 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) { 02733 ast_debug(1, "Hanging up channel '%s'\n", chan->name); 02734 if (chan->tech->hangup) 02735 res = chan->tech->hangup(chan); 02736 } else { 02737 ast_debug(1, "Hanging up zombie '%s'\n", chan->name); 02738 } 02739 02740 ast_channel_unlock(chan); 02741 ast_cc_offer(chan); 02742 ast_manager_event(chan, EVENT_FLAG_CALL, "Hangup", 02743 "Channel: %s\r\n" 02744 "Uniqueid: %s\r\n" 02745 "CallerIDNum: %s\r\n" 02746 "CallerIDName: %s\r\n" 02747 "Cause: %d\r\n" 02748 "Cause-txt: %s\r\n", 02749 chan->name, 02750 chan->uniqueid, 02751 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<unknown>"), 02752 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"), 02753 chan->hangupcause, 02754 ast_cause2str(chan->hangupcause) 02755 ); 02756 02757 if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) && 02758 !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) && 02759 (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) { 02760 ast_channel_lock(chan); 02761 02762 ast_cdr_end(chan->cdr); 02763 ast_cdr_detach(chan->cdr); 02764 chan->cdr = NULL; 02765 ast_channel_unlock(chan); 02766 } 02767 02768 chan = ast_channel_release(chan); 02769 02770 return res; 02771 }
int ast_indicate | ( | struct ast_channel * | chan, | |
int | condition | |||
) |
Indicates condition of channel.
chan | channel to change the indication | |
condition | which condition to indicate on the channel |
Definition at line 4159 of file channel.c.
References ast_indicate_data(), and chanlist::chan.
Referenced by __ast_play_and_record(), agent_new(), 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(), function_remote(), handle_callforward_button(), handle_frame(), handle_recordfile(), handle_request_refer(), local_attended_transfer(), manage_parkinglot(), mgcp_ss(), monitor_dial(), oss_call(), park_call_full(), park_exec_full(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_proceeding(), pbx_builtin_progress(), pbx_builtin_ringing(), pbx_builtin_waitexten(), queue_exec(), rna(), rpt(), rpt_exec(), say_periodic_announcement(), say_position(), send_waveform_to_channel(), skinny_ss(), sla_handle_hold_event(), sla_station_exec(), and sla_trunk_exec().
04160 { 04161 return ast_indicate_data(chan, condition, NULL, 0); 04162 }
int ast_indicate_data | ( | struct ast_channel * | chan, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) |
Indicates condition of channel, with payload.
chan | channel to change the indication | |
condition | which condition to indicate on the channel | |
data | pointer to payload data | |
datalen | size of payload data |
Definition at line 4211 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_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_VIDUPDATE, AST_CONTROL_WINK, ast_debug, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, ast_framehook_list_is_empty(), ast_framehook_list_read_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_parkinglot(), 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().
04213 { 04214 /* By using an enum, we'll get compiler warnings for values not handled 04215 * in switch statements. */ 04216 enum ast_control_frame_type condition = _condition; 04217 struct ast_tone_zone_sound *ts = NULL; 04218 int res; 04219 /* this frame is used by framehooks. if it is set, we must free it at the end of this function */ 04220 struct ast_frame *awesome_frame = NULL; 04221 04222 ast_channel_lock(chan); 04223 04224 /* Don't bother if the channel is about to go away, anyway. */ 04225 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 04226 res = -1; 04227 goto indicate_cleanup; 04228 } 04229 04230 if (!ast_framehook_list_is_empty(chan->framehooks)) { 04231 /* Do framehooks now, do it, go, go now */ 04232 struct ast_frame frame = { 04233 .frametype = AST_FRAME_CONTROL, 04234 .subclass.integer = condition, 04235 .data.ptr = (void *) data, /* this cast from const is only okay because we do the ast_frdup below */ 04236 .datalen = datalen 04237 }; 04238 04239 /* we have now committed to freeing this frame */ 04240 awesome_frame = ast_frdup(&frame); 04241 04242 /* who knows what we will get back! the anticipation is killing me. */ 04243 if (!(awesome_frame = ast_framehook_list_read_event(chan->framehooks, &frame))) { 04244 res = 0; 04245 goto indicate_cleanup; 04246 } 04247 04248 condition = awesome_frame->subclass.integer; 04249 data = awesome_frame->data.ptr; 04250 datalen = awesome_frame->datalen; 04251 } 04252 04253 switch (condition) { 04254 case AST_CONTROL_CONNECTED_LINE: 04255 { 04256 struct ast_party_connected_line connected; 04257 04258 ast_party_connected_line_set_init(&connected, &chan->connected); 04259 res = ast_connected_line_parse_data(data, datalen, &connected); 04260 if (!res) { 04261 ast_channel_set_connected_line(chan, &connected, NULL); 04262 } 04263 ast_party_connected_line_free(&connected); 04264 } 04265 break; 04266 04267 case AST_CONTROL_REDIRECTING: 04268 { 04269 struct ast_party_redirecting redirecting; 04270 04271 ast_party_redirecting_set_init(&redirecting, &chan->redirecting); 04272 res = ast_redirecting_parse_data(data, datalen, &redirecting); 04273 if (!res) { 04274 ast_channel_set_redirecting(chan, &redirecting, NULL); 04275 } 04276 ast_party_redirecting_free(&redirecting); 04277 } 04278 break; 04279 04280 default: 04281 break; 04282 } 04283 04284 if (is_visible_indication(condition)) { 04285 /* A new visible indication is requested. */ 04286 chan->visible_indication = condition; 04287 } else if (condition == AST_CONTROL_UNHOLD || _condition < 0) { 04288 /* Visible indication is cleared/stopped. */ 04289 chan->visible_indication = 0; 04290 } 04291 04292 if (chan->tech->indicate) { 04293 /* See if the channel driver can handle this condition. */ 04294 res = chan->tech->indicate(chan, condition, data, datalen); 04295 } else { 04296 res = -1; 04297 } 04298 04299 if (!res) { 04300 /* The channel driver successfully handled this indication */ 04301 res = 0; 04302 goto indicate_cleanup; 04303 } 04304 04305 /* The channel driver does not support this indication, let's fake 04306 * it by doing our own tone generation if applicable. */ 04307 04308 /*!\note If we compare the enumeration type, which does not have any 04309 * negative constants, the compiler may optimize this code away. 04310 * Therefore, we must perform an integer comparison here. */ 04311 if (_condition < 0) { 04312 /* Stop any tones that are playing */ 04313 ast_playtones_stop(chan); 04314 res = 0; 04315 goto indicate_cleanup; 04316 } 04317 04318 /* Handle conditions that we have tones for. */ 04319 switch (condition) { 04320 case _XXX_AST_CONTROL_T38: 04321 /* deprecated T.38 control frame */ 04322 res = -1; 04323 goto indicate_cleanup; 04324 case AST_CONTROL_T38_PARAMETERS: 04325 /* there is no way to provide 'default' behavior for these 04326 * control frames, so we need to return failure, but there 04327 * is also no value in the log message below being emitted 04328 * since failure to handle these frames is not an 'error' 04329 * so just return right now. in addition, we want to return 04330 * whatever value the channel driver returned, in case it 04331 * has some meaning.*/ 04332 goto indicate_cleanup; 04333 case AST_CONTROL_RINGING: 04334 ts = ast_get_indication_tone(chan->zone, "ring"); 04335 /* It is common practice for channel drivers to return -1 if trying 04336 * to indicate ringing on a channel which is up. The idea is to let the 04337 * core generate the ringing inband. However, we don't want the 04338 * warning message about not being able to handle the specific indication 04339 * to print nor do we want ast_indicate_data to return an "error" for this 04340 * condition 04341 */ 04342 if (chan->_state == AST_STATE_UP) { 04343 res = 0; 04344 } 04345 break; 04346 case AST_CONTROL_BUSY: 04347 ts = ast_get_indication_tone(chan->zone, "busy"); 04348 break; 04349 case AST_CONTROL_CONGESTION: 04350 ts = ast_get_indication_tone(chan->zone, "congestion"); 04351 break; 04352 case AST_CONTROL_PROGRESS: 04353 case AST_CONTROL_PROCEEDING: 04354 case AST_CONTROL_VIDUPDATE: 04355 case AST_CONTROL_SRCUPDATE: 04356 case AST_CONTROL_SRCCHANGE: 04357 case AST_CONTROL_RADIO_KEY: 04358 case AST_CONTROL_RADIO_UNKEY: 04359 case AST_CONTROL_OPTION: 04360 case AST_CONTROL_WINK: 04361 case AST_CONTROL_FLASH: 04362 case AST_CONTROL_OFFHOOK: 04363 case AST_CONTROL_TAKEOFFHOOK: 04364 case AST_CONTROL_ANSWER: 04365 case AST_CONTROL_HANGUP: 04366 case AST_CONTROL_RING: 04367 case AST_CONTROL_HOLD: 04368 case AST_CONTROL_UNHOLD: 04369 case AST_CONTROL_TRANSFER: 04370 case AST_CONTROL_CONNECTED_LINE: 04371 case AST_CONTROL_REDIRECTING: 04372 case AST_CONTROL_CC: 04373 case AST_CONTROL_READ_ACTION: 04374 case AST_CONTROL_AOC: 04375 case AST_CONTROL_END_OF_Q: 04376 /* Nothing left to do for these. */ 04377 res = 0; 04378 break; 04379 } 04380 04381 if (ts) { 04382 /* We have a tone to play, yay. */ 04383 ast_debug(1, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition); 04384 res = ast_playtones_start(chan, 0, ts->data, 1); 04385 ts = ast_tone_zone_sound_unref(ts); 04386 } 04387 04388 if (res) { 04389 /* not handled */ 04390 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); 04391 } 04392 04393 indicate_cleanup: 04394 ast_channel_unlock(chan); 04395 if (awesome_frame) { 04396 ast_frfree(awesome_frame); 04397 } 04398 04399 return res; 04400 }
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 7500 of file channel.c.
References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.
Referenced by load_module().
07503 { 07504 ast_moh_start_ptr = start_ptr; 07505 ast_moh_stop_ptr = stop_ptr; 07506 ast_moh_cleanup_ptr = cleanup_ptr; 07507 }
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 4144 of file channel.c.
References ast_opt_internal_timing, chanlist::chan, and ast_channel::timingfd.
Referenced by add_sdp(), and ast_read_generator_actions().
04145 { 04146 return (ast_opt_internal_timing && chan->timingfd > -1); 04147 }
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 1728 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().
01729 { 01730 /* Do not add a default entry in this switch statement. Each new 01731 * frame type should be addressed directly as to whether it should 01732 * be queued up or not. 01733 */ 01734 switch (frame->frametype) { 01735 case AST_FRAME_CONTROL: 01736 case AST_FRAME_TEXT: 01737 case AST_FRAME_IMAGE: 01738 case AST_FRAME_HTML: 01739 return 1; 01740 01741 case AST_FRAME_DTMF_END: 01742 case AST_FRAME_DTMF_BEGIN: 01743 case AST_FRAME_VOICE: 01744 case AST_FRAME_VIDEO: 01745 case AST_FRAME_NULL: 01746 case AST_FRAME_IAX: 01747 case AST_FRAME_CNG: 01748 case AST_FRAME_MODEM: 01749 return 0; 01750 } 01751 return 0; 01752 }
void ast_moh_cleanup | ( | struct ast_channel * | chan | ) |
Definition at line 7534 of file channel.c.
References ast_moh_cleanup_ptr.
Referenced by ast_channel_destructor().
07535 { 07536 if (ast_moh_cleanup_ptr) 07537 ast_moh_cleanup_ptr(chan); 07538 }
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 7517 of file channel.c.
References ast_moh_start_ptr, and ast_verb.
Referenced by alsa_indicate(), app_exec(), conf_run(), conf_start_moh(), console_indicate(), dahdi_indicate(), dial_exec_full(), feature_exec_app(), gtalk_indicate(), handle_setmusic(), iax2_indicate(), jingle_indicate(), key_call(), 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(), sig_ss7_indicate(), sip_indicate(), skinny_indicate(), start_moh_exec(), TransferCallStep1(), unistim_indicate(), usbradio_indicate(), and wait_moh_exec().
07518 { 07519 if (ast_moh_start_ptr) 07520 return ast_moh_start_ptr(chan, mclass, interpclass); 07521 07522 ast_verb(3, "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : (interpclass ? interpclass : "default")); 07523 07524 return 0; 07525 }
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 7528 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(), sig_ss7_indicate(), sip_indicate(), skinny_indicate(), stop_moh_exec(), unistim_hangup(), unistim_indicate(), usbradio_indicate(), and wait_moh_exec().
07529 { 07530 if (ast_moh_stop_ptr) 07531 ast_moh_stop_ptr(chan); 07532 }
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 2179 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_copy(), and ast_party_caller::id.
Referenced by ast_call_forward(), and do_forward().
02180 { 02181 if (dest == src) { 02182 /* Don't copy to self */ 02183 return; 02184 } 02185 02186 ast_party_id_copy(&dest->id, &src->id); 02187 ast_party_id_copy(&dest->ani, &src->ani); 02188 dest->ani2 = src->ani2; 02189 }
void ast_party_caller_free | ( | struct ast_party_caller * | doomed | ) |
Destroy the caller party contents.
doomed | The caller party to destroy. |
Definition at line 2205 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().
02206 { 02207 ast_party_id_free(&doomed->id); 02208 ast_party_id_free(&doomed->ani); 02209 }
void ast_party_caller_init | ( | struct ast_party_caller * | init | ) |
Initialize the given caller structure.
init | Caller structure to initialize. |
Definition at line 2172 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(), sig_ss7_set_caller_id(), and sla_ring_station().
02173 { 02174 ast_party_id_init(&init->id); 02175 ast_party_id_init(&init->ani); 02176 init->ani2 = 0; 02177 }
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 2198 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().
02199 { 02200 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL); 02201 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL); 02202 dest->ani2 = src->ani2; 02203 }
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 2191 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(), misdn_update_caller_id(), ring_entry(), and sig_pri_handle_subcmds().
02192 { 02193 ast_party_id_set_init(&init->id, &guide->id); 02194 ast_party_id_set_init(&init->ani, &guide->ani); 02195 init->ani2 = guide->ani2; 02196 }
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 2248 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.
Referenced by ast_pickup_call().
02249 { 02250 connected->id = caller->id; 02251 connected->ani = caller->ani; 02252 connected->ani2 = caller->ani2; 02253 connected->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN; 02254 }
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 2219 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(), builtin_atxfer(), dial_exec_full(), do_forward(), local_attended_transfer(), misdn_attempt_transfer(), party_connected_line_copy_transfer(), and pickup_do().
02220 { 02221 if (dest == src) { 02222 /* Don't copy to self */ 02223 return; 02224 } 02225 02226 ast_party_id_copy(&dest->id, &src->id); 02227 ast_party_id_copy(&dest->ani, &src->ani); 02228 dest->ani2 = src->ani2; 02229 dest->source = src->source; 02230 }
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 2256 of file channel.c.
References ast_party_connected_line::ani, ast_party_id_free(), and ast_party_connected_line::id.
Referenced by __ast_read(), ast_channel_destructor(), ast_dummy_channel_destructor(), ast_indicate_data(), atxfer_fail_cleanup(), builtin_atxfer(), callattempt_free(), chanlist_free(), connectedline_write(), feature_request_and_dial(), local_attended_transfer(), misdn_attempt_transfer(), pickup_do(), sig_pri_handle_subcmds(), socket_process(), wait_for_answer(), and xfer_ds_destroy().
02257 { 02258 ast_party_id_free(&doomed->id); 02259 ast_party_id_free(&doomed->ani); 02260 }
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 2211 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(), builtin_atxfer(), handle_request_invite(), handle_request_update(), handle_response_invite(), local_attended_transfer(), misdn_attempt_transfer(), misdn_queue_connected_line_update(), pickup_do(), sig_pri_handle_subcmds(), socket_process(), and wait_for_answer().
02212 { 02213 ast_party_id_init(&init->id); 02214 ast_party_id_init(&init->ani); 02215 init->ani2 = 0; 02216 init->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN; 02217 }
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 2240 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().
02241 { 02242 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL); 02243 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL); 02244 dest->ani2 = src->ani2; 02245 dest->source = src->source; 02246 }
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 2232 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(), and feature_request_and_dial().
02233 { 02234 ast_party_id_set_init(&init->id, &guide->id); 02235 ast_party_id_set_init(&init->ani, &guide->ani); 02236 init->ani2 = guide->ani2; 02237 init->source = guide->source; 02238 }
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 2130 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().
02131 { 02132 if (dest == src) { 02133 /* Don't copy to self */ 02134 return; 02135 } 02136 02137 ast_free(dest->number.str); 02138 dest->number.str = ast_strdup(src->number.str); 02139 dest->number.plan = src->number.plan; 02140 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress); 02141 dest->transit_network_select = src->transit_network_select; 02142 }
void ast_party_dialed_free | ( | struct ast_party_dialed * | doomed | ) |
Destroy the dialed party contents.
doomed | The dialed party to destroy. |
Definition at line 2165 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().
02166 { 02167 ast_free(doomed->number.str); 02168 doomed->number.str = NULL; 02169 ast_party_subaddress_free(&doomed->subaddress); 02170 }
void ast_party_dialed_init | ( | struct ast_party_dialed * | init | ) |
Initialize the given dialed structure.
init | Dialed structure to initialize. |
Definition at line 2122 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().
02123 { 02124 init->number.str = NULL; 02125 init->number.plan = 0;/* Unknown */ 02126 ast_party_subaddress_init(&init->subaddress); 02127 init->transit_network_select = 0; 02128 }
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 2152 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().
02153 { 02154 if (src->number.str && src->number.str != dest->number.str) { 02155 ast_free(dest->number.str); 02156 dest->number.str = ast_strdup(src->number.str); 02157 } 02158 dest->number.plan = src->number.plan; 02159 02160 ast_party_subaddress_set(&dest->subaddress, &src->subaddress); 02161 02162 dest->transit_network_select = src->transit_network_select; 02163 }
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 2144 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().
02145 { 02146 init->number.str = NULL; 02147 init->number.plan = guide->number.plan; 02148 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress); 02149 init->transit_network_select = guide->transit_network_select; 02150 }
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 2001 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(), and ast_party_redirecting_copy().
02002 { 02003 if (dest == src) { 02004 /* Don't copy to self */ 02005 return; 02006 } 02007 02008 ast_party_name_copy(&dest->name, &src->name); 02009 ast_party_number_copy(&dest->number, &src->number); 02010 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress); 02011 02012 ast_free(dest->tag); 02013 dest->tag = ast_strdup(src->tag); 02014 }
void ast_party_id_free | ( | struct ast_party_id * | doomed | ) |
Destroy the party id contents.
doomed | The party id to destroy. |
Definition at line 2047 of file channel.c.
References ast_free, ast_party_name_free(), ast_party_number_free(), ast_party_subaddress_free(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_free(), ast_party_connected_line_free(), ast_party_redirecting_free(), and do_forward().
02048 { 02049 ast_party_name_free(&doomed->name); 02050 ast_party_number_free(&doomed->number); 02051 ast_party_subaddress_free(&doomed->subaddress); 02052 02053 ast_free(doomed->tag); 02054 doomed->tag = NULL; 02055 }
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 1993 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(), and do_forward().
01994 { 01995 ast_party_name_init(&init->name); 01996 ast_party_number_init(&init->number); 01997 ast_party_subaddress_init(&init->subaddress); 01998 init->tag = NULL; 01999 }
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 2057 of file channel.c.
References AST_PRES_ALLOWED, AST_PRES_NUMBER_TYPE, AST_PRES_RESTRICTED, AST_PRES_RESTRICTION, AST_PRES_UNAVAILABLE, AST_PRES_USER_NUMBER_UNSCREENED, 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_handle_subcmds(), sip_call(), and socket_process().
02058 { 02059 int number_priority; 02060 int number_value; 02061 int number_screening; 02062 int name_priority; 02063 int name_value; 02064 02065 /* Determine name presentation priority. */ 02066 if (!id->name.valid) { 02067 name_value = AST_PRES_UNAVAILABLE; 02068 name_priority = 3; 02069 } else { 02070 name_value = id->name.presentation & AST_PRES_RESTRICTION; 02071 switch (name_value) { 02072 case AST_PRES_RESTRICTED: 02073 name_priority = 0; 02074 break; 02075 case AST_PRES_ALLOWED: 02076 name_priority = 1; 02077 break; 02078 case AST_PRES_UNAVAILABLE: 02079 name_priority = 2; 02080 break; 02081 default: 02082 name_value = AST_PRES_UNAVAILABLE; 02083 name_priority = 3; 02084 break; 02085 } 02086 } 02087 02088 /* Determine number presentation priority. */ 02089 if (!id->number.valid) { 02090 number_screening = AST_PRES_USER_NUMBER_UNSCREENED; 02091 number_value = AST_PRES_UNAVAILABLE; 02092 number_priority = 3; 02093 } else { 02094 number_screening = id->number.presentation & AST_PRES_NUMBER_TYPE; 02095 number_value = id->number.presentation & AST_PRES_RESTRICTION; 02096 switch (number_value) { 02097 case AST_PRES_RESTRICTED: 02098 number_priority = 0; 02099 break; 02100 case AST_PRES_ALLOWED: 02101 number_priority = 1; 02102 break; 02103 case AST_PRES_UNAVAILABLE: 02104 number_priority = 2; 02105 break; 02106 default: 02107 number_screening = AST_PRES_USER_NUMBER_UNSCREENED; 02108 number_value = AST_PRES_UNAVAILABLE; 02109 number_priority = 3; 02110 break; 02111 } 02112 } 02113 02114 /* Select the wining presentation value. */ 02115 if (name_priority < number_priority) { 02116 number_value = name_value; 02117 } 02118 02119 return number_value | number_screening; 02120 }
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 2024 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().
02025 { 02026 if (dest == src) { 02027 /* Don't set to self */ 02028 return; 02029 } 02030 02031 if (!update || update->name) { 02032 ast_party_name_set(&dest->name, &src->name); 02033 } 02034 if (!update || update->number) { 02035 ast_party_number_set(&dest->number, &src->number); 02036 } 02037 if (!update || update->subaddress) { 02038 ast_party_subaddress_set(&dest->subaddress, &src->subaddress); 02039 } 02040 02041 if (src->tag && src->tag != dest->tag) { 02042 ast_free(dest->tag); 02043 dest->tag = ast_strdup(src->tag); 02044 } 02045 }
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 2016 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(), and ast_party_redirecting_set_init().
02017 { 02018 ast_party_name_set_init(&init->name, &guide->name); 02019 ast_party_number_set_init(&init->number, &guide->number); 02020 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress); 02021 init->tag = NULL; 02022 }
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 1842 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().
01843 { 01844 if (dest == src) { 01845 /* Don't copy to self */ 01846 return; 01847 } 01848 01849 ast_free(dest->str); 01850 dest->str = ast_strdup(src->str); 01851 dest->char_set = src->char_set; 01852 dest->presentation = src->presentation; 01853 dest->valid = src->valid; 01854 }
void ast_party_name_free | ( | struct ast_party_name * | doomed | ) |
Destroy the party name contents.
doomed | The party name to destroy. |
Definition at line 1881 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 1834 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().
01835 { 01836 init->str = NULL; 01837 init->char_set = AST_PARTY_CHAR_SET_ISO8859_1; 01838 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 01839 init->valid = 0; 01840 }
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 1864 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().
01865 { 01866 if (dest == src) { 01867 /* Don't set to self */ 01868 return; 01869 } 01870 01871 if (src->str && src->str != dest->str) { 01872 ast_free(dest->str); 01873 dest->str = ast_strdup(src->str); 01874 } 01875 01876 dest->char_set = src->char_set; 01877 dest->presentation = src->presentation; 01878 dest->valid = src->valid; 01879 }
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 1856 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().
01857 { 01858 init->str = NULL; 01859 init->char_set = guide->char_set; 01860 init->presentation = guide->presentation; 01861 init->valid = guide->valid; 01862 }
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 1895 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().
01896 { 01897 if (dest == src) { 01898 /* Don't copy to self */ 01899 return; 01900 } 01901 01902 ast_free(dest->str); 01903 dest->str = ast_strdup(src->str); 01904 dest->plan = src->plan; 01905 dest->presentation = src->presentation; 01906 dest->valid = src->valid; 01907 }
void ast_party_number_free | ( | struct ast_party_number * | doomed | ) |
Destroy the party number contents.
doomed | The party number to destroy. |
Definition at line 1934 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 1887 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().
01888 { 01889 init->str = NULL; 01890 init->plan = 0;/* Unknown */ 01891 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 01892 init->valid = 0; 01893 }
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 1917 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().
01918 { 01919 if (dest == src) { 01920 /* Don't set to self */ 01921 return; 01922 } 01923 01924 if (src->str && src->str != dest->str) { 01925 ast_free(dest->str); 01926 dest->str = ast_strdup(src->str); 01927 } 01928 01929 dest->plan = src->plan; 01930 dest->presentation = src->presentation; 01931 dest->valid = src->valid; 01932 }
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 1909 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().
01910 { 01911 init->str = NULL; 01912 init->plan = guide->plan; 01913 init->presentation = guide->presentation; 01914 init->valid = guide->valid; 01915 }
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 2270 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_channel_redirecting_macro(), begin_dial_channel(), dial_exec_full(), do_forward(), local_call(), and ring_entry().
02271 { 02272 if (dest == src) { 02273 /* Don't copy to self */ 02274 return; 02275 } 02276 02277 ast_party_id_copy(&dest->from, &src->from); 02278 ast_party_id_copy(&dest->to, &src->to); 02279 dest->count = src->count; 02280 dest->reason = src->reason; 02281 }
void ast_party_redirecting_free | ( | struct ast_party_redirecting * | doomed | ) |
Destroy the redirecting information contents.
doomed | The redirecting information to destroy. |
Definition at line 2299 of file channel.c.
References ast_party_id_free(), ast_party_redirecting::from, and ast_party_redirecting::to.
Referenced by ast_channel_destructor(), ast_dummy_channel_destructor(), ast_indicate_data(), do_forward(), handle_request_invite(), handle_response(), handle_response_invite(), redirecting_write(), and sig_pri_handle_subcmds().
02300 { 02301 ast_party_id_free(&doomed->from); 02302 ast_party_id_free(&doomed->to); 02303 }
void ast_party_redirecting_init | ( | struct ast_party_redirecting * | init | ) |
Initialize the given redirecting structure.
init | Redirecting structure to initialize. |
Definition at line 2262 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(), do_forward(), handle_request_invite(), handle_response(), and handle_response_invite().
02263 { 02264 ast_party_id_init(&init->from); 02265 ast_party_id_init(&init->to); 02266 init->count = 0; 02267 init->reason = AST_REDIRECTING_REASON_UNKNOWN; 02268 }
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 2291 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().
02292 { 02293 ast_party_id_set(&dest->from, &src->from, update ? &update->from : NULL); 02294 ast_party_id_set(&dest->to, &src->to, update ? &update->to : NULL); 02295 dest->reason = src->reason; 02296 dest->count = src->count; 02297 }
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 2283 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().
02284 { 02285 ast_party_id_set_init(&init->from, &guide->from); 02286 ast_party_id_set_init(&init->to, &guide->to); 02287 init->count = guide->count; 02288 init->reason = guide->reason; 02289 }
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 1948 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().
01949 { 01950 if (dest == src) { 01951 /* Don't copy to self */ 01952 return; 01953 } 01954 01955 ast_free(dest->str); 01956 dest->str = ast_strdup(src->str); 01957 dest->type = src->type; 01958 dest->odd_even_indicator = src->odd_even_indicator; 01959 dest->valid = src->valid; 01960 }
void ast_party_subaddress_free | ( | struct ast_party_subaddress * | doomed | ) |
Destroy the party subaddress contents.
doomed | The party subaddress to destroy. |
Definition at line 1987 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 1940 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().
01941 { 01942 init->str = NULL; 01943 init->type = 0; 01944 init->odd_even_indicator = 0; 01945 init->valid = 0; 01946 }
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 1970 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().
01971 { 01972 if (dest == src) { 01973 /* Don't set to self */ 01974 return; 01975 } 01976 01977 if (src->str && src->str != dest->str) { 01978 ast_free(dest->str); 01979 dest->str = ast_strdup(src->str); 01980 } 01981 01982 dest->type = src->type; 01983 dest->odd_even_indicator = src->odd_even_indicator; 01984 dest->valid = src->valid; 01985 }
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 1962 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().
01963 { 01964 init->str = NULL; 01965 init->type = guide->type; 01966 init->odd_even_indicator = guide->odd_even_indicator; 01967 init->valid = guide->valid; 01968 }
int ast_plc_reload | ( | void | ) |
Reload genericplc configuration value from codecs.conf.
Implementation is in main/channel.c
Definition at line 7553 of file channel.c.
References ast_config_load, AST_OPT_FLAG_GENERIC_PLC, ast_options, ast_set2_flag, ast_true(), ast_variable_browse(), config_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, and var.
Referenced by ast_channels_init().
07554 { 07555 struct ast_variable *var; 07556 struct ast_flags config_flags = { 0 }; 07557 struct ast_config *cfg = ast_config_load("codecs.conf", config_flags); 07558 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) 07559 return 0; 07560 for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) { 07561 if (!strcasecmp(var->name, "genericplc")) { 07562 ast_set2_flag(&ast_options, ast_true(var->value), AST_OPT_FLAG_GENERIC_PLC); 07563 } 07564 } 07565 ast_config_destroy(cfg); 07566 return 0; 07567 }
void ast_poll_channel_add | ( | struct ast_channel * | chan0, | |
struct ast_channel * | chan1 | |||
) |
Add a channel to an optimized waitfor
Definition at line 2560 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().
02561 { 02562 #ifdef HAVE_EPOLL 02563 struct epoll_event ev; 02564 int i = 0; 02565 02566 if (chan0->epfd == -1) 02567 return; 02568 02569 /* Iterate through the file descriptors on chan1, adding them to chan0 */ 02570 for (i = 0; i < AST_MAX_FDS; i++) { 02571 if (chan1->fds[i] == -1) 02572 continue; 02573 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 02574 ev.data.ptr = chan1->epfd_data[i]; 02575 epoll_ctl(chan0->epfd, EPOLL_CTL_ADD, chan1->fds[i], &ev); 02576 } 02577 02578 #endif 02579 return; 02580 }
void ast_poll_channel_del | ( | struct ast_channel * | chan0, | |
struct ast_channel * | chan1 | |||
) |
Delete a channel from an optimized waitfor
Definition at line 2583 of file channel.c.
References AST_MAX_FDS, and ast_channel::fds.
Referenced by feature_request_and_dial(), and monitor_dial().
02584 { 02585 #ifdef HAVE_EPOLL 02586 struct epoll_event ev; 02587 int i = 0; 02588 02589 if (chan0->epfd == -1) 02590 return; 02591 02592 for (i = 0; i < AST_MAX_FDS; i++) { 02593 if (chan1->fds[i] == -1) 02594 continue; 02595 epoll_ctl(chan0->epfd, EPOLL_CTL_DEL, chan1->fds[i], &ev); 02596 } 02597 02598 #endif 02599 return; 02600 }
char* ast_print_group | ( | char * | buf, | |
int | buflen, | |||
ast_group_t | group | |||
) |
print call- and pickup groups into buffer
Definition at line 7701 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().
07702 { 07703 unsigned int i; 07704 int first = 1; 07705 char num[3]; 07706 07707 buf[0] = '\0'; 07708 07709 if (!group) /* Return empty string if no group */ 07710 return buf; 07711 07712 for (i = 0; i <= 63; i++) { /* Max group is 63 */ 07713 if (group & ((ast_group_t) 1 << i)) { 07714 if (!first) { 07715 strncat(buf, ", ", buflen - strlen(buf) - 1); 07716 } else { 07717 first = 0; 07718 } 07719 snprintf(num, sizeof(num), "%u", i); 07720 strncat(buf, num, buflen - strlen(buf) - 1); 07721 } 07722 } 07723 return buf; 07724 }
int ast_prod | ( | struct ast_channel * | chan | ) |
Send empty audio to prime a channel driver.
Definition at line 4521 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().
04522 { 04523 struct ast_frame a = { AST_FRAME_VOICE }; 04524 char nothing[128]; 04525 04526 /* Send an empty audio frame to get things moving */ 04527 if (chan->_state != AST_STATE_UP) { 04528 ast_debug(1, "Prodding channel '%s'\n", chan->name); 04529 a.subclass.codec = chan->rawwriteformat; 04530 a.data.ptr = nothing + AST_FRIENDLY_OFFSET; 04531 a.src = "ast_prod"; /* this better match check in ast_write */ 04532 if (ast_write(chan, &a)) 04533 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 04534 } 04535 return 0; 04536 }
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 1511 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_pickup_call(), 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(), pickup_do(), process_sdp(), receive_digit(), remote_hold(), send_cause2ast(), setup_rtp_connection(), sig_pri_handle_subcmds(), skinny_call(), skinny_transfer(), skinny_unhold(), unistim_call(), and update_state().
01512 { 01513 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control }; 01514 return ast_queue_frame(chan, &f); 01515 }
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 1518 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(), sip_sipredirect(), and skinny_hold().
01520 { 01521 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control, .data.ptr = (void *) data, .datalen = datalen }; 01522 return ast_queue_frame(chan, &f); 01523 }
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 1468 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_new(), 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(), rpt_call(), sig_pri_handle_hold(), sig_ss7_queue_frame(), stream_monitor(), unistim_do_senddigit(), unistim_senddigit_end(), usbradio_read(), and wakeup_sub().
01469 { 01470 return __ast_queue_frame(chan, fin, 0, NULL); 01471 }
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 1473 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().
01474 { 01475 return __ast_queue_frame(chan, fin, 1, NULL); 01476 }
int ast_queue_hangup | ( | struct ast_channel * | chan | ) |
Queue a hangup frame.
Definition at line 1479 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_request_cancel(), handle_soft_key_event_message(), iax2_destroy(), iax2_queue_hangup(), jingle_hangup_farend(), local_fixup(), local_hangup(), and mgcp_queue_hangup().
01480 { 01481 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP }; 01482 /* Yeah, let's not change a lock-critical value without locking */ 01483 if (!ast_channel_trylock(chan)) { 01484 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01485 ast_channel_unlock(chan); 01486 } 01487 return ast_queue_frame(chan, &f); 01488 }
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 1491 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(), handle_response_notify(), HandleCallOutgoing(), hangup_chan(), hangup_connection(), misdn_answer(), retrans_pkt(), and TransferCallStep1().
01492 { 01493 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP }; 01494 01495 if (cause >= 0) 01496 f.data.uint32 = cause; 01497 01498 /* Yeah, let's not change a lock-critical value without locking */ 01499 if (!ast_channel_trylock(chan)) { 01500 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01501 if (cause < 0) 01502 f.data.uint32 = chan->hangupcause; 01503 01504 ast_channel_unlock(chan); 01505 } 01506 01507 return ast_queue_frame(chan, &f); 01508 }
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 2773 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().
02774 { 02775 int res = 0; 02776 02777 ast_channel_lock(chan); 02778 02779 /* You can't answer an outbound call */ 02780 if (ast_test_flag(chan, AST_FLAG_OUTGOING)) { 02781 ast_channel_unlock(chan); 02782 return 0; 02783 } 02784 02785 /* Stop if we're a zombie or need a soft hangup */ 02786 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02787 ast_channel_unlock(chan); 02788 return -1; 02789 } 02790 02791 ast_channel_unlock(chan); 02792 02793 switch (chan->_state) { 02794 case AST_STATE_RINGING: 02795 case AST_STATE_RING: 02796 ast_channel_lock(chan); 02797 if (chan->tech->answer) { 02798 res = chan->tech->answer(chan); 02799 } 02800 ast_setstate(chan, AST_STATE_UP); 02801 if (cdr_answer) { 02802 ast_cdr_answer(chan->cdr); 02803 } 02804 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 02805 ast_channel_unlock(chan); 02806 break; 02807 case AST_STATE_UP: 02808 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 02809 /* Calling ast_cdr_answer when it it has previously been called 02810 * is essentially a no-op, so it is safe. 02811 */ 02812 if (cdr_answer) { 02813 ast_cdr_answer(chan->cdr); 02814 } 02815 break; 02816 default: 02817 break; 02818 } 02819 02820 ast_indicate(chan, -1); 02821 02822 return res; 02823 }
struct ast_frame* ast_read | ( | struct ast_channel * | chan | ) |
Reads a frame.
chan | channel to read a frame from |
Definition at line 4149 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_wait(), autoservice_run(), background_detect_exec(), channel_spy(), check_goto_on_transfer(), 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(), iax_park_thread(), ices_exec(), isAnsweringMachine(), jack_exec(), launch_asyncagi(), local_bridge_loop(), manage_parkinglot(), masq_park_call(), measurenoise(), misdn_bridge(), monitor_dial(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), receivefax_t38_init(), recordthread(), remote_bridge_loop(), rpt(), 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().
04150 { 04151 return __ast_read(chan, 0); 04152 }
static void ast_read_generator_actions | ( | struct ast_channel * | chan, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 3510 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().
03511 { 03512 if (chan->generator && chan->generator->generate && chan->generatordata && !ast_internal_timing_enabled(chan)) { 03513 void *tmp = chan->generatordata; 03514 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = chan->generator->generate; 03515 int res; 03516 int samples; 03517 03518 if (chan->timingfunc) { 03519 ast_debug(1, "Generator got voice, switching to phase locked mode\n"); 03520 ast_settimeout(chan, 0, NULL, NULL); 03521 } 03522 03523 chan->generatordata = NULL; /* reset, to let writes go through */ 03524 03525 if (f->subclass.codec != chan->writeformat) { 03526 float factor; 03527 factor = ((float) ast_format_rate(chan->writeformat)) / ((float) ast_format_rate(f->subclass.codec)); 03528 samples = (int) ( ((float) f->samples) * factor ); 03529 } else { 03530 samples = f->samples; 03531 } 03532 03533 /* This unlock is here based on two assumptions that hold true at this point in the 03534 * code. 1) this function is only called from within __ast_read() and 2) all generators 03535 * call ast_write() in their generate callback. 03536 * 03537 * The reason this is added is so that when ast_write is called, the lock that occurs 03538 * there will not recursively lock the channel. Doing this will cause intended deadlock 03539 * avoidance not to work in deeper functions 03540 */ 03541 ast_channel_unlock(chan); 03542 res = generate(chan, tmp, f->datalen, samples); 03543 ast_channel_lock(chan); 03544 chan->generatordata = tmp; 03545 if (res) { 03546 ast_debug(1, "Auto-deactivating generator\n"); 03547 ast_deactivate_generator(chan); 03548 } 03549 03550 } else if (f->frametype == AST_FRAME_CNG) { 03551 if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) { 03552 ast_debug(1, "Generator got CNG, switching to timed mode\n"); 03553 ast_settimeout(chan, 50, generator_force, chan); 03554 } 03555 } 03556 }
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 4154 of file channel.c.
References __ast_read(), and chanlist::chan.
Referenced by ast_bridge_handle_trip(), and conf_run().
04155 { 04156 return __ast_read(chan, 1); 04157 }
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 5497 of file channel.c.
References ast_readstring_full().
Referenced by ast_adsi_begin_download(), ast_adsi_get_cpeinfo(), ast_adsi_load_session(), ast_app_getdata(), dialout(), do_directory(), forward_message(), privacy_exec(), vm_authenticate(), vm_newuser(), and vm_options().
05498 { 05499 return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1); 05500 }
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 5502 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().
05503 { 05504 int pos = 0; /* index in the buffer where we accumulate digits */ 05505 int to = ftimeout; 05506 05507 struct ast_silence_generator *silgen = NULL; 05508 05509 /* Stop if we're a zombie or need a soft hangup */ 05510 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 05511 return -1; 05512 if (!len) 05513 return -1; 05514 for (;;) { 05515 int d; 05516 if (c->stream) { 05517 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 05518 ast_stopstream(c); 05519 if (!silgen && ast_opt_transmit_silence) 05520 silgen = ast_channel_start_silence_generator(c); 05521 usleep(1000); 05522 if (!d) 05523 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 05524 } else { 05525 if (!silgen && ast_opt_transmit_silence) 05526 silgen = ast_channel_start_silence_generator(c); 05527 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 05528 } 05529 if (d < 0) { 05530 ast_channel_stop_silence_generator(c, silgen); 05531 return AST_GETDATA_FAILED; 05532 } 05533 if (d == 0) { 05534 s[pos] = '\0'; 05535 ast_channel_stop_silence_generator(c, silgen); 05536 return AST_GETDATA_TIMEOUT; 05537 } 05538 if (d == 1) { 05539 s[pos] = '\0'; 05540 ast_channel_stop_silence_generator(c, silgen); 05541 return AST_GETDATA_INTERRUPTED; 05542 } 05543 if (strchr(enders, d) && (pos == 0)) { 05544 s[pos] = '\0'; 05545 ast_channel_stop_silence_generator(c, silgen); 05546 return AST_GETDATA_EMPTY_END_TERMINATED; 05547 } 05548 if (!strchr(enders, d)) { 05549 s[pos++] = d; 05550 } 05551 if (strchr(enders, d) || (pos >= len)) { 05552 s[pos] = '\0'; 05553 ast_channel_stop_silence_generator(c, silgen); 05554 return AST_GETDATA_COMPLETE; 05555 } 05556 to = timeout; 05557 } 05558 /* Never reached */ 05559 return 0; 05560 }
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 4402 of file channel.c.
References ast_free, ast_recvtext(), and chanlist::chan.
Referenced by handle_recvchar().
04403 { 04404 int c; 04405 char *buf = ast_recvtext(chan, timeout); 04406 if (buf == NULL) 04407 return -1; /* error or timeout */ 04408 c = *(unsigned char *)buf; 04409 ast_free(buf); 04410 return c; 04411 }
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 4413 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().
04414 { 04415 int res, done = 0; 04416 char *buf = NULL; 04417 04418 while (!done) { 04419 struct ast_frame *f; 04420 if (ast_check_hangup(chan)) 04421 break; 04422 res = ast_waitfor(chan, timeout); 04423 if (res <= 0) /* timeout or error */ 04424 break; 04425 timeout = res; /* update timeout */ 04426 f = ast_read(chan); 04427 if (f == NULL) 04428 break; /* no frame */ 04429 if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP) 04430 done = 1; /* force a break */ 04431 else if (f->frametype == AST_FRAME_TEXT) { /* what we want */ 04432 buf = ast_strndup((char *) f->data.ptr, f->datalen); /* dup and break */ 04433 done = 1; 04434 } 04435 ast_frfree(f); 04436 } 04437 return buf; 04438 }
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 8603 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().
08604 { 08605 int32_t value; 08606 size_t pos = 0; 08607 int res; 08608 08609 static const struct ast_party_id_ies from_ies = { 08610 .name.str = AST_REDIRECTING_FROM_NAME, 08611 .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET, 08612 .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION, 08613 .name.valid = AST_REDIRECTING_FROM_NAME_VALID, 08614 08615 .number.str = AST_REDIRECTING_FROM_NUMBER, 08616 .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN, 08617 .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION, 08618 .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID, 08619 08620 .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS, 08621 .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE, 08622 .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, 08623 .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID, 08624 08625 .tag = AST_REDIRECTING_FROM_TAG, 08626 .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION, 08627 }; 08628 static const struct ast_party_id_ies to_ies = { 08629 .name.str = AST_REDIRECTING_TO_NAME, 08630 .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET, 08631 .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION, 08632 .name.valid = AST_REDIRECTING_TO_NAME_VALID, 08633 08634 .number.str = AST_REDIRECTING_TO_NUMBER, 08635 .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN, 08636 .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION, 08637 .number.valid = AST_REDIRECTING_TO_NUMBER_VALID, 08638 08639 .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS, 08640 .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE, 08641 .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, 08642 .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID, 08643 08644 .tag = AST_REDIRECTING_TO_TAG, 08645 .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION, 08646 }; 08647 08648 /* Redirecting frame version */ 08649 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08650 ast_log(LOG_WARNING, "No space left for redirecting frame version\n"); 08651 return -1; 08652 } 08653 data[pos++] = AST_REDIRECTING_VERSION; 08654 data[pos++] = 1; 08655 data[pos++] = 2;/* Version 1 did not have a version ie */ 08656 08657 res = party_id_build_data(data + pos, datalen - pos, &redirecting->from, 08658 "redirecting-from", &from_ies, update ? &update->from : NULL); 08659 if (res < 0) { 08660 return -1; 08661 } 08662 pos += res; 08663 08664 res = party_id_build_data(data + pos, datalen - pos, &redirecting->to, 08665 "redirecting-to", &to_ies, update ? &update->to : NULL); 08666 if (res < 0) { 08667 return -1; 08668 } 08669 pos += res; 08670 08671 /* Redirecting reason */ 08672 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 08673 ast_log(LOG_WARNING, "No space left for redirecting reason\n"); 08674 return -1; 08675 } 08676 data[pos++] = AST_REDIRECTING_REASON; 08677 data[pos++] = sizeof(value); 08678 value = htonl(redirecting->reason); 08679 memcpy(data + pos, &value, sizeof(value)); 08680 pos += sizeof(value); 08681 08682 /* Redirecting count */ 08683 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 08684 ast_log(LOG_WARNING, "No space left for redirecting count\n"); 08685 return -1; 08686 } 08687 data[pos++] = AST_REDIRECTING_COUNT; 08688 data[pos++] = sizeof(value); 08689 value = htonl(redirecting->count); 08690 memcpy(data + pos, &value, sizeof(value)); 08691 pos += sizeof(value); 08692 08693 return pos; 08694 }
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 8696 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().
08697 { 08698 size_t pos; 08699 unsigned char ie_len; 08700 unsigned char ie_id; 08701 int32_t value; 08702 int frame_version = 1; 08703 int from_combined_presentation = 0; 08704 int got_from_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 08705 int to_combined_presentation = 0; 08706 int got_to_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 08707 08708 for (pos = 0; pos < datalen; pos += ie_len) { 08709 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) { 08710 ast_log(LOG_WARNING, "Invalid redirecting update\n"); 08711 return -1; 08712 } 08713 ie_id = data[pos++]; 08714 ie_len = data[pos++]; 08715 if (datalen < pos + ie_len) { 08716 ast_log(LOG_WARNING, "Invalid redirecting update\n"); 08717 return -1; 08718 } 08719 08720 switch (ie_id) { 08721 /* Redirecting frame version */ 08722 case AST_REDIRECTING_VERSION: 08723 if (ie_len != 1) { 08724 ast_log(LOG_WARNING, "Invalid redirecting frame version (%u)\n", 08725 (unsigned) ie_len); 08726 break; 08727 } 08728 frame_version = data[pos]; 08729 break; 08730 /* Redirecting-from party id name */ 08731 case AST_REDIRECTING_FROM_NAME: 08732 ast_free(redirecting->from.name.str); 08733 redirecting->from.name.str = ast_malloc(ie_len + 1); 08734 if (redirecting->from.name.str) { 08735 memcpy(redirecting->from.name.str, data + pos, ie_len); 08736 redirecting->from.name.str[ie_len] = 0; 08737 } 08738 break; 08739 case AST_REDIRECTING_FROM_NAME_CHAR_SET: 08740 if (ie_len != 1) { 08741 ast_log(LOG_WARNING, "Invalid redirecting-from name char set (%u)\n", 08742 (unsigned) ie_len); 08743 break; 08744 } 08745 redirecting->from.name.char_set = data[pos]; 08746 break; 08747 case AST_REDIRECTING_FROM_NAME_PRESENTATION: 08748 if (ie_len != 1) { 08749 ast_log(LOG_WARNING, "Invalid redirecting-from name presentation (%u)\n", 08750 (unsigned) ie_len); 08751 break; 08752 } 08753 redirecting->from.name.presentation = data[pos]; 08754 break; 08755 case AST_REDIRECTING_FROM_NAME_VALID: 08756 if (ie_len != 1) { 08757 ast_log(LOG_WARNING, "Invalid redirecting-from name valid (%u)\n", 08758 (unsigned) ie_len); 08759 break; 08760 } 08761 redirecting->from.name.valid = data[pos]; 08762 break; 08763 /* Redirecting-from party id number */ 08764 case AST_REDIRECTING_FROM_NUMBER: 08765 ast_free(redirecting->from.number.str); 08766 redirecting->from.number.str = ast_malloc(ie_len + 1); 08767 if (redirecting->from.number.str) { 08768 memcpy(redirecting->from.number.str, data + pos, ie_len); 08769 redirecting->from.number.str[ie_len] = 0; 08770 } 08771 break; 08772 case AST_REDIRECTING_FROM_NUMBER_PLAN: 08773 if (ie_len != 1) { 08774 ast_log(LOG_WARNING, "Invalid redirecting-from numbering plan (%u)\n", 08775 (unsigned) ie_len); 08776 break; 08777 } 08778 redirecting->from.number.plan = data[pos]; 08779 break; 08780 case AST_REDIRECTING_FROM_NUMBER_PRESENTATION: 08781 if (ie_len != 1) { 08782 ast_log(LOG_WARNING, "Invalid redirecting-from number presentation (%u)\n", 08783 (unsigned) ie_len); 08784 break; 08785 } 08786 redirecting->from.number.presentation = data[pos]; 08787 break; 08788 case AST_REDIRECTING_FROM_NUMBER_VALID: 08789 if (ie_len != 1) { 08790 ast_log(LOG_WARNING, "Invalid redirecting-from number valid (%u)\n", 08791 (unsigned) ie_len); 08792 break; 08793 } 08794 redirecting->from.number.valid = data[pos]; 08795 break; 08796 /* Redirecting-from party id combined presentation */ 08797 case AST_REDIRECTING_FROM_ID_PRESENTATION: 08798 if (ie_len != 1) { 08799 ast_log(LOG_WARNING, "Invalid redirecting-from combined presentation (%u)\n", 08800 (unsigned) ie_len); 08801 break; 08802 } 08803 from_combined_presentation = data[pos]; 08804 got_from_combined_presentation = 1; 08805 break; 08806 /* Redirecting-from party id subaddress */ 08807 case AST_REDIRECTING_FROM_SUBADDRESS: 08808 ast_free(redirecting->from.subaddress.str); 08809 redirecting->from.subaddress.str = ast_malloc(ie_len + 1); 08810 if (redirecting->from.subaddress.str) { 08811 memcpy(redirecting->from.subaddress.str, data + pos, ie_len); 08812 redirecting->from.subaddress.str[ie_len] = 0; 08813 } 08814 break; 08815 case AST_REDIRECTING_FROM_SUBADDRESS_TYPE: 08816 if (ie_len != 1) { 08817 ast_log(LOG_WARNING, "Invalid redirecting-from type of subaddress (%u)\n", 08818 (unsigned) ie_len); 08819 break; 08820 } 08821 redirecting->from.subaddress.type = data[pos]; 08822 break; 08823 case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN: 08824 if (ie_len != 1) { 08825 ast_log(LOG_WARNING, 08826 "Invalid redirecting-from subaddress odd-even indicator (%u)\n", 08827 (unsigned) ie_len); 08828 break; 08829 } 08830 redirecting->from.subaddress.odd_even_indicator = data[pos]; 08831 break; 08832 case AST_REDIRECTING_FROM_SUBADDRESS_VALID: 08833 if (ie_len != 1) { 08834 ast_log(LOG_WARNING, "Invalid redirecting-from subaddress valid (%u)\n", 08835 (unsigned) ie_len); 08836 break; 08837 } 08838 redirecting->from.subaddress.valid = data[pos]; 08839 break; 08840 /* Redirecting-from party id tag */ 08841 case AST_REDIRECTING_FROM_TAG: 08842 ast_free(redirecting->from.tag); 08843 redirecting->from.tag = ast_malloc(ie_len + 1); 08844 if (redirecting->from.tag) { 08845 memcpy(redirecting->from.tag, data + pos, ie_len); 08846 redirecting->from.tag[ie_len] = 0; 08847 } 08848 break; 08849 /* Redirecting-to party id name */ 08850 case AST_REDIRECTING_TO_NAME: 08851 ast_free(redirecting->to.name.str); 08852 redirecting->to.name.str = ast_malloc(ie_len + 1); 08853 if (redirecting->to.name.str) { 08854 memcpy(redirecting->to.name.str, data + pos, ie_len); 08855 redirecting->to.name.str[ie_len] = 0; 08856 } 08857 break; 08858 case AST_REDIRECTING_TO_NAME_CHAR_SET: 08859 if (ie_len != 1) { 08860 ast_log(LOG_WARNING, "Invalid redirecting-to name char set (%u)\n", 08861 (unsigned) ie_len); 08862 break; 08863 } 08864 redirecting->to.name.char_set = data[pos]; 08865 break; 08866 case AST_REDIRECTING_TO_NAME_PRESENTATION: 08867 if (ie_len != 1) { 08868 ast_log(LOG_WARNING, "Invalid redirecting-to name presentation (%u)\n", 08869 (unsigned) ie_len); 08870 break; 08871 } 08872 redirecting->to.name.presentation = data[pos]; 08873 break; 08874 case AST_REDIRECTING_TO_NAME_VALID: 08875 if (ie_len != 1) { 08876 ast_log(LOG_WARNING, "Invalid redirecting-to name valid (%u)\n", 08877 (unsigned) ie_len); 08878 break; 08879 } 08880 redirecting->to.name.valid = data[pos]; 08881 break; 08882 /* Redirecting-to party id number */ 08883 case AST_REDIRECTING_TO_NUMBER: 08884 ast_free(redirecting->to.number.str); 08885 redirecting->to.number.str = ast_malloc(ie_len + 1); 08886 if (redirecting->to.number.str) { 08887 memcpy(redirecting->to.number.str, data + pos, ie_len); 08888 redirecting->to.number.str[ie_len] = 0; 08889 } 08890 break; 08891 case AST_REDIRECTING_TO_NUMBER_PLAN: 08892 if (ie_len != 1) { 08893 ast_log(LOG_WARNING, "Invalid redirecting-to numbering plan (%u)\n", 08894 (unsigned) ie_len); 08895 break; 08896 } 08897 redirecting->to.number.plan = data[pos]; 08898 break; 08899 case AST_REDIRECTING_TO_NUMBER_PRESENTATION: 08900 if (ie_len != 1) { 08901 ast_log(LOG_WARNING, "Invalid redirecting-to number presentation (%u)\n", 08902 (unsigned) ie_len); 08903 break; 08904 } 08905 redirecting->to.number.presentation = data[pos]; 08906 break; 08907 case AST_REDIRECTING_TO_NUMBER_VALID: 08908 if (ie_len != 1) { 08909 ast_log(LOG_WARNING, "Invalid redirecting-to number valid (%u)\n", 08910 (unsigned) ie_len); 08911 break; 08912 } 08913 redirecting->to.number.valid = data[pos]; 08914 break; 08915 /* Redirecting-to party id combined presentation */ 08916 case AST_REDIRECTING_TO_ID_PRESENTATION: 08917 if (ie_len != 1) { 08918 ast_log(LOG_WARNING, "Invalid redirecting-to combined presentation (%u)\n", 08919 (unsigned) ie_len); 08920 break; 08921 } 08922 to_combined_presentation = data[pos]; 08923 got_to_combined_presentation = 1; 08924 break; 08925 /* Redirecting-to party id subaddress */ 08926 case AST_REDIRECTING_TO_SUBADDRESS: 08927 ast_free(redirecting->to.subaddress.str); 08928 redirecting->to.subaddress.str = ast_malloc(ie_len + 1); 08929 if (redirecting->to.subaddress.str) { 08930 memcpy(redirecting->to.subaddress.str, data + pos, ie_len); 08931 redirecting->to.subaddress.str[ie_len] = 0; 08932 } 08933 break; 08934 case AST_REDIRECTING_TO_SUBADDRESS_TYPE: 08935 if (ie_len != 1) { 08936 ast_log(LOG_WARNING, "Invalid redirecting-to type of subaddress (%u)\n", 08937 (unsigned) ie_len); 08938 break; 08939 } 08940 redirecting->to.subaddress.type = data[pos]; 08941 break; 08942 case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN: 08943 if (ie_len != 1) { 08944 ast_log(LOG_WARNING, 08945 "Invalid redirecting-to subaddress odd-even indicator (%u)\n", 08946 (unsigned) ie_len); 08947 break; 08948 } 08949 redirecting->to.subaddress.odd_even_indicator = data[pos]; 08950 break; 08951 case AST_REDIRECTING_TO_SUBADDRESS_VALID: 08952 if (ie_len != 1) { 08953 ast_log(LOG_WARNING, "Invalid redirecting-to subaddress valid (%u)\n", 08954 (unsigned) ie_len); 08955 break; 08956 } 08957 redirecting->to.subaddress.valid = data[pos]; 08958 break; 08959 /* Redirecting-to party id tag */ 08960 case AST_REDIRECTING_TO_TAG: 08961 ast_free(redirecting->to.tag); 08962 redirecting->to.tag = ast_malloc(ie_len + 1); 08963 if (redirecting->to.tag) { 08964 memcpy(redirecting->to.tag, data + pos, ie_len); 08965 redirecting->to.tag[ie_len] = 0; 08966 } 08967 break; 08968 /* Redirecting reason */ 08969 case AST_REDIRECTING_REASON: 08970 if (ie_len != sizeof(value)) { 08971 ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n", 08972 (unsigned) ie_len); 08973 break; 08974 } 08975 memcpy(&value, data + pos, sizeof(value)); 08976 redirecting->reason = ntohl(value); 08977 break; 08978 /* Redirecting count */ 08979 case AST_REDIRECTING_COUNT: 08980 if (ie_len != sizeof(value)) { 08981 ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n", 08982 (unsigned) ie_len); 08983 break; 08984 } 08985 memcpy(&value, data + pos, sizeof(value)); 08986 redirecting->count = ntohl(value); 08987 break; 08988 /* Redirecting unknown element */ 08989 default: 08990 ast_log(LOG_DEBUG, "Unknown redirecting element: %u (%u)\n", 08991 (unsigned) ie_id, (unsigned) ie_len); 08992 break; 08993 } 08994 } 08995 08996 switch (frame_version) { 08997 case 1: 08998 /* 08999 * The other end is an earlier version that we need to adjust 09000 * for compatibility. 09001 */ 09002 redirecting->from.name.valid = 1; 09003 redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 09004 redirecting->from.number.valid = 1; 09005 if (got_from_combined_presentation) { 09006 redirecting->from.name.presentation = from_combined_presentation; 09007 redirecting->from.number.presentation = from_combined_presentation; 09008 } 09009 09010 redirecting->to.name.valid = 1; 09011 redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 09012 redirecting->to.number.valid = 1; 09013 if (got_to_combined_presentation) { 09014 redirecting->to.name.presentation = to_combined_presentation; 09015 redirecting->to.number.presentation = to_combined_presentation; 09016 } 09017 break; 09018 case 2: 09019 /* The other end is at the same level as we are. */ 09020 break; 09021 default: 09022 /* 09023 * The other end is newer than we are. 09024 * We need to assume that they are compatible with us. 09025 */ 09026 ast_log(LOG_DEBUG, "Redirecting frame has newer version: %u\n", 09027 (unsigned) frame_version); 09028 break; 09029 } 09030 09031 return 0; 09032 }
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 | |
status | status |
NULL | failure | |
non-NULL | channel on success |
Definition at line 5355 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(), attempt_reconnect(), begin_dial_channel(), build_conf(), chanavail_exec(), conf_run(), connect_link(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), play_sound_file(), ring_entry(), rpt(), rpt_call(), rpt_exec(), and rpt_tele_thread().
05356 { 05357 struct chanlist *chan; 05358 struct ast_channel *c; 05359 format_t capabilities; 05360 format_t fmt; 05361 int res; 05362 int foo; 05363 format_t videoformat = format & AST_FORMAT_VIDEO_MASK; 05364 format_t textformat = format & AST_FORMAT_TEXT_MASK; 05365 05366 if (!cause) 05367 cause = &foo; 05368 *cause = AST_CAUSE_NOTDEFINED; 05369 05370 if (AST_RWLIST_RDLOCK(&backends)) { 05371 ast_log(LOG_WARNING, "Unable to lock technology backend list\n"); 05372 return NULL; 05373 } 05374 05375 AST_RWLIST_TRAVERSE(&backends, chan, list) { 05376 if (strcasecmp(type, chan->tech->type)) 05377 continue; 05378 05379 capabilities = chan->tech->capabilities; 05380 fmt = format & AST_FORMAT_AUDIO_MASK; 05381 if (fmt) { 05382 /* We have audio - is it possible to connect the various calls to each other? 05383 (Avoid this check for calls without audio, like text+video calls) 05384 */ 05385 res = ast_translator_best_choice(&fmt, &capabilities); 05386 if (res < 0) { 05387 char tmp1[256], tmp2[256]; 05388 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %s) to %s\n", type, 05389 ast_getformatname_multiple(tmp1, sizeof(tmp1), chan->tech->capabilities), 05390 ast_getformatname_multiple(tmp2, sizeof(tmp2), format)); 05391 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05392 AST_RWLIST_UNLOCK(&backends); 05393 return NULL; 05394 } 05395 } 05396 AST_RWLIST_UNLOCK(&backends); 05397 if (!chan->tech->requester) 05398 return NULL; 05399 05400 if (!(c = chan->tech->requester(type, capabilities | videoformat | textformat, requestor, data, cause))) 05401 return NULL; 05402 05403 if (set_security_requirements(requestor, c)) { 05404 ast_log(LOG_WARNING, "Setting security requirements failed\n"); 05405 c = ast_channel_release(c); 05406 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05407 return NULL; 05408 } 05409 05410 /* no need to generate a Newchannel event here; it is done in the channel_alloc call */ 05411 return c; 05412 } 05413 05414 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 05415 *cause = AST_CAUSE_NOSUCHDRIVER; 05416 AST_RWLIST_UNLOCK(&backends); 05417 05418 return NULL; 05419 }
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 5310 of file channel.c.
References __ast_request_and_dial().
Referenced by ast_pbx_outgoing_exten(), and generic_recall().
05311 { 05312 return __ast_request_and_dial(type, format, requestor, data, timeout, outstate, cidnum, cidname, NULL); 05313 }
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 1822 of file channel.c.
References ast_safe_sleep_conditional(), and chanlist::chan.
Referenced by __analog_ss_thread(), alarmreceiver_exec(), analog_ss_thread(), ast_adsi_transmit_message_full(), ast_dtmf_stream(), ast_senddigit(), builtin_atxfer(), conf_run(), dictate_exec(), flash_exec(), function_ilink(), handle_callforward_button(), login_exec(), mgcp_ss(), milliwatt_exec(), misdn_check_l2l1(), old_milliwatt_exec(), park_call_exec(), parkcall_helper(), pbx_builtin_wait(), play_moh_exec(), play_tone_pair(), playtone(), privacy_exec(), receive_ademco_contact_id(), rpt_call(), rpt_exec(), rpt_tele_thread(), send_morse(), send_tone_telemetry(), skinny_ss(), testclient_exec(), testserver_exec(), wait_for_hangup(), wait_interval(), wait_moh_exec(), waituntil_exec(), and zapateller_exec().
01823 { 01824 return ast_safe_sleep_conditional(chan, ms, NULL, NULL); 01825 }
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 1755 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().
01756 { 01757 struct ast_frame *f; 01758 struct ast_silence_generator *silgen = NULL; 01759 int res = 0; 01760 AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames; 01761 01762 AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames); 01763 01764 /* If no other generator is present, start silencegen while waiting */ 01765 if (ast_opt_transmit_silence && !chan->generatordata) { 01766 silgen = ast_channel_start_silence_generator(chan); 01767 } 01768 01769 while (ms > 0) { 01770 struct ast_frame *dup_f = NULL; 01771 if (cond && ((*cond)(data) == 0)) { 01772 break; 01773 } 01774 ms = ast_waitfor(chan, ms); 01775 if (ms < 0) { 01776 res = -1; 01777 break; 01778 } 01779 if (ms > 0) { 01780 f = ast_read(chan); 01781 if (!f) { 01782 res = -1; 01783 break; 01784 } 01785 01786 if (!ast_is_deferrable_frame(f)) { 01787 ast_frfree(f); 01788 continue; 01789 } 01790 01791 if ((dup_f = ast_frisolate(f))) { 01792 if (dup_f != f) { 01793 ast_frfree(f); 01794 } 01795 AST_LIST_INSERT_HEAD(&deferred_frames, dup_f, frame_list); 01796 } 01797 } 01798 } 01799 01800 /* stop silgen if present */ 01801 if (silgen) { 01802 ast_channel_stop_silence_generator(chan, silgen); 01803 } 01804 01805 /* We need to free all the deferred frames, but we only need to 01806 * queue the deferred frames if there was no error and no 01807 * hangup was received 01808 */ 01809 ast_channel_lock(chan); 01810 while ((f = AST_LIST_REMOVE_HEAD(&deferred_frames, frame_list))) { 01811 if (!res) { 01812 ast_queue_frame_head(chan, f); 01813 } 01814 ast_frfree(f); 01815 } 01816 ast_channel_unlock(chan); 01817 01818 return res; 01819 }
int ast_say_character_str | ( | struct ast_channel * | chan, | |
const char * | str, | |||
const char * | ints, | |||
const char * | lang | |||
) |
Definition at line 7863 of file channel.c.
References ast_say_character_str_full.
Referenced by common_exec(), pbx_builtin_saycharacters(), play_mailbox_owner(), rpt_tele_thread(), saycharstr(), saynode(), and vmsayname_exec().
07865 { 07866 return ast_say_character_str_full(chan, str, ints, lang, -1, -1); 07867 }
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 7857 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().
07859 { 07860 return ast_say_digit_str_full(chan, str, ints, lang, -1, -1); 07861 }
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 7851 of file channel.c.
References ast_say_digits_full().
Referenced by common_exec(), conf_exec(), conf_run(), park_call_full(), parkandannounce_exec(), and rpt_tele_thread().
07853 { 07854 return ast_say_digits_full(chan, num, ints, lang, -1, -1); 07855 }
int ast_say_digits_full | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | ints, | |||
const char * | lang, | |||
int | audiofd, | |||
int | ctrlfd | |||
) |
Definition at line 7875 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().
07877 { 07878 char buf[256]; 07879 07880 snprintf(buf, sizeof(buf), "%d", num); 07881 07882 return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd); 07883 }
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 7845 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().
07847 { 07848 return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1); 07849 }
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 7839 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(), rpt_tele_thread(), say_and_wait(), say_position(), saynum(), vm_intro_gr(), vm_intro_he(), vm_intro_multilang(), vm_intro_pt(), and vm_intro_pt_BR().
07841 { 07842 return ast_say_number_full(chan, num, ints, language, options, -1, -1); 07843 }
int ast_say_phonetic_str | ( | struct ast_channel * | chan, | |
const char * | str, | |||
const char * | ints, | |||
const char * | lang | |||
) |
Definition at line 7869 of file channel.c.
References ast_say_phonetic_str_full.
Referenced by pbx_builtin_sayphonetic().
07871 { 07872 return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1); 07873 }
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 4511 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(), do_dtmf_phone(), manager_play_dtmf(), and rpt_call().
04512 { 04513 if (chan->tech->send_digit_begin) { 04514 ast_senddigit_begin(chan, digit); 04515 ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 04516 } 04517 04518 return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 04519 }
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 4453 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().
04454 { 04455 /* Device does not support DTMF tones, lets fake 04456 * it by doing our own generation. */ 04457 static const char * const dtmf_tones[] = { 04458 "941+1336", /* 0 */ 04459 "697+1209", /* 1 */ 04460 "697+1336", /* 2 */ 04461 "697+1477", /* 3 */ 04462 "770+1209", /* 4 */ 04463 "770+1336", /* 5 */ 04464 "770+1477", /* 6 */ 04465 "852+1209", /* 7 */ 04466 "852+1336", /* 8 */ 04467 "852+1477", /* 9 */ 04468 "697+1633", /* A */ 04469 "770+1633", /* B */ 04470 "852+1633", /* C */ 04471 "941+1633", /* D */ 04472 "941+1209", /* * */ 04473 "941+1477" /* # */ 04474 }; 04475 04476 if (!chan->tech->send_digit_begin) 04477 return 0; 04478 04479 if (!chan->tech->send_digit_begin(chan, digit)) 04480 return 0; 04481 04482 if (digit >= '0' && digit <='9') 04483 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0); 04484 else if (digit >= 'A' && digit <= 'D') 04485 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0); 04486 else if (digit == '*') 04487 ast_playtones_start(chan, 0, dtmf_tones[14], 0); 04488 else if (digit == '#') 04489 ast_playtones_start(chan, 0, dtmf_tones[15], 0); 04490 else { 04491 /* not handled */ 04492 ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name); 04493 } 04494 04495 return 0; 04496 }
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 4498 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().
04499 { 04500 int res = -1; 04501 04502 if (chan->tech->send_digit_end) 04503 res = chan->tech->send_digit_end(chan, digit, duration); 04504 04505 if (res && chan->generator) 04506 ast_playtones_stop(chan); 04507 04508 return 0; 04509 }
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 4440 of file channel.c.
References 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(), send_newkey(), and sendtext_exec().
04441 { 04442 int res = 0; 04443 /* Stop if we're a zombie or need a soft hangup */ 04444 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 04445 return -1; 04446 CHECK_BLOCKING(chan); 04447 if (chan->tech->send_text) 04448 res = chan->tech->send_text(chan, text); 04449 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04450 return res; 04451 }
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 6572 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(), ast_call_forward(), cb_events(), dial_exec_full(), do_forward(), findmeexec(), get_pai(), get_rpid(), handle_setcallerid(), mgcp_ss(), ring_entry(), rpt_exec(), skinny_newcall(), and socket_process().
06573 { 06574 ast_channel_lock(chan); 06575 06576 if (cid_num) { 06577 chan->caller.id.number.valid = 1; 06578 ast_free(chan->caller.id.number.str); 06579 chan->caller.id.number.str = ast_strdup(cid_num); 06580 } 06581 if (cid_name) { 06582 chan->caller.id.name.valid = 1; 06583 ast_free(chan->caller.id.name.str); 06584 chan->caller.id.name.str = ast_strdup(cid_name); 06585 } 06586 if (cid_ani) { 06587 chan->caller.ani.number.valid = 1; 06588 ast_free(chan->caller.ani.number.str); 06589 chan->caller.ani.number.str = ast_strdup(cid_ani); 06590 } 06591 if (chan->cdr) { 06592 ast_cdr_setcid(chan->cdr, chan); 06593 } 06594 06595 report_new_callerid(chan); 06596 06597 ast_channel_unlock(chan); 06598 }
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 2639 of file channel.c.
References ast_bridged_channel(), ast_channel_lock, ast_channel_unlock, ast_string_field_set, ast_strlen_zero(), ast_channel::bridge, chanlist::chan, and ast_channel::hangupsource.
Referenced by __dahdi_exception(), func_channel_write_real(), handle_hangup(), handle_request_bye(), handle_request_cancel(), handle_response_invite(), pbx_builtin_hangup(), and set_hangup_source_and_cause().
02640 { 02641 struct ast_channel *bridge; 02642 02643 ast_channel_lock(chan); 02644 if (force || ast_strlen_zero(chan->hangupsource)) { 02645 ast_string_field_set(chan, hangupsource, source); 02646 } 02647 bridge = ast_bridged_channel(chan); 02648 ast_channel_unlock(chan); 02649 02650 if (bridge && (force || ast_strlen_zero(bridge->hangupsource))) { 02651 ast_channel_lock(bridge); 02652 ast_string_field_set(chan, hangupsource, source); 02653 ast_channel_unlock(bridge); 02654 } 02655 }
static void ast_set_owners_and_peers | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 6053 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().
06055 { 06056 if (!ast_strlen_zero(chan1->accountcode) && ast_strlen_zero(chan2->peeraccount)) { 06057 ast_log(LOG_DEBUG, "setting peeraccount to %s for %s from data on channel %s\n", 06058 chan1->accountcode, chan2->name, chan1->name); 06059 ast_string_field_set(chan2, peeraccount, chan1->accountcode); 06060 } 06061 if (!ast_strlen_zero(chan2->accountcode) && ast_strlen_zero(chan1->peeraccount)) { 06062 ast_log(LOG_DEBUG, "setting peeraccount to %s for %s from data on channel %s\n", 06063 chan2->accountcode, chan1->name, chan2->name); 06064 ast_string_field_set(chan1, peeraccount, chan2->accountcode); 06065 } 06066 if (!ast_strlen_zero(chan1->peeraccount) && ast_strlen_zero(chan2->accountcode)) { 06067 ast_log(LOG_DEBUG, "setting accountcode to %s for %s from data on channel %s\n", 06068 chan1->peeraccount, chan2->name, chan1->name); 06069 ast_string_field_set(chan2, accountcode, chan1->peeraccount); 06070 } 06071 if (!ast_strlen_zero(chan2->peeraccount) && ast_strlen_zero(chan1->accountcode)) { 06072 ast_log(LOG_DEBUG, "setting accountcode to %s for %s from data on channel %s\n", 06073 chan2->peeraccount, chan1->name, chan2->name); 06074 ast_string_field_set(chan1, accountcode, chan2->peeraccount); 06075 } 06076 if (0 != strcmp(chan1->accountcode, chan2->peeraccount)) { 06077 ast_log(LOG_DEBUG, "changing peeraccount from %s to %s on %s to match channel %s\n", 06078 chan2->peeraccount, chan1->peeraccount, chan2->name, chan1->name); 06079 ast_string_field_set(chan2, peeraccount, chan1->accountcode); 06080 } 06081 if (0 != strcmp(chan2->accountcode, chan1->peeraccount)) { 06082 ast_log(LOG_DEBUG, "changing peeraccount from %s to %s on %s to match channel %s\n", 06083 chan1->peeraccount, chan2->peeraccount, chan1->name, chan2->name); 06084 ast_string_field_set(chan1, peeraccount, chan2->accountcode); 06085 } 06086 }
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 5022 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(), agent_call(), alarmreceiver_exec(), ast_adsi_transmit_message_full(), ast_channel_make_compatible_helper(), ast_do_masquerade(), attempt_reconnect(), background_detect_exec(), bridge_channel_join(), bridge_make_compatible(), build_conf(), conf_run(), connect_link(), 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(), rpt(), rpt_exec(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), speech_background(), transmit_audio(), and unistim_rtp_read().
05023 { 05024 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat, 05025 &chan->readtrans, 0); 05026 }
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 7726 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().
07727 { 07728 struct ast_variable *cur; 07729 07730 for (cur = vars; cur; cur = cur->next) 07731 pbx_builtin_setvar_helper(chan, cur->name, cur->value); 07732 }
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 5028 of file channel.c.
References chanlist::chan, ast_channel::rawwriteformat, set_format(), ast_channel::writeformat, and ast_channel::writetrans.
Referenced by __oh323_update_info(), agent_call(), alarmreceiver_exec(), ast_adsi_transmit_message_full(), ast_channel_make_compatible_helper(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_do_masquerade(), ast_openstream_full(), ast_stopstream(), attempt_reconnect(), bridge_channel_join(), bridge_make_compatible(), build_conf(), chanspy_exec(), conf_run(), connect_link(), 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(), rpt(), rpt_exec(), 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().
05029 { 05030 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat, 05031 &chan->writetrans, 1); 05032 }
int ast_setstate | ( | struct ast_channel * | chan, | |
enum ast_channel_state | state | |||
) |
Change the state of a channel.
Definition at line 6637 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, EVENT_FLAG_CALL, 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(), sig_ss7_call(), sig_ss7_indicate(), sip_answer(), skinny_answer(), skinny_call(), skinny_newcall(), unistim_answer(), unistim_call(), unistim_new(), unistim_ss(), update_state(), usbradio_answer(), and usbradio_call().
06638 { 06639 int oldstate = chan->_state; 06640 char name[AST_CHANNEL_NAME], *dashptr; 06641 06642 if (oldstate == state) 06643 return 0; 06644 06645 ast_copy_string(name, chan->name, sizeof(name)); 06646 if ((dashptr = strrchr(name, '-'))) { 06647 *dashptr = '\0'; 06648 } 06649 06650 chan->_state = state; 06651 06652 /* We have to pass AST_DEVICE_UNKNOWN here because it is entirely possible that the channel driver 06653 * for this channel is using the callback method for device state. If we pass in an actual state here 06654 * we override what they are saying the state is and things go amuck. */ 06655 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, name); 06656 06657 /* setstate used to conditionally report Newchannel; this is no more */ 06658 ast_manager_event(chan, EVENT_FLAG_CALL, "Newstate", 06659 "Channel: %s\r\n" 06660 "ChannelState: %d\r\n" 06661 "ChannelStateDesc: %s\r\n" 06662 "CallerIDNum: %s\r\n" 06663 "CallerIDName: %s\r\n" 06664 "Uniqueid: %s\r\n", 06665 chan->name, chan->_state, ast_state2str(chan->_state), 06666 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""), 06667 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""), 06668 chan->uniqueid); 06669 06670 return 0; 06671 }
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 3381 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_debug, ast_timer_get_max_rate(), ast_timer_set_rate(), ast_channel::timer, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.
Referenced by ast_activate_generator(), ast_closestream(), ast_deactivate_generator(), ast_read_generator_actions(), ast_readaudio_callback(), and filestream_destructor().
03382 { 03383 int res; 03384 unsigned int real_rate = rate, max_rate; 03385 03386 ast_channel_lock(c); 03387 03388 if (c->timingfd == -1) { 03389 ast_channel_unlock(c); 03390 return -1; 03391 } 03392 03393 if (!func) { 03394 rate = 0; 03395 data = NULL; 03396 } 03397 03398 if (rate && rate > (max_rate = ast_timer_get_max_rate(c->timer))) { 03399 real_rate = max_rate; 03400 } 03401 03402 ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate); 03403 03404 res = ast_timer_set_rate(c->timer, real_rate); 03405 03406 c->timingfunc = func; 03407 c->timingdata = data; 03408 03409 ast_channel_unlock(c); 03410 03411 return res; 03412 }
int ast_shutting_down | ( | void | ) |
Returns non-zero if Asterisk is being shut down.
Definition at line 795 of file channel.c.
Referenced by handle_request_options().
00796 { 00797 return shutting_down; 00798 }
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 2616 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_channel_softhangup_cb(), ast_dial_join(), birdbath(), cc_generic_agent_stop_ringing(), conf_free(), connect_link(), dahdi_handle_event(), flush_telem(), function_ilink(), handle_hangup(), handle_link_data(), handle_softhangup(), login_exec(), manager_park(), mgcp_pktcgate_remove(), read_agent_config(), rpt(), rpt_call(), rpt_do_restart(), rpt_exec(), sla_handle_hold_event(), softhangup_exec(), start_spying(), startmon(), and unload_module().
02617 { 02618 int res; 02619 02620 ast_channel_lock(chan); 02621 res = ast_softhangup_nolock(chan, cause); 02622 ast_channel_unlock(chan); 02623 02624 return res; 02625 }
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 2603 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(), sip_indicate(), and skinny_indicate().
02604 { 02605 ast_debug(1, "Soft-Hanging up channel '%s'\n", chan->name); 02606 /* Inform channel driver that we need to be hung up, if it cares */ 02607 chan->_softhangup |= cause; 02608 ast_queue_frame(chan, &ast_null_frame); 02609 /* Interrupt any poll call or such */ 02610 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) 02611 pthread_kill(chan->blocker, SIGURG); 02612 return 0; 02613 }
const char* ast_state2str | ( | enum ast_channel_state | state | ) |
Gives the string form of a given channel state.
Definition at line 937 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().
00938 { 00939 char *buf; 00940 00941 switch (state) { 00942 case AST_STATE_DOWN: 00943 return "Down"; 00944 case AST_STATE_RESERVED: 00945 return "Rsrvd"; 00946 case AST_STATE_OFFHOOK: 00947 return "OffHook"; 00948 case AST_STATE_DIALING: 00949 return "Dialing"; 00950 case AST_STATE_RING: 00951 return "Ring"; 00952 case AST_STATE_RINGING: 00953 return "Ringing"; 00954 case AST_STATE_UP: 00955 return "Up"; 00956 case AST_STATE_BUSY: 00957 return "Busy"; 00958 case AST_STATE_DIALING_OFFHOOK: 00959 return "Dialing Offhook"; 00960 case AST_STATE_PRERING: 00961 return "Pre-ring"; 00962 default: 00963 if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE))) 00964 return "Unknown"; 00965 snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state); 00966 return buf; 00967 } 00968 }
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 923 of file channel.c.
References ARRAY_LEN, and causes.
Referenced by pbx_builtin_hangup().
00924 { 00925 int x; 00926 00927 for (x = 0; x < ARRAY_LEN(causes); x++) 00928 if (!strncasecmp(causes[x].name, name, strlen(causes[x].name))) 00929 return causes[x].cause; 00930 00931 return -1; 00932 }
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 7446 of file channel.c.
References ast_frfree, ast_read(), ast_tonepair_start(), ast_waitfor(), f, and ast_channel::generatordata.
Referenced by zapateller_exec().
07447 { 07448 int res; 07449 07450 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 07451 return res; 07452 07453 /* Give us some wiggle room */ 07454 while (chan->generatordata && ast_waitfor(chan, 100) >= 0) { 07455 struct ast_frame *f = ast_read(chan); 07456 if (f) 07457 ast_frfree(f); 07458 else 07459 return -1; 07460 } 07461 return 0; 07462 }
int ast_tonepair_start | ( | struct ast_channel * | chan, | |
int | freq1, | |||
int | freq2, | |||
int | duration, | |||
int | vol | |||
) |
Start a tone going
Definition at line 7428 of file channel.c.
References ast_activate_generator(), tonepair_def::duration, tonepair_def::freq1, tonepair_def::freq2, tonepair, and tonepair_def::vol.
Referenced by ast_tonepair(), pbx_builtin_waitexten(), play_dialtone(), play_tone_pair(), rpt_tele_thread(), and sendnoise().
07429 { 07430 struct tonepair_def d = { 0, }; 07431 07432 d.freq1 = freq1; 07433 d.freq2 = freq2; 07434 d.duration = duration; 07435 d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */ 07436 if (ast_activate_generator(chan, &tonepair, &d)) 07437 return -1; 07438 return 0; 07439 }
void ast_tonepair_stop | ( | struct ast_channel * | chan | ) |
Stop a tone from playing
Definition at line 7441 of file channel.c.
References ast_deactivate_generator().
Referenced by sendnoise().
07442 { 07443 ast_deactivate_generator(chan); 07444 }
int ast_transfer | ( | struct ast_channel * | chan, | |
char * | dest | |||
) |
Transfer a channel (if supported).
Called by:
Definition at line 5448 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().
05449 { 05450 int res = -1; 05451 05452 /* Stop if we're a zombie or need a soft hangup */ 05453 ast_channel_lock(chan); 05454 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 05455 if (chan->tech->transfer) { 05456 res = chan->tech->transfer(chan, dest); 05457 if (!res) 05458 res = 1; 05459 } else 05460 res = 0; 05461 } 05462 ast_channel_unlock(chan); 05463 05464 if (res <= 0) { 05465 return res; 05466 } 05467 05468 for (;;) { 05469 struct ast_frame *fr; 05470 05471 res = ast_waitfor(chan, -1); 05472 05473 if (res < 0 || !(fr = ast_read(chan))) { 05474 res = -1; 05475 break; 05476 } 05477 05478 if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_TRANSFER) { 05479 enum ast_control_transfer *message = fr->data.ptr; 05480 05481 if (*message == AST_TRANSFER_SUCCESS) { 05482 res = 1; 05483 } else { 05484 res = -1; 05485 } 05486 05487 ast_frfree(fr); 05488 break; 05489 } 05490 05491 ast_frfree(fr); 05492 } 05493 05494 return res; 05495 }
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 971 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(), sig_pri_new_ast_channel(), and sig_ss7_new_ast_channel().
00972 { 00973 switch (transfercapability) { 00974 case AST_TRANS_CAP_SPEECH: 00975 return "SPEECH"; 00976 case AST_TRANS_CAP_DIGITAL: 00977 return "DIGITAL"; 00978 case AST_TRANS_CAP_RESTRICTED_DIGITAL: 00979 return "RESTRICTED_DIGITAL"; 00980 case AST_TRANS_CAP_3_1K_AUDIO: 00981 return "3K1AUDIO"; 00982 case AST_TRANS_CAP_DIGITAL_W_TONES: 00983 return "DIGITAL_W_TONES"; 00984 case AST_TRANS_CAP_VIDEO: 00985 return "VIDEO"; 00986 default: 00987 return "UNKNOWN"; 00988 } 00989 }
void ast_uninstall_music_functions | ( | void | ) |
Definition at line 7509 of file channel.c.
References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.
Referenced by unload_module().
07510 { 07511 ast_moh_start_ptr = NULL; 07512 ast_moh_stop_ptr = NULL; 07513 ast_moh_cleanup_ptr = NULL; 07514 }
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 3365 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().
03366 { 03367 int oldms = ms; /* -1 if no timeout */ 03368 03369 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms); 03370 if ((ms < 0) && (oldms < 0)) 03371 ms = 0; 03372 return ms; 03373 }
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 3360 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(), rpt(), wait_for_answer(), and wait_for_winner().
03361 { 03362 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 03363 }
int ast_waitfor_n_fd | ( | int * | fds, | |
int | n, | |||
int * | ms, | |||
int * | exception | |||
) |
Waits for input on an fd.
Definition at line 3001 of file channel.c.
References ast_waitfor_nandfds().
Referenced by dundi_lookup_internal(), dundi_precache_internal(), and softmix_bridge_thread().
03002 { 03003 int winner = -1; 03004 ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms); 03005 return winner; 03006 }
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 3013 of file channel.c.
References ast_channel::_softhangup, ast_add_fd(), ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, ast_log(), AST_MAX_FDS, ast_poll, ast_set_flag, AST_SOFTHANGUP_TIMEOUT, ast_tvcmp(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chanlist::chan, CHECK_BLOCKING, errno, and LOG_WARNING.
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().
03016 { 03017 struct timeval start = { 0 , 0 }; 03018 struct pollfd *pfds = NULL; 03019 int res; 03020 long rms; 03021 int x, y, max; 03022 int sz; 03023 struct timeval now = { 0, 0 }; 03024 struct timeval whentohangup = { 0, 0 }, diff; 03025 struct ast_channel *winner = NULL; 03026 struct fdmap { 03027 int chan; 03028 int fdno; 03029 } *fdmap = NULL; 03030 03031 if ((sz = n * AST_MAX_FDS + nfds)) { 03032 pfds = alloca(sizeof(*pfds) * sz); 03033 fdmap = alloca(sizeof(*fdmap) * sz); 03034 } 03035 03036 if (outfd) 03037 *outfd = -99999; 03038 if (exception) 03039 *exception = 0; 03040 03041 /* Perform any pending masquerades */ 03042 for (x = 0; x < n; x++) { 03043 if (c[x]->masq && ast_do_masquerade(c[x])) { 03044 ast_log(LOG_WARNING, "Masquerade failed\n"); 03045 *ms = -1; 03046 return NULL; 03047 } 03048 03049 ast_channel_lock(c[x]); 03050 if (!ast_tvzero(c[x]->whentohangup)) { 03051 if (ast_tvzero(whentohangup)) 03052 now = ast_tvnow(); 03053 diff = ast_tvsub(c[x]->whentohangup, now); 03054 if (diff.tv_sec < 0 || ast_tvzero(diff)) { 03055 /* Should already be hungup */ 03056 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 03057 ast_channel_unlock(c[x]); 03058 return c[x]; 03059 } 03060 if (ast_tvzero(whentohangup) || ast_tvcmp(diff, whentohangup) < 0) 03061 whentohangup = diff; 03062 } 03063 ast_channel_unlock(c[x]); 03064 } 03065 /* Wait full interval */ 03066 rms = *ms; 03067 /* INT_MAX, not LONG_MAX, because it matters on 64-bit */ 03068 if (!ast_tvzero(whentohangup) && whentohangup.tv_sec < INT_MAX / 1000) { 03069 rms = whentohangup.tv_sec * 1000 + whentohangup.tv_usec / 1000; /* timeout in milliseconds */ 03070 if (*ms >= 0 && *ms < rms) { /* original *ms still smaller */ 03071 rms = *ms; 03072 } 03073 } else if (!ast_tvzero(whentohangup) && rms < 0) { 03074 /* Tiny corner case... call would need to last >24 days */ 03075 rms = INT_MAX; 03076 } 03077 /* 03078 * Build the pollfd array, putting the channels' fds first, 03079 * followed by individual fds. Order is important because 03080 * individual fd's must have priority over channel fds. 03081 */ 03082 max = 0; 03083 for (x = 0; x < n; x++) { 03084 for (y = 0; y < AST_MAX_FDS; y++) { 03085 fdmap[max].fdno = y; /* fd y is linked to this pfds */ 03086 fdmap[max].chan = x; /* channel x is linked to this pfds */ 03087 max += ast_add_fd(&pfds[max], c[x]->fds[y]); 03088 } 03089 CHECK_BLOCKING(c[x]); 03090 } 03091 /* Add the individual fds */ 03092 for (x = 0; x < nfds; x++) { 03093 fdmap[max].chan = -1; 03094 max += ast_add_fd(&pfds[max], fds[x]); 03095 } 03096 03097 if (*ms > 0) 03098 start = ast_tvnow(); 03099 03100 if (sizeof(int) == 4) { /* XXX fix timeout > 600000 on linux x86-32 */ 03101 do { 03102 int kbrms = rms; 03103 if (kbrms > 600000) 03104 kbrms = 600000; 03105 res = ast_poll(pfds, max, kbrms); 03106 if (!res) 03107 rms -= kbrms; 03108 } while (!res && (rms > 0)); 03109 } else { 03110 res = ast_poll(pfds, max, rms); 03111 } 03112 for (x = 0; x < n; x++) 03113 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 03114 if (res < 0) { /* Simulate a timeout if we were interrupted */ 03115 if (errno != EINTR) 03116 *ms = -1; 03117 return NULL; 03118 } 03119 if (!ast_tvzero(whentohangup)) { /* if we have a timeout, check who expired */ 03120 now = ast_tvnow(); 03121 for (x = 0; x < n; x++) { 03122 if (!ast_tvzero(c[x]->whentohangup) && ast_tvcmp(c[x]->whentohangup, now) <= 0) { 03123 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 03124 if (winner == NULL) 03125 winner = c[x]; 03126 } 03127 } 03128 } 03129 if (res == 0) { /* no fd ready, reset timeout and done */ 03130 *ms = 0; /* XXX use 0 since we may not have an exact timeout. */ 03131 return winner; 03132 } 03133 /* 03134 * Then check if any channel or fd has a pending event. 03135 * Remember to check channels first and fds last, as they 03136 * must have priority on setting 'winner' 03137 */ 03138 for (x = 0; x < max; x++) { 03139 res = pfds[x].revents; 03140 if (res == 0) 03141 continue; 03142 if (fdmap[x].chan >= 0) { /* this is a channel */ 03143 winner = c[fdmap[x].chan]; /* override previous winners */ 03144 if (res & POLLPRI) 03145 ast_set_flag(winner, AST_FLAG_EXCEPTION); 03146 else 03147 ast_clear_flag(winner, AST_FLAG_EXCEPTION); 03148 winner->fdno = fdmap[x].fdno; 03149 } else { /* this is an fd */ 03150 if (outfd) 03151 *outfd = pfds[x].fd; 03152 if (exception) 03153 *exception = (res & POLLPRI) ? -1 : 0; 03154 winner = NULL; 03155 } 03156 } 03157 if (*ms > 0) { 03158 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 03159 if (*ms < 0) 03160 *ms = 0; 03161 } 03162 return winner; 03163 }
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 3376 of file channel.c.
References ast_waitfordigit_full().
Referenced by __analog_ss_thread(), _while_exec(), advanced_options(), analog_my_getsigstr(), analog_ss_thread(), ast_adsi_get_cpeid(), ast_adsi_get_cpeinfo(), ast_adsi_print(), ast_adsi_read_encoded_dtmf(), ast_adsi_transmit_message_full(), ast_app_dtget(), ast_control_streamfile(), ast_record_review(), bridge_channel_feature(), builtin_atxfer(), collect_digits(), common_exec(), cpeid_exec(), dialout(), directory_exec(), forward_message(), get_folder(), ivr_dispatch(), mgcp_ss(), my_getsigstr(), pbx_builtin_waitexten(), play_record_review(), 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().
03377 { 03378 return ast_waitfordigit_full(c, ms, -1, -1); 03379 }
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 3414 of file channel.c.
References ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_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().
03415 { 03416 /* Stop if we're a zombie or need a soft hangup */ 03417 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 03418 return -1; 03419 03420 /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */ 03421 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY); 03422 03423 /* Wait for a digit, no more than ms milliseconds total. */ 03424 03425 while (ms) { 03426 struct ast_channel *rchan; 03427 int outfd=-1; 03428 03429 errno = 0; 03430 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 03431 03432 if (!rchan && outfd < 0 && ms) { 03433 if (errno == 0 || errno == EINTR) 03434 continue; 03435 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 03436 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03437 return -1; 03438 } else if (outfd > -1) { 03439 /* The FD we were watching has something waiting */ 03440 ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n"); 03441 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03442 return 1; 03443 } else if (rchan) { 03444 int res; 03445 struct ast_frame *f = ast_read(c); 03446 if (!f) 03447 return -1; 03448 03449 switch (f->frametype) { 03450 case AST_FRAME_DTMF_BEGIN: 03451 break; 03452 case AST_FRAME_DTMF_END: 03453 res = f->subclass.integer; 03454 ast_frfree(f); 03455 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03456 return res; 03457 case AST_FRAME_CONTROL: 03458 switch (f->subclass.integer) { 03459 case AST_CONTROL_HANGUP: 03460 ast_frfree(f); 03461 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03462 return -1; 03463 case AST_CONTROL_RINGING: 03464 case AST_CONTROL_ANSWER: 03465 case AST_CONTROL_SRCUPDATE: 03466 case AST_CONTROL_SRCCHANGE: 03467 case AST_CONTROL_CONNECTED_LINE: 03468 case AST_CONTROL_REDIRECTING: 03469 case -1: 03470 /* Unimportant */ 03471 break; 03472 default: 03473 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass.integer); 03474 break; 03475 } 03476 break; 03477 case AST_FRAME_VOICE: 03478 /* Write audio if appropriate */ 03479 if (audiofd > -1) { 03480 if (write(audiofd, f->data.ptr, f->datalen) < 0) { 03481 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 03482 } 03483 } 03484 default: 03485 /* Ignore */ 03486 break; 03487 } 03488 ast_frfree(f); 03489 } 03490 } 03491 03492 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03493 03494 return 0; /* Time is up */ 03495 }
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 4653 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_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_LIST_NEXT, ast_log(), AST_MONITOR_RUNNING, ast_opt_generic_plc, ast_seekstream(), ast_senddigit_begin(), ast_senddigit_end(), 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, 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, and ast_channel::writetrans.
Referenced by adsi_careful_send(), agent_write(), ast_prod(), ast_readaudio_callback(), ast_readvideo_callback(), ast_udptl_bridge(), ast_write_video(), conf_queue_dtmf(), conf_run(), dahdi_bridge(), dictate_exec(), echo_exec(), fax_generator_generate(), feature_request_and_dial(), function_ilink(), gen_generate(), generic_fax_exec(), handle_jack_audio(), handle_link_data(), 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(), rpt(), send_link_dtmf(), send_link_keyquery(), send_tone_burst(), send_usb_txt(), send_waveform_to_channel(), silence_generator_generate(), simple_bridge_write(), softmix_bridge_poke(), softmix_bridge_write(), spy_generate(), and t38_tx_packet_handler().
04654 { 04655 int res = -1; 04656 struct ast_frame *f = NULL; 04657 int count = 0; 04658 04659 /*Deadlock avoidance*/ 04660 while(ast_channel_trylock(chan)) { 04661 /*cannot goto done since the channel is not locked*/ 04662 if(count++ > 10) { 04663 ast_debug(1, "Deadlock avoided for write to channel '%s'\n", chan->name); 04664 return 0; 04665 } 04666 usleep(1); 04667 } 04668 /* Stop if we're a zombie or need a soft hangup */ 04669 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 04670 goto done; 04671 04672 /* Handle any pending masquerades */ 04673 if (chan->masq) { 04674 ast_channel_unlock(chan); 04675 if (ast_do_masquerade(chan)) { 04676 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 04677 return res; /* no need to goto done: chan is already unlocked for masq */ 04678 } 04679 ast_channel_lock(chan); 04680 } 04681 if (chan->masqr) { 04682 res = 0; /* XXX explain, why 0 ? */ 04683 goto done; 04684 } 04685 04686 /* Perform the framehook write event here. After the frame enters the framehook list 04687 * there is no telling what will happen, how awesome is that!!! */ 04688 if (!(fr = ast_framehook_list_write_event(chan->framehooks, fr))) { 04689 res = 0; 04690 goto done; 04691 } 04692 04693 if (chan->generatordata && (!fr->src || strcasecmp(fr->src, "ast_prod"))) { 04694 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) { 04695 ast_deactivate_generator(chan); 04696 } else { 04697 if (fr->frametype == AST_FRAME_DTMF_END) { 04698 /* There is a generator running while we're in the middle of a digit. 04699 * It's probably inband DTMF, so go ahead and pass it so it can 04700 * stop the generator */ 04701 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04702 ast_channel_unlock(chan); 04703 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len); 04704 ast_channel_lock(chan); 04705 CHECK_BLOCKING(chan); 04706 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_UNHOLD) { 04707 /* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */ 04708 res = (chan->tech->indicate == NULL) ? 0 : 04709 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen); 04710 } 04711 res = 0; /* XXX explain, why 0 ? */ 04712 goto done; 04713 } 04714 } 04715 /* High bit prints debugging */ 04716 if (chan->fout & DEBUGCHAN_FLAG) 04717 ast_frame_dump(chan->name, fr, ">>"); 04718 CHECK_BLOCKING(chan); 04719 switch (fr->frametype) { 04720 case AST_FRAME_CONTROL: 04721 res = (chan->tech->indicate == NULL) ? 0 : 04722 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen); 04723 break; 04724 case AST_FRAME_DTMF_BEGIN: 04725 if (chan->audiohooks) { 04726 struct ast_frame *old_frame = fr; 04727 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 04728 if (old_frame != fr) 04729 f = fr; 04730 } 04731 send_dtmf_event(chan, "Sent", fr->subclass.integer, "Yes", "No"); 04732 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04733 ast_channel_unlock(chan); 04734 res = ast_senddigit_begin(chan, fr->subclass.integer); 04735 ast_channel_lock(chan); 04736 CHECK_BLOCKING(chan); 04737 break; 04738 case AST_FRAME_DTMF_END: 04739 if (chan->audiohooks) { 04740 struct ast_frame *new_frame = fr; 04741 04742 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 04743 if (new_frame != fr) { 04744 ast_frfree(new_frame); 04745 } 04746 } 04747 send_dtmf_event(chan, "Sent", fr->subclass.integer, "No", "Yes"); 04748 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04749 ast_channel_unlock(chan); 04750 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len); 04751 ast_channel_lock(chan); 04752 CHECK_BLOCKING(chan); 04753 break; 04754 case AST_FRAME_TEXT: 04755 if (fr->subclass.integer == AST_FORMAT_T140) { 04756 res = (chan->tech->write_text == NULL) ? 0 : 04757 chan->tech->write_text(chan, fr); 04758 } else { 04759 res = (chan->tech->send_text == NULL) ? 0 : 04760 chan->tech->send_text(chan, (char *) fr->data.ptr); 04761 } 04762 break; 04763 case AST_FRAME_HTML: 04764 res = (chan->tech->send_html == NULL) ? 0 : 04765 chan->tech->send_html(chan, fr->subclass.integer, (char *) fr->data.ptr, fr->datalen); 04766 break; 04767 case AST_FRAME_VIDEO: 04768 /* XXX Handle translation of video codecs one day XXX */ 04769 res = (chan->tech->write_video == NULL) ? 0 : 04770 chan->tech->write_video(chan, fr); 04771 break; 04772 case AST_FRAME_MODEM: 04773 res = (chan->tech->write == NULL) ? 0 : 04774 chan->tech->write(chan, fr); 04775 break; 04776 case AST_FRAME_VOICE: 04777 if (chan->tech->write == NULL) 04778 break; /*! \todo XXX should return 0 maybe ? */ 04779 04780 if (ast_opt_generic_plc && fr->subclass.codec == AST_FORMAT_SLINEAR) { 04781 apply_plc(chan, fr); 04782 } 04783 04784 /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */ 04785 if (fr->subclass.codec == chan->rawwriteformat) 04786 f = fr; 04787 else 04788 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr; 04789 04790 if (!f) { 04791 res = 0; 04792 break; 04793 } 04794 04795 if (chan->audiohooks) { 04796 struct ast_frame *prev = NULL, *new_frame, *cur, *dup; 04797 int freeoldlist = 0; 04798 04799 if (f != fr) { 04800 freeoldlist = 1; 04801 } 04802 04803 /* Since ast_audiohook_write may return a new frame, and the cur frame is 04804 * an item in a list of frames, create a new list adding each cur frame back to it 04805 * regardless if the cur frame changes or not. */ 04806 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 04807 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, cur); 04808 04809 /* if this frame is different than cur, preserve the end of the list, 04810 * free the old frames, and set cur to be the new frame */ 04811 if (new_frame != cur) { 04812 04813 /* doing an ast_frisolate here seems silly, but we are not guaranteed the new_frame 04814 * isn't part of local storage, meaning if ast_audiohook_write is called multiple 04815 * times it may override the previous frame we got from it unless we dup it */ 04816 if ((dup = ast_frisolate(new_frame))) { 04817 AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list); 04818 if (freeoldlist) { 04819 AST_LIST_NEXT(cur, frame_list) = NULL; 04820 ast_frfree(cur); 04821 } 04822 if (new_frame != dup) { 04823 ast_frfree(new_frame); 04824 } 04825 cur = dup; 04826 } 04827 } 04828 04829 /* now, regardless if cur is new or not, add it to the new list, 04830 * if the new list has not started, cur will become the first item. */ 04831 if (prev) { 04832 AST_LIST_NEXT(prev, frame_list) = cur; 04833 } else { 04834 f = cur; /* set f to be the beginning of our new list */ 04835 } 04836 prev = cur; 04837 } 04838 } 04839 04840 /* If Monitor is running on this channel, then we have to write frames out there too */ 04841 /* the translator on chan->writetrans may have returned multiple frames 04842 from the single frame we passed in; if so, feed each one of them to the 04843 monitor */ 04844 if (chan->monitor && chan->monitor->write_stream) { 04845 struct ast_frame *cur; 04846 04847 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 04848 /* XXX must explain this code */ 04849 #ifndef MONITOR_CONSTANT_DELAY 04850 int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples; 04851 if (jump >= 0) { 04852 jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 04853 if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1) 04854 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 04855 chan->outsmpl += (chan->insmpl - chan->outsmpl) + cur->samples; 04856 } else { 04857 chan->outsmpl += cur->samples; 04858 } 04859 #else 04860 int jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 04861 if (jump - MONITOR_DELAY >= 0) { 04862 if (ast_seekstream(chan->monitor->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1) 04863 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 04864 chan->outsmpl += chan->insmpl - chan->outsmpl; 04865 } else { 04866 chan->outsmpl += cur->samples; 04867 } 04868 #endif 04869 if (chan->monitor->state == AST_MONITOR_RUNNING) { 04870 if (ast_writestream(chan->monitor->write_stream, cur) < 0) 04871 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 04872 } 04873 } 04874 } 04875 04876 /* the translator on chan->writetrans may have returned multiple frames 04877 from the single frame we passed in; if so, feed each one of them to the 04878 channel, freeing each one after it has been written */ 04879 if ((f != fr) && AST_LIST_NEXT(f, frame_list)) { 04880 struct ast_frame *cur, *next; 04881 unsigned int skip = 0; 04882 04883 for (cur = f, next = AST_LIST_NEXT(cur, frame_list); 04884 cur; 04885 cur = next, next = cur ? AST_LIST_NEXT(cur, frame_list) : NULL) { 04886 if (!skip) { 04887 if ((res = chan->tech->write(chan, cur)) < 0) { 04888 chan->_softhangup |= AST_SOFTHANGUP_DEV; 04889 skip = 1; 04890 } else if (next) { 04891 /* don't do this for the last frame in the list, 04892 as the code outside the loop will do it once 04893 */ 04894 chan->fout = FRAMECOUNT_INC(chan->fout); 04895 } 04896 } 04897 ast_frfree(cur); 04898 } 04899 04900 /* reset f so the code below doesn't attempt to free it */ 04901 f = NULL; 04902 } else { 04903 res = chan->tech->write(chan, f); 04904 } 04905 break; 04906 case AST_FRAME_NULL: 04907 case AST_FRAME_IAX: 04908 /* Ignore these */ 04909 res = 0; 04910 break; 04911 default: 04912 /* At this point, fr is the incoming frame and f is NULL. Channels do 04913 * not expect to get NULL as a frame pointer and will segfault. Hence, 04914 * we output the original frame passed in. */ 04915 res = chan->tech->write(chan, fr); 04916 break; 04917 } 04918 04919 if (f && f != fr) 04920 ast_frfree(f); 04921 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04922 04923 /* Consider a write failure to force a soft hangup */ 04924 if (res < 0) { 04925 chan->_softhangup |= AST_SOFTHANGUP_DEV; 04926 } else { 04927 chan->fout = FRAMECOUNT_INC(chan->fout); 04928 } 04929 done: 04930 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) { 04931 /* The list gets recreated if audiohooks are added again later */ 04932 ast_audiohook_detach_list(chan->audiohooks); 04933 chan->audiohooks = NULL; 04934 } 04935 ast_channel_unlock(chan); 04936 return res; 04937 }
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 4538 of file channel.c.
References ast_write(), chanlist::chan, ast_channel::tech, and ast_channel_tech::write_video.
04539 { 04540 int res; 04541 if (!chan->tech->write_video) 04542 return 0; 04543 res = ast_write(chan, fr); 04544 if (!res) 04545 res = 1; 04546 return res; 04547 }
static void bridge_play_sounds | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1 | |||
) | [static] |
Definition at line 6989 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().
06990 { 06991 const char *s, *sound; 06992 06993 /* See if we need to play an audio file to any side of the bridge */ 06994 06995 ast_channel_lock(c0); 06996 if ((s = pbx_builtin_getvar_helper(c0, "BRIDGE_PLAY_SOUND"))) { 06997 sound = ast_strdupa(s); 06998 ast_channel_unlock(c0); 06999 bridge_playfile(c0, c1, sound, 0); 07000 pbx_builtin_setvar_helper(c0, "BRIDGE_PLAY_SOUND", NULL); 07001 } else { 07002 ast_channel_unlock(c0); 07003 } 07004 07005 ast_channel_lock(c1); 07006 if ((s = pbx_builtin_getvar_helper(c1, "BRIDGE_PLAY_SOUND"))) { 07007 sound = ast_strdupa(s); 07008 ast_channel_unlock(c1); 07009 bridge_playfile(c1, c0, sound, 0); 07010 pbx_builtin_setvar_helper(c1, "BRIDGE_PLAY_SOUND", NULL); 07011 } else { 07012 ast_channel_unlock(c1); 07013 } 07014 }
static void bridge_playfile | ( | struct ast_channel * | chan, | |
struct ast_channel * | peer, | |||
const char * | sound, | |||
int | remain | |||
) | [static] |
Definition at line 6683 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().
06684 { 06685 int min = 0, sec = 0, check; 06686 06687 check = ast_autoservice_start(peer); 06688 if (check) 06689 return; 06690 06691 if (remain > 0) { 06692 if (remain / 60 > 1) { 06693 min = remain / 60; 06694 sec = remain % 60; 06695 } else { 06696 sec = remain; 06697 } 06698 } 06699 06700 if (!strcmp(sound,"timeleft")) { /* Queue support */ 06701 ast_stream_and_wait(chan, "vm-youhave", ""); 06702 if (min) { 06703 ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, NULL); 06704 ast_stream_and_wait(chan, "queue-minutes", ""); 06705 } 06706 if (sec) { 06707 ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, NULL); 06708 ast_stream_and_wait(chan, "queue-seconds", ""); 06709 } 06710 } else { 06711 ast_stream_and_wait(chan, sound, ""); 06712 } 06713 06714 ast_autoservice_stop(peer); 06715 }
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 3603 of file channel.c.
Referenced by __ast_read(), and ast_write().
03604 { 03605 int diff = sample_rate - seek_rate; 03606 03607 if (diff > 0) { 03608 samples = samples / (float) (sample_rate / seek_rate); 03609 } else if (diff < 0) { 03610 samples = samples * (float) (seek_rate / sample_rate); 03611 } 03612 03613 return samples; 03614 }
static void* channel_cc_params_copy | ( | void * | data | ) | [static] |
Definition at line 9139 of file channel.c.
References ast_cc_config_params_init, and ast_cc_copy_config_params().
09140 { 09141 const struct ast_cc_config_params *src = data; 09142 struct ast_cc_config_params *dest = ast_cc_config_params_init(); 09143 if (!dest) { 09144 return NULL; 09145 } 09146 ast_cc_copy_config_params(dest, src); 09147 return dest; 09148 }
static void channel_cc_params_destroy | ( | void * | data | ) | [static] |
Definition at line 9150 of file channel.c.
References ast_cc_config_params_destroy().
09151 { 09152 struct ast_cc_config_params *cc_params = data; 09153 ast_cc_config_params_destroy(cc_params); 09154 }
static void channel_data_add_flags | ( | struct ast_data * | tree, | |
struct ast_channel * | chan | |||
) | [static] |
Definition at line 268 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().
00270 { 00271 ast_data_add_bool(tree, "DEFER_DTMF", ast_test_flag(chan, AST_FLAG_DEFER_DTMF)); 00272 ast_data_add_bool(tree, "WRITE_INT", ast_test_flag(chan, AST_FLAG_WRITE_INT)); 00273 ast_data_add_bool(tree, "BLOCKING", ast_test_flag(chan, AST_FLAG_BLOCKING)); 00274 ast_data_add_bool(tree, "ZOMBIE", ast_test_flag(chan, AST_FLAG_ZOMBIE)); 00275 ast_data_add_bool(tree, "EXCEPTION", ast_test_flag(chan, AST_FLAG_EXCEPTION)); 00276 ast_data_add_bool(tree, "MOH", ast_test_flag(chan, AST_FLAG_MOH)); 00277 ast_data_add_bool(tree, "SPYING", ast_test_flag(chan, AST_FLAG_SPYING)); 00278 ast_data_add_bool(tree, "NBRIDGE", ast_test_flag(chan, AST_FLAG_NBRIDGE)); 00279 ast_data_add_bool(tree, "IN_AUTOLOOP", ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)); 00280 ast_data_add_bool(tree, "OUTGOING", ast_test_flag(chan, AST_FLAG_OUTGOING)); 00281 ast_data_add_bool(tree, "IN_DTMF", ast_test_flag(chan, AST_FLAG_IN_DTMF)); 00282 ast_data_add_bool(tree, "EMULATE_DTMF", ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)); 00283 ast_data_add_bool(tree, "END_DTMF_ONLY", ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)); 00284 ast_data_add_bool(tree, "ANSWERED_ELSEWHERE", ast_test_flag(chan, AST_FLAG_ANSWERED_ELSEWHERE)); 00285 ast_data_add_bool(tree, "MASQ_NOSTREAM", ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM)); 00286 ast_data_add_bool(tree, "BRIDGE_HANGUP_RUN", ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN)); 00287 ast_data_add_bool(tree, "BRIDGE_HANGUP_DONT", ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT)); 00288 ast_data_add_bool(tree, "DISABLE_WORKAROUNDS", ast_test_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS)); 00289 }
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 1567 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().
01570 { 01571 struct ast_channel_iterator *i; 01572 struct ast_channel tmp_chan = { 01573 .name = name, 01574 /* This is sort of a hack. Basically, we're using an arbitrary field 01575 * in ast_channel to pass the name_len for a prefix match. If this 01576 * gets changed, then the compare callback must be changed, too. */ 01577 .rings = name_len, 01578 }; 01579 01580 if (!(i = ast_calloc(1, sizeof(*i)))) { 01581 return NULL; 01582 } 01583 01584 if (exten) { 01585 ast_copy_string(tmp_chan.exten, exten, sizeof(tmp_chan.exten)); 01586 } 01587 01588 if (context) { 01589 ast_copy_string(tmp_chan.context, context, sizeof(tmp_chan.context)); 01590 } 01591 01592 if (!(i->active_iterator = ao2_find(channels, &tmp_chan, 01593 OBJ_MULTIPLE | ((!ast_strlen_zero(name) && (name_len == 0)) ? OBJ_POINTER : 0)))) { 01594 ast_free(i); 01595 return NULL; 01596 } 01597 01598 return i; 01599 }
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 7814 of file channel.c.
References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.
07815 { 07816 switch (reason) { 07817 case CHANNEL_MODULE_LOAD: 07818 return "LOAD (Channel module load)"; 07819 07820 case CHANNEL_MODULE_RELOAD: 07821 return "RELOAD (Channel module reload)"; 07822 07823 case CHANNEL_CLI_RELOAD: 07824 return "CLIRELOAD (Channel module reload by CLI command)"; 07825 07826 default: 07827 return "MANAGERRELOAD (Channel module reload by manager)"; 07828 } 07829 };
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 5915 of file channel.c.
References AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_var_assign(), ast_var_t::entries, ast_var_t::name, ast_var_t::value, and ast_channel::varshead.
Referenced by ast_do_masquerade().
05916 { 05917 struct ast_var_t *current, *newvar; 05918 /* Append variables from clone channel into original channel */ 05919 /* XXX Is this always correct? We have to in order to keep MACROS working XXX */ 05920 if (AST_LIST_FIRST(&clonechan->varshead)) 05921 AST_LIST_APPEND_LIST(&original->varshead, &clonechan->varshead, entries); 05922 05923 /* then, dup the varshead list into the clone */ 05924 05925 AST_LIST_TRAVERSE(&original->varshead, current, entries) { 05926 newvar = ast_var_assign(current->name, current->value); 05927 if (newvar) 05928 AST_LIST_INSERT_TAIL(&clonechan->varshead, newvar, entries); 05929 } 05930 }
static char* complete_channeltypes | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 523 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().
00524 { 00525 struct chanlist *cl; 00526 int which = 0; 00527 int wordlen; 00528 char *ret = NULL; 00529 00530 if (a->pos != 3) 00531 return NULL; 00532 00533 wordlen = strlen(a->word); 00534 00535 AST_RWLIST_RDLOCK(&backends); 00536 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00537 if (!strncasecmp(a->word, cl->tech->type, wordlen) && ++which > a->n) { 00538 ret = ast_strdup(cl->tech->type); 00539 break; 00540 } 00541 } 00542 AST_RWLIST_UNLOCK(&backends); 00543 00544 return ret; 00545 }
static int data_channels_provider_handler | ( | const struct ast_data_search * | search, | |
struct ast_data * | root | |||
) | [static] |
Definition at line 7573 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.
07575 { 07576 struct ast_channel *c; 07577 struct ast_channel_iterator *iter = NULL; 07578 struct ast_data *data_channel; 07579 07580 for (iter = ast_channel_iterator_all_new(); 07581 iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) { 07582 ast_channel_lock(c); 07583 07584 data_channel = ast_data_add_node(root, "channel"); 07585 if (!data_channel) { 07586 ast_channel_unlock(c); 07587 continue; 07588 } 07589 07590 if (ast_channel_data_add_structure(data_channel, c, 1) < 0) { 07591 ast_log(LOG_ERROR, "Unable to add channel structure for channel: %s\n", c->name); 07592 } 07593 07594 ast_channel_unlock(c); 07595 07596 if (!ast_data_search_match(search, data_channel)) { 07597 ast_data_remove_node(root, data_channel); 07598 } 07599 } 07600 if (iter) { 07601 ast_channel_iterator_destroy(iter); 07602 } 07603 07604 return 0; 07605 }
static int data_channeltypes_provider_handler | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 7611 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.
07613 { 07614 struct chanlist *cl; 07615 struct ast_data *data_type; 07616 07617 AST_RWLIST_RDLOCK(&backends); 07618 AST_RWLIST_TRAVERSE(&backends, cl, list) { 07619 data_type = ast_data_add_node(data_root, "type"); 07620 if (!data_type) { 07621 continue; 07622 } 07623 ast_data_add_str(data_type, "name", cl->tech->type); 07624 ast_data_add_str(data_type, "description", cl->tech->description); 07625 ast_data_add_bool(data_type, "devicestate", cl->tech->devicestate ? 1 : 0); 07626 ast_data_add_bool(data_type, "indications", cl->tech->indicate ? 1 : 0); 07627 ast_data_add_bool(data_type, "transfer", cl->tech->transfer ? 1 : 0); 07628 ast_data_add_bool(data_type, "send_digit_begin", cl->tech->send_digit_begin ? 1 : 0); 07629 ast_data_add_bool(data_type, "send_digit_end", cl->tech->send_digit_end ? 1 : 0); 07630 ast_data_add_bool(data_type, "call", cl->tech->call ? 1 : 0); 07631 ast_data_add_bool(data_type, "hangup", cl->tech->hangup ? 1 : 0); 07632 ast_data_add_bool(data_type, "answer", cl->tech->answer ? 1 : 0); 07633 ast_data_add_bool(data_type, "read", cl->tech->read ? 1 : 0); 07634 ast_data_add_bool(data_type, "write", cl->tech->write ? 1 : 0); 07635 ast_data_add_bool(data_type, "send_text", cl->tech->send_text ? 1 : 0); 07636 ast_data_add_bool(data_type, "send_image", cl->tech->send_image ? 1 : 0); 07637 ast_data_add_bool(data_type, "send_html", cl->tech->send_html ? 1 : 0); 07638 ast_data_add_bool(data_type, "exception", cl->tech->exception ? 1 : 0); 07639 ast_data_add_bool(data_type, "bridge", cl->tech->bridge ? 1 : 0); 07640 ast_data_add_bool(data_type, "early_bridge", cl->tech->early_bridge ? 1 : 0); 07641 ast_data_add_bool(data_type, "fixup", cl->tech->fixup ? 1 : 0); 07642 ast_data_add_bool(data_type, "setoption", cl->tech->setoption ? 1 : 0); 07643 ast_data_add_bool(data_type, "queryoption", cl->tech->queryoption ? 1 : 0); 07644 ast_data_add_bool(data_type, "write_video", cl->tech->write_video ? 1 : 0); 07645 ast_data_add_bool(data_type, "write_text", cl->tech->write_text ? 1 : 0); 07646 ast_data_add_bool(data_type, "bridged_channel", cl->tech->bridged_channel ? 1 : 0); 07647 ast_data_add_bool(data_type, "func_channel_read", cl->tech->func_channel_read ? 1 : 0); 07648 ast_data_add_bool(data_type, "func_channel_write", cl->tech->func_channel_write ? 1 : 0); 07649 ast_data_add_bool(data_type, "get_base_channel", cl->tech->get_base_channel ? 1 : 0); 07650 ast_data_add_bool(data_type, "set_base_channel", cl->tech->set_base_channel ? 1 : 0); 07651 ast_data_add_bool(data_type, "get_pvt_uniqueid", cl->tech->get_pvt_uniqueid ? 1 : 0); 07652 ast_data_add_bool(data_type, "cc_callback", cl->tech->cc_callback ? 1 : 0); 07653 07654 ast_data_add_codecs(data_type, "capabilities", cl->tech->capabilities); 07655 07656 if (!ast_data_search_match(search, data_type)) { 07657 ast_data_remove_node(data_root, data_type); 07658 } 07659 } 07660 AST_RWLIST_UNLOCK(&backends); 07661 07662 return 0; 07663 }
static void free_translation | ( | struct ast_channel * | clonechan | ) | [static] |
Definition at line 2627 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().
02628 { 02629 if (clonechan->writetrans) 02630 ast_translator_free_path(clonechan->writetrans); 02631 if (clonechan->readtrans) 02632 ast_translator_free_path(clonechan->readtrans); 02633 clonechan->writetrans = NULL; 02634 clonechan->readtrans = NULL; 02635 clonechan->rawwriteformat = clonechan->nativeformats; 02636 clonechan->rawreadformat = clonechan->nativeformats; 02637 }
static int generator_force | ( | const void * | data | ) | [static] |
Definition at line 2946 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().
02947 { 02948 /* Called if generator doesn't have data */ 02949 void *tmp; 02950 int res; 02951 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL; 02952 struct ast_channel *chan = (struct ast_channel *)data; 02953 02954 ast_channel_lock(chan); 02955 tmp = chan->generatordata; 02956 chan->generatordata = NULL; 02957 if (chan->generator) 02958 generate = chan->generator->generate; 02959 ast_channel_unlock(chan); 02960 02961 if (!tmp || !generate) 02962 return 0; 02963 02964 res = generate(chan, tmp, 0, ast_format_rate(chan->writeformat & AST_FORMAT_AUDIO_MASK) / 50); 02965 02966 chan->generatordata = tmp; 02967 02968 if (res) { 02969 ast_debug(1, "Auto-deactivating generator\n"); 02970 ast_deactivate_generator(chan); 02971 } 02972 02973 return 0; 02974 }
static void handle_cause | ( | int | cause, | |
int * | outstate | |||
) | [static] |
Definition at line 5057 of file channel.c.
References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CONTROL_BUSY, and AST_CONTROL_CONGESTION.
05058 { 05059 if (outstate) { 05060 /* compute error and return */ 05061 if (cause == AST_CAUSE_BUSY) 05062 *outstate = AST_CONTROL_BUSY; 05063 else if (cause == AST_CAUSE_CONGESTION) 05064 *outstate = AST_CONTROL_CONGESTION; 05065 else 05066 *outstate = 0; 05067 } 05068 }
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 548 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.
00549 { 00550 struct chanlist *cl = NULL; 00551 char buf[512]; 00552 00553 switch (cmd) { 00554 case CLI_INIT: 00555 e->command = "core show channeltype"; 00556 e->usage = 00557 "Usage: core show channeltype <name>\n" 00558 " Show details about the specified channel type, <name>.\n"; 00559 return NULL; 00560 case CLI_GENERATE: 00561 return complete_channeltypes(a); 00562 } 00563 00564 if (a->argc != 4) 00565 return CLI_SHOWUSAGE; 00566 00567 AST_RWLIST_RDLOCK(&backends); 00568 00569 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00570 if (!strncasecmp(cl->tech->type, a->argv[3], strlen(cl->tech->type))) 00571 break; 00572 } 00573 00574 00575 if (!cl) { 00576 ast_cli(a->fd, "\n%s is not a registered channel driver.\n", a->argv[3]); 00577 AST_RWLIST_UNLOCK(&backends); 00578 return CLI_FAILURE; 00579 } 00580 00581 ast_cli(a->fd, 00582 "-- Info about channel driver: %s --\n" 00583 " Device State: %s\n" 00584 " Indication: %s\n" 00585 " Transfer : %s\n" 00586 " Capabilities: %s\n" 00587 " Digit Begin: %s\n" 00588 " Digit End: %s\n" 00589 " Send HTML : %s\n" 00590 " Image Support: %s\n" 00591 " Text Support: %s\n", 00592 cl->tech->type, 00593 (cl->tech->devicestate) ? "yes" : "no", 00594 (cl->tech->indicate) ? "yes" : "no", 00595 (cl->tech->transfer) ? "yes" : "no", 00596 ast_getformatname_multiple(buf, sizeof(buf), (cl->tech->capabilities) ? cl->tech->capabilities : -1), 00597 (cl->tech->send_digit_begin) ? "yes" : "no", 00598 (cl->tech->send_digit_end) ? "yes" : "no", 00599 (cl->tech->send_html) ? "yes" : "no", 00600 (cl->tech->send_image) ? "yes" : "no", 00601 (cl->tech->send_text) ? "yes" : "no" 00602 00603 ); 00604 00605 AST_RWLIST_UNLOCK(&backends); 00606 00607 return CLI_SUCCESS; 00608 }
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 482 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.
00483 { 00484 #define FORMAT "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\n" 00485 struct chanlist *cl; 00486 int count_chan = 0; 00487 00488 switch (cmd) { 00489 case CLI_INIT: 00490 e->command = "core show channeltypes"; 00491 e->usage = 00492 "Usage: core show channeltypes\n" 00493 " Lists available channel types registered in your\n" 00494 " Asterisk server.\n"; 00495 return NULL; 00496 case CLI_GENERATE: 00497 return NULL; 00498 } 00499 00500 if (a->argc != 3) 00501 return CLI_SHOWUSAGE; 00502 00503 ast_cli(a->fd, FORMAT, "Type", "Description", "Devicestate", "Indications", "Transfer"); 00504 ast_cli(a->fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------"); 00505 00506 AST_RWLIST_RDLOCK(&backends); 00507 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00508 ast_cli(a->fd, FORMAT, cl->tech->type, cl->tech->description, 00509 (cl->tech->devicestate) ? "yes" : "no", 00510 (cl->tech->indicate) ? "yes" : "no", 00511 (cl->tech->transfer) ? "yes" : "no"); 00512 count_chan++; 00513 } 00514 AST_RWLIST_UNLOCK(&backends); 00515 00516 ast_cli(a->fd, "----------\n%d channel drivers registered.\n", count_chan); 00517 00518 return CLI_SUCCESS; 00519 00520 #undef FORMAT 00521 }
static int attribute_const is_visible_indication | ( | enum ast_control_frame_type | condition | ) | [static] |
Definition at line 4164 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_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_VIDUPDATE, and AST_CONTROL_WINK.
Referenced by ast_indicate_data().
04165 { 04166 /* Don't include a default case here so that we get compiler warnings 04167 * when a new type is added. */ 04168 04169 switch (condition) { 04170 case AST_CONTROL_PROGRESS: 04171 case AST_CONTROL_PROCEEDING: 04172 case AST_CONTROL_VIDUPDATE: 04173 case AST_CONTROL_SRCUPDATE: 04174 case AST_CONTROL_SRCCHANGE: 04175 case AST_CONTROL_RADIO_KEY: 04176 case AST_CONTROL_RADIO_UNKEY: 04177 case AST_CONTROL_OPTION: 04178 case AST_CONTROL_WINK: 04179 case AST_CONTROL_FLASH: 04180 case AST_CONTROL_OFFHOOK: 04181 case AST_CONTROL_TAKEOFFHOOK: 04182 case AST_CONTROL_ANSWER: 04183 case AST_CONTROL_HANGUP: 04184 case AST_CONTROL_CONNECTED_LINE: 04185 case AST_CONTROL_REDIRECTING: 04186 case AST_CONTROL_TRANSFER: 04187 case AST_CONTROL_T38_PARAMETERS: 04188 case _XXX_AST_CONTROL_T38: 04189 case AST_CONTROL_CC: 04190 case AST_CONTROL_READ_ACTION: 04191 case AST_CONTROL_AOC: 04192 case AST_CONTROL_END_OF_Q: 04193 break; 04194 04195 case AST_CONTROL_CONGESTION: 04196 case AST_CONTROL_BUSY: 04197 case AST_CONTROL_RINGING: 04198 case AST_CONTROL_RING: 04199 case AST_CONTROL_HOLD: 04200 /* You can hear these */ 04201 return 1; 04202 04203 case AST_CONTROL_UNHOLD: 04204 /* This is a special case. You stop hearing this. */ 04205 break; 04206 } 04207 04208 return 0; 04209 }
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 6932 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().
06933 { 06934 struct ast_channel *chans[2] = { c0, c1 }; 06935 ast_manager_event_multichan(EVENT_FLAG_CALL, "Bridge", 2, chans, 06936 "Bridgestate: %s\r\n" 06937 "Bridgetype: %s\r\n" 06938 "Channel1: %s\r\n" 06939 "Channel2: %s\r\n" 06940 "Uniqueid1: %s\r\n" 06941 "Uniqueid2: %s\r\n" 06942 "CallerID1: %s\r\n" 06943 "CallerID2: %s\r\n", 06944 onoff ? "Link" : "Unlink", 06945 type == 1 ? "core" : "native", 06946 c0->name, c1->name, 06947 c0->uniqueid, c1->uniqueid, 06948 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, ""), 06949 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "")); 06950 }
static void masquerade_colp_transfer | ( | struct ast_channel * | transferee, | |
struct xfer_masquerade_ds * | colp | |||
) | [static] |
Definition at line 6121 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().
06122 { 06123 struct ast_control_read_action_payload *frame_payload; 06124 int payload_size; 06125 int frame_size; 06126 unsigned char connected_line_data[1024]; 06127 06128 /* Release any hold on the target. */ 06129 if (colp->target_held) { 06130 ast_queue_control(transferee, AST_CONTROL_UNHOLD); 06131 } 06132 06133 /* 06134 * Since transferee may not actually be bridged to another channel, 06135 * there is no way for us to queue a frame so that its connected 06136 * line status will be updated. Instead, we use the somewhat 06137 * hackish approach of using a special control frame type that 06138 * instructs ast_read() to perform a specific action. In this 06139 * case, the frame we queue tells ast_read() to call the 06140 * connected line interception macro configured for transferee. 06141 */ 06142 payload_size = ast_connected_line_build_data(connected_line_data, 06143 sizeof(connected_line_data), &colp->target_id, NULL); 06144 if (payload_size != -1) { 06145 frame_size = payload_size + sizeof(*frame_payload); 06146 frame_payload = alloca(frame_size); 06147 frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO; 06148 frame_payload->payload_size = payload_size; 06149 memcpy(frame_payload->payload, connected_line_data, payload_size); 06150 ast_queue_control_data(transferee, AST_CONTROL_READ_ACTION, frame_payload, 06151 frame_size); 06152 } 06153 /* 06154 * In addition to queueing the read action frame so that the 06155 * connected line info on transferee will be updated, we also are 06156 * going to queue a plain old connected line update on transferee to 06157 * update the target. 06158 */ 06159 ast_channel_queue_connected_line_update(transferee, &colp->transferee_id, NULL); 06160 }
static const char* oldest_linkedid | ( | const char * | a, | |
const char * | b | |||
) | [static] |
Definition at line 5945 of file channel.c.
References ast_strlen_zero().
Referenced by ast_channel_set_linkgroup().
05946 { 05947 const char *satime, *saseq; 05948 const char *sbtime, *sbseq; 05949 const char *dash; 05950 05951 unsigned int atime, aseq, btime, bseq; 05952 05953 if (ast_strlen_zero(a)) 05954 return b; 05955 05956 if (ast_strlen_zero(b)) 05957 return a; 05958 05959 satime = a; 05960 sbtime = b; 05961 05962 /* jump over the system name */ 05963 if ((dash = strrchr(satime, '-'))) { 05964 satime = dash+1; 05965 } 05966 if ((dash = strrchr(sbtime, '-'))) { 05967 sbtime = dash+1; 05968 } 05969 05970 /* the sequence comes after the '.' */ 05971 saseq = strchr(satime, '.'); 05972 sbseq = strchr(sbtime, '.'); 05973 if (!saseq || !sbseq) 05974 return NULL; 05975 saseq++; 05976 sbseq++; 05977 05978 /* convert it all to integers */ 05979 atime = atoi(satime); /* note that atoi is ignoring the '.' after the time string */ 05980 btime = atoi(sbtime); /* note that atoi is ignoring the '.' after the time string */ 05981 aseq = atoi(saseq); 05982 bseq = atoi(sbseq); 05983 05984 /* and finally compare */ 05985 if (atime == btime) { 05986 return (aseq < bseq) ? a : b; 05987 } 05988 else { 05989 return (atime < btime) ? a : b; 05990 } 05991 }
static void party_connected_line_copy_transfer | ( | struct ast_party_connected_line * | dest, | |
const struct ast_party_connected_line * | src | |||
) | [static] |
Definition at line 5752 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().
05753 { 05754 struct ast_party_connected_line connected; 05755 05756 connected = *((struct ast_party_connected_line *) src); 05757 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; 05758 05759 /* Make sure empty strings will be erased. */ 05760 if (!connected.id.name.str) { 05761 connected.id.name.str = ""; 05762 } 05763 if (!connected.id.number.str) { 05764 connected.id.number.str = ""; 05765 } 05766 if (!connected.id.subaddress.str) { 05767 connected.id.subaddress.str = ""; 05768 } 05769 if (!connected.id.tag) { 05770 connected.id.tag = ""; 05771 } 05772 05773 ast_party_connected_line_copy(dest, &connected); 05774 }
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 8164 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().
08167 { 08168 size_t length; 08169 size_t pos = 0; 08170 int res; 08171 08172 /* 08173 * The size of integer values must be fixed in case the frame is 08174 * shipped to another machine. 08175 */ 08176 08177 if (!update || update->name) { 08178 res = party_name_build_data(data + pos, datalen - pos, &id->name, label, 08179 &ies->name); 08180 if (res < 0) { 08181 return -1; 08182 } 08183 pos += res; 08184 } 08185 08186 if (!update || update->number) { 08187 res = party_number_build_data(data + pos, datalen - pos, &id->number, label, 08188 &ies->number); 08189 if (res < 0) { 08190 return -1; 08191 } 08192 pos += res; 08193 } 08194 08195 if (!update || update->subaddress) { 08196 res = party_subaddress_build_data(data + pos, datalen - pos, &id->subaddress, 08197 label, &ies->subaddress); 08198 if (res < 0) { 08199 return -1; 08200 } 08201 pos += res; 08202 } 08203 08204 /* *************** Party id user tag **************************** */ 08205 if (id->tag) { 08206 length = strlen(id->tag); 08207 if (datalen < pos + (sizeof(data[0]) * 2) + length) { 08208 ast_log(LOG_WARNING, "No space left for %s tag\n", label); 08209 return -1; 08210 } 08211 data[pos++] = ies->tag; 08212 data[pos++] = length; 08213 memcpy(data + pos, id->tag, length); 08214 pos += length; 08215 } 08216 08217 /* *************** Party id combined presentation *************** */ 08218 if (!update || update->number) { 08219 int presentation; 08220 08221 if (!update || update->name) { 08222 presentation = ast_party_id_presentation(id); 08223 } else { 08224 /* 08225 * We must compromise because not all the information is available 08226 * to determine a combined presentation value. 08227 * We will only send the number presentation instead. 08228 */ 08229 presentation = id->number.presentation; 08230 } 08231 08232 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08233 ast_log(LOG_WARNING, "No space left for %s combined presentation\n", label); 08234 return -1; 08235 } 08236 data[pos++] = ies->combined_presentation; 08237 data[pos++] = 1; 08238 data[pos++] = presentation; 08239 } 08240 08241 return pos; 08242 }
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 7938 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().
07939 { 07940 size_t length; 07941 size_t pos = 0; 07942 07943 /* 07944 * The size of integer values must be fixed in case the frame is 07945 * shipped to another machine. 07946 */ 07947 if (name->str) { 07948 length = strlen(name->str); 07949 if (datalen < pos + (sizeof(data[0]) * 2) + length) { 07950 ast_log(LOG_WARNING, "No space left for %s name\n", label); 07951 return -1; 07952 } 07953 data[pos++] = ies->str; 07954 data[pos++] = length; 07955 memcpy(data + pos, name->str, length); 07956 pos += length; 07957 } 07958 07959 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 07960 ast_log(LOG_WARNING, "No space left for %s name char set\n", label); 07961 return -1; 07962 } 07963 data[pos++] = ies->char_set; 07964 data[pos++] = 1; 07965 data[pos++] = name->char_set; 07966 07967 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 07968 ast_log(LOG_WARNING, "No space left for %s name presentation\n", label); 07969 return -1; 07970 } 07971 data[pos++] = ies->presentation; 07972 data[pos++] = 1; 07973 data[pos++] = name->presentation; 07974 07975 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 07976 ast_log(LOG_WARNING, "No space left for %s name valid\n", label); 07977 return -1; 07978 } 07979 data[pos++] = ies->valid; 07980 data[pos++] = 1; 07981 data[pos++] = name->valid; 07982 07983 return pos; 07984 }
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 8012 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().
08013 { 08014 size_t length; 08015 size_t pos = 0; 08016 08017 /* 08018 * The size of integer values must be fixed in case the frame is 08019 * shipped to another machine. 08020 */ 08021 if (number->str) { 08022 length = strlen(number->str); 08023 if (datalen < pos + (sizeof(data[0]) * 2) + length) { 08024 ast_log(LOG_WARNING, "No space left for %s number\n", label); 08025 return -1; 08026 } 08027 data[pos++] = ies->str; 08028 data[pos++] = length; 08029 memcpy(data + pos, number->str, length); 08030 pos += length; 08031 } 08032 08033 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08034 ast_log(LOG_WARNING, "No space left for %s numbering plan\n", label); 08035 return -1; 08036 } 08037 data[pos++] = ies->plan; 08038 data[pos++] = 1; 08039 data[pos++] = number->plan; 08040 08041 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08042 ast_log(LOG_WARNING, "No space left for %s number presentation\n", label); 08043 return -1; 08044 } 08045 data[pos++] = ies->presentation; 08046 data[pos++] = 1; 08047 data[pos++] = number->presentation; 08048 08049 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08050 ast_log(LOG_WARNING, "No space left for %s number valid\n", label); 08051 return -1; 08052 } 08053 data[pos++] = ies->valid; 08054 data[pos++] = 1; 08055 data[pos++] = number->valid; 08056 08057 return pos; 08058 }
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 8086 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().
08087 { 08088 size_t length; 08089 size_t pos = 0; 08090 08091 /* 08092 * The size of integer values must be fixed in case the frame is 08093 * shipped to another machine. 08094 */ 08095 if (subaddress->str) { 08096 length = strlen(subaddress->str); 08097 if (datalen < pos + (sizeof(data[0]) * 2) + length) { 08098 ast_log(LOG_WARNING, "No space left for %s subaddress\n", label); 08099 return -1; 08100 } 08101 data[pos++] = ies->str; 08102 data[pos++] = length; 08103 memcpy(data + pos, subaddress->str, length); 08104 pos += length; 08105 } 08106 08107 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08108 ast_log(LOG_WARNING, "No space left for %s type of subaddress\n", label); 08109 return -1; 08110 } 08111 data[pos++] = ies->type; 08112 data[pos++] = 1; 08113 data[pos++] = subaddress->type; 08114 08115 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08116 ast_log(LOG_WARNING, 08117 "No space left for %s subaddress odd-even indicator\n", label); 08118 return -1; 08119 } 08120 data[pos++] = ies->odd_even_indicator; 08121 data[pos++] = 1; 08122 data[pos++] = subaddress->odd_even_indicator; 08123 08124 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08125 ast_log(LOG_WARNING, "No space left for %s subaddress valid\n", label); 08126 return -1; 08127 } 08128 data[pos++] = ies->valid; 08129 data[pos++] = 1; 08130 data[pos++] = subaddress->valid; 08131 08132 return pos; 08133 }
static void plc_ds_destroy | ( | void * | data | ) | [static] |
Definition at line 4562 of file channel.c.
References ast_free, and plc_ds::samples_buf.
04563 { 04564 struct plc_ds *plc = data; 04565 ast_free(plc->samples_buf); 04566 ast_free(plc); 04567 }
static void queue_dtmf_readq | ( | struct ast_channel * | chan, | |
struct ast_frame * | f | |||
) | [inline, static] |
Definition at line 3558 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().
03559 { 03560 struct ast_frame *fr = &chan->dtmff; 03561 03562 fr->frametype = AST_FRAME_DTMF_END; 03563 fr->subclass.integer = f->subclass.integer; 03564 fr->len = f->len; 03565 03566 /* The only time this function will be called is for a frame that just came 03567 * out of the channel driver. So, we want to stick it on the tail of the 03568 * readq. */ 03569 03570 ast_queue_frame(chan, fr); 03571 }
static void report_new_callerid | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6091 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().
06092 { 06093 int pres; 06094 06095 pres = ast_party_id_presentation(&chan->caller.id); 06096 ast_manager_event(chan, EVENT_FLAG_CALL, "NewCallerid", 06097 "Channel: %s\r\n" 06098 "CallerIDNum: %s\r\n" 06099 "CallerIDName: %s\r\n" 06100 "Uniqueid: %s\r\n" 06101 "CID-CallingPres: %d (%s)\r\n", 06102 chan->name, 06103 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""), 06104 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""), 06105 chan->uniqueid, 06106 pres, 06107 ast_describe_caller_presentation(pres) 06108 ); 06109 }
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 3497 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().
03498 { 03499 ast_manager_event(chan, EVENT_FLAG_DTMF, 03500 "DTMF", 03501 "Channel: %s\r\n" 03502 "Uniqueid: %s\r\n" 03503 "Digit: %c\r\n" 03504 "Direction: %s\r\n" 03505 "Begin: %s\r\n" 03506 "End: %s\r\n", 03507 chan->name, chan->uniqueid, digit, direction, begin, end); 03508 }
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 4939 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().
04941 { 04942 format_t native, native_fmt = ast_best_codec(fmt); 04943 int res; 04944 char from[200], to[200]; 04945 04946 /* Make sure we only consider audio */ 04947 fmt &= AST_FORMAT_AUDIO_MASK; 04948 04949 native = chan->nativeformats; 04950 04951 if (!fmt || !native) /* No audio requested */ 04952 return 0; /* Let's try a call without any sounds (video, text) */ 04953 04954 /* See if the underlying channel driver is capable of performing transcoding for us */ 04955 if (!ast_channel_setoption(chan, direction ? AST_OPTION_FORMAT_WRITE : AST_OPTION_FORMAT_READ, &native_fmt, sizeof(int*), 0)) { 04956 ast_debug(1, "Channel driver natively set channel %s to %s format %s\n", chan->name, 04957 direction ? "write" : "read", ast_getformatname(native_fmt)); 04958 chan->nativeformats = *rawformat = *format = native_fmt; 04959 if (*trans) { 04960 ast_translator_free_path(*trans); 04961 } 04962 *trans = NULL; 04963 return 0; 04964 } 04965 04966 /* Find a translation path from the native format to one of the desired formats */ 04967 if (!direction) 04968 /* reading */ 04969 res = ast_translator_best_choice(&fmt, &native); 04970 else 04971 /* writing */ 04972 res = ast_translator_best_choice(&native, &fmt); 04973 04974 if (res < 0) { 04975 ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n", 04976 ast_getformatname_multiple(from, sizeof(from), native), 04977 ast_getformatname_multiple(to, sizeof(to), fmt)); 04978 return -1; 04979 } 04980 04981 /* Now we have a good choice for both. */ 04982 ast_channel_lock(chan); 04983 04984 if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) { 04985 /* the channel is already in these formats, so nothing to do */ 04986 ast_channel_unlock(chan); 04987 return 0; 04988 } 04989 04990 *rawformat = native; 04991 /* User perspective is fmt */ 04992 *format = fmt; 04993 /* Free any read translation we have right now */ 04994 if (*trans) { 04995 ast_translator_free_path(*trans); 04996 *trans = NULL; 04997 } 04998 /* Build a translation path from the raw format to the desired format */ 04999 if (*format == *rawformat) { 05000 /* 05001 * If we were able to swap the native format to the format that 05002 * has been requested, then there is no need to try to build 05003 * a translation path. 05004 */ 05005 res = 0; 05006 } else { 05007 if (!direction) { 05008 /* reading */ 05009 *trans = ast_translator_build_path(*format, *rawformat); 05010 } else { 05011 /* writing */ 05012 *trans = ast_translator_build_path(*rawformat, *format); 05013 } 05014 res = *trans ? 0 : -1; 05015 } 05016 ast_channel_unlock(chan); 05017 ast_debug(1, "Set channel %s to %s format %s\n", chan->name, 05018 direction ? "write" : "read", ast_getformatname(fmt)); 05019 return res; 05020 }
static int set_security_requirements | ( | const struct ast_channel * | requestor, | |
struct ast_channel * | out | |||
) | [static] |
Definition at line 5315 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().
05316 { 05317 int ops[2][2] = { 05318 {AST_OPTION_SECURE_SIGNALING, 0}, 05319 {AST_OPTION_SECURE_MEDIA, 0}, 05320 }; 05321 int i; 05322 struct ast_channel *r = (struct ast_channel *) requestor; /* UGLY */ 05323 struct ast_datastore *ds; 05324 05325 if (!requestor || !out) { 05326 return 0; 05327 } 05328 05329 ast_channel_lock(r); 05330 if ((ds = ast_channel_datastore_find(r, &secure_call_info, NULL))) { 05331 struct ast_secure_call_store *encrypt = ds->data; 05332 ops[0][1] = encrypt->signaling; 05333 ops[1][1] = encrypt->media; 05334 } else { 05335 ast_channel_unlock(r); 05336 return 0; 05337 } 05338 ast_channel_unlock(r); 05339 05340 for (i = 0; i < 2; i++) { 05341 if (ops[i][1]) { 05342 if (ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0)) { 05343 /* We require a security feature, but the channel won't provide it */ 05344 return -1; 05345 } 05346 } else { 05347 /* We don't care if we can't clear the option on a channel that doesn't support it */ 05348 ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0); 05349 } 05350 } 05351 05352 return 0; 05353 }
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 3576 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().
03577 { 03578 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)) { 03579 /* We're in the middle of emulating a digit, or DTMF has been 03580 * explicitly deferred. Skip this digit, then. */ 03581 return 1; 03582 } 03583 03584 if (!ast_tvzero(chan->dtmf_tv) && 03585 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) { 03586 /* We're not in the middle of a digit, but it hasn't been long enough 03587 * since the last digit, so we'll have to skip DTMF for now. */ 03588 return 1; 03589 } 03590 03591 return 0; 03592 }
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 7745 of file channel.c.
References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_write(), and ast_frame::frametype.
07746 { 07747 short buf[samples]; 07748 struct ast_frame frame = { 07749 .frametype = AST_FRAME_VOICE, 07750 .subclass.codec = AST_FORMAT_SLINEAR, 07751 .data.ptr = buf, 07752 .samples = samples, 07753 .datalen = sizeof(buf), 07754 }; 07755 07756 memset(buf, 0, sizeof(buf)); 07757 07758 if (ast_write(chan, &frame)) 07759 return -1; 07760 07761 return 0; 07762 }
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 7346 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.
07347 { 07348 struct tonepair_state *ts; 07349 struct tonepair_def *td = params; 07350 07351 if (!(ts = ast_calloc(1, sizeof(*ts)))) 07352 return NULL; 07353 ts->origwfmt = chan->writeformat; 07354 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) { 07355 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name); 07356 tonepair_release(NULL, ts); 07357 ts = NULL; 07358 } else { 07359 ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0; 07360 ts->v1_1 = 0; 07361 ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol; 07362 ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol; 07363 ts->v2_1 = 0; 07364 ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0; 07365 ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol; 07366 ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol; 07367 ts->duration = td->duration; 07368 ts->modulate = 0; 07369 } 07370 /* Let interrupts interrupt :) */ 07371 ast_set_flag(chan, AST_FLAG_WRITE_INT); 07372 return ts; 07373 }
static int tonepair_generator | ( | struct ast_channel * | chan, | |
void * | data, | |||
int | len, | |||
int | samples | |||
) | [static] |
Definition at line 7375 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.
07376 { 07377 struct tonepair_state *ts = data; 07378 int x; 07379 07380 /* we need to prepare a frame with 16 * timelen samples as we're 07381 * generating SLIN audio 07382 */ 07383 len = samples * 2; 07384 07385 if (len > sizeof(ts->data) / 2 - 1) { 07386 ast_log(LOG_WARNING, "Can't generate that much data!\n"); 07387 return -1; 07388 } 07389 memset(&ts->f, 0, sizeof(ts->f)); 07390 for (x=0;x<len/2;x++) { 07391 ts->v1_1 = ts->v2_1; 07392 ts->v2_1 = ts->v3_1; 07393 ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1; 07394 07395 ts->v1_2 = ts->v2_2; 07396 ts->v2_2 = ts->v3_2; 07397 ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2; 07398 if (ts->modulate) { 07399 int p; 07400 p = ts->v3_2 - 32768; 07401 if (p < 0) p = -p; 07402 p = ((p * 9) / 10) + 1; 07403 ts->data[x] = (ts->v3_1 * p) >> 15; 07404 } else 07405 ts->data[x] = ts->v3_1 + ts->v3_2; 07406 } 07407 ts->f.frametype = AST_FRAME_VOICE; 07408 ts->f.subclass.codec = AST_FORMAT_SLINEAR; 07409 ts->f.datalen = len; 07410 ts->f.samples = samples; 07411 ts->f.offset = AST_FRIENDLY_OFFSET; 07412 ts->f.data.ptr = ts->data; 07413 ast_write(chan, &ts->f); 07414 ts->pos += x; 07415 if (ts->duration > 0) { 07416 if (ts->pos >= ts->duration * 8) 07417 return -1; 07418 } 07419 return 0; 07420 }
static void tonepair_release | ( | struct ast_channel * | chan, | |
void * | params | |||
) | [static] |
Definition at line 7337 of file channel.c.
References ast_free, ast_set_write_format(), chanlist::chan, and tonepair_state::origwfmt.
Referenced by tonepair_alloc().
07338 { 07339 struct tonepair_state *ts = params; 07340 07341 if (chan) 07342 ast_set_write_format(chan, ts->origwfmt); 07343 ast_free(ts); 07344 }
static void update_bridge_vars | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1 | |||
) | [static] |
Definition at line 6952 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().
06953 { 06954 const char *c0_name; 06955 const char *c1_name; 06956 const char *c0_pvtid = NULL; 06957 const char *c1_pvtid = NULL; 06958 06959 ast_channel_lock(c1); 06960 c1_name = ast_strdupa(c1->name); 06961 if (c1->tech->get_pvt_uniqueid) { 06962 c1_pvtid = ast_strdupa(c1->tech->get_pvt_uniqueid(c1)); 06963 } 06964 ast_channel_unlock(c1); 06965 06966 ast_channel_lock(c0); 06967 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER"))) { 06968 pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1_name); 06969 } 06970 if (c1_pvtid) { 06971 pbx_builtin_setvar_helper(c0, "BRIDGEPVTCALLID", c1_pvtid); 06972 } 06973 c0_name = ast_strdupa(c0->name); 06974 if (c0->tech->get_pvt_uniqueid) { 06975 c0_pvtid = ast_strdupa(c0->tech->get_pvt_uniqueid(c0)); 06976 } 06977 ast_channel_unlock(c0); 06978 06979 ast_channel_lock(c1); 06980 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER"))) { 06981 pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0_name); 06982 } 06983 if (c0_pvtid) { 06984 pbx_builtin_setvar_helper(c1, "BRIDGEPVTCALLID", c0_pvtid); 06985 } 06986 ast_channel_unlock(c1); 06987 }
static void xfer_ds_destroy | ( | void * | data | ) | [static] |
Definition at line 5797 of file channel.c.
References ast_free, ast_party_connected_line_free(), xfer_masquerade_ds::target_id, and xfer_masquerade_ds::transferee_id.
05798 { 05799 struct xfer_masquerade_ds *ds = data; 05800 05801 ast_party_connected_line_free(&ds->target_id); 05802 ast_party_connected_line_free(&ds->transferee_id); 05803 ast_free(ds); 05804 }
void(*) ast_moh_cleanup_ptr(struct ast_channel *) = NULL [static] |
Definition at line 7498 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 7496 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 7497 of file channel.c.
Referenced by ast_install_music_functions(), ast_moh_stop(), and ast_uninstall_music_functions().
int cause |
Definition at line 198 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(), sig_ss7_hangup(), sms_messagerx(), and sms_messagerx2().
struct { ... } causes[] [static] |
map AST_CAUSE's to readable string representations
Referenced by ast_cause2str(), ast_str2cause(), and dump_cause().
struct ast_datastore_info cc_channel_datastore_info [static] |
Initial value:
{ .type = "Call Completion", .duplicate = channel_cc_params_copy, .destroy = channel_cc_params_destroy, }
Definition at line 9156 of file channel.c.
Referenced by ast_channel_cc_params_init(), and ast_channel_get_cc_config_params().
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 7683 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 610 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 98 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 1050 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 4569 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 7764 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 7422 of file channel.c.
Referenced by ast_tonepair_start().
struct ast_datastore_info xfer_ds_info [static] |
Initial value:
{ .type = "xfer_colp", .destroy = xfer_ds_destroy, }
Definition at line 5806 of file channel.c.
Referenced by ast_channel_transfer_masquerade(), and ast_do_masquerade().