#include "asterisk.h"
#include "asterisk/_private.h"
#include <sys/time.h>
#include <signal.h>
#include <math.h>
#include "asterisk/paths.h"
#include "asterisk/pbx.h"
#include "asterisk/frame.h"
#include "asterisk/mod_format.h"
#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include "asterisk/musiconhold.h"
#include "asterisk/say.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/manager.h"
#include "asterisk/cel.h"
#include "asterisk/chanvars.h"
#include "asterisk/linkedlists.h"
#include "asterisk/indications.h"
#include "asterisk/monitor.h"
#include "asterisk/causes.h"
#include "asterisk/callerid.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/app.h"
#include "asterisk/transcap.h"
#include "asterisk/devicestate.h"
#include "asterisk/threadstorage.h"
#include "asterisk/slinfactory.h"
#include "asterisk/audiohook.h"
#include "asterisk/framehook.h"
#include "asterisk/timing.h"
#include "asterisk/autochan.h"
#include "asterisk/stringfields.h"
#include "asterisk/global_datastores.h"
#include "asterisk/data.h"
Go to the source code of this file.
Data Structures | |
struct | ast_channel_iterator |
struct | ast_epoll_data |
struct | ast_party_id_ies |
struct | ast_party_name_ies |
struct | ast_party_number_ies |
struct | ast_party_subaddress_ies |
struct | ast_silence_generator |
struct | backends |
the list of registered channel types More... | |
struct | chanlist |
List of channel drivers. More... | |
struct | plc_ds |
struct | tonepair_def |
struct | tonepair_state |
struct | xfer_masquerade_ds |
Defines | |
#define | AST_DEFAULT_EMULATE_DTMF_DURATION 100 |
#define | AST_MIN_DTMF_DURATION 80 |
#define | AST_MIN_DTMF_GAP 45 |
#define | DATA_EXPORT_CHANNEL(MEMBER) |
#define | FORMAT "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\n" |
#define | NUM_CHANNEL_BUCKETS 1567 |
#define | STATE2STR_BUFSIZE 32 |
Enumerations | |
enum | { AST_CONNECTED_LINE_NUMBER, AST_CONNECTED_LINE_NAME, AST_CONNECTED_LINE_NUMBER_PLAN, AST_CONNECTED_LINE_ID_PRESENTATION, AST_CONNECTED_LINE_SOURCE, AST_CONNECTED_LINE_SUBADDRESS, AST_CONNECTED_LINE_SUBADDRESS_TYPE, AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, AST_CONNECTED_LINE_SUBADDRESS_VALID, AST_CONNECTED_LINE_TAG, AST_CONNECTED_LINE_VERSION, AST_CONNECTED_LINE_NAME_VALID, AST_CONNECTED_LINE_NAME_CHAR_SET, AST_CONNECTED_LINE_NAME_PRESENTATION, AST_CONNECTED_LINE_NUMBER_VALID, AST_CONNECTED_LINE_NUMBER_PRESENTATION } |
Element identifiers for connected line indication frame data. More... | |
enum | { AST_REDIRECTING_FROM_NUMBER, AST_REDIRECTING_FROM_NAME, AST_REDIRECTING_FROM_NUMBER_PLAN, AST_REDIRECTING_FROM_ID_PRESENTATION, AST_REDIRECTING_TO_NUMBER, AST_REDIRECTING_TO_NAME, AST_REDIRECTING_TO_NUMBER_PLAN, AST_REDIRECTING_TO_ID_PRESENTATION, AST_REDIRECTING_REASON, AST_REDIRECTING_COUNT, AST_REDIRECTING_FROM_SUBADDRESS, AST_REDIRECTING_FROM_SUBADDRESS_TYPE, AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_FROM_SUBADDRESS_VALID, AST_REDIRECTING_TO_SUBADDRESS, AST_REDIRECTING_TO_SUBADDRESS_TYPE, AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_TO_SUBADDRESS_VALID, AST_REDIRECTING_FROM_TAG, AST_REDIRECTING_TO_TAG, AST_REDIRECTING_VERSION, AST_REDIRECTING_FROM_NAME_VALID, AST_REDIRECTING_FROM_NAME_CHAR_SET, AST_REDIRECTING_FROM_NAME_PRESENTATION, AST_REDIRECTING_FROM_NUMBER_VALID, AST_REDIRECTING_FROM_NUMBER_PRESENTATION, AST_REDIRECTING_TO_NAME_VALID, AST_REDIRECTING_TO_NAME_CHAR_SET, AST_REDIRECTING_TO_NAME_PRESENTATION, AST_REDIRECTING_TO_NUMBER_VALID, AST_REDIRECTING_TO_NUMBER_PRESENTATION } |
Element identifiers for redirecting indication frame data. More... | |
Functions | |
int | __ast_answer (struct ast_channel *chan, unsigned int delay, int cdr_answer) |
Answer a channel, with a selectable delay before returning. | |
static void | __ast_change_name_nolink (struct ast_channel *chan, const char *newname) |
this function simply changes the name of the channel and issues a manager_event with out unlinking and linking the channel from the ao2_container. This should only be used when the channel has already been unlinked from the ao2_container. | |
ast_channel * | __ast_channel_alloc (int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const char *linkedid, const int amaflag, const char *file, int line, const char *function, const char *name_fmt,...) |
Create a channel structure. | |
static struct ast_channel *attribute_malloc | __ast_channel_alloc_ap (int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const char *linkedid, const int amaflag, const char *file, int line, const char *function, const char *name_fmt, va_list ap1, va_list ap2) |
Create a new channel structure. | |
static int | __ast_channel_masquerade (struct ast_channel *original, struct ast_channel *clonechan, struct ast_datastore *xfer_ds) |
static int | __ast_queue_frame (struct ast_channel *chan, struct ast_frame *fin, int head, struct ast_frame *after) |
static struct ast_frame * | __ast_read (struct ast_channel *chan, int dropaudio) |
ast_channel * | __ast_request_and_dial (const char *type, format_t format, const struct ast_channel *requestor, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh) |
Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it. | |
static void | __init_state2str_threadbuf (void) |
static void | adjust_frame_for_plc (struct ast_channel *chan, struct ast_frame *frame, struct ast_datastore *datastore) |
static void | apply_plc (struct ast_channel *chan, struct ast_frame *frame) |
int | ast_activate_generator (struct ast_channel *chan, struct ast_generator *gen, void *params) |
int | ast_active_channels (void) |
returns number of active/allocated channels | |
int | ast_answer (struct ast_channel *chan) |
Answer a channel. | |
void | ast_begin_shutdown (int hangup) |
format_t | ast_best_codec (format_t fmts) |
Pick the best audio codec. | |
ast_channel * | ast_bridged_channel (struct ast_channel *chan) |
Find bridged channel. | |
int | ast_call (struct ast_channel *chan, char *addr, int timeout) |
Make a call. | |
ast_channel * | ast_call_forward (struct ast_channel *caller, struct ast_channel *orig, int *timeout, format_t format, struct outgoing_helper *oh, int *outstate) |
Forwards a call to a new channel specified by the original channel's call_forward str. If possible, the new forwarded channel is created and returned while the original one is terminated. | |
void | ast_cancel_shutdown (void) |
Cancel a shutdown in progress. | |
const char * | ast_cause2str (int cause) |
Gives the string form of a given cause code. | |
void | ast_change_name (struct ast_channel *chan, const char *newname) |
Change channel name. | |
ast_channel * | ast_channel_alloc (int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const char *linkedid, const int amaflag, const char *name_fmt,...) |
enum ast_bridge_result | ast_channel_bridge (struct ast_channel *c0, struct ast_channel *c1, struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc) |
Bridge two channels together. | |
ast_channel * | ast_channel_callback (ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags) |
Call a function with every active channel. | |
int | ast_channel_cc_params_init (struct ast_channel *chan, const struct ast_cc_config_params *base_params) |
Set up datastore with CCSS parameters for a channel. | |
static void | ast_channel_change_linkedid (struct ast_channel *chan, const char *linkedid) |
void | ast_channel_clear_softhangup (struct ast_channel *chan, int flag) |
Clear a set of softhangup flags from a channel. | |
static int | ast_channel_cmp_cb (void *obj, void *arg, int flags) |
int | ast_channel_cmpwhentohangup (struct ast_channel *chan, time_t offset) |
Compare a offset with the settings of when to hang a channel up. | |
int | ast_channel_cmpwhentohangup_tv (struct ast_channel *chan, struct timeval offset) |
Compare a offset with the settings of when to hang a channel up. | |
int | ast_channel_connected_line_macro (struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int is_caller, int is_frame) |
Run a connected line interception macro and update a channel's connected line information. | |
int | ast_channel_data_add_structure (struct ast_data *tree, struct ast_channel *chan, int add_bridged) |
Insert into an astdata tree, the channel structure. | |
int | ast_channel_data_cmp_structure (const struct ast_data_search *tree, struct ast_channel *chan, const char *structure_name) |
Compare to channel structures using the data api. | |
int | ast_channel_datastore_add (struct ast_channel *chan, struct ast_datastore *datastore) |
Add a datastore to a channel. | |
ast_datastore * | ast_channel_datastore_alloc (const 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 | call_forward_inherit (struct ast_channel *new_chan, struct ast_channel *parent, struct ast_channel *orig) |
static void * | channel_cc_params_copy (void *data) |
static void | channel_cc_params_destroy (void *data) |
static void | channel_data_add_flags (struct ast_data *tree, struct ast_channel *chan) |
static struct ast_channel_iterator * | channel_iterator_search (const char *name, size_t name_len, const char *exten, const char *context) |
const char * | channelreloadreason2txt (enum channelreloadreason reason) |
Convert enum channelreloadreason to text string for manager event. | |
static void | clone_variables (struct ast_channel *original, struct ast_channel *clonechan) |
Clone channel variables from 'clone' channel into 'original' channel. | |
static char * | complete_channeltypes (struct ast_cli_args *a) |
static int | data_channels_provider_handler (const struct ast_data_search *search, struct ast_data *root) |
static int | data_channeltypes_provider_handler (const struct ast_data_search *search, struct ast_data *data_root) |
static void | free_translation (struct ast_channel *clonechan) |
static int | generator_force (const void *data) |
static void | handle_cause (int cause, int *outstate) |
static char * | handle_cli_core_show_channeltype (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show details about a channel driver - CLI command. | |
static char * | handle_cli_core_show_channeltypes (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show channel types - CLI command. | |
static int attribute_const | is_visible_indication (enum ast_control_frame_type condition) |
static struct ast_frame * | kill_exception (struct ast_channel *chan) |
static int | kill_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
static int | kill_hangup (struct ast_channel *chan) |
static struct ast_frame * | kill_read (struct ast_channel *chan) |
static int | kill_write (struct ast_channel *chan, struct ast_frame *frame) |
static void | manager_bridge_event (int onoff, int type, struct ast_channel *c0, struct ast_channel *c1) |
Send manager event for bridge link and unlink events. | |
static void | masquerade_colp_transfer (struct ast_channel *transferee, struct xfer_masquerade_ds *colp) |
static const char * | oldest_linkedid (const char *a, const char *b) |
static void | party_connected_line_copy_transfer (struct ast_party_connected_line *dest, const struct ast_party_connected_line *src) |
static int | party_id_build_data (unsigned char *data, size_t datalen, const struct ast_party_id *id, const char *label, const struct ast_party_id_ies *ies, const struct ast_set_party_id *update) |
static int | party_name_build_data (unsigned char *data, size_t datalen, const struct ast_party_name *name, const char *label, const struct ast_party_name_ies *ies) |
static int | party_number_build_data (unsigned char *data, size_t datalen, const struct ast_party_number *number, const char *label, const struct ast_party_number_ies *ies) |
static int | party_subaddress_build_data (unsigned char *data, size_t datalen, const struct ast_party_subaddress *subaddress, const char *label, const struct ast_party_subaddress_ies *ies) |
static void | plc_ds_destroy (void *data) |
static void | queue_dtmf_readq (struct ast_channel *chan, struct ast_frame *f) |
static void | report_new_callerid (struct ast_channel *chan) |
static void | send_dtmf_event (struct ast_channel *chan, const char *direction, const char digit, const char *begin, const char *end) |
static int | set_format (struct ast_channel *chan, format_t fmt, format_t *rawformat, format_t *format, struct ast_trans_pvt **trans, const int direction) |
static int | set_security_requirements (const struct ast_channel *requestor, struct ast_channel *out) |
static int | should_skip_dtmf (struct ast_channel *chan) |
Determine whether or not we should ignore DTMF in the readq. | |
static void * | silence_generator_alloc (struct ast_channel *chan, void *data) |
static int | silence_generator_generate (struct ast_channel *chan, void *data, int len, int samples) |
static void | silence_generator_release (struct ast_channel *chan, void *data) |
static void * | tonepair_alloc (struct ast_channel *chan, void *params) |
static int | tonepair_generator (struct ast_channel *chan, void *data, int len, int samples) |
static void | tonepair_release (struct ast_channel *chan, void *params) |
static void | update_bridge_vars (struct ast_channel *c0, struct ast_channel *c1) |
static void | xfer_ds_destroy (void *data) |
Variables | |
ast_channel_tech | ast_kill_tech |
Kill the channel channel driver technology descriptor. | |
static void(*) | ast_moh_cleanup_ptr (struct ast_channel *) = NULL |
static int(*) | ast_moh_start_ptr (struct ast_channel *, const char *, const char *) = NULL |
static void(*) | ast_moh_stop_ptr (struct ast_channel *) = NULL |
struct { | |
int cause | |
const char * desc | |
const char * name | |
} | causes [] |
map AST_CAUSE's to readable string representations | |
static struct ast_datastore_info | cc_channel_datastore_info |
static struct ast_data_entry | channel_providers [] |
static struct ao2_container * | channels |
All active channels on the system. | |
static struct ast_data_handler | channels_provider |
static struct ast_data_handler | channeltypes_provider |
static struct ast_cli_entry | cli_channel [] |
unsigned long | global_fin |
unsigned long | global_fout |
static struct ast_channel_tech | null_tech |
static struct ast_datastore_info | plc_ds_info |
static int | shutting_down |
Prevent new channel allocation if shutting down. | |
static struct ast_generator | silence_generator |
static struct ast_threadstorage | state2str_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_state2str_threadbuf , .custom_init = NULL , } |
static struct ast_generator | tonepair |
static int | uniqueint |
static struct ast_datastore_info | xfer_ds_info |
Definition in file channel.c.
#define AST_DEFAULT_EMULATE_DTMF_DURATION 100 |
Default amount of time to use when emulating a digit as a begin and end 100ms
Definition at line 104 of file channel.c.
Referenced by __ast_read(), and ast_senddigit().
#define AST_MIN_DTMF_DURATION 80 |
Minimum allowed digit length - 80ms
Definition at line 107 of file channel.c.
Referenced by __ast_read().
#define AST_MIN_DTMF_GAP 45 |
Minimum amount of time between the end of the last digit and the beginning of a new one - 45ms
Definition at line 111 of file channel.c.
Referenced by __ast_read(), and should_skip_dtmf().
#define FORMAT "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\n" |
#define NUM_CHANNEL_BUCKETS 1567 |
#define STATE2STR_BUFSIZE 32 |
anonymous enum |
Element identifiers for connected line indication frame data.
Definition at line 8510 of file channel.c.
08510 { 08511 AST_CONNECTED_LINE_NUMBER, 08512 AST_CONNECTED_LINE_NAME, 08513 AST_CONNECTED_LINE_NUMBER_PLAN, 08514 AST_CONNECTED_LINE_ID_PRESENTATION,/* Combined number and name presentation. */ 08515 AST_CONNECTED_LINE_SOURCE, 08516 AST_CONNECTED_LINE_SUBADDRESS, 08517 AST_CONNECTED_LINE_SUBADDRESS_TYPE, 08518 AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, 08519 AST_CONNECTED_LINE_SUBADDRESS_VALID, 08520 AST_CONNECTED_LINE_TAG, 08521 AST_CONNECTED_LINE_VERSION, 08522 AST_CONNECTED_LINE_NAME_VALID, 08523 AST_CONNECTED_LINE_NAME_CHAR_SET, 08524 AST_CONNECTED_LINE_NAME_PRESENTATION, 08525 AST_CONNECTED_LINE_NUMBER_VALID, 08526 AST_CONNECTED_LINE_NUMBER_PRESENTATION, 08527 };
anonymous enum |
Element identifiers for redirecting indication frame data.
Definition at line 8831 of file channel.c.
08831 { 08832 AST_REDIRECTING_FROM_NUMBER, 08833 AST_REDIRECTING_FROM_NAME, 08834 AST_REDIRECTING_FROM_NUMBER_PLAN, 08835 AST_REDIRECTING_FROM_ID_PRESENTATION, 08836 AST_REDIRECTING_TO_NUMBER, 08837 AST_REDIRECTING_TO_NAME, 08838 AST_REDIRECTING_TO_NUMBER_PLAN, 08839 AST_REDIRECTING_TO_ID_PRESENTATION, 08840 AST_REDIRECTING_REASON, 08841 AST_REDIRECTING_COUNT, 08842 AST_REDIRECTING_FROM_SUBADDRESS, 08843 AST_REDIRECTING_FROM_SUBADDRESS_TYPE, 08844 AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, 08845 AST_REDIRECTING_FROM_SUBADDRESS_VALID, 08846 AST_REDIRECTING_TO_SUBADDRESS, 08847 AST_REDIRECTING_TO_SUBADDRESS_TYPE, 08848 AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, 08849 AST_REDIRECTING_TO_SUBADDRESS_VALID, 08850 AST_REDIRECTING_FROM_TAG, 08851 AST_REDIRECTING_TO_TAG, 08852 AST_REDIRECTING_VERSION, 08853 AST_REDIRECTING_FROM_NAME_VALID, 08854 AST_REDIRECTING_FROM_NAME_CHAR_SET, 08855 AST_REDIRECTING_FROM_NAME_PRESENTATION, 08856 AST_REDIRECTING_FROM_NUMBER_VALID, 08857 AST_REDIRECTING_FROM_NUMBER_PRESENTATION, 08858 AST_REDIRECTING_TO_NAME_VALID, 08859 AST_REDIRECTING_TO_NAME_CHAR_SET, 08860 AST_REDIRECTING_TO_NAME_PRESENTATION, 08861 AST_REDIRECTING_TO_NUMBER_VALID, 08862 AST_REDIRECTING_TO_NUMBER_PRESENTATION, 08863 };
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 2923 of file channel.c.
References ast_channel::_state, ast_channel_lock, ast_channel_unlock, AST_CONTROL_HANGUP, ast_debug, AST_FRAME_CNG, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_frisolate(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_log(), ast_queue_frame_head(), ast_raw_answer(), ast_read(), AST_STATE_RING, AST_STATE_RINGING, ast_waitfor(), chanlist::chan, errno, frames, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, MAX, ast_channel::name, and ast_frame::subclass.
Referenced by ast_answer(), pbx_builtin_answer(), and pbx_builtin_incomplete().
02924 { 02925 int res = 0; 02926 enum ast_channel_state old_state; 02927 02928 old_state = chan->_state; 02929 if ((res = ast_raw_answer(chan, cdr_answer))) { 02930 return res; 02931 } 02932 02933 switch (old_state) { 02934 case AST_STATE_RINGING: 02935 case AST_STATE_RING: 02936 /* wait for media to start flowing, but don't wait any longer 02937 * than 'delay' or 500 milliseconds, whichever is longer 02938 */ 02939 do { 02940 AST_LIST_HEAD_NOLOCK(, ast_frame) frames; 02941 struct ast_frame *cur, *new; 02942 int ms = MAX(delay, 500); 02943 unsigned int done = 0; 02944 02945 AST_LIST_HEAD_INIT_NOLOCK(&frames); 02946 02947 for (;;) { 02948 ms = ast_waitfor(chan, ms); 02949 if (ms < 0) { 02950 ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", chan->name, strerror(errno)); 02951 res = -1; 02952 break; 02953 } 02954 if (ms == 0) { 02955 ast_debug(2, "Didn't receive a media frame from %s within %d ms of answering. Continuing anyway\n", chan->name, MAX(delay, 500)); 02956 break; 02957 } 02958 cur = ast_read(chan); 02959 if (!cur || ((cur->frametype == AST_FRAME_CONTROL) && 02960 (cur->subclass.integer == AST_CONTROL_HANGUP))) { 02961 if (cur) { 02962 ast_frfree(cur); 02963 } 02964 res = -1; 02965 ast_debug(2, "Hangup of channel %s detected in answer routine\n", chan->name); 02966 break; 02967 } 02968 02969 if ((new = ast_frisolate(cur)) != cur) { 02970 ast_frfree(cur); 02971 } 02972 02973 AST_LIST_INSERT_HEAD(&frames, new, frame_list); 02974 02975 /* if a specific delay period was requested, continue 02976 * until that delay has passed. don't stop just because 02977 * incoming media has arrived. 02978 */ 02979 if (delay) { 02980 continue; 02981 } 02982 02983 switch (new->frametype) { 02984 /* all of these frametypes qualify as 'media' */ 02985 case AST_FRAME_VOICE: 02986 case AST_FRAME_VIDEO: 02987 case AST_FRAME_TEXT: 02988 case AST_FRAME_DTMF_BEGIN: 02989 case AST_FRAME_DTMF_END: 02990 case AST_FRAME_IMAGE: 02991 case AST_FRAME_HTML: 02992 case AST_FRAME_MODEM: 02993 done = 1; 02994 break; 02995 case AST_FRAME_CONTROL: 02996 case AST_FRAME_IAX: 02997 case AST_FRAME_NULL: 02998 case AST_FRAME_CNG: 02999 break; 03000 } 03001 03002 if (done) { 03003 break; 03004 } 03005 } 03006 03007 if (res == 0) { 03008 ast_channel_lock(chan); 03009 while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list))) { 03010 ast_queue_frame_head(chan, cur); 03011 ast_frfree(cur); 03012 } 03013 ast_channel_unlock(chan); 03014 } 03015 } while (0); 03016 break; 03017 default: 03018 break; 03019 } 03020 03021 return res; 03022 }
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 6072 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().
06073 { 06074 ast_manager_event(chan, EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid); 06075 ast_string_field_set(chan, name, newname); 06076 }
struct ast_channel* __ast_channel_alloc | ( | int | needqueue, | |
int | state, | |||
const char * | cid_num, | |||
const char * | cid_name, | |||
const char * | acctcode, | |||
const char * | exten, | |||
const char * | context, | |||
const char * | linkedid, | |||
const int | amaflag, | |||
const char * | file, | |||
int | line, | |||
const char * | function, | |||
const char * | name_fmt, | |||
... | ||||
) |
Create a channel structure.
NULL | failure | |
non-NULL | successfully allocated channel |
By default, new channels are set to the "s" extension and "default" context.
Definition at line 1344 of file channel.c.
References __ast_channel_alloc_ap().
01350 { 01351 va_list ap1, ap2; 01352 struct ast_channel *result; 01353 01354 va_start(ap1, name_fmt); 01355 va_start(ap2, name_fmt); 01356 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context, 01357 linkedid, amaflag, file, line, function, name_fmt, ap1, ap2); 01358 va_end(ap1); 01359 va_end(ap2); 01360 01361 return result; 01362 }
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 1109 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().
01113 { 01114 struct ast_channel *tmp; 01115 int x; 01116 int flags; 01117 struct varshead *headp; 01118 char *tech = "", *tech2 = NULL; 01119 01120 /* If shutting down, don't allocate any new channels */ 01121 if (shutting_down) { 01122 ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n"); 01123 return NULL; 01124 } 01125 01126 #if defined(REF_DEBUG) 01127 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_channel_destructor, "", file, line, 01128 function, 1); 01129 #elif defined(__AST_DEBUG_MALLOC) 01130 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_channel_destructor, "", file, line, 01131 function, 0); 01132 #else 01133 tmp = ao2_alloc(sizeof(*tmp), ast_channel_destructor); 01134 #endif 01135 if (!tmp) { 01136 /* Channel structure allocation failure. */ 01137 return NULL; 01138 } 01139 01140 /* 01141 * Init file descriptors to unopened state so 01142 * the destructor can know not to close them. 01143 */ 01144 tmp->timingfd = -1; 01145 for (x = 0; x < ARRAY_LEN(tmp->alertpipe); ++x) { 01146 tmp->alertpipe[x] = -1; 01147 } 01148 for (x = 0; x < ARRAY_LEN(tmp->fds); ++x) { 01149 tmp->fds[x] = -1; 01150 } 01151 #ifdef HAVE_EPOLL 01152 tmp->epfd = epoll_create(25); 01153 #endif 01154 01155 if (!(tmp->sched = sched_context_create())) { 01156 ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n"); 01157 return ast_channel_unref(tmp); 01158 } 01159 01160 ast_party_dialed_init(&tmp->dialed); 01161 ast_party_caller_init(&tmp->caller); 01162 ast_party_connected_line_init(&tmp->connected); 01163 ast_party_redirecting_init(&tmp->redirecting); 01164 01165 if (cid_name) { 01166 tmp->caller.id.name.valid = 1; 01167 tmp->caller.id.name.str = ast_strdup(cid_name); 01168 if (!tmp->caller.id.name.str) { 01169 return ast_channel_unref(tmp); 01170 } 01171 } 01172 if (cid_num) { 01173 tmp->caller.id.number.valid = 1; 01174 tmp->caller.id.number.str = ast_strdup(cid_num); 01175 if (!tmp->caller.id.number.str) { 01176 return ast_channel_unref(tmp); 01177 } 01178 } 01179 01180 if ((tmp->timer = ast_timer_open())) { 01181 if (strcmp(ast_timer_get_name(tmp->timer), "timerfd")) { 01182 needqueue = 0; 01183 } 01184 tmp->timingfd = ast_timer_fd(tmp->timer); 01185 } 01186 01187 if (needqueue) { 01188 if (pipe(tmp->alertpipe)) { 01189 ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe! Try increasing max file descriptors with ulimit -n\n"); 01190 return ast_channel_unref(tmp); 01191 } else { 01192 flags = fcntl(tmp->alertpipe[0], F_GETFL); 01193 if (fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) { 01194 ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno)); 01195 return ast_channel_unref(tmp); 01196 } 01197 flags = fcntl(tmp->alertpipe[1], F_GETFL); 01198 if (fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK) < 0) { 01199 ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno)); 01200 return ast_channel_unref(tmp); 01201 } 01202 } 01203 } 01204 01205 /* 01206 * This is the last place the channel constructor can fail. 01207 * 01208 * The destructor takes advantage of this fact to ensure that the 01209 * AST_CEL_CHANNEL_END is not posted if we have not posted the 01210 * AST_CEL_CHANNEL_START yet. 01211 */ 01212 if ((ast_string_field_init(tmp, 128))) { 01213 return ast_channel_unref(tmp); 01214 } 01215 01216 /* Always watch the alertpipe */ 01217 ast_channel_set_fd(tmp, AST_ALERT_FD, tmp->alertpipe[0]); 01218 /* And timing pipe */ 01219 ast_channel_set_fd(tmp, AST_TIMING_FD, tmp->timingfd); 01220 01221 /* Initial state */ 01222 tmp->_state = state; 01223 01224 tmp->streamid = -1; 01225 01226 tmp->fin = global_fin; 01227 tmp->fout = global_fout; 01228 01229 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) { 01230 ast_string_field_build(tmp, uniqueid, "%li.%d", (long) time(NULL), 01231 ast_atomic_fetchadd_int(&uniqueint, 1)); 01232 } else { 01233 ast_string_field_build(tmp, uniqueid, "%s-%li.%d", ast_config_AST_SYSTEM_NAME, 01234 (long) time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1)); 01235 } 01236 01237 if (!ast_strlen_zero(linkedid)) { 01238 ast_string_field_set(tmp, linkedid, linkedid); 01239 } else { 01240 ast_string_field_set(tmp, linkedid, tmp->uniqueid); 01241 } 01242 01243 if (!ast_strlen_zero(name_fmt)) { 01244 char *slash, *slash2; 01245 /* Almost every channel is calling this function, and setting the name via the ast_string_field_build() call. 01246 * And they all use slightly different formats for their name string. 01247 * This means, to set the name here, we have to accept variable args, and call the string_field_build from here. 01248 * This means, that the stringfields must have a routine that takes the va_lists directly, and 01249 * uses them to build the string, instead of forming the va_lists internally from the vararg ... list. 01250 * This new function was written so this can be accomplished. 01251 */ 01252 ast_string_field_build_va(tmp, name, name_fmt, ap1, ap2); 01253 tech = ast_strdupa(tmp->name); 01254 if ((slash = strchr(tech, '/'))) { 01255 if ((slash2 = strchr(slash + 1, '/'))) { 01256 tech2 = slash + 1; 01257 *slash2 = '\0'; 01258 } 01259 *slash = '\0'; 01260 } 01261 } else { 01262 /* 01263 * Start the string with '-' so it becomes an empty string 01264 * in the destructor. 01265 */ 01266 ast_string_field_set(tmp, name, "-**Unknown**"); 01267 } 01268 01269 /* Reminder for the future: under what conditions do we NOT want to track cdrs on channels? */ 01270 01271 /* These 4 variables need to be set up for the cdr_init() to work right */ 01272 if (amaflag) 01273 tmp->amaflags = amaflag; 01274 else 01275 tmp->amaflags = ast_default_amaflags; 01276 01277 if (!ast_strlen_zero(acctcode)) 01278 ast_string_field_set(tmp, accountcode, acctcode); 01279 else 01280 ast_string_field_set(tmp, accountcode, ast_default_accountcode); 01281 01282 if (!ast_strlen_zero(context)) 01283 ast_copy_string(tmp->context, context, sizeof(tmp->context)); 01284 else 01285 strcpy(tmp->context, "default"); 01286 01287 if (!ast_strlen_zero(exten)) 01288 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); 01289 else 01290 strcpy(tmp->exten, "s"); 01291 01292 tmp->priority = 1; 01293 01294 tmp->cdr = ast_cdr_alloc(); 01295 ast_cdr_init(tmp->cdr, tmp); 01296 ast_cdr_start(tmp->cdr); 01297 01298 ast_cel_report_event(tmp, AST_CEL_CHANNEL_START, NULL, NULL, NULL); 01299 01300 headp = &tmp->varshead; 01301 AST_LIST_HEAD_INIT_NOLOCK(headp); 01302 01303 AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores); 01304 01305 AST_LIST_HEAD_INIT_NOLOCK(&tmp->autochans); 01306 01307 ast_string_field_set(tmp, language, defaultlanguage); 01308 01309 tmp->tech = &null_tech; 01310 01311 ao2_link(channels, tmp); 01312 01313 /* 01314 * And now, since the channel structure is built, and has its name, let's 01315 * call the manager event generator with this Newchannel event. This is the 01316 * proper and correct place to make this call, but you sure do have to pass 01317 * a lot of data into this func to do it here! 01318 */ 01319 if (ast_get_channel_tech(tech) || (tech2 && ast_get_channel_tech(tech2))) { 01320 ast_manager_event(tmp, EVENT_FLAG_CALL, "Newchannel", 01321 "Channel: %s\r\n" 01322 "ChannelState: %d\r\n" 01323 "ChannelStateDesc: %s\r\n" 01324 "CallerIDNum: %s\r\n" 01325 "CallerIDName: %s\r\n" 01326 "AccountCode: %s\r\n" 01327 "Exten: %s\r\n" 01328 "Context: %s\r\n" 01329 "Uniqueid: %s\r\n", 01330 tmp->name, 01331 state, 01332 ast_state2str(state), 01333 S_OR(cid_num, ""), 01334 S_OR(cid_name, ""), 01335 tmp->accountcode, 01336 S_OR(exten, ""), 01337 S_OR(context, ""), 01338 tmp->uniqueid); 01339 } 01340 01341 return tmp; 01342 }
static int __ast_channel_masquerade | ( | struct ast_channel * | original, | |
struct ast_channel * | clonechan, | |||
struct ast_datastore * | xfer_ds | |||
) | [static] |
Definition at line 5836 of file channel.c.
References ast_channel::_bridge, ast_bridged_channel(), ast_channel_datastore_add(), ast_channel_lock_both, ast_channel_trylock, ast_channel_unlock, ast_debug, AST_FLAG_ZOMBIE, ast_log(), ast_null_frame, ast_queue_frame(), ast_test_flag, ast_channel_tech::get_base_channel, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::name, and ast_channel::tech.
Referenced by ast_channel_masquerade(), and ast_channel_transfer_masquerade().
05837 { 05838 int res = -1; 05839 struct ast_channel *final_orig, *final_clone, *base; 05840 05841 for (;;) { 05842 final_orig = original; 05843 final_clone = clonechan; 05844 05845 ast_channel_lock_both(original, clonechan); 05846 05847 if (ast_test_flag(original, AST_FLAG_ZOMBIE) 05848 || ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) { 05849 /* Zombies! Run! */ 05850 ast_log(LOG_WARNING, 05851 "Can't setup masquerade. One or both channels is dead. (%s <-- %s)\n", 05852 original->name, clonechan->name); 05853 ast_channel_unlock(clonechan); 05854 ast_channel_unlock(original); 05855 return -1; 05856 } 05857 05858 /* 05859 * Each of these channels may be sitting behind a channel proxy 05860 * (i.e. chan_agent) and if so, we don't really want to 05861 * masquerade it, but its proxy 05862 */ 05863 if (original->_bridge 05864 && (original->_bridge != ast_bridged_channel(original)) 05865 && (original->_bridge->_bridge != original)) { 05866 final_orig = original->_bridge; 05867 } 05868 if (clonechan->_bridge 05869 && (clonechan->_bridge != ast_bridged_channel(clonechan)) 05870 && (clonechan->_bridge->_bridge != clonechan)) { 05871 final_clone = clonechan->_bridge; 05872 } 05873 if (final_clone->tech->get_base_channel 05874 && (base = final_clone->tech->get_base_channel(final_clone))) { 05875 final_clone = base; 05876 } 05877 05878 if ((final_orig != original) || (final_clone != clonechan)) { 05879 /* 05880 * Lots and lots of deadlock avoidance. The main one we're 05881 * competing with is ast_write(), which locks channels 05882 * recursively, when working with a proxy channel. 05883 */ 05884 if (ast_channel_trylock(final_orig)) { 05885 ast_channel_unlock(clonechan); 05886 ast_channel_unlock(original); 05887 05888 /* Try again */ 05889 continue; 05890 } 05891 if (ast_channel_trylock(final_clone)) { 05892 ast_channel_unlock(final_orig); 05893 ast_channel_unlock(clonechan); 05894 ast_channel_unlock(original); 05895 05896 /* Try again */ 05897 continue; 05898 } 05899 ast_channel_unlock(clonechan); 05900 ast_channel_unlock(original); 05901 original = final_orig; 05902 clonechan = final_clone; 05903 05904 if (ast_test_flag(original, AST_FLAG_ZOMBIE) 05905 || ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) { 05906 /* Zombies! Run! */ 05907 ast_log(LOG_WARNING, 05908 "Can't setup masquerade. One or both channels is dead. (%s <-- %s)\n", 05909 original->name, clonechan->name); 05910 ast_channel_unlock(clonechan); 05911 ast_channel_unlock(original); 05912 return -1; 05913 } 05914 } 05915 break; 05916 } 05917 05918 if (original == clonechan) { 05919 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name); 05920 ast_channel_unlock(clonechan); 05921 ast_channel_unlock(original); 05922 return -1; 05923 } 05924 05925 ast_debug(1, "Planning to masquerade channel %s into the structure of %s\n", 05926 clonechan->name, original->name); 05927 05928 if (!original->masqr && !original->masq && !clonechan->masq && !clonechan->masqr) { 05929 original->masq = clonechan; 05930 clonechan->masqr = original; 05931 if (xfer_ds) { 05932 ast_channel_datastore_add(original, xfer_ds); 05933 } 05934 ast_queue_frame(original, &ast_null_frame); 05935 ast_queue_frame(clonechan, &ast_null_frame); 05936 ast_debug(1, "Done planning to masquerade channel %s into the structure of %s\n", clonechan->name, original->name); 05937 res = 0; 05938 } else if (original->masq) { 05939 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 05940 original->masq->name, original->name); 05941 } else if (original->masqr) { 05942 /* not yet as a previously planned masq hasn't yet happened */ 05943 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 05944 original->name, original->masqr->name); 05945 } else if (clonechan->masq) { 05946 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 05947 clonechan->masq->name, clonechan->name); 05948 } else { /* (clonechan->masqr) */ 05949 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 05950 clonechan->name, clonechan->masqr->name); 05951 } 05952 05953 ast_channel_unlock(clonechan); 05954 ast_channel_unlock(original); 05955 05956 return res; 05957 }
static int __ast_queue_frame | ( | struct ast_channel * | chan, | |
struct ast_frame * | fin, | |||
int | head, | |||
struct ast_frame * | after | |||
) | [static] |
Definition at line 1399 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().
01400 { 01401 struct ast_frame *f; 01402 struct ast_frame *cur; 01403 unsigned int new_frames = 0; 01404 unsigned int new_voice_frames = 0; 01405 unsigned int queued_frames = 0; 01406 unsigned int queued_voice_frames = 0; 01407 AST_LIST_HEAD_NOLOCK(, ast_frame) frames; 01408 01409 ast_channel_lock(chan); 01410 01411 /* 01412 * Check the last frame on the queue if we are queuing the new 01413 * frames after it. 01414 */ 01415 cur = AST_LIST_LAST(&chan->readq); 01416 if (cur && cur->frametype == AST_FRAME_CONTROL && !head && (!after || after == cur)) { 01417 switch (cur->subclass.integer) { 01418 case AST_CONTROL_END_OF_Q: 01419 if (fin->frametype == AST_FRAME_CONTROL 01420 && fin->subclass.integer == AST_CONTROL_HANGUP) { 01421 /* 01422 * Destroy the end-of-Q marker frame so we can queue the hangup 01423 * frame in its place. 01424 */ 01425 AST_LIST_REMOVE(&chan->readq, cur, frame_list); 01426 ast_frfree(cur); 01427 01428 /* 01429 * This has degenerated to a normal queue append anyway. Since 01430 * we just destroyed the last frame in the queue we must make 01431 * sure that "after" is NULL or bad things will happen. 01432 */ 01433 after = NULL; 01434 break; 01435 } 01436 /* Fall through */ 01437 case AST_CONTROL_HANGUP: 01438 /* Don't queue anything. */ 01439 ast_channel_unlock(chan); 01440 return 0; 01441 default: 01442 break; 01443 } 01444 } 01445 01446 /* Build copies of all the new frames and count them */ 01447 AST_LIST_HEAD_INIT_NOLOCK(&frames); 01448 for (cur = fin; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 01449 if (!(f = ast_frdup(cur))) { 01450 if (AST_LIST_FIRST(&frames)) { 01451 ast_frfree(AST_LIST_FIRST(&frames)); 01452 } 01453 ast_channel_unlock(chan); 01454 return -1; 01455 } 01456 01457 AST_LIST_INSERT_TAIL(&frames, f, frame_list); 01458 new_frames++; 01459 if (f->frametype == AST_FRAME_VOICE) { 01460 new_voice_frames++; 01461 } 01462 } 01463 01464 /* Count how many frames exist on the queue */ 01465 AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) { 01466 queued_frames++; 01467 if (cur->frametype == AST_FRAME_VOICE) { 01468 queued_voice_frames++; 01469 } 01470 } 01471 01472 if ((queued_frames + new_frames > 128 || queued_voice_frames + new_voice_frames > 96)) { 01473 int count = 0; 01474 ast_log(LOG_WARNING, "Exceptionally long %squeue length queuing to %s\n", queued_frames + new_frames > 128 ? "" : "voice ", chan->name); 01475 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, cur, frame_list) { 01476 /* Save the most recent frame */ 01477 if (!AST_LIST_NEXT(cur, frame_list)) { 01478 break; 01479 } else if (cur->frametype == AST_FRAME_VOICE || cur->frametype == AST_FRAME_VIDEO || cur->frametype == AST_FRAME_NULL) { 01480 if (++count > 64) { 01481 break; 01482 } 01483 AST_LIST_REMOVE_CURRENT(frame_list); 01484 ast_frfree(cur); 01485 } 01486 } 01487 AST_LIST_TRAVERSE_SAFE_END; 01488 } 01489 01490 if (after) { 01491 AST_LIST_INSERT_LIST_AFTER(&chan->readq, &frames, after, frame_list); 01492 } else { 01493 if (head) { 01494 AST_LIST_APPEND_LIST(&frames, &chan->readq, frame_list); 01495 AST_LIST_HEAD_INIT_NOLOCK(&chan->readq); 01496 } 01497 AST_LIST_APPEND_LIST(&chan->readq, &frames, frame_list); 01498 } 01499 01500 if (chan->alertpipe[1] > -1) { 01501 int blah[new_frames]; 01502 01503 memset(blah, 1, sizeof(blah)); 01504 if (write(chan->alertpipe[1], &blah, sizeof(blah)) != (sizeof(blah))) { 01505 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s (qlen = %d): %s!\n", 01506 chan->name, queued_frames, strerror(errno)); 01507 } 01508 } else if (chan->timingfd > -1) { 01509 ast_timer_enable_continuous(chan->timer); 01510 } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 01511 pthread_kill(chan->blocker, SIGURG); 01512 } 01513 01514 ast_channel_unlock(chan); 01515 01516 return 0; 01517 }
static struct ast_frame* __ast_read | ( | struct ast_channel * | chan, | |
int | dropaudio | |||
) | [static] |
Definition at line 3715 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().
03716 { 03717 struct ast_frame *f = NULL; /* the return value */ 03718 int blah; 03719 int prestate; 03720 int cause = 0; 03721 03722 /* this function is very long so make sure there is only one return 03723 * point at the end (there are only two exceptions to this). 03724 */ 03725 03726 if (chan->masq) { 03727 if (ast_do_masquerade(chan)) 03728 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 03729 else 03730 f = &ast_null_frame; 03731 return f; 03732 } 03733 03734 /* if here, no masq has happened, lock the channel and proceed */ 03735 ast_channel_lock(chan); 03736 03737 /* Stop if we're a zombie or need a soft hangup */ 03738 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 03739 if (chan->generator) 03740 ast_deactivate_generator(chan); 03741 03742 /* 03743 * It is possible for chan->_softhangup to be set and there 03744 * still be control frames that need to be read. Instead of 03745 * just going to 'done' in the case of ast_check_hangup(), we 03746 * need to queue the end-of-Q frame so that it can mark the end 03747 * of the read queue. If there are frames to be read, 03748 * ast_queue_control() will be called repeatedly, but will only 03749 * queue the first end-of-Q frame. 03750 */ 03751 if (chan->_softhangup) { 03752 ast_queue_control(chan, AST_CONTROL_END_OF_Q); 03753 } else { 03754 goto done; 03755 } 03756 } else { 03757 #ifdef AST_DEVMODE 03758 /* 03759 * The ast_waitfor() code records which of the channel's file 03760 * descriptors reported that data is available. In theory, 03761 * ast_read() should only be called after ast_waitfor() reports 03762 * that a channel has data available for reading. However, 03763 * there still may be some edge cases throughout the code where 03764 * ast_read() is called improperly. This can potentially cause 03765 * problems, so if this is a developer build, make a lot of 03766 * noise if this happens so that it can be addressed. 03767 * 03768 * One of the potential problems is blocking on a dead channel. 03769 */ 03770 if (chan->fdno == -1) { 03771 ast_log(LOG_ERROR, 03772 "ast_read() on chan '%s' called with no recorded file descriptor.\n", 03773 chan->name); 03774 } 03775 #endif 03776 } 03777 03778 prestate = chan->_state; 03779 03780 /* Read and ignore anything on the alertpipe, but read only 03781 one sizeof(blah) per frame that we send from it */ 03782 if (chan->alertpipe[0] > -1) { 03783 int flags = fcntl(chan->alertpipe[0], F_GETFL); 03784 /* For some odd reason, the alertpipe occasionally loses nonblocking status, 03785 * which immediately causes a deadlock scenario. Detect and prevent this. */ 03786 if ((flags & O_NONBLOCK) == 0) { 03787 ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", chan->name); 03788 if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) { 03789 ast_log(LOG_WARNING, "Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno)); 03790 f = &ast_null_frame; 03791 goto done; 03792 } 03793 } 03794 if (read(chan->alertpipe[0], &blah, sizeof(blah)) < 0) { 03795 if (errno != EINTR && errno != EAGAIN) 03796 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 03797 } 03798 } 03799 03800 if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD) { 03801 enum ast_timer_event res; 03802 03803 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 03804 03805 res = ast_timer_get_event(chan->timer); 03806 03807 switch (res) { 03808 case AST_TIMING_EVENT_EXPIRED: 03809 ast_timer_ack(chan->timer, 1); 03810 03811 if (chan->timingfunc) { 03812 /* save a copy of func/data before unlocking the channel */ 03813 int (*func)(const void *) = chan->timingfunc; 03814 void *data = chan->timingdata; 03815 chan->fdno = -1; 03816 ast_channel_unlock(chan); 03817 func(data); 03818 } else { 03819 ast_timer_set_rate(chan->timer, 0); 03820 chan->fdno = -1; 03821 ast_channel_unlock(chan); 03822 } 03823 03824 /* cannot 'goto done' because the channel is already unlocked */ 03825 return &ast_null_frame; 03826 03827 case AST_TIMING_EVENT_CONTINUOUS: 03828 if (AST_LIST_EMPTY(&chan->readq) || 03829 !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) { 03830 ast_timer_disable_continuous(chan->timer); 03831 } 03832 break; 03833 } 03834 03835 } else if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) { 03836 /* if the AST_GENERATOR_FD is set, call the generator with args 03837 * set to -1 so it can do whatever it needs to. 03838 */ 03839 void *tmp = chan->generatordata; 03840 chan->generatordata = NULL; /* reset to let ast_write get through */ 03841 chan->generator->generate(chan, tmp, -1, -1); 03842 chan->generatordata = tmp; 03843 f = &ast_null_frame; 03844 chan->fdno = -1; 03845 goto done; 03846 } 03847 03848 /* Check for pending read queue */ 03849 if (!AST_LIST_EMPTY(&chan->readq)) { 03850 int skip_dtmf = should_skip_dtmf(chan); 03851 03852 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, f, frame_list) { 03853 /* We have to be picky about which frame we pull off of the readq because 03854 * there are cases where we want to leave DTMF frames on the queue until 03855 * some later time. */ 03856 03857 if ( (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && skip_dtmf) { 03858 continue; 03859 } 03860 03861 AST_LIST_REMOVE_CURRENT(frame_list); 03862 break; 03863 } 03864 AST_LIST_TRAVERSE_SAFE_END; 03865 03866 if (!f) { 03867 /* There were no acceptable frames on the readq. */ 03868 f = &ast_null_frame; 03869 if (chan->alertpipe[0] > -1) { 03870 int poke = 0; 03871 /* Restore the state of the alertpipe since we aren't ready for any 03872 * of the frames in the readq. */ 03873 if (write(chan->alertpipe[1], &poke, sizeof(poke)) != sizeof(poke)) { 03874 ast_log(LOG_ERROR, "Failed to write to alertpipe: %s\n", strerror(errno)); 03875 } 03876 } 03877 } 03878 03879 /* Interpret hangup and end-of-Q frames to return NULL */ 03880 /* XXX why not the same for frames from the channel ? */ 03881 if (f->frametype == AST_FRAME_CONTROL) { 03882 switch (f->subclass.integer) { 03883 case AST_CONTROL_HANGUP: 03884 chan->_softhangup |= AST_SOFTHANGUP_DEV; 03885 cause = f->data.uint32; 03886 /* Fall through */ 03887 case AST_CONTROL_END_OF_Q: 03888 ast_frfree(f); 03889 f = NULL; 03890 break; 03891 default: 03892 break; 03893 } 03894 } 03895 } else { 03896 chan->blocker = pthread_self(); 03897 if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) { 03898 if (chan->tech->exception) 03899 f = chan->tech->exception(chan); 03900 else { 03901 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name); 03902 f = &ast_null_frame; 03903 } 03904 /* Clear the exception flag */ 03905 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 03906 } else if (chan->tech && chan->tech->read) 03907 f = chan->tech->read(chan); 03908 else 03909 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name); 03910 } 03911 03912 /* 03913 * Reset the recorded file descriptor that triggered this read so that we can 03914 * easily detect when ast_read() is called without properly using ast_waitfor(). 03915 */ 03916 chan->fdno = -1; 03917 03918 /* Perform the framehook read event here. After the frame enters the framehook list 03919 * there is no telling what will happen, <insert mad scientist laugh here>!!! */ 03920 f = ast_framehook_list_read_event(chan->framehooks, f); 03921 03922 if (f) { 03923 struct ast_frame *readq_tail = AST_LIST_LAST(&chan->readq); 03924 struct ast_control_read_action_payload *read_action_payload; 03925 struct ast_party_connected_line connected; 03926 03927 /* if the channel driver returned more than one frame, stuff the excess 03928 into the readq for the next ast_read call 03929 */ 03930 if (AST_LIST_NEXT(f, frame_list)) { 03931 ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list)); 03932 ast_frfree(AST_LIST_NEXT(f, frame_list)); 03933 AST_LIST_NEXT(f, frame_list) = NULL; 03934 } 03935 03936 switch (f->frametype) { 03937 case AST_FRAME_CONTROL: 03938 if (f->subclass.integer == AST_CONTROL_ANSWER) { 03939 if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) { 03940 ast_debug(1, "Ignoring answer on an inbound call!\n"); 03941 ast_frfree(f); 03942 f = &ast_null_frame; 03943 } else if (prestate == AST_STATE_UP && ast_bridged_channel(chan)) { 03944 ast_debug(1, "Dropping duplicate answer!\n"); 03945 ast_frfree(f); 03946 f = &ast_null_frame; 03947 } else { 03948 /* Answer the CDR */ 03949 ast_setstate(chan, AST_STATE_UP); 03950 /* removed a call to ast_cdr_answer(chan->cdr) from here. */ 03951 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 03952 } 03953 } else if (f->subclass.integer == AST_CONTROL_READ_ACTION) { 03954 read_action_payload = f->data.ptr; 03955 switch (read_action_payload->action) { 03956 case AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO: 03957 ast_party_connected_line_init(&connected); 03958 ast_party_connected_line_copy(&connected, &chan->connected); 03959 if (ast_connected_line_parse_data(read_action_payload->payload, 03960 read_action_payload->payload_size, &connected)) { 03961 ast_party_connected_line_free(&connected); 03962 break; 03963 } 03964 if (ast_channel_connected_line_macro(NULL, chan, &connected, 1, 0)) { 03965 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, 03966 read_action_payload->payload, 03967 read_action_payload->payload_size); 03968 } 03969 ast_party_connected_line_free(&connected); 03970 break; 03971 } 03972 ast_frfree(f); 03973 f = &ast_null_frame; 03974 } 03975 break; 03976 case AST_FRAME_DTMF_END: 03977 send_dtmf_event(chan, "Received", f->subclass.integer, "No", "Yes"); 03978 ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass.integer, chan->name, f->len); 03979 /* Queue it up if DTMF is deferred, or if DTMF emulation is forced. */ 03980 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) || ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) { 03981 queue_dtmf_readq(chan, f); 03982 ast_frfree(f); 03983 f = &ast_null_frame; 03984 } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) { 03985 if (!ast_tvzero(chan->dtmf_tv) && 03986 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) { 03987 /* If it hasn't been long enough, defer this digit */ 03988 queue_dtmf_readq(chan, f); 03989 ast_frfree(f); 03990 f = &ast_null_frame; 03991 } else { 03992 /* There was no begin, turn this into a begin and send the end later */ 03993 f->frametype = AST_FRAME_DTMF_BEGIN; 03994 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF); 03995 chan->emulate_dtmf_digit = f->subclass.integer; 03996 chan->dtmf_tv = ast_tvnow(); 03997 if (f->len) { 03998 if (f->len > AST_MIN_DTMF_DURATION) 03999 chan->emulate_dtmf_duration = f->len; 04000 else 04001 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION; 04002 } else 04003 chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION; 04004 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); 04005 } 04006 if (chan->audiohooks) { 04007 struct ast_frame *old_frame = f; 04008 /*! 04009 * \todo XXX It is possible to write a digit to the audiohook twice 04010 * if the digit was originally read while the channel was in autoservice. */ 04011 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 04012 if (old_frame != f) 04013 ast_frfree(old_frame); 04014 } 04015 } else { 04016 struct timeval now = ast_tvnow(); 04017 if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) { 04018 ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass.integer, chan->name); 04019 ast_clear_flag(chan, AST_FLAG_IN_DTMF); 04020 if (!f->len) 04021 f->len = ast_tvdiff_ms(now, chan->dtmf_tv); 04022 04023 /* detect tones that were received on 04024 * the wire with durations shorter than 04025 * AST_MIN_DTMF_DURATION and set f->len 04026 * to the actual duration of the DTMF 04027 * frames on the wire. This will cause 04028 * dtmf emulation to be triggered later 04029 * on. 04030 */ 04031 if (ast_tvdiff_ms(now, chan->dtmf_tv) < AST_MIN_DTMF_DURATION) { 04032 f->len = ast_tvdiff_ms(now, chan->dtmf_tv); 04033 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); 04034 } 04035 } else if (!f->len) { 04036 ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass.integer, chan->name); 04037 f->len = AST_MIN_DTMF_DURATION; 04038 } 04039 if (f->len < AST_MIN_DTMF_DURATION && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) { 04040 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); 04041 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF); 04042 chan->emulate_dtmf_digit = f->subclass.integer; 04043 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len; 04044 ast_frfree(f); 04045 f = &ast_null_frame; 04046 } else { 04047 ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass.integer, chan->name); 04048 if (f->len < AST_MIN_DTMF_DURATION) { 04049 f->len = AST_MIN_DTMF_DURATION; 04050 } 04051 chan->dtmf_tv = now; 04052 } 04053 if (chan->audiohooks) { 04054 struct ast_frame *old_frame = f; 04055 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 04056 if (old_frame != f) 04057 ast_frfree(old_frame); 04058 } 04059 } 04060 break; 04061 case AST_FRAME_DTMF_BEGIN: 04062 send_dtmf_event(chan, "Received", f->subclass.integer, "Yes", "No"); 04063 ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass.integer, chan->name); 04064 if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) || 04065 (!ast_tvzero(chan->dtmf_tv) && 04066 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) { 04067 ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass.integer, chan->name); 04068 ast_frfree(f); 04069 f = &ast_null_frame; 04070 } else { 04071 ast_set_flag(chan, AST_FLAG_IN_DTMF); 04072 chan->dtmf_tv = ast_tvnow(); 04073 ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass.integer, chan->name); 04074 } 04075 break; 04076 case AST_FRAME_NULL: 04077 /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration 04078 * is reached , because we want to make sure we pass at least one 04079 * voice frame through before starting the next digit, to ensure a gap 04080 * between DTMF digits. */ 04081 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) { 04082 struct timeval now = ast_tvnow(); 04083 if (!chan->emulate_dtmf_duration) { 04084 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF); 04085 chan->emulate_dtmf_digit = 0; 04086 } else if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) { 04087 chan->emulate_dtmf_duration = 0; 04088 ast_frfree(f); 04089 f = &chan->dtmff; 04090 f->frametype = AST_FRAME_DTMF_END; 04091 f->subclass.integer = chan->emulate_dtmf_digit; 04092 f->len = ast_tvdiff_ms(now, chan->dtmf_tv); 04093 chan->dtmf_tv = now; 04094 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF); 04095 chan->emulate_dtmf_digit = 0; 04096 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, chan->name); 04097 if (chan->audiohooks) { 04098 struct ast_frame *old_frame = f; 04099 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 04100 if (old_frame != f) { 04101 ast_frfree(old_frame); 04102 } 04103 } 04104 } 04105 } 04106 break; 04107 case AST_FRAME_VOICE: 04108 /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration 04109 * is reached , because we want to make sure we pass at least one 04110 * voice frame through before starting the next digit, to ensure a gap 04111 * between DTMF digits. */ 04112 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) { 04113 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF); 04114 chan->emulate_dtmf_digit = 0; 04115 } 04116 04117 if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) { 04118 if (dropaudio) 04119 ast_read_generator_actions(chan, f); 04120 ast_frfree(f); 04121 f = &ast_null_frame; 04122 } 04123 04124 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_IN_DTMF)) { 04125 struct timeval now = ast_tvnow(); 04126 if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) { 04127 chan->emulate_dtmf_duration = 0; 04128 ast_frfree(f); 04129 f = &chan->dtmff; 04130 f->frametype = AST_FRAME_DTMF_END; 04131 f->subclass.integer = chan->emulate_dtmf_digit; 04132 f->len = ast_tvdiff_ms(now, chan->dtmf_tv); 04133 chan->dtmf_tv = now; 04134 if (chan->audiohooks) { 04135 struct ast_frame *old_frame = f; 04136 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 04137 if (old_frame != f) 04138 ast_frfree(old_frame); 04139 } 04140 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass.integer, chan->name); 04141 } else { 04142 /* Drop voice frames while we're still in the middle of the digit */ 04143 ast_frfree(f); 04144 f = &ast_null_frame; 04145 } 04146 } else if ((f->frametype == AST_FRAME_VOICE) && !(f->subclass.codec & chan->nativeformats)) { 04147 /* This frame is not one of the current native formats -- drop it on the floor */ 04148 char to[200]; 04149 ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n", 04150 chan->name, ast_getformatname(f->subclass.codec), ast_getformatname_multiple(to, sizeof(to), chan->nativeformats)); 04151 ast_frfree(f); 04152 f = &ast_null_frame; 04153 } else if ((f->frametype == AST_FRAME_VOICE)) { 04154 /* Send frame to audiohooks if present */ 04155 if (chan->audiohooks) { 04156 struct ast_frame *old_frame = f; 04157 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 04158 if (old_frame != f) 04159 ast_frfree(old_frame); 04160 } 04161 if (chan->monitor && chan->monitor->read_stream ) { 04162 /* XXX what does this do ? */ 04163 #ifndef MONITOR_CONSTANT_DELAY 04164 int jump = chan->outsmpl - chan->insmpl - 4 * f->samples; 04165 if (jump >= 0) { 04166 jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 04167 if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1) 04168 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 04169 chan->insmpl += (chan->outsmpl - chan->insmpl) + f->samples; 04170 } else 04171 chan->insmpl+= f->samples; 04172 #else 04173 int jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 04174 if (jump - MONITOR_DELAY >= 0) { 04175 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1) 04176 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 04177 chan->insmpl += chan->outsmpl - chan->insmpl; 04178 } else 04179 chan->insmpl += f->samples; 04180 #endif 04181 if (chan->monitor->state == AST_MONITOR_RUNNING) { 04182 if (ast_writestream(chan->monitor->read_stream, f) < 0) 04183 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n"); 04184 } 04185 } 04186 04187 if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL) { 04188 f = &ast_null_frame; 04189 } 04190 04191 /* it is possible for the translation process on chan->readtrans to have 04192 produced multiple frames from the single input frame we passed it; if 04193 this happens, queue the additional frames *before* the frames we may 04194 have queued earlier. if the readq was empty, put them at the head of 04195 the queue, and if it was not, put them just after the frame that was 04196 at the end of the queue. 04197 */ 04198 if (AST_LIST_NEXT(f, frame_list)) { 04199 if (!readq_tail) { 04200 ast_queue_frame_head(chan, AST_LIST_NEXT(f, frame_list)); 04201 } else { 04202 __ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list), 0, readq_tail); 04203 } 04204 ast_frfree(AST_LIST_NEXT(f, frame_list)); 04205 AST_LIST_NEXT(f, frame_list) = NULL; 04206 } 04207 04208 /* Run generator sitting on the line if timing device not available 04209 * and synchronous generation of outgoing frames is necessary */ 04210 ast_read_generator_actions(chan, f); 04211 } 04212 break; 04213 default: 04214 /* Just pass it on! */ 04215 break; 04216 } 04217 } else { 04218 /* Make sure we always return NULL in the future */ 04219 if (!chan->_softhangup) { 04220 chan->_softhangup |= AST_SOFTHANGUP_DEV; 04221 } 04222 if (cause) 04223 chan->hangupcause = cause; 04224 if (chan->generator) 04225 ast_deactivate_generator(chan); 04226 /* We no longer End the CDR here */ 04227 } 04228 04229 /* High bit prints debugging */ 04230 if (chan->fin & DEBUGCHAN_FLAG) 04231 ast_frame_dump(chan->name, f, "<<"); 04232 chan->fin = FRAMECOUNT_INC(chan->fin); 04233 04234 done: 04235 if (chan->music_state && chan->generator && chan->generator->digit && f && f->frametype == AST_FRAME_DTMF_END) 04236 chan->generator->digit(chan, f->subclass.integer); 04237 04238 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) { 04239 /* The list gets recreated if audiohooks are added again later */ 04240 ast_audiohook_detach_list(chan->audiohooks); 04241 chan->audiohooks = NULL; 04242 } 04243 ast_channel_unlock(chan); 04244 return f; 04245 }
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 5306 of file channel.c.
References ast_channel::_state, outgoing_helper::account, ast_call(), ast_call_forward(), AST_CAUSE_NO_ANSWER, ast_cdr_alloc(), ast_cdr_answer(), ast_cdr_busy(), ast_cdr_disposition(), ast_cdr_end(), ast_cdr_failed(), AST_CDR_FLAG_ORIGINATED, ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_setapp(), ast_cdr_start(), ast_cdr_update(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_lock_both, ast_channel_set_connected_line(), ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_copy_string(), AST_FRAME_CONTROL, ast_frfree, ast_hangup(), ast_log(), ast_party_connected_line_set_init(), AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, ast_read(), ast_request(), ast_set_callerid(), ast_set_flag, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_waitfor(), ast_channel::call_forward, cause, ast_channel::cdr, chanlist::chan, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_channel::connected, chanlist::connected, ast_channel::context, outgoing_helper::context, ast_channel::exten, outgoing_helper::exten, f, handle_cause(), ast_channel::hangupcause, ast_party_connected_line::id, LOG_NOTICE, ast_party_id::name, ast_party_id::number, outgoing_helper::parent_channel, ast_party_name::presentation, ast_party_number::presentation, ast_channel::priority, outgoing_helper::priority, ast_party_name::str, ast_party_number::str, ast_party_name::valid, ast_party_number::valid, and outgoing_helper::vars.
Referenced by ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_request_and_dial(), and parkandannounce_exec().
05307 { 05308 int dummy_outstate; 05309 int cause = 0; 05310 struct ast_channel *chan; 05311 int res = 0; 05312 int last_subclass = 0; 05313 struct ast_party_connected_line connected; 05314 05315 if (outstate) 05316 *outstate = 0; 05317 else 05318 outstate = &dummy_outstate; /* make outstate always a valid pointer */ 05319 05320 chan = ast_request(type, format, requestor, data, &cause); 05321 if (!chan) { 05322 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 05323 handle_cause(cause, outstate); 05324 return NULL; 05325 } 05326 05327 if (oh) { 05328 if (oh->vars) { 05329 ast_set_variables(chan, oh->vars); 05330 } 05331 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) { 05332 /* 05333 * Use the oh values instead of the function parameters for the 05334 * outgoing CallerID. 05335 */ 05336 cid_num = oh->cid_num; 05337 cid_name = oh->cid_name; 05338 } 05339 if (oh->parent_channel) { 05340 /* Safely inherit variables and datastores from the parent channel. */ 05341 ast_channel_lock_both(oh->parent_channel, chan); 05342 ast_channel_inherit_variables(oh->parent_channel, chan); 05343 ast_channel_datastore_inherit(oh->parent_channel, chan); 05344 ast_channel_unlock(oh->parent_channel); 05345 ast_channel_unlock(chan); 05346 } 05347 if (oh->account) { 05348 ast_channel_lock(chan); 05349 ast_cdr_setaccount(chan, oh->account); 05350 ast_channel_unlock(chan); 05351 } 05352 } 05353 05354 /* 05355 * I seems strange to set the CallerID on an outgoing call leg 05356 * to whom we are calling, but this function's callers are doing 05357 * various Originate methods. This call leg goes to the local 05358 * user. Once the local user answers, the dialplan needs to be 05359 * able to access the CallerID from the CALLERID function as if 05360 * the local user had placed this call. 05361 */ 05362 ast_set_callerid(chan, cid_num, cid_name, cid_num); 05363 05364 ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED); 05365 ast_party_connected_line_set_init(&connected, &chan->connected); 05366 if (cid_num) { 05367 connected.id.number.valid = 1; 05368 connected.id.number.str = (char *) cid_num; 05369 connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 05370 } 05371 if (cid_name) { 05372 connected.id.name.valid = 1; 05373 connected.id.name.str = (char *) cid_name; 05374 connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 05375 } 05376 ast_channel_set_connected_line(chan, &connected, NULL); 05377 05378 if (ast_call(chan, data, 0)) { /* ast_call failed... */ 05379 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data); 05380 } else { 05381 res = 1; /* mark success in case chan->_state is already AST_STATE_UP */ 05382 while (timeout && chan->_state != AST_STATE_UP) { 05383 struct ast_frame *f; 05384 res = ast_waitfor(chan, timeout); 05385 if (res == 0) { /* timeout, treat it like ringing */ 05386 *outstate = AST_CONTROL_RINGING; 05387 break; 05388 } 05389 if (res < 0) /* error or done */ 05390 break; 05391 if (timeout > -1) 05392 timeout = res; 05393 if (!ast_strlen_zero(chan->call_forward)) { 05394 if (!(chan = ast_call_forward(NULL, chan, NULL, format, oh, outstate))) { 05395 return NULL; 05396 } 05397 continue; 05398 } 05399 05400 f = ast_read(chan); 05401 if (!f) { 05402 *outstate = AST_CONTROL_HANGUP; 05403 res = 0; 05404 break; 05405 } 05406 if (f->frametype == AST_FRAME_CONTROL) { 05407 switch (f->subclass.integer) { 05408 case AST_CONTROL_RINGING: /* record but keep going */ 05409 *outstate = f->subclass.integer; 05410 break; 05411 05412 case AST_CONTROL_BUSY: 05413 ast_cdr_busy(chan->cdr); 05414 *outstate = f->subclass.integer; 05415 timeout = 0; 05416 break; 05417 05418 case AST_CONTROL_INCOMPLETE: 05419 ast_cdr_failed(chan->cdr); 05420 *outstate = AST_CONTROL_CONGESTION; 05421 timeout = 0; 05422 break; 05423 05424 case AST_CONTROL_CONGESTION: 05425 ast_cdr_failed(chan->cdr); 05426 *outstate = f->subclass.integer; 05427 timeout = 0; 05428 break; 05429 05430 case AST_CONTROL_ANSWER: 05431 ast_cdr_answer(chan->cdr); 05432 *outstate = f->subclass.integer; 05433 timeout = 0; /* trick to force exit from the while() */ 05434 break; 05435 05436 /* Ignore these */ 05437 case AST_CONTROL_PROGRESS: 05438 case AST_CONTROL_PROCEEDING: 05439 case AST_CONTROL_HOLD: 05440 case AST_CONTROL_UNHOLD: 05441 case AST_CONTROL_VIDUPDATE: 05442 case AST_CONTROL_SRCUPDATE: 05443 case AST_CONTROL_SRCCHANGE: 05444 case AST_CONTROL_CONNECTED_LINE: 05445 case AST_CONTROL_REDIRECTING: 05446 case AST_CONTROL_CC: 05447 case -1: /* Ignore -- just stopping indications */ 05448 break; 05449 05450 default: 05451 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass.integer); 05452 } 05453 last_subclass = f->subclass.integer; 05454 } 05455 ast_frfree(f); 05456 } 05457 } 05458 05459 /* Final fixups */ 05460 if (oh) { 05461 if (!ast_strlen_zero(oh->context)) 05462 ast_copy_string(chan->context, oh->context, sizeof(chan->context)); 05463 if (!ast_strlen_zero(oh->exten)) 05464 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten)); 05465 if (oh->priority) 05466 chan->priority = oh->priority; 05467 } 05468 if (chan->_state == AST_STATE_UP) 05469 *outstate = AST_CONTROL_ANSWER; 05470 05471 if (res <= 0) { 05472 ast_channel_lock(chan); 05473 if (AST_CONTROL_RINGING == last_subclass) { 05474 chan->hangupcause = AST_CAUSE_NO_ANSWER; 05475 } 05476 if (!chan->cdr && (chan->cdr = ast_cdr_alloc())) { 05477 ast_cdr_init(chan->cdr, chan); 05478 } 05479 if (chan->cdr) { 05480 char tmp[256]; 05481 05482 snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data); 05483 ast_cdr_setapp(chan->cdr, "Dial", tmp); 05484 ast_cdr_update(chan); 05485 ast_cdr_start(chan->cdr); 05486 ast_cdr_end(chan->cdr); 05487 /* If the cause wasn't handled properly */ 05488 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) { 05489 ast_cdr_failed(chan->cdr); 05490 } 05491 } 05492 ast_channel_unlock(chan); 05493 ast_hangup(chan); 05494 chan = NULL; 05495 } 05496 return chan; 05497 }
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 4688 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().
04689 { 04690 int num_new_samples = frame->samples; 04691 struct plc_ds *plc = datastore->data; 04692 04693 /* As a general note, let me explain the somewhat odd calculations used when taking 04694 * the frame offset into account here. According to documentation in frame.h, the frame's 04695 * offset field indicates the number of bytes that the audio is offset. The plc->samples_buf 04696 * is not an array of bytes, but rather an array of 16-bit integers since it holds SLIN 04697 * samples. So I had two choices to make here with the offset. 04698 * 04699 * 1. Make the offset AST_FRIENDLY_OFFSET bytes. The main downside for this is that 04700 * I can't just add AST_FRIENDLY_OFFSET to the plc->samples_buf and have the pointer 04701 * arithmetic come out right. I would have to do some odd casting or division for this to 04702 * work as I wanted. 04703 * 2. Make the offset AST_FRIENDLY_OFFSET * 2 bytes. This allows the pointer arithmetic 04704 * to work out better with the plc->samples_buf. The downside here is that the buffer's 04705 * allocation contains an extra 64 bytes of unused space. 04706 * 04707 * I decided to go with option 2. This is why in the calloc statement and the statement that 04708 * sets the frame's offset, AST_FRIENDLY_OFFSET is multiplied by 2. 04709 */ 04710 04711 /* If this audio frame has no samples to fill in, ignore it */ 04712 if (!num_new_samples) { 04713 return; 04714 } 04715 04716 /* First, we need to be sure that our buffer is large enough to accomodate 04717 * the samples we need to fill in. This will likely only occur on the first 04718 * frame we write. 04719 */ 04720 if (plc->num_samples < num_new_samples) { 04721 ast_free(plc->samples_buf); 04722 plc->samples_buf = ast_calloc(1, (num_new_samples * sizeof(*plc->samples_buf)) + (AST_FRIENDLY_OFFSET * 2)); 04723 if (!plc->samples_buf) { 04724 ast_channel_datastore_remove(chan, datastore); 04725 ast_datastore_free(datastore); 04726 return; 04727 } 04728 plc->num_samples = num_new_samples; 04729 } 04730 04731 if (frame->datalen == 0) { 04732 plc_fillin(&plc->plc_state, plc->samples_buf + AST_FRIENDLY_OFFSET, frame->samples); 04733 frame->data.ptr = plc->samples_buf + AST_FRIENDLY_OFFSET; 04734 frame->datalen = num_new_samples * 2; 04735 frame->offset = AST_FRIENDLY_OFFSET * 2; 04736 } else { 04737 plc_rx(&plc->plc_state, frame->data.ptr, frame->samples); 04738 } 04739 }
static void apply_plc | ( | struct ast_channel * | chan, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 4741 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().
04742 { 04743 struct ast_datastore *datastore; 04744 struct plc_ds *plc; 04745 04746 datastore = ast_channel_datastore_find(chan, &plc_ds_info, NULL); 04747 if (datastore) { 04748 plc = datastore->data; 04749 adjust_frame_for_plc(chan, frame, datastore); 04750 return; 04751 } 04752 04753 datastore = ast_datastore_alloc(&plc_ds_info, NULL); 04754 if (!datastore) { 04755 return; 04756 } 04757 plc = ast_calloc(1, sizeof(*plc)); 04758 if (!plc) { 04759 ast_datastore_free(datastore); 04760 return; 04761 } 04762 datastore->data = plc; 04763 ast_channel_datastore_add(chan, datastore); 04764 adjust_frame_for_plc(chan, frame, datastore); 04765 }
int ast_activate_generator | ( | struct ast_channel * | chan, | |
struct ast_generator * | gen, | |||
void * | params | |||
) |
Activate a given generator
Definition at line 3074 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().
03075 { 03076 int res = 0; 03077 03078 ast_channel_lock(chan); 03079 if (chan->generatordata) { 03080 if (chan->generator && chan->generator->release) 03081 chan->generator->release(chan, chan->generatordata); 03082 chan->generatordata = NULL; 03083 } 03084 if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) { 03085 res = -1; 03086 } 03087 if (!res) { 03088 ast_settimeout(chan, 50, generator_force, chan); 03089 chan->generator = gen; 03090 } 03091 ast_channel_unlock(chan); 03092 03093 ast_prod(chan); 03094 03095 return res; 03096 }
int ast_active_channels | ( | void | ) |
returns number of active/allocated channels
Definition at line 832 of file channel.c.
References ao2_container_count(), and channels.
Referenced by action_corestatus(), ast_var_channels(), ast_var_channels_table(), can_safely_quit(), handle_chanlist(), handle_show_settings(), and really_quit().
00833 { 00834 return channels ? ao2_container_count(channels) : 0; 00835 }
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 3024 of file channel.c.
References __ast_answer(), and chanlist::chan.
Referenced by action_bridge(), agi_exec_full(), alarmreceiver_exec(), answer_trunk_chan(), app_exec(), ast_control_streamfile(), ast_do_pickup(), ast_pickup_call(), auth_exec(), background_detect_exec(), bridge_exec(), builtin_parkcall(), common_exec(), conf_exec(), count_exec(), dahdiras_exec(), dial_exec_full(), dictate_exec(), directory_exec(), disa_exec(), eivr_comm(), handle_answer(), ices_exec(), login_exec(), minivm_accmess_exec(), minivm_greet_exec(), minivm_record_exec(), old_milliwatt_exec(), park_call_exec(), parked_call_exec(), pbx_builtin_background(), playback_exec(), privacy_exec(), read_exec(), readexten_exec(), receivefax_exec(), 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().
03025 { 03026 return __ast_answer(chan, 0, 1); 03027 }
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 822 of file channel.c.
References ao2_callback, ast_channel_softhangup_cb(), channels, OBJ_MULTIPLE, and OBJ_NODATA.
Referenced by can_safely_quit().
00823 { 00824 shutting_down = 1; 00825 00826 if (hangup) { 00827 ao2_callback(channels, OBJ_NODATA | OBJ_MULTIPLE, ast_channel_softhangup_cb, NULL); 00828 } 00829 }
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 1041 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().
01042 { 01043 /* This just our opinion, expressed in code. We are asked to choose 01044 the best codec to use, given no information */ 01045 int x; 01046 static const format_t prefs[] = 01047 { 01048 /*! Okay, ulaw is used by all telephony equipment, so start with it */ 01049 AST_FORMAT_ULAW, 01050 /*! Unless of course, you're a silly European, so then prefer ALAW */ 01051 AST_FORMAT_ALAW, 01052 AST_FORMAT_G719, 01053 AST_FORMAT_SIREN14, 01054 AST_FORMAT_SIREN7, 01055 AST_FORMAT_TESTLAW, 01056 /*! G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority */ 01057 AST_FORMAT_G722, 01058 /*! Okay, well, signed linear is easy to translate into other stuff */ 01059 AST_FORMAT_SLINEAR16, 01060 AST_FORMAT_SLINEAR, 01061 /*! G.726 is standard ADPCM, in RFC3551 packing order */ 01062 AST_FORMAT_G726, 01063 /*! G.726 is standard ADPCM, in AAL2 packing order */ 01064 AST_FORMAT_G726_AAL2, 01065 /*! ADPCM has great sound quality and is still pretty easy to translate */ 01066 AST_FORMAT_ADPCM, 01067 /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to 01068 translate and sounds pretty good */ 01069 AST_FORMAT_GSM, 01070 /*! iLBC is not too bad */ 01071 AST_FORMAT_ILBC, 01072 /*! Speex is free, but computationally more expensive than GSM */ 01073 AST_FORMAT_SPEEX16, 01074 AST_FORMAT_SPEEX, 01075 /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough 01076 to use it */ 01077 AST_FORMAT_LPC10, 01078 /*! G.729a is faster than 723 and slightly less expensive */ 01079 AST_FORMAT_G729A, 01080 /*! Down to G.723.1 which is proprietary but at least designed for voice */ 01081 AST_FORMAT_G723_1, 01082 }; 01083 char buf[512]; 01084 01085 /* Strip out video */ 01086 fmts &= AST_FORMAT_AUDIO_MASK; 01087 01088 /* Find the first preferred codec in the format given */ 01089 for (x = 0; x < ARRAY_LEN(prefs); x++) { 01090 if (fmts & prefs[x]) 01091 return prefs[x]; 01092 } 01093 01094 ast_log(LOG_WARNING, "Don't know any of %s formats\n", ast_getformatname_multiple(buf, sizeof(buf), fmts)); 01095 01096 return 0; 01097 }
struct ast_channel* ast_bridged_channel | ( | struct ast_channel * | chan | ) |
Find bridged channel.
chan | Current channel |
Definition at line 6920 of file channel.c.
References ast_channel::_bridge, ast_channel_tech::bridged_channel, chanlist::chan, and ast_channel::tech.
Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_channel_masquerade(), __ast_read(), __dahdi_exception(), _skinny_show_lines(), action_agents(), action_coreshowchannels(), agents_data_provider_get(), agents_show(), agents_show_online(), analog_attempt_transfer(), analog_exception(), analog_hangup(), analog_ss_thread(), ast_bridge_call(), ast_cel_report_event(), ast_channel_data_add_structure(), ast_channel_set_linkgroup(), ast_do_masquerade(), ast_rtp_instance_set_stats_vars(), ast_set_hangupsource(), ast_var_channel_bridge(), ast_var_channels_table(), attempt_transfer(), cb_events(), channel_spy(), check_bridge(), common_exec(), console_transfer(), create_jb(), dahdi_handle_event(), dahdi_hangup(), export_aoc_vars(), func_channel_read(), get_refer_info(), handle_chanlist(), handle_hd_hf(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_refer(), handle_showchan(), handle_soft_key_event_message(), handle_stimulus_message(), key_call(), key_dial_page(), local_attended_transfer(), local_queryoption(), mgcp_hangup(), mgcp_ss(), misdn_attempt_transfer(), mixmonitor_thread(), my_get_sigpvt_bridged_channel(), park_call_full(), schedule_delivery(), serialize_showchan(), sig_pri_attempt_transfer(), sig_pri_handle_hold(), sip_hangup(), sip_set_rtp_peer(), skinny_transfer(), socket_process(), start_spying(), startmon(), TransferCallStep1(), and unistim_hangup().
06921 { 06922 struct ast_channel *bridged; 06923 bridged = chan->_bridge; 06924 if (bridged && bridged->tech->bridged_channel) 06925 bridged = bridged->tech->bridged_channel(chan, bridged); 06926 return bridged; 06927 }
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 5610 of file channel.c.
References AST_CDR_FLAG_DIALED, ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_set_flag, ast_test_flag, ast_channel_tech::call, ast_channel::cdr, 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().
05611 { 05612 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 05613 If the remote end does not answer within the timeout, then do NOT hang up, but 05614 return anyway. */ 05615 int res = -1; 05616 /* Stop if we're a zombie or need a soft hangup */ 05617 ast_channel_lock(chan); 05618 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 05619 if (chan->cdr) { 05620 ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED); 05621 } 05622 if (chan->tech->call) 05623 res = chan->tech->call(chan, addr, timeout); 05624 ast_set_flag(chan, AST_FLAG_OUTGOING); 05625 } 05626 ast_channel_unlock(chan); 05627 return res; 05628 }
struct ast_channel* ast_call_forward | ( | struct ast_channel * | caller, | |
struct ast_channel * | orig, | |||
int * | timeout, | |||
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 5236 of file channel.c.
References outgoing_helper::account, ast_channel::accountcode, accountcode, ast_call(), AST_CDR_FLAG_ORIGINATED, ast_cdr_setaccount(), ast_channel_lock, ast_channel_lock_both, ast_channel_unlock, ast_copy_flags, ast_copy_string(), ast_hangup(), ast_log(), ast_party_connected_line_copy(), ast_party_redirecting_copy(), ast_request(), ast_set_variables(), ast_string_field_set, ast_channel::call_forward, call_forward_inherit(), ast_channel::caller, cause, ast_channel::cdr, ast_channel::connected, ast_channel::context, handle_cause(), LOG_NOTICE, outgoing_helper::parent_channel, pbx_builtin_getvar_helper(), ast_channel::redirecting, S_OR, type, and outgoing_helper::vars.
Referenced by __ast_request_and_dial(), and feature_request_and_dial().
05237 { 05238 char tmpchan[256]; 05239 struct ast_channel *new_chan = NULL; 05240 char *data, *type; 05241 int cause = 0; 05242 int res; 05243 05244 /* gather data and request the new forward channel */ 05245 ast_copy_string(tmpchan, orig->call_forward, sizeof(tmpchan)); 05246 if ((data = strchr(tmpchan, '/'))) { 05247 *data++ = '\0'; 05248 type = tmpchan; 05249 } else { 05250 const char *forward_context; 05251 ast_channel_lock(orig); 05252 forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT"); 05253 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", orig->call_forward, S_OR(forward_context, orig->context)); 05254 ast_channel_unlock(orig); 05255 data = tmpchan; 05256 type = "Local"; 05257 } 05258 if (!(new_chan = ast_request(type, format, orig, data, &cause))) { 05259 ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause); 05260 handle_cause(cause, outstate); 05261 ast_hangup(orig); 05262 return NULL; 05263 } 05264 05265 /* Copy/inherit important information into new channel */ 05266 if (oh) { 05267 if (oh->vars) { 05268 ast_set_variables(new_chan, oh->vars); 05269 } 05270 if (oh->parent_channel) { 05271 call_forward_inherit(new_chan, oh->parent_channel, orig); 05272 } 05273 if (oh->account) { 05274 ast_channel_lock(new_chan); 05275 ast_cdr_setaccount(new_chan, oh->account); 05276 ast_channel_unlock(new_chan); 05277 } 05278 } else if (caller) { /* no outgoing helper so use caller if avaliable */ 05279 call_forward_inherit(new_chan, caller, orig); 05280 } 05281 05282 ast_channel_lock_both(orig, new_chan); 05283 ast_copy_flags(new_chan->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED); 05284 ast_string_field_set(new_chan, accountcode, orig->accountcode); 05285 ast_party_connected_line_copy(&new_chan->connected, &orig->connected); 05286 ast_party_redirecting_copy(&new_chan->redirecting, &orig->redirecting); 05287 ast_channel_unlock(new_chan); 05288 ast_channel_unlock(orig); 05289 05290 /* call new channel */ 05291 res = ast_call(new_chan, data, 0); 05292 if (timeout) { 05293 *timeout = res; 05294 } 05295 if (res) { 05296 ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data); 05297 ast_hangup(orig); 05298 ast_hangup(new_chan); 05299 return NULL; 05300 } 05301 ast_hangup(orig); 05302 05303 return new_chan; 05304 }
void ast_cancel_shutdown | ( | void | ) |
Cancel a shutdown in progress.
Cancels an existing shutdown and returns to normal operation
Definition at line 838 of file channel.c.
Referenced by handle_abort_shutdown().
00839 { 00840 shutting_down = 0; 00841 }
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 959 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().
00960 { 00961 int x; 00962 00963 for (x = 0; x < ARRAY_LEN(causes); x++) { 00964 if (causes[x].cause == cause) 00965 return causes[x].desc; 00966 } 00967 00968 return "Unknown"; 00969 }
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 6078 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().
06079 { 06080 /* We must re-link, as the hash value will change here. */ 06081 ao2_unlink(channels, chan); 06082 ast_channel_lock(chan); 06083 __ast_change_name_nolink(chan, newname); 06084 ast_channel_unlock(chan); 06085 ao2_link(channels, chan); 06086 }
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 9518 of file channel.c.
References __ast_channel_alloc_ap().
09523 { 09524 va_list ap1, ap2; 09525 struct ast_channel *result; 09526 09527 09528 va_start(ap1, name_fmt); 09529 va_start(ap2, name_fmt); 09530 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context, 09531 linkedid, amaflag, __FILE__, __LINE__, __FUNCTION__, name_fmt, ap1, ap2); 09532 va_end(ap1); 09533 va_end(ap2); 09534 09535 return result; 09536 }
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 7263 of file channel.c.
References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_RETRY, ast_channel_clear_softhangup(), ast_channel_make_compatible(), ast_check_hangup(), ast_check_hangup_locked(), ast_clear_flag, AST_CONTROL_SRCUPDATE, ast_debug, AST_FEATURE_PLAY_WARNING, AST_FEATURE_WARNING_ACTIVE, AST_FLAG_END_DTMF_ONLY, AST_FLAG_NBRIDGE, AST_FLAG_ZOMBIE, ast_framehook_list_is_empty(), ast_generic_bridge(), ast_indicate(), ast_log(), ast_manager_event_multichan, ast_samp2tv(), ast_set_flag, ast_set_owners_and_peers(), AST_SOFTHANGUP_UNBRIDGE, ast_test_flag, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), ast_verb, ast_channel::audiohooks, ast_channel_tech::bridge, bridge_play_sounds(), bridge_playfile(), ast_channel::caller, config, EVENT_FLAG_CALL, ast_channel::framehooks, ast_channel::generator, ast_party_caller::id, LOG_WARNING, manager_bridge_event(), ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, ast_party_id::number, ast_channel::readformat, S_COR, ast_channel_tech::send_digit_begin, ast_party_number::str, ast_channel::tech, ast_channel::uniqueid, update_bridge_vars(), ast_party_number::valid, and ast_channel::writeformat.
Referenced by ast_bridge_call().
07265 { 07266 struct ast_channel *chans[2] = { c0, c1 }; 07267 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 07268 format_t o0nativeformats; 07269 format_t o1nativeformats; 07270 long time_left_ms=0; 07271 char caller_warning = 0; 07272 char callee_warning = 0; 07273 07274 *fo = NULL; 07275 07276 if (c0->_bridge) { 07277 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 07278 c0->name, c0->_bridge->name); 07279 return -1; 07280 } 07281 if (c1->_bridge) { 07282 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 07283 c1->name, c1->_bridge->name); 07284 return -1; 07285 } 07286 07287 /* Stop if we're a zombie or need a soft hangup */ 07288 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 07289 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 07290 return -1; 07291 07292 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING); 07293 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING); 07294 07295 if (ast_tvzero(config->start_time)) { 07296 config->start_time = ast_tvnow(); 07297 if (config->start_sound) { 07298 if (caller_warning) { 07299 bridge_playfile(c0, c1, config->start_sound, config->timelimit / 1000); 07300 } 07301 if (callee_warning) { 07302 bridge_playfile(c1, c0, config->start_sound, config->timelimit / 1000); 07303 } 07304 } 07305 } 07306 07307 /* Keep track of bridge */ 07308 c0->_bridge = c1; 07309 c1->_bridge = c0; 07310 07311 ast_set_owners_and_peers(c0, c1); 07312 07313 o0nativeformats = c0->nativeformats; 07314 o1nativeformats = c1->nativeformats; 07315 07316 if (config->feature_timer && !ast_tvzero(config->nexteventts)) { 07317 config->nexteventts = ast_tvadd(config->feature_start_time, ast_samp2tv(config->feature_timer, 1000)); 07318 } else if (config->timelimit) { 07319 time_left_ms = config->timelimit - ast_tvdiff_ms(ast_tvnow(), config->start_time); 07320 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 07321 if ((caller_warning || callee_warning) && config->play_warning) { 07322 long next_warn = config->play_warning; 07323 if (time_left_ms < config->play_warning && config->warning_freq > 0) { 07324 /* At least one warning was played, which means we are returning after feature */ 07325 long warns_passed = (config->play_warning - time_left_ms) / config->warning_freq; 07326 /* It is 'warns_passed * warning_freq' NOT '(warns_passed + 1) * warning_freq', 07327 because nexteventts will be updated once again in the 'if (!to)' block */ 07328 next_warn = config->play_warning - warns_passed * config->warning_freq; 07329 } 07330 config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(next_warn, 1000)); 07331 } 07332 } else { 07333 config->nexteventts.tv_sec = 0; 07334 config->nexteventts.tv_usec = 0; 07335 } 07336 07337 if (!c0->tech->send_digit_begin) 07338 ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY); 07339 if (!c1->tech->send_digit_begin) 07340 ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY); 07341 manager_bridge_event(1, 1, c0, c1); 07342 07343 /* Before we enter in and bridge these two together tell them both the source of audio has changed */ 07344 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 07345 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 07346 07347 for (/* ever */;;) { 07348 struct timeval now = { 0, }; 07349 int to; 07350 07351 to = -1; 07352 07353 if (!ast_tvzero(config->nexteventts)) { 07354 now = ast_tvnow(); 07355 to = ast_tvdiff_ms(config->nexteventts, now); 07356 if (to <= 0) { 07357 if (!config->timelimit) { 07358 res = AST_BRIDGE_COMPLETE; 07359 break; 07360 } 07361 to = 0; 07362 } 07363 } 07364 07365 if (config->timelimit) { 07366 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time); 07367 if (time_left_ms < to) 07368 to = time_left_ms; 07369 07370 if (time_left_ms <= 0) { 07371 if (caller_warning && config->end_sound) 07372 bridge_playfile(c0, c1, config->end_sound, 0); 07373 if (callee_warning && config->end_sound) 07374 bridge_playfile(c1, c0, config->end_sound, 0); 07375 *fo = NULL; 07376 res = 0; 07377 break; 07378 } 07379 07380 if (!to) { 07381 if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) { 07382 int t = (time_left_ms + 500) / 1000; /* round to nearest second */ 07383 if (caller_warning) 07384 bridge_playfile(c0, c1, config->warning_sound, t); 07385 if (callee_warning) 07386 bridge_playfile(c1, c0, config->warning_sound, t); 07387 } 07388 07389 if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) { 07390 config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000)); 07391 } else { 07392 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 07393 } 07394 } 07395 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE); 07396 } 07397 07398 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 07399 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07400 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE); 07401 } 07402 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07403 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE); 07404 } 07405 c0->_bridge = c1; 07406 c1->_bridge = c0; 07407 ast_debug(1, "Unbridge signal received. Ending native bridge.\n"); 07408 continue; 07409 } 07410 07411 /* Stop if we're a zombie or need a soft hangup */ 07412 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 07413 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) { 07414 *fo = NULL; 07415 res = 0; 07416 ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n", 07417 c0->name, c1->name, 07418 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No", 07419 ast_check_hangup(c0) ? "Yes" : "No", 07420 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No", 07421 ast_check_hangup(c1) ? "Yes" : "No"); 07422 break; 07423 } 07424 07425 update_bridge_vars(c0, c1); 07426 07427 bridge_play_sounds(c0, c1); 07428 07429 if (c0->tech->bridge && 07430 /* if < 1 ms remains use generic bridging for accurate timing */ 07431 (!config->timelimit || to > 1000 || to == 0) && 07432 (c0->tech->bridge == c1->tech->bridge) && 07433 !c0->monitor && !c1->monitor && 07434 !c0->audiohooks && !c1->audiohooks && 07435 ast_framehook_list_is_empty(c0->framehooks) && ast_framehook_list_is_empty(c1->framehooks) && 07436 !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) { 07437 int timeoutms = to - 1000 > 0 ? to - 1000 : to; 07438 /* Looks like they share a bridge method and nothing else is in the way */ 07439 ast_set_flag(c0, AST_FLAG_NBRIDGE); 07440 ast_set_flag(c1, AST_FLAG_NBRIDGE); 07441 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, timeoutms)) == AST_BRIDGE_COMPLETE) { 07442 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans, 07443 "Channel1: %s\r\n" 07444 "Channel2: %s\r\n" 07445 "Uniqueid1: %s\r\n" 07446 "Uniqueid2: %s\r\n" 07447 "CallerID1: %s\r\n" 07448 "CallerID2: %s\r\n", 07449 c0->name, c1->name, 07450 c0->uniqueid, c1->uniqueid, 07451 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"), 07452 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>")); 07453 07454 ast_debug(1, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name); 07455 07456 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 07457 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 07458 07459 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 07460 continue; 07461 } 07462 07463 c0->_bridge = NULL; 07464 c1->_bridge = NULL; 07465 return res; 07466 } else { 07467 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 07468 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 07469 } 07470 switch (res) { 07471 case AST_BRIDGE_RETRY: 07472 if (config->play_warning) { 07473 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE); 07474 } 07475 continue; 07476 default: 07477 ast_verb(3, "Native bridging %s and %s ended\n", c0->name, c1->name); 07478 /* fallthrough */ 07479 case AST_BRIDGE_FAILED_NOWARN: 07480 break; 07481 } 07482 } 07483 07484 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) || 07485 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) && 07486 !(c0->generator || c1->generator)) { 07487 if (ast_channel_make_compatible(c0, c1)) { 07488 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 07489 manager_bridge_event(0, 1, c0, c1); 07490 return AST_BRIDGE_FAILED; 07491 } 07492 o0nativeformats = c0->nativeformats; 07493 o1nativeformats = c1->nativeformats; 07494 } 07495 07496 update_bridge_vars(c0, c1); 07497 07498 res = ast_generic_bridge(c0, c1, config, fo, rc); 07499 if (res != AST_BRIDGE_RETRY) { 07500 break; 07501 } else if (config->feature_timer) { 07502 /* feature timer expired but has not been updated, sending to ast_bridge_call to do so */ 07503 break; 07504 } 07505 } 07506 07507 ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY); 07508 ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY); 07509 07510 /* Now that we have broken the bridge the source will change yet again */ 07511 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 07512 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 07513 07514 c0->_bridge = NULL; 07515 c1->_bridge = NULL; 07516 07517 ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans, 07518 "Channel1: %s\r\n" 07519 "Channel2: %s\r\n" 07520 "Uniqueid1: %s\r\n" 07521 "Uniqueid2: %s\r\n" 07522 "CallerID1: %s\r\n" 07523 "CallerID2: %s\r\n", 07524 c0->name, c1->name, 07525 c0->uniqueid, c1->uniqueid, 07526 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"), 07527 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>")); 07528 ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name); 07529 07530 return res; 07531 }
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 1595 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_group(), pickup_by_mark(), pickup_by_part(), and state_notify_build_xml().
01597 { 01598 return ao2_callback_data(channels, ao2_flags, cb_fn, arg, data); 01599 }
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 9424 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().
09426 { 09427 struct ast_cc_config_params *cc_params; 09428 struct ast_datastore *cc_datastore; 09429 09430 if (!(cc_params = ast_cc_config_params_init())) { 09431 return -1; 09432 } 09433 09434 if (!(cc_datastore = ast_datastore_alloc(&cc_channel_datastore_info, NULL))) { 09435 ast_cc_config_params_destroy(cc_params); 09436 return -1; 09437 } 09438 09439 if (base_params) { 09440 ast_cc_copy_config_params(cc_params, base_params); 09441 } 09442 cc_datastore->data = cc_params; 09443 ast_channel_datastore_add(chan, cc_datastore); 09444 return 0; 09445 }
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 6217 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().
06218 { 06219 /* if the linkedid for this channel is being changed from something, check... */ 06220 if (!ast_strlen_zero(chan->linkedid) && 0 != strcmp(chan->linkedid, linkedid)) { 06221 ast_cel_check_retire_linkedid(chan); 06222 } 06223 06224 ast_string_field_set(chan, linkedid, linkedid); 06225 }
void ast_channel_clear_softhangup | ( | struct ast_channel * | chan, | |
int | flag | |||
) |
Clear a set of softhangup flags from a channel.
Never clear a softhangup flag from a channel directly. Instead, use this function. This ensures that all aspects of the softhangup process are aborted.
chan | the channel to clear the flag on | |
flag | the flag or flags to clear |
Definition at line 2652 of file channel.c.
References ast_channel::_softhangup, ast_channel_lock, ast_channel_unlock, AST_CONTROL_END_OF_Q, AST_FRAME_CONTROL, ast_frfree, AST_LIST_LAST, AST_LIST_REMOVE, chanlist::chan, ast_frame::frametype, ast_frame_subclass::integer, ast_channel::readq, and ast_frame::subclass.
Referenced by __ast_pbx_run(), ast_channel_bridge(), check_goto_on_transfer(), and collect_digits().
02653 { 02654 ast_channel_lock(chan); 02655 02656 chan->_softhangup &= ~flag; 02657 02658 if (!chan->_softhangup) { 02659 struct ast_frame *fr; 02660 02661 /* If we have completely cleared the softhangup flag, 02662 * then we need to fully abort the hangup process. This requires 02663 * pulling the END_OF_Q frame out of the channel frame queue if it 02664 * still happens to be there. */ 02665 02666 fr = AST_LIST_LAST(&chan->readq); 02667 if (fr && fr->frametype == AST_FRAME_CONTROL && 02668 fr->subclass.integer == AST_CONTROL_END_OF_Q) { 02669 AST_LIST_REMOVE(&chan->readq, fr, frame_list); 02670 ast_frfree(fr); 02671 } 02672 } 02673 02674 ast_channel_unlock(chan); 02675 }
static int ast_channel_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1681 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.
01682 { 01683 struct ast_channel *chan = obj, *cmp_args = arg; 01684 size_t name_len; 01685 int ret = CMP_MATCH; 01686 01687 /* This is sort of a hack. Basically, we're using an arbitrary field 01688 * in ast_channel to pass the name_len for a prefix match. If this 01689 * gets changed, then the uses of ao2_find() must be changed, too. */ 01690 name_len = cmp_args->rings; 01691 01692 ast_channel_lock(chan); 01693 01694 if (!ast_strlen_zero(cmp_args->name)) { /* match by name */ 01695 if ((!name_len && strcasecmp(chan->name, cmp_args->name)) || 01696 (name_len && strncasecmp(chan->name, cmp_args->name, name_len))) { 01697 ret = 0; /* name match failed */ 01698 } 01699 } else if (!ast_strlen_zero(cmp_args->exten)) { 01700 if (cmp_args->context && strcasecmp(chan->context, cmp_args->context) && 01701 strcasecmp(chan->macrocontext, cmp_args->context)) { 01702 ret = 0; /* context match failed */ 01703 } 01704 if (ret && strcasecmp(chan->exten, cmp_args->exten) && 01705 strcasecmp(chan->macroexten, cmp_args->exten)) { 01706 ret = 0; /* exten match failed */ 01707 } 01708 } else if (!ast_strlen_zero(cmp_args->uniqueid)) { 01709 if ((!name_len && strcasecmp(chan->uniqueid, cmp_args->uniqueid)) || 01710 (name_len && strncasecmp(chan->uniqueid, cmp_args->uniqueid, name_len))) { 01711 ret = 0; /* uniqueid match failed */ 01712 } 01713 } else { 01714 ret = 0; 01715 } 01716 01717 ast_channel_unlock(chan); 01718 01719 return ret; 01720 }
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 879 of file channel.c.
References ast_channel_cmpwhentohangup_tv(), and chanlist::chan.
00880 { 00881 struct timeval when = { offset, }; 00882 return ast_channel_cmpwhentohangup_tv(chan, when); 00883 }
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 864 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().
00865 { 00866 struct timeval whentohangup; 00867 00868 if (ast_tvzero(chan->whentohangup)) 00869 return ast_tvzero(offset) ? 0 : -1; 00870 00871 if (ast_tvzero(offset)) 00872 return 1; 00873 00874 whentohangup = ast_tvadd(offset, ast_tvnow()); 00875 00876 return ast_tvdiff_ms(whentohangup, chan->whentohangup); 00877 }
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 9322 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(), app_exec(), ast_bridge_call(), ast_do_pickup(), atxfer_fail_cleanup(), builtin_atxfer(), feature_request_and_dial(), handle_frame(), parked_call_exec(), remote_bridge_loop(), and wait_for_answer().
09323 { 09324 const char *macro; 09325 const char *macro_args; 09326 int retval; 09327 09328 ast_channel_lock(macro_chan); 09329 macro = pbx_builtin_getvar_helper(macro_chan, is_caller 09330 ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO"); 09331 macro = ast_strdupa(S_OR(macro, "")); 09332 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller 09333 ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS"); 09334 macro_args = ast_strdupa(S_OR(macro_args, "")); 09335 09336 if (ast_strlen_zero(macro)) { 09337 ast_channel_unlock(macro_chan); 09338 return -1; 09339 } 09340 09341 if (is_frame) { 09342 const struct ast_frame *frame = connected_info; 09343 09344 ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->connected); 09345 } else { 09346 const struct ast_party_connected_line *connected = connected_info; 09347 09348 ast_party_connected_line_copy(¯o_chan->connected, connected); 09349 } 09350 ast_channel_unlock(macro_chan); 09351 09352 if (!(retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args))) { 09353 ast_channel_lock(macro_chan); 09354 ast_channel_update_connected_line(macro_chan, ¯o_chan->connected, NULL); 09355 ast_channel_unlock(macro_chan); 09356 } 09357 09358 return retval; 09359 }
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 342 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().
00344 { 00345 struct ast_channel *bc; 00346 struct ast_data *data_bridged; 00347 struct ast_data *data_cdr; 00348 struct ast_data *data_flags; 00349 struct ast_data *data_zones; 00350 struct ast_data *enum_node; 00351 struct ast_data *data_softhangup; 00352 #if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */ 00353 struct ast_data *data_callerid; 00354 char value_str[100]; 00355 #endif 00356 00357 if (!tree) { 00358 return -1; 00359 } 00360 00361 ast_data_add_structure(ast_channel, tree, chan); 00362 00363 if (add_bridged) { 00364 bc = ast_bridged_channel(chan); 00365 if (bc) { 00366 data_bridged = ast_data_add_node(tree, "bridged"); 00367 if (!data_bridged) { 00368 return -1; 00369 } 00370 ast_channel_data_add_structure(data_bridged, bc, 0); 00371 } 00372 } 00373 00374 ast_data_add_codecs(tree, "oldwriteformat", chan->oldwriteformat); 00375 ast_data_add_codecs(tree, "nativeformats", chan->nativeformats); 00376 ast_data_add_codecs(tree, "readformat", chan->readformat); 00377 ast_data_add_codecs(tree, "writeformat", chan->writeformat); 00378 ast_data_add_codecs(tree, "rawreadformat", chan->rawreadformat); 00379 ast_data_add_codecs(tree, "rawwriteformat", chan->rawwriteformat); 00380 00381 /* state */ 00382 enum_node = ast_data_add_node(tree, "state"); 00383 if (!enum_node) { 00384 return -1; 00385 } 00386 ast_data_add_str(enum_node, "text", ast_state2str(chan->_state)); 00387 ast_data_add_int(enum_node, "value", chan->_state); 00388 00389 /* hangupcause */ 00390 enum_node = ast_data_add_node(tree, "hangupcause"); 00391 if (!enum_node) { 00392 return -1; 00393 } 00394 ast_data_add_str(enum_node, "text", ast_cause2str(chan->hangupcause)); 00395 ast_data_add_int(enum_node, "value", chan->hangupcause); 00396 00397 /* amaflags */ 00398 enum_node = ast_data_add_node(tree, "amaflags"); 00399 if (!enum_node) { 00400 return -1; 00401 } 00402 ast_data_add_str(enum_node, "text", ast_cdr_flags2str(chan->amaflags)); 00403 ast_data_add_int(enum_node, "value", chan->amaflags); 00404 00405 /* transfercapability */ 00406 enum_node = ast_data_add_node(tree, "transfercapability"); 00407 if (!enum_node) { 00408 return -1; 00409 } 00410 ast_data_add_str(enum_node, "text", ast_transfercapability2str(chan->transfercapability)); 00411 ast_data_add_int(enum_node, "value", chan->transfercapability); 00412 00413 /* _softphangup */ 00414 data_softhangup = ast_data_add_node(tree, "softhangup"); 00415 if (!data_softhangup) { 00416 return -1; 00417 } 00418 ast_data_add_bool(data_softhangup, "dev", chan->_softhangup & AST_SOFTHANGUP_DEV); 00419 ast_data_add_bool(data_softhangup, "asyncgoto", chan->_softhangup & AST_SOFTHANGUP_ASYNCGOTO); 00420 ast_data_add_bool(data_softhangup, "shutdown", chan->_softhangup & AST_SOFTHANGUP_SHUTDOWN); 00421 ast_data_add_bool(data_softhangup, "timeout", chan->_softhangup & AST_SOFTHANGUP_TIMEOUT); 00422 ast_data_add_bool(data_softhangup, "appunload", chan->_softhangup & AST_SOFTHANGUP_APPUNLOAD); 00423 ast_data_add_bool(data_softhangup, "explicit", chan->_softhangup & AST_SOFTHANGUP_EXPLICIT); 00424 ast_data_add_bool(data_softhangup, "unbridge", chan->_softhangup & AST_SOFTHANGUP_UNBRIDGE); 00425 00426 /* channel flags */ 00427 data_flags = ast_data_add_node(tree, "flags"); 00428 if (!data_flags) { 00429 return -1; 00430 } 00431 channel_data_add_flags(data_flags, chan); 00432 00433 ast_data_add_uint(tree, "timetohangup", chan->whentohangup.tv_sec); 00434 00435 #if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */ 00436 /* callerid */ 00437 data_callerid = ast_data_add_node(tree, "callerid"); 00438 if (!data_callerid) { 00439 return -1; 00440 } 00441 ast_data_add_structure(ast_callerid, data_callerid, &(chan->cid)); 00442 /* insert the callerid ton */ 00443 enum_node = ast_data_add_node(data_callerid, "cid_ton"); 00444 if (!enum_node) { 00445 return -1; 00446 } 00447 ast_data_add_int(enum_node, "value", chan->cid.cid_ton); 00448 snprintf(value_str, sizeof(value_str), "TON: %s/Plan: %s", 00449 party_number_ton2str(chan->cid.cid_ton), 00450 party_number_plan2str(chan->cid.cid_ton)); 00451 ast_data_add_str(enum_node, "text", value_str); 00452 #endif 00453 00454 /* tone zone */ 00455 if (chan->zone) { 00456 data_zones = ast_data_add_node(tree, "zone"); 00457 if (!data_zones) { 00458 return -1; 00459 } 00460 ast_tone_zone_data_add_structure(data_zones, chan->zone); 00461 } 00462 00463 /* insert cdr */ 00464 data_cdr = ast_data_add_node(tree, "cdr"); 00465 if (!data_cdr) { 00466 return -1; 00467 } 00468 00469 ast_cdr_data_add_structure(data_cdr, chan->cdr, 1); 00470 00471 return 0; 00472 }
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 474 of file channel.c.
References ast_data_search_cmp_structure, and chanlist::chan.
00476 { 00477 return ast_data_search_cmp_structure(tree, ast_channel, chan, structure_name); 00478 }
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 2535 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_do_pickup(), ast_iax2_new(), ast_setup_cc_recall_datastore(), audiohook_volume_get(), authenticate_reply(), calendar_query_exec(), cc_interfaces_datastore_init(), dial_exec_full(), do_notify(), dundi_query_read(), enable_jack_hook(), enum_query_read(), find_or_create_details(), find_transaction(), frame_trace_helper(), func_channel_write_real(), get_lock(), gosub_exec(), lua_get_state(), mute_add_audiohook(), pitchshift_helper(), raise_exception(), 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().
02536 { 02537 int res = 0; 02538 02539 AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry); 02540 02541 return res; 02542 }
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 2508 of file channel.c.
References ast_datastore_alloc, and ast_datastore::info.
02509 { 02510 return ast_datastore_alloc(info, uid); 02511 }
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 2549 of file channel.c.
References AST_LIST_TRAVERSE, 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_can_pickup(), ast_cc_agent_set_interfaces_chanvar(), ast_cc_call_init(), ast_cc_completed(), ast_cc_extension_monitor_add_dialstring(), ast_cc_get_current_core_id(), ast_cc_is_recall(), ast_cc_offer(), ast_channel_get_cc_config_params(), ast_do_masquerade(), ast_handle_cc_control_frame(), ast_ignore_cc(), ast_odbc_retrieve_transaction_obj(), ast_set_cc_interfaces_chanvar(), attended_transfer_occurred(), audiohook_volume_callback(), audiohook_volume_get(), builtin_atxfer(), calendar_event_read(), calendar_query_exec(), calendar_query_result_exec(), cc_build_payload(), clear_dialed_interfaces(), dial_exec_full(), disable_jack_hook(), dundi_result_read(), enable_jack_hook(), enum_result_read(), exec_odbcfinish(), find_details(), find_speech(), find_transaction(), frame_trace_helper(), func_channel_read(), func_channel_write_real(), func_inheritance_write(), func_mute_write(), get_agi_cmd(), get_lock(), gosub_exec(), handle_gosub(), iax2_call(), jack_hook_callback(), local_read(), local_write(), lock_fixup(), lua_get_state(), manage_parked_call(), manager_mutestream(), mark_transaction_active(), mute_callback(), parked_call_exec(), pitchshift_cb(), pitchshift_helper(), pop_exec(), queue_transfer_fixup(), raise_exception(), release_transaction(), return_exec(), set_security_requirements(), shared_read(), shared_write(), smdi_msg_read(), speech_background(), speech_destroy(), speex_callback(), speex_read(), speex_write(), srv_query_read(), srv_result_read(), stop_mixmonitor_exec(), try_calling(), unlock_read(), volume_callback(), and volume_write().
02550 { 02551 struct ast_datastore *datastore = NULL; 02552 02553 if (info == NULL) 02554 return NULL; 02555 02556 AST_LIST_TRAVERSE(&chan->datastores, datastore, entry) { 02557 if (datastore->info != info) { 02558 continue; 02559 } 02560 02561 if (uid == NULL) { 02562 /* matched by type only */ 02563 break; 02564 } 02565 02566 if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) { 02567 /* Matched by type AND uid */ 02568 break; 02569 } 02570 } 02571 02572 return datastore; 02573 }
int ast_channel_datastore_free | ( | struct ast_datastore * | datastore | ) |
Free a channel data store object.
Definition at line 2513 of file channel.c.
References ast_datastore_free().
02514 { 02515 return ast_datastore_free(datastore); 02516 }
int ast_channel_datastore_inherit | ( | struct ast_channel * | from, | |
struct ast_channel * | to | |||
) |
Inherit datastores from a parent to a child.
Definition at line 2518 of file channel.c.
References ast_datastore_alloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_channel::datastores, ast_datastore_info::duplicate, ast_datastore::entry, ast_datastore::info, ast_datastore::inheritance, and ast_datastore::uid.
Referenced by __ast_request_and_dial(), begin_dial_channel(), call_forward_inherit(), dial_exec_full(), dial_transfer(), do_forward(), findmeexec(), local_call(), and ring_entry().
02519 { 02520 struct ast_datastore *datastore = NULL, *datastore2; 02521 02522 AST_LIST_TRAVERSE(&from->datastores, datastore, entry) { 02523 if (datastore->inheritance > 0) { 02524 datastore2 = ast_datastore_alloc(datastore->info, datastore->uid); 02525 if (datastore2) { 02526 datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL; 02527 datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1; 02528 AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry); 02529 } 02530 } 02531 } 02532 return 0; 02533 }
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 2544 of file channel.c.
References AST_LIST_REMOVE, chanlist::chan, ast_channel::datastores, and ast_datastore::entry.
Referenced by acf_fetch(), adjust_frame_for_plc(), ast_do_masquerade(), ast_do_pickup(), clear_dialed_interfaces(), dial_exec_full(), disable_jack_hook(), exec_odbcfinish(), frame_trace_helper(), lua_get_state(), queue_transfer_fixup(), speech_background(), speech_destroy(), speex_write(), srv_query_read(), and stop_mixmonitor_exec().
02545 { 02546 return AST_LIST_REMOVE(&chan->datastores, datastore, entry) ? 0 : -1; 02547 }
int ast_channel_defer_dtmf | ( | struct ast_channel * | chan | ) |
Defers DTMF so that you only read things like hangups and audio.
Definition at line 1577 of file channel.c.
References AST_FLAG_DEFER_DTMF, ast_set_flag, ast_test_flag, and chanlist::chan.
Referenced by find_cache().
01578 { 01579 int pre = 0; 01580 01581 if (chan) { 01582 pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF); 01583 ast_set_flag(chan, AST_FLAG_DEFER_DTMF); 01584 } 01585 return pre; 01586 }
static void ast_channel_destructor | ( | void * | obj | ) | [static] |
Free a channel structure.
Definition at line 2357 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().
02358 { 02359 struct ast_channel *chan = obj; 02360 int fd; 02361 #ifdef HAVE_EPOLL 02362 int i; 02363 #endif 02364 struct ast_var_t *vardata; 02365 struct ast_frame *f; 02366 struct varshead *headp; 02367 struct ast_datastore *datastore; 02368 char device_name[AST_CHANNEL_NAME]; 02369 02370 if (chan->name) { 02371 /* The string fields were initialized. */ 02372 ast_cel_report_event(chan, AST_CEL_CHANNEL_END, NULL, NULL, NULL); 02373 ast_cel_check_retire_linkedid(chan); 02374 } 02375 02376 /* Get rid of each of the data stores on the channel */ 02377 ast_channel_lock(chan); 02378 while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry))) 02379 /* Free the data store */ 02380 ast_datastore_free(datastore); 02381 ast_channel_unlock(chan); 02382 02383 /* Lock and unlock the channel just to be sure nobody has it locked still 02384 due to a reference that was stored in a datastore. (i.e. app_chanspy) */ 02385 ast_channel_lock(chan); 02386 ast_channel_unlock(chan); 02387 02388 if (chan->tech_pvt) { 02389 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name); 02390 ast_free(chan->tech_pvt); 02391 } 02392 02393 if (chan->sched) 02394 sched_context_destroy(chan->sched); 02395 02396 if (chan->name) { 02397 char *dashptr; 02398 02399 /* The string fields were initialized. */ 02400 ast_copy_string(device_name, chan->name, sizeof(device_name)); 02401 if ((dashptr = strrchr(device_name, '-'))) { 02402 *dashptr = '\0'; 02403 } 02404 } else { 02405 device_name[0] = '\0'; 02406 } 02407 02408 /* Stop monitoring */ 02409 if (chan->monitor) 02410 chan->monitor->stop( chan, 0 ); 02411 02412 /* If there is native format music-on-hold state, free it */ 02413 if (chan->music_state) 02414 ast_moh_cleanup(chan); 02415 02416 /* Free translators */ 02417 if (chan->readtrans) 02418 ast_translator_free_path(chan->readtrans); 02419 if (chan->writetrans) 02420 ast_translator_free_path(chan->writetrans); 02421 if (chan->pbx) 02422 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name); 02423 02424 ast_party_dialed_free(&chan->dialed); 02425 ast_party_caller_free(&chan->caller); 02426 ast_party_connected_line_free(&chan->connected); 02427 ast_party_redirecting_free(&chan->redirecting); 02428 02429 /* Close pipes if appropriate */ 02430 if ((fd = chan->alertpipe[0]) > -1) 02431 close(fd); 02432 if ((fd = chan->alertpipe[1]) > -1) 02433 close(fd); 02434 if (chan->timer) { 02435 ast_timer_close(chan->timer); 02436 } 02437 #ifdef HAVE_EPOLL 02438 for (i = 0; i < AST_MAX_FDS; i++) { 02439 if (chan->epfd_data[i]) 02440 free(chan->epfd_data[i]); 02441 } 02442 close(chan->epfd); 02443 #endif 02444 while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list))) 02445 ast_frfree(f); 02446 02447 /* loop over the variables list, freeing all data and deleting list items */ 02448 /* no need to lock the list, as the channel is already locked */ 02449 headp = &chan->varshead; 02450 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) 02451 ast_var_delete(vardata); 02452 02453 ast_app_group_discard(chan); 02454 02455 /* Destroy the jitterbuffer */ 02456 ast_jb_destroy(chan); 02457 02458 if (chan->cdr) { 02459 ast_cdr_discard(chan->cdr); 02460 chan->cdr = NULL; 02461 } 02462 02463 if (chan->zone) { 02464 chan->zone = ast_tone_zone_unref(chan->zone); 02465 } 02466 02467 ast_string_field_free_memory(chan); 02468 02469 if (device_name[0]) { 02470 /* 02471 * We have a device name to notify of a new state. 02472 * 02473 * Queue an unknown state, because, while we know that this particular 02474 * instance is dead, we don't know the state of all other possible 02475 * instances. 02476 */ 02477 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name); 02478 } 02479 }
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 7163 of file channel.c.
References ast_channel_tech::early_bridge, and ast_channel::tech.
Referenced by dial_exec_full().
07164 { 07165 /* Make sure we can early bridge, if not error out */ 07166 if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge))) 07167 return -1; 07168 07169 return c0->tech->early_bridge(c0, c1); 07170 }
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 1774 of file channel.c.
References ast_channel_get_full().
01775 { 01776 return ast_channel_get_full(NULL, 0, exten, context); 01777 }
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 1764 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().
01765 { 01766 return ast_channel_get_full(name, 0, NULL, NULL); 01767 }
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 1769 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().
01770 { 01771 return ast_channel_get_full(name, name_len, NULL, NULL); 01772 }
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 9486 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().
09487 { 09488 int len = size; 09489 char *slash; 09490 09491 if (!ast_channel_queryoption(chan, AST_OPTION_CC_AGENT_TYPE, agent_type, &len, 0)) { 09492 return 0; 09493 } 09494 09495 ast_copy_string(agent_type, chan->name, size); 09496 if ((slash = strchr(agent_type, '/'))) { 09497 *slash = '\0'; 09498 } 09499 return 0; 09500 }
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 9447 of file channel.c.
References ast_assert, ast_channel_cc_params_init(), ast_channel_datastore_find(), cc_channel_datastore_info, and ast_datastore::data.
Referenced by acf_cc_read(), acf_cc_write(), analog_call(), ast_cc_call_failed(), ast_cc_call_init(), ast_queue_cc_frame(), cc_agent_init(), cc_core_init_instance(), find_agent_callbacks(), local_call(), local_request(), sig_pri_cc_available(), and sig_pri_cc_generic_check().
09448 { 09449 struct ast_datastore *cc_datastore; 09450 09451 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) { 09452 /* If we can't find the datastore, it almost definitely means that the channel type being 09453 * used has not had its driver modified to parse CC config parameters. The best action 09454 * to take here is to create the parameters on the spot with the defaults set. 09455 */ 09456 if (ast_channel_cc_params_init(chan, NULL)) { 09457 return NULL; 09458 } 09459 if (!(cc_datastore = ast_channel_datastore_find(chan, &cc_channel_datastore_info, NULL))) { 09460 /* Should be impossible */ 09461 return NULL; 09462 } 09463 } 09464 09465 ast_assert(cc_datastore->data != NULL); 09466 return cc_datastore->data; 09467 }
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 9469 of file channel.c.
References ast_channel_queryoption(), ast_copy_string(), AST_OPTION_DEVICE_NAME, and ast_channel::name.
Referenced by ast_cc_call_failed(), ast_cc_is_recall(), ast_queue_cc_frame(), cc_core_init_instance(), cccancel_exec(), ccreq_exec(), dial_exec_full(), sig_pri_call(), sig_pri_cc_available(), sig_pri_cc_generic_check(), sip_call(), and sip_handle_cc().
09470 { 09471 int len = name_buffer_length; 09472 char *dash; 09473 if (!ast_channel_queryoption(chan, AST_OPTION_DEVICE_NAME, device_name, &len, 0)) { 09474 return 0; 09475 } 09476 09477 /* Dang. Do it the old-fashioned way */ 09478 ast_copy_string(device_name, chan->name, name_buffer_length); 09479 if ((dash = strrchr(device_name, '-'))) { 09480 *dash = '\0'; 09481 } 09482 09483 return 0; 09484 }
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 1722 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().
01724 { 01725 struct ast_channel tmp_chan = { 01726 .name = name, 01727 /* This is sort of a hack. Basically, we're using an arbitrary field 01728 * in ast_channel to pass the name_len for a prefix match. If this 01729 * gets changed, then the compare callback must be changed, too. */ 01730 .rings = name_len, 01731 }; 01732 struct ast_channel *chan; 01733 01734 if (exten) { 01735 ast_copy_string(tmp_chan.exten, exten, sizeof(tmp_chan.exten)); 01736 } 01737 01738 if (context) { 01739 ast_copy_string(tmp_chan.context, context, sizeof(tmp_chan.context)); 01740 } 01741 01742 if ((chan = ao2_find(channels, &tmp_chan, 01743 (!ast_strlen_zero(name) && (name_len == 0)) ? OBJ_POINTER : 0))) { 01744 return chan; 01745 } 01746 01747 if (!name) { 01748 return NULL; 01749 } 01750 01751 /* If name was specified, but the result was NULL, 01752 * try a search on uniqueid, instead. */ 01753 01754 { 01755 struct ast_channel tmp_chan2 = { 01756 .uniqueid = name, 01757 .rings = name_len, 01758 }; 01759 01760 return ao2_find(channels, &tmp_chan2, 0); 01761 } 01762 }
static int ast_channel_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 7802 of file channel.c.
References ast_str_case_hash(), ast_strlen_zero(), and ast_channel::name.
07803 { 07804 const struct ast_channel *chan = obj; 07805 07806 /* If the name isn't set, return 0 so that the ao2_find() search will 07807 * start in the first bucket. */ 07808 if (ast_strlen_zero(chan->name)) { 07809 return 0; 07810 } 07811 07812 return ast_str_case_hash(chan->name); 07813 }
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 6088 of file channel.c.
References ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_var_assign(), ast_var_full_name(), ast_var_name(), ast_var_value(), ast_var_t::entries, and ast_channel::varshead.
Referenced by __ast_request_and_dial(), begin_dial_channel(), call_forward_inherit(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), and ring_entry().
06089 { 06090 struct ast_var_t *current, *newvar; 06091 const char *varname; 06092 06093 AST_LIST_TRAVERSE(&parent->varshead, current, entries) { 06094 int vartype = 0; 06095 06096 varname = ast_var_full_name(current); 06097 if (!varname) 06098 continue; 06099 06100 if (varname[0] == '_') { 06101 vartype = 1; 06102 if (varname[1] == '_') 06103 vartype = 2; 06104 } 06105 06106 switch (vartype) { 06107 case 1: 06108 newvar = ast_var_assign(&varname[1], ast_var_value(current)); 06109 if (newvar) { 06110 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 06111 ast_debug(1, "Copying soft-transferable variable %s.\n", ast_var_name(newvar)); 06112 } 06113 break; 06114 case 2: 06115 newvar = ast_var_assign(varname, ast_var_value(current)); 06116 if (newvar) { 06117 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 06118 ast_debug(1, "Copying hard-transferable variable %s.\n", ast_var_name(newvar)); 06119 } 06120 break; 06121 default: 06122 ast_debug(1, "Not copying variable %s.\n", ast_var_name(current)); 06123 break; 06124 } 06125 } 06126 }
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 1662 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().
01663 { 01664 struct ast_channel_iterator *i; 01665 01666 if (!(i = ast_calloc(1, sizeof(*i)))) { 01667 return NULL; 01668 } 01669 01670 i->simple_iterator = ao2_iterator_init(channels, 0); 01671 i->active_iterator = &i->simple_iterator; 01672 01673 return i; 01674 }
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 1652 of file channel.c.
References channel_iterator_search().
Referenced by common_exec(), and pickup_by_exten().
01653 { 01654 return channel_iterator_search(NULL, 0, exten, context); 01655 }
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 1657 of file channel.c.
References channel_iterator_search().
Referenced by ast_complete_channels(), common_exec(), and softhangup_exec().
01658 { 01659 return channel_iterator_search(name, name_len, NULL, NULL); 01660 }
struct ast_channel_iterator* ast_channel_iterator_destroy | ( | struct ast_channel_iterator * | i | ) |
Destroy a channel iterator.
Definition at line 1610 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().
01611 { 01612 ao2_iterator_destroy(i->active_iterator); 01613 ast_free(i); 01614 01615 return NULL; 01616 }
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 1676 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().
01677 { 01678 return ao2_iterator_next(i->active_iterator); 01679 }
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 5819 of file channel.c.
References ast_channel_make_compatible_helper(), and chanlist::chan.
Referenced by action_bridge(), app_exec(), ast_channel_bridge(), bridge_exec(), check_compat(), dial_exec_full(), do_forward(), multiplexed_bridge_join(), parked_call_exec(), simple_bridge_join(), and wait_for_answer().
05820 { 05821 /* Some callers do not check return code, and we must try to set all call legs correctly */ 05822 int rc = 0; 05823 05824 /* Set up translation from the chan to the peer */ 05825 rc = ast_channel_make_compatible_helper(chan, peer); 05826 05827 if (rc < 0) 05828 return rc; 05829 05830 /* Set up translation from the peer to the chan */ 05831 rc = ast_channel_make_compatible_helper(peer, chan); 05832 05833 return rc; 05834 }
static int ast_channel_make_compatible_helper | ( | struct ast_channel * | from, | |
struct ast_channel * | to | |||
) | [static] |
Set up translation from one channel to another.
Definition at line 5769 of file channel.c.
References ast_channel_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().
05770 { 05771 format_t src, dst; 05772 int use_slin; 05773 05774 /* See if the channel driver can natively make these two channels compatible */ 05775 if (from->tech->bridge && from->tech->bridge == to->tech->bridge && 05776 !ast_channel_setoption(from, AST_OPTION_MAKE_COMPATIBLE, to, sizeof(struct ast_channel *), 0)) { 05777 return 0; 05778 } 05779 05780 if (from->readformat == to->writeformat && from->writeformat == to->readformat) { 05781 /* Already compatible! Moving on ... */ 05782 return 0; 05783 } 05784 05785 /* Set up translation from the 'from' channel to the 'to' channel */ 05786 src = from->nativeformats; 05787 dst = to->nativeformats; 05788 05789 /* If there's no audio in this call, don't bother with trying to find a translation path */ 05790 if ((src & AST_FORMAT_AUDIO_MASK) == 0 || (dst & AST_FORMAT_AUDIO_MASK) == 0) 05791 return 0; 05792 05793 if (ast_translator_best_choice(&dst, &src) < 0) { 05794 ast_log(LOG_WARNING, "No path to translate from %s to %s\n", from->name, to->name); 05795 return -1; 05796 } 05797 05798 /* if the best path is not 'pass through', then 05799 * transcoding is needed; if desired, force transcode path 05800 * to use SLINEAR between channels, but only if there is 05801 * no direct conversion available. If generic PLC is 05802 * desired, then transcoding via SLINEAR is a requirement 05803 */ 05804 use_slin = (src == AST_FORMAT_SLINEAR || dst == AST_FORMAT_SLINEAR); 05805 if ((src != dst) && (ast_opt_generic_plc || ast_opt_transcode_via_slin) && 05806 (ast_translate_path_steps(dst, src) != 1 || use_slin)) 05807 dst = AST_FORMAT_SLINEAR; 05808 if (ast_set_read_format(from, dst) < 0) { 05809 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %s\n", from->name, ast_getformatname(dst)); 05810 return -1; 05811 } 05812 if (ast_set_write_format(to, dst) < 0) { 05813 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %s\n", to->name, ast_getformatname(dst)); 05814 return -1; 05815 } 05816 return 0; 05817 }
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 5959 of file channel.c.
References __ast_channel_masquerade().
Referenced by ast_async_goto(), ast_do_pickup(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), masq_park_call(), sip_park(), and skinny_transfer().
05960 { 05961 return __ast_channel_masquerade(original, clone, NULL); 05962 }
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 7554 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), chanlist::chan, errno, LOG_ERROR, ast_channel_tech::queryoption, and ast_channel::tech.
Referenced by ast_channel_get_cc_agent_type(), ast_channel_get_device_name(), ast_channel_get_t38_state(), local_queryoption(), rcvfax_exec(), and sndfax_exec().
07555 { 07556 int res; 07557 07558 ast_channel_lock(chan); 07559 if (!chan->tech->queryoption) { 07560 errno = ENOSYS; 07561 ast_channel_unlock(chan); 07562 return -1; 07563 } 07564 07565 if (block) 07566 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 07567 07568 res = chan->tech->queryoption(chan, option, data, datalen); 07569 ast_channel_unlock(chan); 07570 07571 return res; 07572 }
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 8802 of file channel.c.
References ast_connected_line_build_data(), AST_CONTROL_CONNECTED_LINE, ast_queue_control_data(), connected, and update().
Referenced by ast_do_pickup(), handle_request_invite(), handle_request_update(), handle_response_invite(), local_attended_transfer(), masquerade_colp_transfer(), misdn_queue_connected_line_update(), sig_pri_handle_subcmds(), and sip_call().
08803 { 08804 unsigned char data[1024]; /* This should be large enough */ 08805 size_t datalen; 08806 08807 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update); 08808 if (datalen == (size_t) -1) { 08809 return; 08810 } 08811 08812 ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen); 08813 }
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 9309 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().
09310 { 09311 unsigned char data[1024]; /* This should be large enough */ 09312 size_t datalen; 09313 09314 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update); 09315 if (datalen == (size_t) -1) { 09316 return; 09317 } 09318 09319 ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen); 09320 }
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 5163 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().
05164 { 05165 switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */ 05166 { 05167 case 0: 05168 return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)"; 05169 case AST_CONTROL_HANGUP: 05170 return "Hangup"; 05171 case AST_CONTROL_RING: 05172 return "Local Ring"; 05173 case AST_CONTROL_RINGING: 05174 return "Remote end Ringing"; 05175 case AST_CONTROL_ANSWER: 05176 return "Remote end has Answered"; 05177 case AST_CONTROL_BUSY: 05178 return "Remote end is Busy"; 05179 case AST_CONTROL_CONGESTION: 05180 return "Congestion (circuits busy)"; 05181 default: 05182 return "Unknown Reason!!"; 05183 } 05184 }
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 9361 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(), call_forward_inherit(), do_forward(), feature_request_and_dial(), handle_frame(), and remote_bridge_loop().
09362 { 09363 const char *macro; 09364 const char *macro_args; 09365 int retval; 09366 09367 ast_channel_lock(macro_chan); 09368 macro = pbx_builtin_getvar_helper(macro_chan, is_caller 09369 ? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO"); 09370 macro = ast_strdupa(S_OR(macro, "")); 09371 macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller 09372 ? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS"); 09373 macro_args = ast_strdupa(S_OR(macro_args, "")); 09374 09375 if (ast_strlen_zero(macro)) { 09376 ast_channel_unlock(macro_chan); 09377 return -1; 09378 } 09379 09380 if (is_frame) { 09381 const struct ast_frame *frame = redirecting_info; 09382 09383 ast_redirecting_parse_data(frame->data.ptr, frame->datalen, ¯o_chan->redirecting); 09384 } else { 09385 const struct ast_party_redirecting *redirecting = redirecting_info; 09386 09387 ast_party_redirecting_copy(¯o_chan->redirecting, redirecting); 09388 } 09389 ast_channel_unlock(macro_chan); 09390 09391 retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args); 09392 if (!retval) { 09393 ast_channel_lock(macro_chan); 09394 ast_channel_update_redirecting(macro_chan, ¯o_chan->redirecting, NULL); 09395 ast_channel_unlock(macro_chan); 09396 } 09397 09398 return retval; 09399 }
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 886 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().
00887 { 00888 struct chanlist *chan; 00889 00890 AST_RWLIST_WRLOCK(&backends); 00891 00892 AST_RWLIST_TRAVERSE(&backends, chan, list) { 00893 if (!strcasecmp(tech->type, chan->tech->type)) { 00894 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type); 00895 AST_RWLIST_UNLOCK(&backends); 00896 return -1; 00897 } 00898 } 00899 00900 if (!(chan = ast_calloc(1, sizeof(*chan)))) { 00901 AST_RWLIST_UNLOCK(&backends); 00902 return -1; 00903 } 00904 chan->tech = tech; 00905 AST_RWLIST_INSERT_HEAD(&backends, chan, list); 00906 00907 ast_debug(1, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description); 00908 00909 ast_verb(2, "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description); 00910 00911 AST_RWLIST_UNLOCK(&backends); 00912 00913 return 0; 00914 }
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 1878 of file channel.c.
References ao2_unlink, ast_channel_unref, chanlist::chan, and channels.
Referenced by agent_cleanup(), ast_do_masquerade(), ast_iax2_new(), ast_request(), bridge_request(), do_notify(), gtalk_newcall(), local_new(), and local_request().
01879 { 01880 /* Safe, even if already unlinked. */ 01881 ao2_unlink(channels, chan); 01882 return ast_channel_unref(chan); 01883 }
int ast_channel_sendhtml | ( | struct ast_channel * | channel, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) |
Sends HTML on given channel Send HTML or URL on link.
Definition at line 5756 of file channel.c.
References chanlist::chan, ast_channel_tech::send_html, and ast_channel::tech.
Referenced by agent_sendhtml(), and ast_channel_sendurl().
05757 { 05758 if (chan->tech->send_html) 05759 return chan->tech->send_html(chan, subclass, data, datalen); 05760 return -1; 05761 }
int ast_channel_sendurl | ( | struct ast_channel * | channel, | |
const char * | url | |||
) |
Sends a URL on a given link Send URL on link.
Definition at line 5763 of file channel.c.
References ast_channel_sendhtml(), AST_HTML_URL, and chanlist::chan.
Referenced by dial_exec_full(), and sendurl_exec().
05764 { 05765 return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1); 05766 }
void ast_channel_set_caller | ( | struct ast_channel * | chan, | |
const struct ast_party_caller * | caller, | |||
const struct ast_set_party_caller * | update | |||
) |
Set the caller id information in the Asterisk channel.
chan | Asterisk channel to set caller id information | |
caller | Caller id information | |
update | What caller information to update. NULL if all. |
Definition at line 6839 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_party_caller_set(), ast_channel::caller, chanlist::chan, and update().
06840 { 06841 if (&chan->caller == caller) { 06842 /* Don't set to self */ 06843 return; 06844 } 06845 06846 ast_channel_lock(chan); 06847 ast_party_caller_set(&chan->caller, caller, update); 06848 ast_channel_unlock(chan); 06849 }
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 6851 of file channel.c.
References ast_cdr_setcid(), ast_channel_lock, ast_channel_unlock, ast_party_caller_set(), ast_channel::caller, ast_channel::cdr, chanlist::chan, ast_party_caller::id, ast_party_id::name, ast_party_id::number, report_new_callerid(), S_COR, ast_party_name::str, ast_party_number::str, update(), ast_party_name::valid, and ast_party_number::valid.
Referenced by callerid_write(), dial_exec_full(), do_forward(), misdn_update_caller_id(), ring_entry(), and sig_pri_handle_subcmds().
06852 { 06853 const char *pre_set_number; 06854 const char *pre_set_name; 06855 06856 if (&chan->caller == caller) { 06857 /* Don't set to self */ 06858 return; 06859 } 06860 06861 ast_channel_lock(chan); 06862 pre_set_number = 06863 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL); 06864 pre_set_name = S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL); 06865 ast_party_caller_set(&chan->caller, caller, update); 06866 if (S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL) 06867 != pre_set_number 06868 || S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL) 06869 != pre_set_name) { 06870 /* The caller id name or number changed. */ 06871 report_new_callerid(chan); 06872 } 06873 if (chan->cdr) { 06874 ast_cdr_setcid(chan->cdr, chan); 06875 } 06876 ast_channel_unlock(chan); 06877 }
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 8162 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().
08163 { 08164 if (&chan->connected == connected) { 08165 /* Don't set to self */ 08166 return; 08167 } 08168 08169 ast_channel_lock(chan); 08170 ast_party_connected_line_set(&chan->connected, connected, update); 08171 ast_channel_unlock(chan); 08172 }
void ast_channel_set_fd | ( | struct ast_channel * | chan, | |
int | which, | |||
int | fd | |||
) |
Set the file descriptor on the channel
Definition at line 2576 of file channel.c.
References ast_calloc, chanlist::chan, ast_channel::data, ast_channel::fds, and free.
Referenced by __ast_channel_alloc_ap(), __oh323_new(), __oh323_rtp_create(), __oh323_update_info(), alsa_new(), ast_deactivate_generator(), ast_do_masquerade(), dahdi_new(), gtalk_new(), initialize_udptl(), jingle_new(), mgcp_new(), misdn_new(), my_swap_subchannels(), nbs_new(), oss_new(), phone_new(), process_sdp(), setformat(), sip_new(), skinny_new(), start_rtp(), and swap_subs().
02577 { 02578 #ifdef HAVE_EPOLL 02579 struct epoll_event ev; 02580 struct ast_epoll_data *aed = NULL; 02581 02582 if (chan->fds[which] > -1) { 02583 epoll_ctl(chan->epfd, EPOLL_CTL_DEL, chan->fds[which], &ev); 02584 aed = chan->epfd_data[which]; 02585 } 02586 02587 /* If this new fd is valid, add it to the epoll */ 02588 if (fd > -1) { 02589 if (!aed && (!(aed = ast_calloc(1, sizeof(*aed))))) 02590 return; 02591 02592 chan->epfd_data[which] = aed; 02593 aed->chan = chan; 02594 aed->which = which; 02595 02596 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 02597 ev.data.ptr = aed; 02598 epoll_ctl(chan->epfd, EPOLL_CTL_ADD, fd, &ev); 02599 } else if (aed) { 02600 /* We don't have to keep around this epoll data structure now */ 02601 free(aed); 02602 chan->epfd_data[which] = NULL; 02603 } 02604 #endif 02605 chan->fds[which] = fd; 02606 return; 02607 }
void ast_channel_set_linkgroup | ( | struct ast_channel * | chan, | |
struct ast_channel * | peer | |||
) |
propagate the linked id between chan and peer
Definition at line 6232 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().
06233 { 06234 const char* linkedid=NULL; 06235 struct ast_channel *bridged; 06236 06237 linkedid = oldest_linkedid(chan->linkedid, peer->linkedid); 06238 linkedid = oldest_linkedid(linkedid, chan->uniqueid); 06239 linkedid = oldest_linkedid(linkedid, peer->uniqueid); 06240 if (chan->_bridge) { 06241 bridged = ast_bridged_channel(chan); 06242 if (bridged != peer) { 06243 linkedid = oldest_linkedid(linkedid, bridged->linkedid); 06244 linkedid = oldest_linkedid(linkedid, bridged->uniqueid); 06245 } 06246 } 06247 if (peer->_bridge) { 06248 bridged = ast_bridged_channel(peer); 06249 if (bridged != chan) { 06250 linkedid = oldest_linkedid(linkedid, bridged->linkedid); 06251 linkedid = oldest_linkedid(linkedid, bridged->uniqueid); 06252 } 06253 } 06254 06255 /* just in case setting a stringfield to itself causes problems */ 06256 linkedid = ast_strdupa(linkedid); 06257 06258 ast_channel_change_linkedid(chan, linkedid); 06259 ast_channel_change_linkedid(peer, linkedid); 06260 if (chan->_bridge) { 06261 bridged = ast_bridged_channel(chan); 06262 if (bridged != peer) { 06263 ast_channel_change_linkedid(bridged, linkedid); 06264 } 06265 } 06266 if (peer->_bridge) { 06267 bridged = ast_bridged_channel(peer); 06268 if (bridged != chan) { 06269 ast_channel_change_linkedid(bridged, linkedid); 06270 } 06271 } 06272 }
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 8815 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_party_redirecting_set(), ast_channel::redirecting, and update().
Referenced by ast_indicate_data(), do_forward(), handle_request_invite(), handle_response(), misdn_copy_redirecting_to_ast(), redirecting_write(), and sig_pri_handle_subcmds().
08816 { 08817 if (&chan->redirecting == redirecting) { 08818 /* Don't set to self */ 08819 return; 08820 } 08821 08822 ast_channel_lock(chan); 08823 ast_party_redirecting_set(&chan->redirecting, redirecting, update); 08824 ast_channel_unlock(chan); 08825 }
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 7534 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), chanlist::chan, errno, LOG_ERROR, ast_channel_tech::setoption, and ast_channel::tech.
Referenced by analog_hangup(), ast_bridge_call(), ast_channel_make_compatible_helper(), common_exec(), conf_run(), dahdi_hangup(), dial_exec_full(), func_channel_write(), func_channel_write_real(), handle_tddmode(), play_record_review(), rcvfax_exec(), reset_volumes(), rpt(), rpt_exec(), set_format(), set_listen_volume(), set_security_requirements(), set_talk_volume(), sndfax_exec(), and vm_forwardoptions().
07535 { 07536 int res; 07537 07538 ast_channel_lock(chan); 07539 if (!chan->tech->setoption) { 07540 errno = ENOSYS; 07541 ast_channel_unlock(chan); 07542 return -1; 07543 } 07544 07545 if (block) 07546 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 07547 07548 res = chan->tech->setoption(chan, option, data, datalen); 07549 ast_channel_unlock(chan); 07550 07551 return res; 07552 }
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 857 of file channel.c.
References ast_channel_setwhentohangup_tv(), and chanlist::chan.
00858 { 00859 struct timeval when = { offset, }; 00860 ast_channel_setwhentohangup_tv(chan, when); 00861 }
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 850 of file channel.c.
References ast_null_frame, ast_queue_frame(), ast_tvadd(), ast_tvnow(), ast_tvzero(), chanlist::chan, and ast_channel::whentohangup.
Referenced by action_timeout(), ast_channel_setwhentohangup(), handle_autohangup(), sig_pri_send_aoce_termination_request(), and timeout_write().
00851 { 00852 chan->whentohangup = ast_tvzero(offset) ? offset : ast_tvadd(offset, ast_tvnow()); 00853 ast_queue_frame(chan, &ast_null_frame); 00854 return; 00855 }
static int ast_channel_softhangup_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 813 of file channel.c.
References ast_softhangup(), AST_SOFTHANGUP_SHUTDOWN, and chanlist::chan.
Referenced by ast_begin_shutdown().
00814 { 00815 struct ast_channel *chan = obj; 00816 00817 ast_softhangup(chan, AST_SOFTHANGUP_SHUTDOWN); 00818 00819 return 0; 00820 }
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 8036 of file channel.c.
References ast_activate_generator(), ast_calloc, ast_debug, AST_FORMAT_SLINEAR, ast_free, ast_log(), ast_set_write_format(), LOG_ERROR, ast_channel::name, ast_silence_generator::old_write_format, silence_generator, state, and ast_channel::writeformat.
Referenced by __ast_play_and_record(), ast_bridge_call(), ast_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), TransferCallStep1(), waitfor_exec(), and waitforring_exec().
08037 { 08038 struct ast_silence_generator *state; 08039 08040 if (!(state = ast_calloc(1, sizeof(*state)))) { 08041 return NULL; 08042 } 08043 08044 state->old_write_format = chan->writeformat; 08045 08046 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) { 08047 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n"); 08048 ast_free(state); 08049 return NULL; 08050 } 08051 08052 ast_activate_generator(chan, &silence_generator, state); 08053 08054 ast_debug(1, "Started silence generator on '%s'\n", chan->name); 08055 08056 return state; 08057 }
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 8059 of file channel.c.
References ast_deactivate_generator(), ast_debug, ast_free, ast_log(), ast_set_write_format(), LOG_ERROR, ast_channel::name, and state.
Referenced by ast_bridge_call(), ast_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), HandleCallOutgoing(), key_dial_page(), unistim_hangup(), waitfor_exec(), and waitforring_exec().
08060 { 08061 if (!state) 08062 return; 08063 08064 ast_deactivate_generator(chan); 08065 08066 ast_debug(1, "Stopped silence generator on '%s'\n", chan->name); 08067 08068 if (ast_set_write_format(chan, state->old_write_format) < 0) 08069 ast_log(LOG_ERROR, "Could not return write format to its original state\n"); 08070 08071 ast_free(state); 08072 }
int ast_channel_supports_html | ( | struct ast_channel * | channel | ) |
Checks for HTML support on a channel.
Definition at line 5751 of file channel.c.
References 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 6033 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().
06040 { 06041 struct ast_datastore *xfer_ds; 06042 struct xfer_masquerade_ds *xfer_colp; 06043 int res; 06044 06045 xfer_ds = ast_datastore_alloc(&xfer_ds_info, NULL); 06046 if (!xfer_ds) { 06047 return -1; 06048 } 06049 06050 xfer_colp = ast_calloc(1, sizeof(*xfer_colp)); 06051 if (!xfer_colp) { 06052 ast_datastore_free(xfer_ds); 06053 return -1; 06054 } 06055 party_connected_line_copy_transfer(&xfer_colp->target_id, target_id); 06056 xfer_colp->target_held = target_held; 06057 party_connected_line_copy_transfer(&xfer_colp->transferee_id, transferee_id); 06058 xfer_colp->transferee_held = transferee_held; 06059 xfer_ds->data = xfer_colp; 06060 06061 res = __ast_channel_masquerade(target_chan, transferee_chan, xfer_ds); 06062 if (res) { 06063 ast_datastore_free(xfer_ds); 06064 } 06065 return res; 06066 }
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 1589 of file channel.c.
References ast_clear_flag, AST_FLAG_DEFER_DTMF, and chanlist::chan.
Referenced by find_cache(), and rpt_call().
01590 { 01591 if (chan) 01592 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF); 01593 }
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 917 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().
00918 { 00919 struct chanlist *chan; 00920 00921 ast_debug(1, "Unregistering channel type '%s'\n", tech->type); 00922 00923 AST_RWLIST_WRLOCK(&backends); 00924 00925 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) { 00926 if (chan->tech == tech) { 00927 AST_LIST_REMOVE_CURRENT(list); 00928 ast_free(chan); 00929 ast_verb(2, "Unregistered channel type '%s'\n", tech->type); 00930 break; 00931 } 00932 } 00933 AST_LIST_TRAVERSE_SAFE_END; 00934 00935 AST_RWLIST_UNLOCK(&backends); 00936 }
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 8789 of file channel.c.
References ast_connected_line_build_data(), AST_CONTROL_CONNECTED_LINE, ast_indicate_data(), connected, and update().
Referenced by app_exec(), ast_channel_connected_line_macro(), ast_do_pickup(), atxfer_fail_cleanup(), builtin_atxfer(), connectedline_write(), parked_call_exec(), and wait_for_answer().
08790 { 08791 unsigned char data[1024]; /* This should be large enough */ 08792 size_t datalen; 08793 08794 datalen = ast_connected_line_build_data(data, sizeof(data), connected, update); 08795 if (datalen == (size_t) -1) { 08796 return; 08797 } 08798 08799 ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen); 08800 }
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 9296 of file channel.c.
References AST_CONTROL_REDIRECTING, ast_indicate_data(), ast_redirecting_build_data(), and update().
Referenced by ast_channel_redirecting_macro(), call_forward_inherit(), do_forward(), and redirecting_write().
09297 { 09298 unsigned char data[1024]; /* This should be large enough */ 09299 size_t datalen; 09300 09301 datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update); 09302 if (datalen == (size_t) -1) { 09303 return; 09304 } 09305 09306 ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen); 09307 }
void ast_channels_init | ( | void | ) |
Provided by channel.c
Definition at line 7950 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().
07951 { 07952 channels = ao2_container_alloc(NUM_CHANNEL_BUCKETS, 07953 ast_channel_hash_cb, ast_channel_cmp_cb); 07954 07955 ast_cli_register_multiple(cli_channel, ARRAY_LEN(cli_channel)); 07956 07957 ast_data_register_multiple_core(channel_providers, ARRAY_LEN(channel_providers)); 07958 07959 ast_plc_reload(); 07960 }
struct ast_variable* ast_channeltype_list | ( | void | ) |
return an ast_variable list of channeltypes
Definition at line 247 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().
00248 { 00249 struct chanlist *cl; 00250 struct ast_variable *var = NULL, *prev = NULL; 00251 00252 AST_RWLIST_RDLOCK(&backends); 00253 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00254 if (prev) { 00255 if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description, ""))) 00256 prev = prev->next; 00257 } else { 00258 var = ast_variable_new(cl->tech->type, cl->tech->description, ""); 00259 prev = var; 00260 } 00261 } 00262 AST_RWLIST_UNLOCK(&backends); 00263 00264 return var; 00265 }
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 791 of file channel.c.
References ast_channel::_softhangup, ast_debug, AST_SOFTHANGUP_TIMEOUT, ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), chanlist::chan, and ast_channel::whentohangup.
Referenced by __ast_pbx_run(), __ast_read(), _macro_exec(), agent_indicate(), agi_exec(), agi_handle_command(), announce_thread(), ast_bridge_call(), ast_call(), ast_channel_bridge(), ast_check_hangup_locked(), ast_indicate_data(), ast_raw_answer(), ast_readstring_full(), ast_recvtext(), ast_rtp_instance_bridge(), ast_sendtext(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), ast_write(), autoservice_run(), bridge_call_thread(), bridge_exec(), builtin_atxfer(), call_forward_inherit(), channel_spy(), check_bridge(), common_exec(), conf_play(), conf_run(), dahdi_sendtext(), dahdi_setoption(), dial_exec_full(), dundi_lookup_internal(), eagi_exec(), eivr_comm(), feature_request_and_dial(), findmeexec(), func_channel_read(), handle_sendimage(), launch_asyncagi(), local_fixup(), lua_check_hangup(), ospfinished_exec(), pbx_builtin_incomplete(), pbx_builtin_waitexten(), pbx_exec(), read_exec(), readexten_exec(), remote_bridge_loop(), rpt(), run_agi(), and run_ras().
00792 { 00793 if (chan->_softhangup) /* yes if soft hangup flag set */ 00794 return 1; 00795 if (ast_tvzero(chan->whentohangup)) /* no if no hangup scheduled */ 00796 return 0; 00797 if (ast_tvdiff_ms(chan->whentohangup, ast_tvnow()) > 0) /* no if hangup time has not come yet. */ 00798 return 0; 00799 ast_debug(4, "Hangup time has come: %" PRIi64 "\n", ast_tvdiff_ms(chan->whentohangup, ast_tvnow())); 00800 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */ 00801 return 1; 00802 }
int ast_check_hangup_locked | ( | struct ast_channel * | chan | ) |
Definition at line 804 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().
00805 { 00806 int res; 00807 ast_channel_lock(chan); 00808 res = ast_check_hangup(chan); 00809 ast_channel_unlock(chan); 00810 return res; 00811 }
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 8529 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().
08530 { 08531 int32_t value; 08532 size_t pos = 0; 08533 int res; 08534 08535 static const struct ast_party_id_ies ies = { 08536 .name.str = AST_CONNECTED_LINE_NAME, 08537 .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET, 08538 .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION, 08539 .name.valid = AST_CONNECTED_LINE_NAME_VALID, 08540 08541 .number.str = AST_CONNECTED_LINE_NUMBER, 08542 .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN, 08543 .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION, 08544 .number.valid = AST_CONNECTED_LINE_NUMBER_VALID, 08545 08546 .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS, 08547 .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE, 08548 .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, 08549 .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID, 08550 08551 .tag = AST_CONNECTED_LINE_TAG, 08552 .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION, 08553 }; 08554 08555 /* 08556 * The size of integer values must be fixed in case the frame is 08557 * shipped to another machine. 08558 */ 08559 08560 /* Connected line frame version */ 08561 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08562 ast_log(LOG_WARNING, "No space left for connected line frame version\n"); 08563 return -1; 08564 } 08565 data[pos++] = AST_CONNECTED_LINE_VERSION; 08566 data[pos++] = 1; 08567 data[pos++] = 2;/* Version 1 did not have a version ie */ 08568 08569 res = party_id_build_data(data + pos, datalen - pos, &connected->id, 08570 "connected line", &ies, update ? &update->id : NULL); 08571 if (res < 0) { 08572 return -1; 08573 } 08574 pos += res; 08575 08576 /* Connected line source */ 08577 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 08578 ast_log(LOG_WARNING, "No space left for connected line source\n"); 08579 return -1; 08580 } 08581 data[pos++] = AST_CONNECTED_LINE_SOURCE; 08582 data[pos++] = sizeof(value); 08583 value = htonl(connected->source); 08584 memcpy(data + pos, &value, sizeof(value)); 08585 pos += sizeof(value); 08586 08587 return pos; 08588 }
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 8147 of file channel.c.
References ast_party_caller::ani, ast_party_connected_line::ani, ast_party_caller::ani2, ast_party_connected_line::ani2, ast_party_id_copy(), ast_party_caller::id, and ast_party_connected_line::id.
Referenced by app_exec(), ast_do_pickup(), begin_dial_channel(), builtin_atxfer(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), local_call(), parked_call_exec(), ring_entry(), and wait_for_answer().
08148 { 08149 ast_party_id_copy(&dest->id, &src->id); 08150 ast_party_id_copy(&dest->ani, &src->ani); 08151 dest->ani2 = src->ani2; 08152 }
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 8154 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().
08155 { 08156 ast_party_id_copy(&dest->id, &src->id); 08157 ast_party_id_copy(&dest->ani, &src->ani); 08158 08159 dest->ani2 = src->ani2; 08160 }
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 8590 of file channel.c.
References AST_CONNECTED_LINE_ID_PRESENTATION, AST_CONNECTED_LINE_NAME, AST_CONNECTED_LINE_NAME_CHAR_SET, AST_CONNECTED_LINE_NAME_PRESENTATION, AST_CONNECTED_LINE_NAME_VALID, AST_CONNECTED_LINE_NUMBER, AST_CONNECTED_LINE_NUMBER_PLAN, AST_CONNECTED_LINE_NUMBER_PRESENTATION, AST_CONNECTED_LINE_NUMBER_VALID, AST_CONNECTED_LINE_SOURCE, AST_CONNECTED_LINE_SUBADDRESS, AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, AST_CONNECTED_LINE_SUBADDRESS_TYPE, AST_CONNECTED_LINE_SUBADDRESS_VALID, AST_CONNECTED_LINE_TAG, AST_CONNECTED_LINE_VERSION, ast_free, ast_log(), ast_malloc, AST_PARTY_CHAR_SET_ISO8859_1, ast_party_id_ies::combined_presentation, connected, LOG_DEBUG, LOG_WARNING, and value.
Referenced by __ast_read(), ast_channel_connected_line_macro(), ast_indicate_data(), feature_request_and_dial(), socket_process(), and wait_for_winner().
08591 { 08592 size_t pos; 08593 unsigned char ie_len; 08594 unsigned char ie_id; 08595 int32_t value; 08596 int frame_version = 1; 08597 int combined_presentation = 0; 08598 int got_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 08599 08600 for (pos = 0; pos < datalen; pos += ie_len) { 08601 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) { 08602 ast_log(LOG_WARNING, "Invalid connected line update\n"); 08603 return -1; 08604 } 08605 ie_id = data[pos++]; 08606 ie_len = data[pos++]; 08607 if (datalen < pos + ie_len) { 08608 ast_log(LOG_WARNING, "Invalid connected line update\n"); 08609 return -1; 08610 } 08611 08612 switch (ie_id) { 08613 /* Connected line party frame version */ 08614 case AST_CONNECTED_LINE_VERSION: 08615 if (ie_len != 1) { 08616 ast_log(LOG_WARNING, "Invalid connected line frame version (%u)\n", 08617 (unsigned) ie_len); 08618 break; 08619 } 08620 frame_version = data[pos]; 08621 break; 08622 /* Connected line party id name */ 08623 case AST_CONNECTED_LINE_NAME: 08624 ast_free(connected->id.name.str); 08625 connected->id.name.str = ast_malloc(ie_len + 1); 08626 if (connected->id.name.str) { 08627 memcpy(connected->id.name.str, data + pos, ie_len); 08628 connected->id.name.str[ie_len] = 0; 08629 } 08630 break; 08631 case AST_CONNECTED_LINE_NAME_CHAR_SET: 08632 if (ie_len != 1) { 08633 ast_log(LOG_WARNING, "Invalid connected line name char set (%u)\n", 08634 (unsigned) ie_len); 08635 break; 08636 } 08637 connected->id.name.char_set = data[pos]; 08638 break; 08639 case AST_CONNECTED_LINE_NAME_PRESENTATION: 08640 if (ie_len != 1) { 08641 ast_log(LOG_WARNING, "Invalid connected line name presentation (%u)\n", 08642 (unsigned) ie_len); 08643 break; 08644 } 08645 connected->id.name.presentation = data[pos]; 08646 break; 08647 case AST_CONNECTED_LINE_NAME_VALID: 08648 if (ie_len != 1) { 08649 ast_log(LOG_WARNING, "Invalid connected line name valid (%u)\n", 08650 (unsigned) ie_len); 08651 break; 08652 } 08653 connected->id.name.valid = data[pos]; 08654 break; 08655 /* Connected line party id number */ 08656 case AST_CONNECTED_LINE_NUMBER: 08657 ast_free(connected->id.number.str); 08658 connected->id.number.str = ast_malloc(ie_len + 1); 08659 if (connected->id.number.str) { 08660 memcpy(connected->id.number.str, data + pos, ie_len); 08661 connected->id.number.str[ie_len] = 0; 08662 } 08663 break; 08664 case AST_CONNECTED_LINE_NUMBER_PLAN: 08665 if (ie_len != 1) { 08666 ast_log(LOG_WARNING, "Invalid connected line numbering plan (%u)\n", 08667 (unsigned) ie_len); 08668 break; 08669 } 08670 connected->id.number.plan = data[pos]; 08671 break; 08672 case AST_CONNECTED_LINE_NUMBER_PRESENTATION: 08673 if (ie_len != 1) { 08674 ast_log(LOG_WARNING, "Invalid connected line number presentation (%u)\n", 08675 (unsigned) ie_len); 08676 break; 08677 } 08678 connected->id.number.presentation = data[pos]; 08679 break; 08680 case AST_CONNECTED_LINE_NUMBER_VALID: 08681 if (ie_len != 1) { 08682 ast_log(LOG_WARNING, "Invalid connected line number valid (%u)\n", 08683 (unsigned) ie_len); 08684 break; 08685 } 08686 connected->id.number.valid = data[pos]; 08687 break; 08688 /* Connected line party id combined presentation */ 08689 case AST_CONNECTED_LINE_ID_PRESENTATION: 08690 if (ie_len != 1) { 08691 ast_log(LOG_WARNING, "Invalid connected line combined presentation (%u)\n", 08692 (unsigned) ie_len); 08693 break; 08694 } 08695 combined_presentation = data[pos]; 08696 got_combined_presentation = 1; 08697 break; 08698 /* Connected line party id subaddress */ 08699 case AST_CONNECTED_LINE_SUBADDRESS: 08700 ast_free(connected->id.subaddress.str); 08701 connected->id.subaddress.str = ast_malloc(ie_len + 1); 08702 if (connected->id.subaddress.str) { 08703 memcpy(connected->id.subaddress.str, data + pos, ie_len); 08704 connected->id.subaddress.str[ie_len] = 0; 08705 } 08706 break; 08707 case AST_CONNECTED_LINE_SUBADDRESS_TYPE: 08708 if (ie_len != 1) { 08709 ast_log(LOG_WARNING, "Invalid connected line type of subaddress (%u)\n", 08710 (unsigned) ie_len); 08711 break; 08712 } 08713 connected->id.subaddress.type = data[pos]; 08714 break; 08715 case AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN: 08716 if (ie_len != 1) { 08717 ast_log(LOG_WARNING, 08718 "Invalid connected line subaddress odd-even indicator (%u)\n", 08719 (unsigned) ie_len); 08720 break; 08721 } 08722 connected->id.subaddress.odd_even_indicator = data[pos]; 08723 break; 08724 case AST_CONNECTED_LINE_SUBADDRESS_VALID: 08725 if (ie_len != 1) { 08726 ast_log(LOG_WARNING, "Invalid connected line subaddress valid (%u)\n", 08727 (unsigned) ie_len); 08728 break; 08729 } 08730 connected->id.subaddress.valid = data[pos]; 08731 break; 08732 /* Connected line party tag */ 08733 case AST_CONNECTED_LINE_TAG: 08734 ast_free(connected->id.tag); 08735 connected->id.tag = ast_malloc(ie_len + 1); 08736 if (connected->id.tag) { 08737 memcpy(connected->id.tag, data + pos, ie_len); 08738 connected->id.tag[ie_len] = 0; 08739 } 08740 break; 08741 /* Connected line party source */ 08742 case AST_CONNECTED_LINE_SOURCE: 08743 if (ie_len != sizeof(value)) { 08744 ast_log(LOG_WARNING, "Invalid connected line source (%u)\n", 08745 (unsigned) ie_len); 08746 break; 08747 } 08748 memcpy(&value, data + pos, sizeof(value)); 08749 connected->source = ntohl(value); 08750 break; 08751 /* Connected line party unknown element */ 08752 default: 08753 ast_log(LOG_DEBUG, "Unknown connected line element: %u (%u)\n", 08754 (unsigned) ie_id, (unsigned) ie_len); 08755 break; 08756 } 08757 } 08758 08759 switch (frame_version) { 08760 case 1: 08761 /* 08762 * The other end is an earlier version that we need to adjust 08763 * for compatibility. 08764 */ 08765 connected->id.name.valid = 1; 08766 connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 08767 connected->id.number.valid = 1; 08768 if (got_combined_presentation) { 08769 connected->id.name.presentation = combined_presentation; 08770 connected->id.number.presentation = combined_presentation; 08771 } 08772 break; 08773 case 2: 08774 /* The other end is at the same level as we are. */ 08775 break; 08776 default: 08777 /* 08778 * The other end is newer than we are. 08779 * We need to assume that they are compatible with us. 08780 */ 08781 ast_log(LOG_DEBUG, "Connected line frame has newer version: %u\n", 08782 (unsigned) frame_version); 08783 break; 08784 } 08785 08786 return 0; 08787 }
AST_DATA_STRUCTURE | ( | ast_channel | , | |
DATA_EXPORT_CHANNEL | ||||
) |
void ast_deactivate_generator | ( | struct ast_channel * | chan | ) |
Deactivate an active generator
Definition at line 3029 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().
03030 { 03031 ast_channel_lock(chan); 03032 if (chan->generatordata) { 03033 if (chan->generator && chan->generator->release) 03034 chan->generator->release(chan, chan->generatordata); 03035 chan->generatordata = NULL; 03036 chan->generator = NULL; 03037 ast_channel_set_fd(chan, AST_GENERATOR_FD, -1); 03038 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 03039 ast_settimeout(chan, 0, NULL, NULL); 03040 } 03041 ast_channel_unlock(chan); 03042 }
int ast_do_masquerade | ( | struct ast_channel * | original | ) |
Start masquerading a channel.
Definition at line 6391 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_kill_tech, AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_HEAD_NOLOCK, AST_LIST_HEAD_SET_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_manager_event, ast_manager_event_multichan, AST_MAX_FDS, ast_null_frame, ast_queue_frame(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_state2str(), ast_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_do_pickup(), ast_hangup(), ast_waitfor_nandfds(), ast_write(), builtin_atxfer(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), local_attended_transfer(), masq_park_call(), and sip_park().
06392 { 06393 format_t x; 06394 int i; 06395 int res=0; 06396 int origstate; 06397 int visible_indication; 06398 struct ast_frame *current; 06399 const struct ast_channel_tech *t; 06400 void *t_pvt; 06401 union { 06402 struct ast_party_dialed dialed; 06403 struct ast_party_caller caller; 06404 struct ast_party_connected_line connected; 06405 struct ast_party_redirecting redirecting; 06406 } exchange; 06407 struct ast_channel *clonechan, *chans[2]; 06408 struct ast_channel *bridged; 06409 struct ast_cdr *cdr; 06410 struct ast_datastore *xfer_ds; 06411 struct xfer_masquerade_ds *xfer_colp; 06412 format_t rformat = original->readformat; 06413 format_t wformat = original->writeformat; 06414 char newn[AST_CHANNEL_NAME]; 06415 char orig[AST_CHANNEL_NAME]; 06416 char masqn[AST_CHANNEL_NAME]; 06417 char zombn[AST_CHANNEL_NAME]; 06418 06419 /* XXX This operation is a bit odd. We're essentially putting the guts of 06420 * the clone channel into the original channel. Start by killing off the 06421 * original channel's backend. While the features are nice, which is the 06422 * reason we're keeping it, it's still awesomely weird. XXX */ 06423 06424 /* The reasoning for the channels ao2_container lock here is complex. 06425 * 06426 * In order to check for a race condition, the original channel must 06427 * be locked. If it is determined that the masquerade should proceed 06428 * the original channel can absolutely not be unlocked until the end 06429 * of the function. Since after determining the masquerade should 06430 * continue requires the channels to be unlinked from the ao2_container, 06431 * the container lock must be held first to achieve proper locking order. 06432 */ 06433 ao2_lock(channels); 06434 06435 /* lock the original channel to determine if the masquerade is required or not */ 06436 ast_channel_lock(original); 06437 06438 /* 06439 * This checks to see if the masquerade has already happened or 06440 * not. There is a race condition that exists for this 06441 * function. Since all pvt and channel locks must be let go 06442 * before calling do_masquerade, it is possible that it could be 06443 * called multiple times for the same channel. This check 06444 * verifies whether or not the masquerade has already been 06445 * completed by another thread. 06446 */ 06447 while ((clonechan = original->masq) && ast_channel_trylock(clonechan)) { 06448 /* 06449 * A masq is needed but we could not get the clonechan lock 06450 * immediately. Since this function already holds the global 06451 * container lock, unlocking original for deadlock avoidance 06452 * will not result in any sort of masquerade race condition. If 06453 * masq is called by a different thread while this happens, it 06454 * will be stuck waiting until we unlock the container. 06455 */ 06456 CHANNEL_DEADLOCK_AVOIDANCE(original); 06457 } 06458 06459 /* 06460 * A final masq check must be done after deadlock avoidance for 06461 * clonechan above or we could get a double masq. This is 06462 * posible with ast_hangup at least. 06463 */ 06464 if (!clonechan) { 06465 /* masq already completed by another thread, or never needed to be done to begin with */ 06466 ast_channel_unlock(original); 06467 ao2_unlock(channels); 06468 return 0; 06469 } 06470 06471 /* Get any transfer masquerade connected line exchange data. */ 06472 xfer_ds = ast_channel_datastore_find(original, &xfer_ds_info, NULL); 06473 if (xfer_ds) { 06474 ast_channel_datastore_remove(original, xfer_ds); 06475 xfer_colp = xfer_ds->data; 06476 } else { 06477 xfer_colp = NULL; 06478 } 06479 06480 /* 06481 * Release any hold on the transferee channel before proceeding 06482 * with the masquerade. 06483 */ 06484 if (xfer_colp && xfer_colp->transferee_held) { 06485 ast_indicate(clonechan, AST_CONTROL_UNHOLD); 06486 } 06487 06488 /* clear the masquerade channels */ 06489 original->masq = NULL; 06490 clonechan->masqr = NULL; 06491 06492 /* unlink from channels container as name (which is the hash value) will change */ 06493 ao2_unlink(channels, original); 06494 ao2_unlink(channels, clonechan); 06495 06496 ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", 06497 clonechan->name, clonechan->_state, original->name, original->_state); 06498 06499 /* 06500 * Stop any visible indiction on the original channel so we can 06501 * transfer it to the clonechan taking the original's place. 06502 */ 06503 visible_indication = original->visible_indication; 06504 ast_indicate(original, -1); 06505 06506 chans[0] = clonechan; 06507 chans[1] = original; 06508 ast_manager_event_multichan(EVENT_FLAG_CALL, "Masquerade", 2, chans, 06509 "Clone: %s\r\n" 06510 "CloneState: %s\r\n" 06511 "Original: %s\r\n" 06512 "OriginalState: %s\r\n", 06513 clonechan->name, ast_state2str(clonechan->_state), original->name, ast_state2str(original->_state)); 06514 06515 /* Having remembered the original read/write formats, we turn off any translation on either 06516 one */ 06517 free_translation(clonechan); 06518 free_translation(original); 06519 06520 /* Save the original name */ 06521 ast_copy_string(orig, original->name, sizeof(orig)); 06522 /* Save the new name */ 06523 ast_copy_string(newn, clonechan->name, sizeof(newn)); 06524 /* Create the masq name */ 06525 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn); 06526 06527 /* Mangle the name of the clone channel */ 06528 __ast_change_name_nolink(clonechan, masqn); 06529 06530 /* Copy the name from the clone channel */ 06531 __ast_change_name_nolink(original, newn); 06532 06533 /* share linked id's */ 06534 ast_channel_set_linkgroup(original, clonechan); 06535 06536 /* Swap the technologies */ 06537 t = original->tech; 06538 original->tech = clonechan->tech; 06539 clonechan->tech = t; 06540 06541 /* Swap the cdrs */ 06542 cdr = original->cdr; 06543 original->cdr = clonechan->cdr; 06544 clonechan->cdr = cdr; 06545 06546 t_pvt = original->tech_pvt; 06547 original->tech_pvt = clonechan->tech_pvt; 06548 clonechan->tech_pvt = t_pvt; 06549 06550 /* Swap the alertpipes */ 06551 for (i = 0; i < 2; i++) { 06552 x = original->alertpipe[i]; 06553 original->alertpipe[i] = clonechan->alertpipe[i]; 06554 clonechan->alertpipe[i] = x; 06555 } 06556 06557 /* 06558 * Swap the readq's. The end result should be this: 06559 * 06560 * 1) All frames should be on the new (original) channel. 06561 * 2) Any frames that were already on the new channel before this 06562 * masquerade need to be at the end of the readq, after all of the 06563 * frames on the old (clone) channel. 06564 * 3) The alertpipe needs to get poked for every frame that was already 06565 * on the new channel, since we are now using the alert pipe from the 06566 * old (clone) channel. 06567 */ 06568 { 06569 AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq; 06570 AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL); 06571 06572 AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list); 06573 AST_LIST_APPEND_LIST(&original->readq, &clonechan->readq, frame_list); 06574 06575 while ((current = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) { 06576 AST_LIST_INSERT_TAIL(&original->readq, current, frame_list); 06577 if (original->alertpipe[1] > -1) { 06578 int poke = 0; 06579 06580 if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) { 06581 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 06582 } 06583 } 06584 } 06585 } 06586 06587 /* Swap the raw formats */ 06588 x = original->rawreadformat; 06589 original->rawreadformat = clonechan->rawreadformat; 06590 clonechan->rawreadformat = x; 06591 x = original->rawwriteformat; 06592 original->rawwriteformat = clonechan->rawwriteformat; 06593 clonechan->rawwriteformat = x; 06594 06595 clonechan->_softhangup = AST_SOFTHANGUP_DEV; 06596 06597 /* And of course, so does our current state. Note we need not 06598 call ast_setstate since the event manager doesn't really consider 06599 these separate. We do this early so that the clone has the proper 06600 state of the original channel. */ 06601 origstate = original->_state; 06602 original->_state = clonechan->_state; 06603 clonechan->_state = origstate; 06604 06605 if (clonechan->tech->fixup && clonechan->tech->fixup(original, clonechan)) { 06606 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clonechan->name); 06607 } 06608 06609 /* Start by disconnecting the original's physical side */ 06610 if (clonechan->tech->hangup && clonechan->tech->hangup(clonechan)) { 06611 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n"); 06612 res = -1; 06613 goto done; 06614 } 06615 06616 /* 06617 * We just hung up the physical side of the channel. Set the 06618 * new zombie to use the kill channel driver for safety. 06619 */ 06620 clonechan->tech = &ast_kill_tech; 06621 06622 /* Mangle the name of the clone channel */ 06623 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); /* quick, hide the brains! */ 06624 __ast_change_name_nolink(clonechan, zombn); 06625 06626 /* Update the type. */ 06627 t_pvt = original->monitor; 06628 original->monitor = clonechan->monitor; 06629 clonechan->monitor = t_pvt; 06630 06631 /* Keep the same language. */ 06632 ast_string_field_set(original, language, clonechan->language); 06633 /* Copy the FD's other than the generator fd */ 06634 for (x = 0; x < AST_MAX_FDS; x++) { 06635 if (x != AST_GENERATOR_FD) 06636 ast_channel_set_fd(original, x, clonechan->fds[x]); 06637 } 06638 06639 ast_app_group_update(clonechan, original); 06640 06641 /* Move data stores over */ 06642 if (AST_LIST_FIRST(&clonechan->datastores)) { 06643 struct ast_datastore *ds; 06644 /* We use a safe traversal here because some fixup routines actually 06645 * remove the datastore from the list and free them. 06646 */ 06647 AST_LIST_TRAVERSE_SAFE_BEGIN(&clonechan->datastores, ds, entry) { 06648 if (ds->info->chan_fixup) 06649 ds->info->chan_fixup(ds->data, clonechan, original); 06650 } 06651 AST_LIST_TRAVERSE_SAFE_END; 06652 AST_LIST_APPEND_LIST(&original->datastores, &clonechan->datastores, entry); 06653 } 06654 06655 ast_autochan_new_channel(clonechan, original); 06656 06657 clone_variables(original, clonechan); 06658 /* Presense of ADSI capable CPE follows clone */ 06659 original->adsicpe = clonechan->adsicpe; 06660 /* Bridge remains the same */ 06661 /* CDR fields remain the same */ 06662 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 06663 /* Application and data remain the same */ 06664 /* Clone exception becomes real one, as with fdno */ 06665 ast_set_flag(original, ast_test_flag(clonechan, AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING)); 06666 original->fdno = clonechan->fdno; 06667 /* Schedule context remains the same */ 06668 /* Stream stuff stays the same */ 06669 /* Keep the original state. The fixup code will need to work with it most likely */ 06670 06671 /* 06672 * Just swap the whole structures, nevermind the allocations, 06673 * they'll work themselves out. 06674 */ 06675 exchange.dialed = original->dialed; 06676 original->dialed = clonechan->dialed; 06677 clonechan->dialed = exchange.dialed; 06678 06679 exchange.caller = original->caller; 06680 original->caller = clonechan->caller; 06681 clonechan->caller = exchange.caller; 06682 06683 exchange.connected = original->connected; 06684 original->connected = clonechan->connected; 06685 clonechan->connected = exchange.connected; 06686 06687 exchange.redirecting = original->redirecting; 06688 original->redirecting = clonechan->redirecting; 06689 clonechan->redirecting = exchange.redirecting; 06690 06691 report_new_callerid(original); 06692 06693 /* Restore original timing file descriptor */ 06694 ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd); 06695 06696 /* Our native formats are different now */ 06697 original->nativeformats = clonechan->nativeformats; 06698 06699 /* Context, extension, priority, app data, jump table, remain the same */ 06700 /* pvt switches. pbx stays the same, as does next */ 06701 06702 /* Set the write format */ 06703 ast_set_write_format(original, wformat); 06704 06705 /* Set the read format */ 06706 ast_set_read_format(original, rformat); 06707 06708 /* Copy the music class */ 06709 ast_string_field_set(original, musicclass, clonechan->musicclass); 06710 06711 /* copy over accuntcode and set peeraccount across the bridge */ 06712 ast_string_field_set(original, accountcode, S_OR(clonechan->accountcode, "")); 06713 if (original->_bridge) { 06714 /* XXX - should we try to lock original->_bridge here? */ 06715 ast_string_field_set(original->_bridge, peeraccount, S_OR(clonechan->accountcode, "")); 06716 ast_cel_report_event(original, AST_CEL_BRIDGE_UPDATE, NULL, NULL, NULL); 06717 } 06718 06719 ast_debug(1, "Putting channel %s in %s/%s formats\n", original->name, 06720 ast_getformatname(wformat), ast_getformatname(rformat)); 06721 06722 /* Okay. Last thing is to let the channel driver know about all this mess, so he 06723 can fix up everything as best as possible */ 06724 if (original->tech->fixup) { 06725 if (original->tech->fixup(clonechan, original)) { 06726 ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n", 06727 original->tech->type, original->name); 06728 res = -1; 06729 goto done; 06730 } 06731 } else 06732 ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)! Bad things may happen.\n", 06733 original->tech->type, original->name); 06734 06735 /* 06736 * If an indication is currently playing, maintain it on the channel 06737 * that is taking the place of original 06738 * 06739 * This is needed because the masquerade is swapping out in the internals 06740 * of this channel, and the new channel private data needs to be made 06741 * aware of the current visible indication (RINGING, CONGESTION, etc.) 06742 */ 06743 if (visible_indication) { 06744 ast_indicate(original, visible_indication); 06745 } 06746 06747 /* Now, at this point, the "clone" channel is totally F'd up. We mark it as 06748 a zombie so nothing tries to touch it. If it's already been marked as a 06749 zombie, then free it now (since it already is considered invalid). */ 06750 if (ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) { 06751 ast_debug(1, "Destroying channel clone '%s'\n", clonechan->name); 06752 ast_channel_unlock(clonechan); 06753 ast_manager_event(clonechan, EVENT_FLAG_CALL, "Hangup", 06754 "Channel: %s\r\n" 06755 "Uniqueid: %s\r\n" 06756 "Cause: %d\r\n" 06757 "Cause-txt: %s\r\n", 06758 clonechan->name, 06759 clonechan->uniqueid, 06760 clonechan->hangupcause, 06761 ast_cause2str(clonechan->hangupcause) 06762 ); 06763 clonechan = ast_channel_release(clonechan); 06764 } else { 06765 ast_debug(1, "Released clone lock on '%s'\n", clonechan->name); 06766 ast_set_flag(clonechan, AST_FLAG_ZOMBIE); 06767 ast_queue_frame(clonechan, &ast_null_frame); 06768 } 06769 06770 /* Signal any blocker */ 06771 if (ast_test_flag(original, AST_FLAG_BLOCKING)) 06772 pthread_kill(original->blocker, SIGURG); 06773 ast_debug(1, "Done Masquerading %s (%d)\n", original->name, original->_state); 06774 06775 if ((bridged = ast_bridged_channel(original))) { 06776 ast_channel_lock(bridged); 06777 ast_indicate(bridged, AST_CONTROL_SRCCHANGE); 06778 ast_channel_unlock(bridged); 06779 } 06780 ast_indicate(original, AST_CONTROL_SRCCHANGE); 06781 06782 if (xfer_colp) { 06783 /* 06784 * After the masquerade, the original channel pointer actually 06785 * points to the new transferee channel and the bridged channel 06786 * is still the intended transfer target party. 06787 */ 06788 masquerade_colp_transfer(original, xfer_colp); 06789 } 06790 06791 done: 06792 if (xfer_ds) { 06793 ast_datastore_free(xfer_ds); 06794 } 06795 /* it is possible for the clone channel to disappear during this */ 06796 if (clonechan) { 06797 ast_channel_unlock(original); 06798 ast_channel_unlock(clonechan); 06799 ao2_link(channels, clonechan); 06800 ao2_link(channels, original); 06801 } else { 06802 ast_channel_unlock(original); 06803 ao2_link(channels, original); 06804 } 06805 06806 ao2_unlock(channels); 06807 06808 return res; 06809 }
struct ast_channel* ast_dummy_channel_alloc | ( | void | ) |
Create a fake channel structure.
NULL | failure | |
non-NULL | successfully allocated channel |
The created dummy channel should be destroyed by ast_channel_unref(). Using ast_channel_release() needlessly grabs the channel container lock and can cause a deadlock as a result. Also grabbing the channel container lock reduces system performance.
Definition at line 1369 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().
01371 { 01372 struct ast_channel *tmp; 01373 struct varshead *headp; 01374 01375 #if defined(REF_DEBUG) 01376 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel", 01377 file, line, function, 1); 01378 #elif defined(__AST_DEBUG_MALLOC) 01379 tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel", 01380 file, line, function, 0); 01381 #else 01382 tmp = ao2_alloc(sizeof(*tmp), ast_dummy_channel_destructor); 01383 #endif 01384 if (!tmp) { 01385 /* Dummy channel structure allocation failure. */ 01386 return NULL; 01387 } 01388 01389 if ((ast_string_field_init(tmp, 128))) { 01390 return ast_channel_unref(tmp); 01391 } 01392 01393 headp = &tmp->varshead; 01394 AST_LIST_HEAD_INIT_NOLOCK(headp); 01395 01396 return tmp; 01397 }
static void ast_dummy_channel_destructor | ( | void * | obj | ) | [static] |
Free a dummy channel structure.
Definition at line 2482 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().
02483 { 02484 struct ast_channel *chan = obj; 02485 struct ast_var_t *vardata; 02486 struct varshead *headp; 02487 02488 headp = &chan->varshead; 02489 02490 ast_party_dialed_free(&chan->dialed); 02491 ast_party_caller_free(&chan->caller); 02492 ast_party_connected_line_free(&chan->connected); 02493 ast_party_redirecting_free(&chan->redirecting); 02494 02495 /* loop over the variables list, freeing all data and deleting list items */ 02496 /* no need to lock the list, as the channel is already locked */ 02497 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) 02498 ast_var_delete(vardata); 02499 02500 if (chan->cdr) { 02501 ast_cdr_discard(chan->cdr); 02502 chan->cdr = NULL; 02503 } 02504 02505 ast_string_field_free_memory(chan); 02506 }
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 6963 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().
06966 { 06967 /* Copy voice back and forth between the two channels. */ 06968 struct ast_channel *cs[3]; 06969 struct ast_frame *f; 06970 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 06971 format_t o0nativeformats; 06972 format_t o1nativeformats; 06973 int watch_c0_dtmf; 06974 int watch_c1_dtmf; 06975 void *pvt0, *pvt1; 06976 /* Indicates whether a frame was queued into a jitterbuffer */ 06977 int frame_put_in_jb = 0; 06978 int jb_in_use; 06979 int to; 06980 06981 cs[0] = c0; 06982 cs[1] = c1; 06983 pvt0 = c0->tech_pvt; 06984 pvt1 = c1->tech_pvt; 06985 o0nativeformats = c0->nativeformats; 06986 o1nativeformats = c1->nativeformats; 06987 watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0; 06988 watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1; 06989 06990 /* Check the need of a jitterbuffer for each channel */ 06991 jb_in_use = ast_jb_do_usecheck(c0, c1); 06992 if (jb_in_use) 06993 ast_jb_empty_and_reset(c0, c1); 06994 06995 ast_poll_channel_add(c0, c1); 06996 06997 if (config->feature_timer > 0 && ast_tvzero(config->nexteventts)) { 06998 /* nexteventts is not set when the bridge is not scheduled to 06999 * break, so calculate when the bridge should possibly break 07000 * if a partial feature match timed out */ 07001 config->nexteventts = ast_tvadd(ast_tvnow(), ast_samp2tv(config->feature_timer, 1000)); 07002 } 07003 07004 for (;;) { 07005 struct ast_channel *who, *other; 07006 07007 if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) || 07008 (o0nativeformats != c0->nativeformats) || 07009 (o1nativeformats != c1->nativeformats)) { 07010 /* Check for Masquerade, codec changes, etc */ 07011 res = AST_BRIDGE_RETRY; 07012 break; 07013 } 07014 if (config->nexteventts.tv_sec) { 07015 to = ast_tvdiff_ms(config->nexteventts, ast_tvnow()); 07016 if (to <= 0) { 07017 if (config->timelimit && !config->feature_timer && !ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) { 07018 res = AST_BRIDGE_RETRY; 07019 /* generic bridge ending to play warning */ 07020 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE); 07021 } else if (config->feature_timer) { 07022 /* feature timer expired - make sure we do not play warning */ 07023 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE); 07024 res = AST_BRIDGE_RETRY; 07025 } else { 07026 res = AST_BRIDGE_COMPLETE; 07027 } 07028 break; 07029 } 07030 } else { 07031 /* If a feature has been started and the bridge is configured to 07032 * to not break, leave the channel bridge when the feature timer 07033 * time has elapsed so the DTMF will be sent to the other side. 07034 */ 07035 if (!ast_tvzero(config->nexteventts)) { 07036 int diff = ast_tvdiff_ms(config->nexteventts, ast_tvnow()); 07037 if (diff <= 0) { 07038 res = AST_BRIDGE_RETRY; 07039 break; 07040 } 07041 } 07042 to = -1; 07043 } 07044 /* Calculate the appropriate max sleep interval - in general, this is the time, 07045 left to the closest jb delivery moment */ 07046 if (jb_in_use) 07047 to = ast_jb_get_when_to_wakeup(c0, c1, to); 07048 who = ast_waitfor_n(cs, 2, &to); 07049 if (!who) { 07050 /* No frame received within the specified timeout - check if we have to deliver now */ 07051 if (jb_in_use) 07052 ast_jb_get_and_deliver(c0, c1); 07053 if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */ 07054 if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07055 ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE); 07056 } 07057 if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) { 07058 ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE); 07059 } 07060 c0->_bridge = c1; 07061 c1->_bridge = c0; 07062 } 07063 continue; 07064 } 07065 f = ast_read(who); 07066 if (!f) { 07067 *fo = NULL; 07068 *rc = who; 07069 ast_debug(1, "Didn't get a frame from channel: %s\n",who->name); 07070 break; 07071 } 07072 07073 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 07074 /* Try add the frame info the who's bridged channel jitterbuff */ 07075 if (jb_in_use) 07076 frame_put_in_jb = !ast_jb_put(other, f); 07077 07078 if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) { 07079 int bridge_exit = 0; 07080 07081 switch (f->subclass.integer) { 07082 case AST_CONTROL_AOC: 07083 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen); 07084 break; 07085 case AST_CONTROL_REDIRECTING: 07086 if (ast_channel_redirecting_macro(who, other, f, other == c0, 1)) { 07087 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen); 07088 } 07089 break; 07090 case AST_CONTROL_CONNECTED_LINE: 07091 if (ast_channel_connected_line_macro(who, other, f, other == c0, 1)) { 07092 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen); 07093 } 07094 break; 07095 case AST_CONTROL_HOLD: 07096 case AST_CONTROL_UNHOLD: 07097 case AST_CONTROL_VIDUPDATE: 07098 case AST_CONTROL_SRCUPDATE: 07099 case AST_CONTROL_SRCCHANGE: 07100 case AST_CONTROL_T38_PARAMETERS: 07101 ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen); 07102 if (jb_in_use) { 07103 ast_jb_empty_and_reset(c0, c1); 07104 } 07105 break; 07106 default: 07107 *fo = f; 07108 *rc = who; 07109 bridge_exit = 1; 07110 ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass.integer, who->name); 07111 break; 07112 } 07113 if (bridge_exit) 07114 break; 07115 } 07116 if ((f->frametype == AST_FRAME_VOICE) || 07117 (f->frametype == AST_FRAME_DTMF_BEGIN) || 07118 (f->frametype == AST_FRAME_DTMF) || 07119 (f->frametype == AST_FRAME_VIDEO) || 07120 (f->frametype == AST_FRAME_IMAGE) || 07121 (f->frametype == AST_FRAME_HTML) || 07122 (f->frametype == AST_FRAME_MODEM) || 07123 (f->frametype == AST_FRAME_TEXT)) { 07124 /* monitored dtmf causes exit from bridge */ 07125 int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf; 07126 07127 if (monitored_source && 07128 (f->frametype == AST_FRAME_DTMF_END || 07129 f->frametype == AST_FRAME_DTMF_BEGIN)) { 07130 *fo = f; 07131 *rc = who; 07132 ast_debug(1, "Got DTMF %s on channel (%s)\n", 07133 f->frametype == AST_FRAME_DTMF_END ? "end" : "begin", 07134 who->name); 07135 07136 break; 07137 } 07138 /* Write immediately frames, not passed through jb */ 07139 if (!frame_put_in_jb) 07140 ast_write(other, f); 07141 07142 /* Check if we have to deliver now */ 07143 if (jb_in_use) 07144 ast_jb_get_and_deliver(c0, c1); 07145 } 07146 /* XXX do we want to pass on also frames not matched above ? */ 07147 ast_frfree(f); 07148 07149 #ifndef HAVE_EPOLL 07150 /* Swap who gets priority */ 07151 cs[2] = cs[0]; 07152 cs[0] = cs[1]; 07153 cs[1] = cs[2]; 07154 #endif 07155 } 07156 07157 ast_poll_channel_del(c0, c1); 07158 07159 return res; 07160 }
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 939 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().
00940 { 00941 struct chanlist *chanls; 00942 const struct ast_channel_tech *ret = NULL; 00943 00944 AST_RWLIST_RDLOCK(&backends); 00945 00946 AST_RWLIST_TRAVERSE(&backends, chanls, list) { 00947 if (!strcasecmp(name, chanls->tech->type)) { 00948 ret = chanls->tech; 00949 break; 00950 } 00951 } 00952 00953 AST_RWLIST_UNLOCK(&backends); 00954 00955 return ret; 00956 }
ast_group_t ast_get_group | ( | const char * | s | ) |
Definition at line 7726 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().
07727 { 07728 char *piece; 07729 char *c; 07730 int start=0, finish=0, x; 07731 ast_group_t group = 0; 07732 07733 if (ast_strlen_zero(s)) 07734 return 0; 07735 07736 c = ast_strdupa(s); 07737 07738 while ((piece = strsep(&c, ","))) { 07739 if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) { 07740 /* Range */ 07741 } else if (sscanf(piece, "%30d", &start)) { 07742 /* Just one */ 07743 finish = start; 07744 } else { 07745 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece); 07746 continue; 07747 } 07748 for (x = start; x <= finish; x++) { 07749 if ((x > 63) || (x < 0)) { 07750 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x); 07751 } else 07752 group |= ((ast_group_t) 1 << x); 07753 } 07754 } 07755 return group; 07756 }
int ast_hangup | ( | struct ast_channel * | chan | ) |
Hang up a channel.
This function performs a hard hangup on a channel. Unlike the soft-hangup, this function performs all stream stopping, etc, on the channel that needs to end. chan is no longer valid after this call.
chan | channel to hang up |
Definition at line 2733 of file channel.c.
References ao2_lock, ao2_unlink, ao2_unlock, 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_unlock, ast_channel_unref, 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_channel::connected, ast_cdr::disposition, EVENT_FLAG_CALL, free_translation(), ast_channel::generator, ast_channel::generatordata, ast_channel_tech::hangup, ast_channel::hangupcause, ast_channel::hangupsource, ast_party_connected_line::id, ast_party_caller::id, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_party_id::name, ast_channel::name, ast_party_id::number, pbx_builtin_getvar_helper(), ast_generator::release, S_COR, S_OR, ast_channel::sched, sched_context_destroy(), ast_party_name::str, ast_party_number::str, ast_channel::stream, ast_channel::tech, ast_channel::uniqueid, ast_party_name::valid, ast_party_number::valid, and ast_channel::vstream.
Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_request_and_dial(), __oh323_new(), action_bridge(), alsa_new(), analog_handle_init_event(), analog_ss_thread(), answer_exec_run(), app_exec(), ast_async_goto(), ast_call_forward(), ast_dial_destroy(), ast_dial_hangup(), ast_iax2_new(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run_app(), async_wait(), begin_dial_channel(), bridge_call_thread(), bridge_channel_thread(), bridge_exec(), build_conf(), builtin_atxfer(), chanavail_exec(), check_availability(), 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_parked_call(), masq_park_call(), mgcp_new(), mgcp_ss(), monitor_dial(), mwi_thread(), my_distinctive_ring(), my_handle_notify_message(), nbs_new(), oss_new(), parkandannounce_exec(), parked_call_exec(), phone_new(), play_sound_file(), pri_dchannel(), pri_ss_thread(), rpt(), rpt_call(), rpt_tele_thread(), sip_park(), sip_park_thread(), sip_pickup_thread(), skinny_new(), skinny_ss(), ss7_start_call(), unistim_new(), usbradio_new(), and wait_for_winner().
02734 { 02735 char extra_str[64]; /* used for cel logging below */ 02736 02737 ast_autoservice_stop(chan); 02738 02739 ao2_lock(channels); 02740 ast_channel_lock(chan); 02741 02742 if (chan->audiohooks) { 02743 ast_audiohook_detach_list(chan->audiohooks); 02744 chan->audiohooks = NULL; 02745 } 02746 ast_framehook_list_destroy(chan); 02747 02748 /* 02749 * Do the masquerade if someone is setup to masquerade into us. 02750 * 02751 * NOTE: We must hold the channel lock after testing for a 02752 * pending masquerade and setting the channel as a zombie to 02753 * prevent __ast_channel_masquerade() from setting up a 02754 * masquerade with a dead channel. 02755 */ 02756 while (chan->masq) { 02757 ast_channel_unlock(chan); 02758 ao2_unlock(channels); 02759 if (ast_do_masquerade(chan)) { 02760 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 02761 02762 /* Abort the loop or we might never leave. */ 02763 ao2_lock(channels); 02764 ast_channel_lock(chan); 02765 break; 02766 } 02767 ao2_lock(channels); 02768 ast_channel_lock(chan); 02769 } 02770 02771 if (chan->masqr) { 02772 /* 02773 * This channel is one which will be masqueraded into something. 02774 * Mark it as a zombie already so ast_do_masquerade() will know 02775 * to free it later. 02776 */ 02777 ast_set_flag(chan, AST_FLAG_ZOMBIE); 02778 ast_channel_unlock(chan); 02779 ao2_unlock(channels); 02780 return 0; 02781 } 02782 02783 ao2_unlink(channels, chan); 02784 ao2_unlock(channels); 02785 02786 free_translation(chan); 02787 /* Close audio stream */ 02788 if (chan->stream) { 02789 ast_closestream(chan->stream); 02790 chan->stream = NULL; 02791 } 02792 /* Close video stream */ 02793 if (chan->vstream) { 02794 ast_closestream(chan->vstream); 02795 chan->vstream = NULL; 02796 } 02797 if (chan->sched) { 02798 sched_context_destroy(chan->sched); 02799 chan->sched = NULL; 02800 } 02801 02802 if (chan->generatordata) { /* Clear any tone stuff remaining */ 02803 if (chan->generator && chan->generator->release) { 02804 chan->generator->release(chan, chan->generatordata); 02805 } 02806 } 02807 chan->generatordata = NULL; 02808 chan->generator = NULL; 02809 02810 snprintf(extra_str, sizeof(extra_str), "%d,%s,%s", chan->hangupcause, chan->hangupsource, S_OR(pbx_builtin_getvar_helper(chan, "DIALSTATUS"), "")); 02811 ast_cel_report_event(chan, AST_CEL_HANGUP, NULL, extra_str, NULL); 02812 02813 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 02814 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 02815 "is blocked by thread %ld in procedure %s! Expect a failure\n", 02816 (long) pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 02817 ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0); 02818 } 02819 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) { 02820 ast_debug(1, "Hanging up channel '%s'\n", chan->name); 02821 02822 /* 02823 * This channel is now dead so mark it as a zombie so anyone 02824 * left holding a reference to this channel will not use it. 02825 */ 02826 ast_set_flag(chan, AST_FLAG_ZOMBIE); 02827 if (chan->tech->hangup) { 02828 chan->tech->hangup(chan); 02829 } 02830 } else { 02831 ast_debug(1, "Hanging up zombie '%s'\n", chan->name); 02832 } 02833 02834 ast_channel_unlock(chan); 02835 02836 ast_cc_offer(chan); 02837 ast_manager_event(chan, EVENT_FLAG_CALL, "Hangup", 02838 "Channel: %s\r\n" 02839 "Uniqueid: %s\r\n" 02840 "CallerIDNum: %s\r\n" 02841 "CallerIDName: %s\r\n" 02842 "ConnectedLineNum: %s\r\n" 02843 "ConnectedLineName: %s\r\n" 02844 "Cause: %d\r\n" 02845 "Cause-txt: %s\r\n", 02846 chan->name, 02847 chan->uniqueid, 02848 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<unknown>"), 02849 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"), 02850 S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, "<unknown>"), 02851 S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, "<unknown>"), 02852 chan->hangupcause, 02853 ast_cause2str(chan->hangupcause) 02854 ); 02855 02856 if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) && 02857 !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) && 02858 (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) { 02859 ast_channel_lock(chan); 02860 ast_cdr_end(chan->cdr); 02861 ast_cdr_detach(chan->cdr); 02862 chan->cdr = NULL; 02863 ast_channel_unlock(chan); 02864 } 02865 02866 ast_channel_unref(chan); 02867 02868 return 0; 02869 }
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 4262 of file channel.c.
References ast_indicate_data(), and chanlist::chan.
Referenced by __ast_play_and_record(), agent_request(), alsa_call(), answer_trunk_chan(), ast_bridge_call(), ast_channel_bridge(), ast_do_masquerade(), ast_dtmf_stream(), ast_raw_answer(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), cli_console_answer(), conf_run(), console_call(), dial_exec_full(), do_forward(), feature_request_and_dial(), finishup(), function_remote(), handle_callforward_button(), handle_frame(), handle_recordfile(), handle_request_refer(), local_attended_transfer(), manage_parked_call(), mgcp_ss(), monitor_dial(), oss_call(), park_call_full(), parked_call_exec(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_incomplete(), pbx_builtin_proceeding(), pbx_builtin_progress(), pbx_builtin_ringing(), pbx_builtin_waitexten(), queue_exec(), 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().
04263 { 04264 return ast_indicate_data(chan, condition, NULL, 0); 04265 }
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 4316 of file channel.c.
References ast_channel::_state, _XXX_AST_CONTROL_T38, ast_channel_lock, ast_channel_set_connected_line(), ast_channel_set_redirecting(), ast_channel_unlock, ast_check_hangup(), ast_connected_line_parse_data(), AST_CONTROL_ANSWER, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_END_OF_Q, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_READ_ACTION, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_TRANSFER, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, AST_CONTROL_WINK, ast_debug, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, ast_framehook_list_is_empty(), ast_framehook_list_write_event(), ast_frdup(), ast_frfree, ast_get_indication_tone(), ast_log(), ast_party_connected_line_free(), ast_party_connected_line_set_init(), ast_party_redirecting_free(), ast_party_redirecting_set_init(), ast_playtones_start(), ast_playtones_stop(), ast_redirecting_parse_data(), AST_STATE_UP, ast_test_flag, ast_tone_zone_sound_unref(), chanlist::chan, ast_channel::connected, chanlist::connected, ast_tone_zone_sound::data, ast_frame::data, ast_frame::datalen, ast_channel::framehooks, ast_frame::frametype, ast_channel_tech::indicate, ast_frame_subclass::integer, is_visible_indication(), LOG_WARNING, ast_channel::name, ast_frame::ptr, ast_channel::redirecting, ast_frame::subclass, ast_channel::tech, ast_channel::visible_indication, and ast_channel::zone.
Referenced by __ast_read(), action_aocmessage(), agent_hangup(), ast_bridge_call(), ast_channel_update_connected_line(), ast_channel_update_redirecting(), ast_handle_cc_control_frame(), ast_indicate(), disable_t38(), feature_request_and_dial(), generic_fax_exec(), handle_frame(), login_exec(), manage_parked_call(), park_call_full(), pbx_builtin_waitexten(), receivefax_t38_init(), remote_bridge_loop(), sendfax_t38_init(), set_fax_t38_caps(), transmit_audio(), transmit_t38(), and wait_for_answer().
04318 { 04319 /* By using an enum, we'll get compiler warnings for values not handled 04320 * in switch statements. */ 04321 enum ast_control_frame_type condition = _condition; 04322 struct ast_tone_zone_sound *ts = NULL; 04323 int res; 04324 /* this frame is used by framehooks. if it is set, we must free it at the end of this function */ 04325 struct ast_frame *awesome_frame = NULL; 04326 04327 ast_channel_lock(chan); 04328 04329 /* Don't bother if the channel is about to go away, anyway. */ 04330 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 04331 res = -1; 04332 goto indicate_cleanup; 04333 } 04334 04335 if (!ast_framehook_list_is_empty(chan->framehooks)) { 04336 /* Do framehooks now, do it, go, go now */ 04337 struct ast_frame frame = { 04338 .frametype = AST_FRAME_CONTROL, 04339 .subclass.integer = condition, 04340 .data.ptr = (void *) data, /* this cast from const is only okay because we do the ast_frdup below */ 04341 .datalen = datalen 04342 }; 04343 04344 /* we have now committed to freeing this frame */ 04345 awesome_frame = ast_frdup(&frame); 04346 04347 /* who knows what we will get back! the anticipation is killing me. */ 04348 if (!(awesome_frame = ast_framehook_list_write_event(chan->framehooks, awesome_frame)) 04349 || awesome_frame->frametype != AST_FRAME_CONTROL) { 04350 04351 res = 0; 04352 goto indicate_cleanup; 04353 } 04354 04355 condition = awesome_frame->subclass.integer; 04356 data = awesome_frame->data.ptr; 04357 datalen = awesome_frame->datalen; 04358 } 04359 04360 switch (condition) { 04361 case AST_CONTROL_CONNECTED_LINE: 04362 { 04363 struct ast_party_connected_line connected; 04364 04365 ast_party_connected_line_set_init(&connected, &chan->connected); 04366 res = ast_connected_line_parse_data(data, datalen, &connected); 04367 if (!res) { 04368 ast_channel_set_connected_line(chan, &connected, NULL); 04369 } 04370 ast_party_connected_line_free(&connected); 04371 } 04372 break; 04373 04374 case AST_CONTROL_REDIRECTING: 04375 { 04376 struct ast_party_redirecting redirecting; 04377 04378 ast_party_redirecting_set_init(&redirecting, &chan->redirecting); 04379 res = ast_redirecting_parse_data(data, datalen, &redirecting); 04380 if (!res) { 04381 ast_channel_set_redirecting(chan, &redirecting, NULL); 04382 } 04383 ast_party_redirecting_free(&redirecting); 04384 } 04385 break; 04386 04387 default: 04388 break; 04389 } 04390 04391 if (is_visible_indication(condition)) { 04392 /* A new visible indication is requested. */ 04393 chan->visible_indication = condition; 04394 } else if (condition == AST_CONTROL_UNHOLD || _condition < 0) { 04395 /* Visible indication is cleared/stopped. */ 04396 chan->visible_indication = 0; 04397 } 04398 04399 if (chan->tech->indicate) { 04400 /* See if the channel driver can handle this condition. */ 04401 res = chan->tech->indicate(chan, condition, data, datalen); 04402 } else { 04403 res = -1; 04404 } 04405 04406 if (!res) { 04407 /* The channel driver successfully handled this indication */ 04408 res = 0; 04409 goto indicate_cleanup; 04410 } 04411 04412 /* The channel driver does not support this indication, let's fake 04413 * it by doing our own tone generation if applicable. */ 04414 04415 /*!\note If we compare the enumeration type, which does not have any 04416 * negative constants, the compiler may optimize this code away. 04417 * Therefore, we must perform an integer comparison here. */ 04418 if (_condition < 0) { 04419 /* Stop any tones that are playing */ 04420 ast_playtones_stop(chan); 04421 res = 0; 04422 goto indicate_cleanup; 04423 } 04424 04425 /* Handle conditions that we have tones for. */ 04426 switch (condition) { 04427 case _XXX_AST_CONTROL_T38: 04428 /* deprecated T.38 control frame */ 04429 res = -1; 04430 goto indicate_cleanup; 04431 case AST_CONTROL_T38_PARAMETERS: 04432 /* there is no way to provide 'default' behavior for these 04433 * control frames, so we need to return failure, but there 04434 * is also no value in the log message below being emitted 04435 * since failure to handle these frames is not an 'error' 04436 * so just return right now. in addition, we want to return 04437 * whatever value the channel driver returned, in case it 04438 * has some meaning.*/ 04439 goto indicate_cleanup; 04440 case AST_CONTROL_RINGING: 04441 ts = ast_get_indication_tone(chan->zone, "ring"); 04442 /* It is common practice for channel drivers to return -1 if trying 04443 * to indicate ringing on a channel which is up. The idea is to let the 04444 * core generate the ringing inband. However, we don't want the 04445 * warning message about not being able to handle the specific indication 04446 * to print nor do we want ast_indicate_data to return an "error" for this 04447 * condition 04448 */ 04449 if (chan->_state == AST_STATE_UP) { 04450 res = 0; 04451 } 04452 break; 04453 case AST_CONTROL_BUSY: 04454 ts = ast_get_indication_tone(chan->zone, "busy"); 04455 break; 04456 case AST_CONTROL_INCOMPLETE: 04457 case AST_CONTROL_CONGESTION: 04458 ts = ast_get_indication_tone(chan->zone, "congestion"); 04459 break; 04460 case AST_CONTROL_PROGRESS: 04461 case AST_CONTROL_PROCEEDING: 04462 case AST_CONTROL_VIDUPDATE: 04463 case AST_CONTROL_SRCUPDATE: 04464 case AST_CONTROL_SRCCHANGE: 04465 case AST_CONTROL_RADIO_KEY: 04466 case AST_CONTROL_RADIO_UNKEY: 04467 case AST_CONTROL_OPTION: 04468 case AST_CONTROL_WINK: 04469 case AST_CONTROL_FLASH: 04470 case AST_CONTROL_OFFHOOK: 04471 case AST_CONTROL_TAKEOFFHOOK: 04472 case AST_CONTROL_ANSWER: 04473 case AST_CONTROL_HANGUP: 04474 case AST_CONTROL_RING: 04475 case AST_CONTROL_HOLD: 04476 case AST_CONTROL_UNHOLD: 04477 case AST_CONTROL_TRANSFER: 04478 case AST_CONTROL_CONNECTED_LINE: 04479 case AST_CONTROL_REDIRECTING: 04480 case AST_CONTROL_CC: 04481 case AST_CONTROL_READ_ACTION: 04482 case AST_CONTROL_AOC: 04483 case AST_CONTROL_END_OF_Q: 04484 case AST_CONTROL_UPDATE_RTP_PEER: 04485 /* Nothing left to do for these. */ 04486 res = 0; 04487 break; 04488 } 04489 04490 if (ts) { 04491 /* We have a tone to play, yay. */ 04492 ast_debug(1, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition); 04493 res = ast_playtones_start(chan, 0, ts->data, 1); 04494 ts = ast_tone_zone_sound_unref(ts); 04495 } 04496 04497 if (res) { 04498 /* not handled */ 04499 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); 04500 } 04501 04502 indicate_cleanup: 04503 ast_channel_unlock(chan); 04504 if (awesome_frame) { 04505 ast_frfree(awesome_frame); 04506 } 04507 04508 return res; 04509 }
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 7762 of file channel.c.
References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.
Referenced by load_module().
07765 { 07766 ast_moh_start_ptr = start_ptr; 07767 ast_moh_stop_ptr = stop_ptr; 07768 ast_moh_cleanup_ptr = cleanup_ptr; 07769 }
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 4247 of file channel.c.
References ast_opt_internal_timing, chanlist::chan, and ast_channel::timingfd.
Referenced by add_sdp(), and ast_read_generator_actions().
04248 { 04249 return (ast_opt_internal_timing && chan->timingfd > -1); 04250 }
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 1779 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().
01780 { 01781 /* Do not add a default entry in this switch statement. Each new 01782 * frame type should be addressed directly as to whether it should 01783 * be queued up or not. 01784 */ 01785 switch (frame->frametype) { 01786 case AST_FRAME_CONTROL: 01787 case AST_FRAME_TEXT: 01788 case AST_FRAME_IMAGE: 01789 case AST_FRAME_HTML: 01790 return 1; 01791 01792 case AST_FRAME_DTMF_END: 01793 case AST_FRAME_DTMF_BEGIN: 01794 case AST_FRAME_VOICE: 01795 case AST_FRAME_VIDEO: 01796 case AST_FRAME_NULL: 01797 case AST_FRAME_IAX: 01798 case AST_FRAME_CNG: 01799 case AST_FRAME_MODEM: 01800 return 0; 01801 } 01802 return 0; 01803 }
void ast_moh_cleanup | ( | struct ast_channel * | chan | ) |
Definition at line 7796 of file channel.c.
References ast_moh_cleanup_ptr.
Referenced by ast_channel_destructor().
07797 { 07798 if (ast_moh_cleanup_ptr) 07799 ast_moh_cleanup_ptr(chan); 07800 }
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 7779 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().
07780 { 07781 if (ast_moh_start_ptr) 07782 return ast_moh_start_ptr(chan, mclass, interpclass); 07783 07784 ast_verb(3, "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : (interpclass ? interpclass : "default")); 07785 07786 return 0; 07787 }
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 7790 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().
07791 { 07792 if (ast_moh_stop_ptr) 07793 ast_moh_stop_ptr(chan); 07794 }
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 2230 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_copy(), and ast_party_caller::id.
02231 { 02232 if (dest == src) { 02233 /* Don't copy to self */ 02234 return; 02235 } 02236 02237 ast_party_id_copy(&dest->id, &src->id); 02238 ast_party_id_copy(&dest->ani, &src->ani); 02239 dest->ani2 = src->ani2; 02240 }
void ast_party_caller_free | ( | struct ast_party_caller * | doomed | ) |
Destroy the caller party contents.
doomed | The caller party to destroy. |
Definition at line 2256 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().
02257 { 02258 ast_party_id_free(&doomed->id); 02259 ast_party_id_free(&doomed->ani); 02260 }
void ast_party_caller_init | ( | struct ast_party_caller * | init | ) |
Initialize the given caller structure.
init | Caller structure to initialize. |
Definition at line 2223 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().
02224 { 02225 ast_party_id_init(&init->id); 02226 ast_party_id_init(&init->ani); 02227 init->ani2 = 0; 02228 }
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 2249 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().
02250 { 02251 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL); 02252 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL); 02253 dest->ani2 = src->ani2; 02254 }
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 2242 of file channel.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_id_set_init(), and ast_party_caller::id.
Referenced by callerid_write(), dial_exec_full(), do_forward(), misdn_update_caller_id(), ring_entry(), and sig_pri_handle_subcmds().
02243 { 02244 ast_party_id_set_init(&init->id, &guide->id); 02245 ast_party_id_set_init(&init->ani, &guide->ani); 02246 init->ani2 = guide->ani2; 02247 }
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 2299 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.
02300 { 02301 connected->id = caller->id; 02302 connected->ani = caller->ani; 02303 connected->ani2 = caller->ani2; 02304 connected->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN; 02305 }
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 2270 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_copy(), ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by __ast_read(), ast_call_forward(), ast_channel_connected_line_macro(), ast_do_pickup(), builtin_atxfer(), dial_exec_full(), do_forward(), local_attended_transfer(), misdn_attempt_transfer(), and party_connected_line_copy_transfer().
02271 { 02272 if (dest == src) { 02273 /* Don't copy to self */ 02274 return; 02275 } 02276 02277 ast_party_id_copy(&dest->id, &src->id); 02278 ast_party_id_copy(&dest->ani, &src->ani); 02279 dest->ani2 = src->ani2; 02280 dest->source = src->source; 02281 }
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 2307 of file channel.c.
References ast_party_connected_line::ani, ast_party_id_free(), and ast_party_connected_line::id.
Referenced by __ast_read(), app_exec(), ast_channel_destructor(), ast_do_pickup(), ast_dummy_channel_destructor(), ast_indicate_data(), atxfer_fail_cleanup(), builtin_atxfer(), callattempt_free(), chanlist_free(), connectedline_write(), destroy_calling_tree(), feature_request_and_dial(), local_attended_transfer(), misdn_attempt_transfer(), parked_call_exec(), sig_pri_handle_subcmds(), socket_process(), wait_for_answer(), wait_for_winner(), and xfer_ds_destroy().
02308 { 02309 ast_party_id_free(&doomed->id); 02310 ast_party_id_free(&doomed->ani); 02311 }
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 2262 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN, ast_party_id_init(), ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by __ast_channel_alloc_ap(), __ast_read(), ast_do_pickup(), builtin_atxfer(), do_forward(), handle_request_invite(), handle_request_update(), handle_response_invite(), local_attended_transfer(), misdn_attempt_transfer(), misdn_queue_connected_line_update(), parked_call_exec(), sig_pri_handle_subcmds(), sip_call(), socket_process(), and wait_for_answer().
02263 { 02264 ast_party_id_init(&init->id); 02265 ast_party_id_init(&init->ani); 02266 init->ani2 = 0; 02267 init->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN; 02268 }
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 2291 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_set(), ast_party_connected_line::id, ast_party_connected_line::source, and update().
Referenced by ast_channel_set_connected_line(), and wait_for_winner().
02292 { 02293 ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL); 02294 ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL); 02295 dest->ani2 = src->ani2; 02296 dest->source = src->source; 02297 }
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 2283 of file channel.c.
References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_party_id_set_init(), ast_party_connected_line::id, and ast_party_connected_line::source.
Referenced by __ast_request_and_dial(), ast_indicate_data(), connectedline_write(), dial_exec_full(), feature_request_and_dial(), and wait_for_winner().
02284 { 02285 ast_party_id_set_init(&init->id, &guide->id); 02286 ast_party_id_set_init(&init->ani, &guide->ani); 02287 init->ani2 = guide->ani2; 02288 init->source = guide->source; 02289 }
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 2181 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().
02182 { 02183 if (dest == src) { 02184 /* Don't copy to self */ 02185 return; 02186 } 02187 02188 ast_free(dest->number.str); 02189 dest->number.str = ast_strdup(src->number.str); 02190 dest->number.plan = src->number.plan; 02191 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress); 02192 dest->transit_network_select = src->transit_network_select; 02193 }
void ast_party_dialed_free | ( | struct ast_party_dialed * | doomed | ) |
Destroy the dialed party contents.
doomed | The dialed party to destroy. |
Definition at line 2216 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().
02217 { 02218 ast_free(doomed->number.str); 02219 doomed->number.str = NULL; 02220 ast_party_subaddress_free(&doomed->subaddress); 02221 }
void ast_party_dialed_init | ( | struct ast_party_dialed * | init | ) |
Initialize the given dialed structure.
init | Dialed structure to initialize. |
Definition at line 2173 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().
02174 { 02175 init->number.str = NULL; 02176 init->number.plan = 0;/* Unknown */ 02177 ast_party_subaddress_init(&init->subaddress); 02178 init->transit_network_select = 0; 02179 }
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 2203 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().
02204 { 02205 if (src->number.str && src->number.str != dest->number.str) { 02206 ast_free(dest->number.str); 02207 dest->number.str = ast_strdup(src->number.str); 02208 } 02209 dest->number.plan = src->number.plan; 02210 02211 ast_party_subaddress_set(&dest->subaddress, &src->subaddress); 02212 02213 dest->transit_network_select = src->transit_network_select; 02214 }
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 2195 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().
02196 { 02197 init->number.str = NULL; 02198 init->number.plan = guide->number.plan; 02199 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress); 02200 init->transit_network_select = guide->transit_network_select; 02201 }
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 2052 of file channel.c.
References ast_free, ast_party_name_copy(), ast_party_number_copy(), ast_party_subaddress_copy(), ast_strdup, ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_connected_line_copy_from_caller(), ast_connected_line_copy_to_caller(), ast_party_caller_copy(), ast_party_connected_line_copy(), ast_party_redirecting_copy(), and parkandannounce_exec().
02053 { 02054 if (dest == src) { 02055 /* Don't copy to self */ 02056 return; 02057 } 02058 02059 ast_party_name_copy(&dest->name, &src->name); 02060 ast_party_number_copy(&dest->number, &src->number); 02061 ast_party_subaddress_copy(&dest->subaddress, &src->subaddress); 02062 02063 ast_free(dest->tag); 02064 dest->tag = ast_strdup(src->tag); 02065 }
void ast_party_id_free | ( | struct ast_party_id * | doomed | ) |
Destroy the party id contents.
doomed | The party id to destroy. |
Definition at line 2098 of file channel.c.
References ast_free, ast_party_name_free(), ast_party_number_free(), ast_party_subaddress_free(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_free(), ast_party_connected_line_free(), ast_party_redirecting_free(), parkandannounce_exec(), and sig_pri_mcid_event().
02099 { 02100 ast_party_name_free(&doomed->name); 02101 ast_party_number_free(&doomed->number); 02102 ast_party_subaddress_free(&doomed->subaddress); 02103 02104 ast_free(doomed->tag); 02105 doomed->tag = NULL; 02106 }
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 2044 of file channel.c.
References ast_party_name_init(), ast_party_number_init(), ast_party_subaddress_init(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_init(), ast_party_connected_line_init(), ast_party_redirecting_init(), dial_exec_full(), parkandannounce_exec(), and sig_pri_mcid_event().
02045 { 02046 ast_party_name_init(&init->name); 02047 ast_party_number_init(&init->number); 02048 ast_party_subaddress_init(&init->subaddress); 02049 init->tag = NULL; 02050 }
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 2108 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_event_party_id(), sig_pri_handle_subcmds(), sip_call(), and socket_process().
02109 { 02110 int number_priority; 02111 int number_value; 02112 int number_screening; 02113 int name_priority; 02114 int name_value; 02115 02116 /* Determine name presentation priority. */ 02117 if (!id->name.valid) { 02118 name_value = AST_PRES_UNAVAILABLE; 02119 name_priority = 3; 02120 } else { 02121 name_value = id->name.presentation & AST_PRES_RESTRICTION; 02122 switch (name_value) { 02123 case AST_PRES_RESTRICTED: 02124 name_priority = 0; 02125 break; 02126 case AST_PRES_ALLOWED: 02127 name_priority = 1; 02128 break; 02129 case AST_PRES_UNAVAILABLE: 02130 name_priority = 2; 02131 break; 02132 default: 02133 name_value = AST_PRES_UNAVAILABLE; 02134 name_priority = 3; 02135 break; 02136 } 02137 } 02138 02139 /* Determine number presentation priority. */ 02140 if (!id->number.valid) { 02141 number_screening = AST_PRES_USER_NUMBER_UNSCREENED; 02142 number_value = AST_PRES_UNAVAILABLE; 02143 number_priority = 3; 02144 } else { 02145 number_screening = id->number.presentation & AST_PRES_NUMBER_TYPE; 02146 number_value = id->number.presentation & AST_PRES_RESTRICTION; 02147 switch (number_value) { 02148 case AST_PRES_RESTRICTED: 02149 number_priority = 0; 02150 break; 02151 case AST_PRES_ALLOWED: 02152 number_priority = 1; 02153 break; 02154 case AST_PRES_UNAVAILABLE: 02155 number_priority = 2; 02156 break; 02157 default: 02158 number_screening = AST_PRES_USER_NUMBER_UNSCREENED; 02159 number_value = AST_PRES_UNAVAILABLE; 02160 number_priority = 3; 02161 break; 02162 } 02163 } 02164 02165 /* Select the wining presentation value. */ 02166 if (name_priority < number_priority) { 02167 number_value = name_value; 02168 } 02169 02170 return number_value | number_screening; 02171 }
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 2075 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().
02076 { 02077 if (dest == src) { 02078 /* Don't set to self */ 02079 return; 02080 } 02081 02082 if (!update || update->name) { 02083 ast_party_name_set(&dest->name, &src->name); 02084 } 02085 if (!update || update->number) { 02086 ast_party_number_set(&dest->number, &src->number); 02087 } 02088 if (!update || update->subaddress) { 02089 ast_party_subaddress_set(&dest->subaddress, &src->subaddress); 02090 } 02091 02092 if (src->tag && src->tag != dest->tag) { 02093 ast_free(dest->tag); 02094 dest->tag = ast_strdup(src->tag); 02095 } 02096 }
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 2067 of file channel.c.
References ast_party_name_set_init(), ast_party_number_set_init(), ast_party_subaddress_set_init(), ast_party_id::name, ast_party_id::number, ast_party_id::subaddress, and ast_party_id::tag.
Referenced by ast_party_caller_set_init(), ast_party_connected_line_set_init(), ast_party_redirecting_set_init(), and dial_exec_full().
02068 { 02069 ast_party_name_set_init(&init->name, &guide->name); 02070 ast_party_number_set_init(&init->number, &guide->number); 02071 ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress); 02072 init->tag = NULL; 02073 }
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 1893 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().
01894 { 01895 if (dest == src) { 01896 /* Don't copy to self */ 01897 return; 01898 } 01899 01900 ast_free(dest->str); 01901 dest->str = ast_strdup(src->str); 01902 dest->char_set = src->char_set; 01903 dest->presentation = src->presentation; 01904 dest->valid = src->valid; 01905 }
void ast_party_name_free | ( | struct ast_party_name * | doomed | ) |
Destroy the party name contents.
doomed | The party name to destroy. |
Definition at line 1932 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 1885 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().
01886 { 01887 init->str = NULL; 01888 init->char_set = AST_PARTY_CHAR_SET_ISO8859_1; 01889 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 01890 init->valid = 0; 01891 }
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 1915 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().
01916 { 01917 if (dest == src) { 01918 /* Don't set to self */ 01919 return; 01920 } 01921 01922 if (src->str && src->str != dest->str) { 01923 ast_free(dest->str); 01924 dest->str = ast_strdup(src->str); 01925 } 01926 01927 dest->char_set = src->char_set; 01928 dest->presentation = src->presentation; 01929 dest->valid = src->valid; 01930 }
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 1907 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().
01908 { 01909 init->str = NULL; 01910 init->char_set = guide->char_set; 01911 init->presentation = guide->presentation; 01912 init->valid = guide->valid; 01913 }
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 1946 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().
01947 { 01948 if (dest == src) { 01949 /* Don't copy to self */ 01950 return; 01951 } 01952 01953 ast_free(dest->str); 01954 dest->str = ast_strdup(src->str); 01955 dest->plan = src->plan; 01956 dest->presentation = src->presentation; 01957 dest->valid = src->valid; 01958 }
void ast_party_number_free | ( | struct ast_party_number * | doomed | ) |
Destroy the party number contents.
doomed | The party number to destroy. |
Definition at line 1985 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 1938 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().
01939 { 01940 init->str = NULL; 01941 init->plan = 0;/* Unknown */ 01942 init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 01943 init->valid = 0; 01944 }
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 1968 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().
01969 { 01970 if (dest == src) { 01971 /* Don't set to self */ 01972 return; 01973 } 01974 01975 if (src->str && src->str != dest->str) { 01976 ast_free(dest->str); 01977 dest->str = ast_strdup(src->str); 01978 } 01979 01980 dest->plan = src->plan; 01981 dest->presentation = src->presentation; 01982 dest->valid = src->valid; 01983 }
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 1960 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().
01961 { 01962 init->str = NULL; 01963 init->plan = guide->plan; 01964 init->presentation = guide->presentation; 01965 init->valid = guide->valid; 01966 }
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 2321 of file channel.c.
References ast_party_id_copy(), ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, and ast_party_redirecting::to.
Referenced by ast_call_forward(), ast_channel_redirecting_macro(), begin_dial_channel(), call_forward_inherit(), dial_exec_full(), do_forward(), local_call(), and ring_entry().
02322 { 02323 if (dest == src) { 02324 /* Don't copy to self */ 02325 return; 02326 } 02327 02328 ast_party_id_copy(&dest->from, &src->from); 02329 ast_party_id_copy(&dest->to, &src->to); 02330 dest->count = src->count; 02331 dest->reason = src->reason; 02332 }
void ast_party_redirecting_free | ( | struct ast_party_redirecting * | doomed | ) |
Destroy the redirecting information contents.
doomed | The redirecting information to destroy. |
Definition at line 2350 of file channel.c.
References ast_party_id_free(), ast_party_redirecting::from, and ast_party_redirecting::to.
Referenced by ast_channel_destructor(), ast_dummy_channel_destructor(), ast_indicate_data(), call_forward_inherit(), do_forward(), handle_request_invite(), handle_response(), handle_response_invite(), redirecting_write(), and sig_pri_handle_subcmds().
02351 { 02352 ast_party_id_free(&doomed->from); 02353 ast_party_id_free(&doomed->to); 02354 }
void ast_party_redirecting_init | ( | struct ast_party_redirecting * | init | ) |
Initialize the given redirecting structure.
init | Redirecting structure to initialize. |
Definition at line 2313 of file channel.c.
References ast_party_id_init(), AST_REDIRECTING_REASON_UNKNOWN, ast_party_redirecting::count, ast_party_redirecting::from, ast_party_redirecting::reason, and ast_party_redirecting::to.
Referenced by __ast_channel_alloc_ap(), call_forward_inherit(), do_forward(), handle_request_invite(), handle_response(), and handle_response_invite().
02314 { 02315 ast_party_id_init(&init->from); 02316 ast_party_id_init(&init->to); 02317 init->count = 0; 02318 init->reason = AST_REDIRECTING_REASON_UNKNOWN; 02319 }
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 2342 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().
02343 { 02344 ast_party_id_set(&dest->from, &src->from, update ? &update->from : NULL); 02345 ast_party_id_set(&dest->to, &src->to, update ? &update->to : NULL); 02346 dest->reason = src->reason; 02347 dest->count = src->count; 02348 }
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 2334 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().
02335 { 02336 ast_party_id_set_init(&init->from, &guide->from); 02337 ast_party_id_set_init(&init->to, &guide->to); 02338 init->count = guide->count; 02339 init->reason = guide->reason; 02340 }
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 1999 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().
02000 { 02001 if (dest == src) { 02002 /* Don't copy to self */ 02003 return; 02004 } 02005 02006 ast_free(dest->str); 02007 dest->str = ast_strdup(src->str); 02008 dest->type = src->type; 02009 dest->odd_even_indicator = src->odd_even_indicator; 02010 dest->valid = src->valid; 02011 }
void ast_party_subaddress_free | ( | struct ast_party_subaddress * | doomed | ) |
Destroy the party subaddress contents.
doomed | The party subaddress to destroy. |
Definition at line 2038 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 1991 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().
01992 { 01993 init->str = NULL; 01994 init->type = 0; 01995 init->odd_even_indicator = 0; 01996 init->valid = 0; 01997 }
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 2021 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().
02022 { 02023 if (dest == src) { 02024 /* Don't set to self */ 02025 return; 02026 } 02027 02028 if (src->str && src->str != dest->str) { 02029 ast_free(dest->str); 02030 dest->str = ast_strdup(src->str); 02031 } 02032 02033 dest->type = src->type; 02034 dest->odd_even_indicator = src->odd_even_indicator; 02035 dest->valid = src->valid; 02036 }
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 2013 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().
02014 { 02015 init->str = NULL; 02016 init->type = guide->type; 02017 init->odd_even_indicator = guide->odd_even_indicator; 02018 init->valid = guide->valid; 02019 }
int ast_plc_reload | ( | void | ) |
Reload genericplc configuration value from codecs.conf.
Implementation is in main/channel.c
Definition at line 7815 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().
07816 { 07817 struct ast_variable *var; 07818 struct ast_flags config_flags = { 0 }; 07819 struct ast_config *cfg = ast_config_load("codecs.conf", config_flags); 07820 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) 07821 return 0; 07822 for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) { 07823 if (!strcasecmp(var->name, "genericplc")) { 07824 ast_set2_flag(&ast_options, ast_true(var->value), AST_OPT_FLAG_GENERIC_PLC); 07825 } 07826 } 07827 ast_config_destroy(cfg); 07828 return 0; 07829 }
void ast_poll_channel_add | ( | struct ast_channel * | chan0, | |
struct ast_channel * | chan1 | |||
) |
Add a channel to an optimized waitfor
Definition at line 2610 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().
02611 { 02612 #ifdef HAVE_EPOLL 02613 struct epoll_event ev; 02614 int i = 0; 02615 02616 if (chan0->epfd == -1) 02617 return; 02618 02619 /* Iterate through the file descriptors on chan1, adding them to chan0 */ 02620 for (i = 0; i < AST_MAX_FDS; i++) { 02621 if (chan1->fds[i] == -1) 02622 continue; 02623 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 02624 ev.data.ptr = chan1->epfd_data[i]; 02625 epoll_ctl(chan0->epfd, EPOLL_CTL_ADD, chan1->fds[i], &ev); 02626 } 02627 02628 #endif 02629 return; 02630 }
void ast_poll_channel_del | ( | struct ast_channel * | chan0, | |
struct ast_channel * | chan1 | |||
) |
Delete a channel from an optimized waitfor
Definition at line 2633 of file channel.c.
References AST_MAX_FDS, and ast_channel::fds.
Referenced by feature_request_and_dial(), and monitor_dial().
02634 { 02635 #ifdef HAVE_EPOLL 02636 struct epoll_event ev; 02637 int i = 0; 02638 02639 if (chan0->epfd == -1) 02640 return; 02641 02642 for (i = 0; i < AST_MAX_FDS; i++) { 02643 if (chan1->fds[i] == -1) 02644 continue; 02645 epoll_ctl(chan0->epfd, EPOLL_CTL_DEL, chan1->fds[i], &ev); 02646 } 02647 02648 #endif 02649 return; 02650 }
char* ast_print_group | ( | char * | buf, | |
int | buflen, | |||
ast_group_t | group | |||
) |
print call- and pickup groups into buffer
Definition at line 7963 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().
07964 { 07965 unsigned int i; 07966 int first = 1; 07967 char num[3]; 07968 07969 buf[0] = '\0'; 07970 07971 if (!group) /* Return empty string if no group */ 07972 return buf; 07973 07974 for (i = 0; i <= 63; i++) { /* Max group is 63 */ 07975 if (group & ((ast_group_t) 1 << i)) { 07976 if (!first) { 07977 strncat(buf, ", ", buflen - strlen(buf) - 1); 07978 } else { 07979 first = 0; 07980 } 07981 snprintf(num, sizeof(num), "%u", i); 07982 strncat(buf, num, buflen - strlen(buf) - 1); 07983 } 07984 } 07985 return buf; 07986 }
int ast_prod | ( | struct ast_channel * | chan | ) |
Send empty audio to prime a channel driver.
Definition at line 4635 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().
04636 { 04637 struct ast_frame a = { AST_FRAME_VOICE }; 04638 char nothing[128]; 04639 04640 /* Send an empty audio frame to get things moving */ 04641 if (chan->_state != AST_STATE_UP) { 04642 ast_debug(1, "Prodding channel '%s'\n", chan->name); 04643 a.subclass.codec = chan->rawwriteformat; 04644 a.data.ptr = nothing + AST_FRIENDLY_OFFSET; 04645 a.src = "ast_prod"; /* this better match check in ast_write */ 04646 if (ast_write(chan, &a)) 04647 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 04648 } 04649 return 0; 04650 }
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 1562 of file channel.c.
References AST_FRAME_CONTROL, ast_queue_frame(), chanlist::chan, and f.
Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_read(), __dahdi_exception(), __oh323_update_info(), analog_call(), analog_exception(), analog_hangup(), analog_ss_thread(), ast_do_pickup(), attempt_transfer(), auto_congest(), cb_events(), cli_console_answer(), cli_console_flash(), console_answer(), console_call(), console_sendtext(), dahdi_handle_event(), dahdi_hangup(), gtalk_is_answered(), gtalk_ringing_ack(), handle_hd_hf(), handle_offhook_message(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_refer(), handle_soft_key_event_message(), handle_stimulus_message(), HandleCallIncoming(), jingle_is_answered(), jingle_ringing_ack(), masquerade_colp_transfer(), misdn_facility_ie_handler(), multicast_rtp_call(), nbs_call(), phone_call(), process_sdp(), receive_digit(), remote_hold(), send_cause2ast(), setup_rtp_connection(), skinny_call(), skinny_transfer(), skinny_unhold(), unistim_call(), and update_state().
01563 { 01564 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control }; 01565 return ast_queue_frame(chan, &f); 01566 }
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 1569 of file channel.c.
References AST_FRAME_CONTROL, ast_queue_frame(), chanlist::chan, and f.
Referenced by __analog_handle_event(), analog_hangup(), ast_channel_queue_connected_line_update(), ast_channel_queue_redirecting_update(), change_t38_state(), dahdi_handle_event(), dahdi_hangup(), handle_request_notify(), handle_response_refer(), iax2_queue_control_data(), iax2_transfer(), interpret_t38_parameters(), local_attended_transfer(), masquerade_colp_transfer(), process_sdp(), sig_pri_aoc_d_from_pri(), sig_pri_aoc_e_from_pri(), sig_pri_aoc_s_from_pri(), sig_pri_send_aoce_termination_request(), sip_sipredirect(), and skinny_hold().
01571 { 01572 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = control, .data.ptr = (void *) data, .datalen = datalen }; 01573 return ast_queue_frame(chan, &f); 01574 }
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 1519 of file channel.c.
References __ast_queue_frame(), and chanlist::chan.
Referenced by __ast_channel_masquerade(), __ast_read(), __oh323_rtp_create(), __oh323_update_info(), action_atxfer(), agent_request(), alsa_call(), ast_channel_setwhentohangup_tv(), ast_do_masquerade(), ast_queue_cc_frame(), ast_queue_control(), ast_queue_control_data(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_softhangup_nolock(), bridge_write(), cb_events(), cli_console_dial(), cli_console_sendtext(), console_dial(), console_do_answer(), console_flash(), console_sendtext(), dahdi_queue_frame(), dahdi_read(), dictate_exec(), do_immediate_setup(), gtalk_handle_dtmf(), handle_keypad_button_message(), handle_request_info(), handle_request_invite(), handle_response_invite(), iax2_queue_frame(), jingle_handle_dtmf(), keypad_digit(), local_queue_frame(), mgcp_queue_frame(), oh323_simulate_dtmf_end(), oss_call(), pri_queue_frame(), process_sdp(), queue_dtmf_readq(), receive_digit(), receive_message(), rpt_call(), sig_pri_handle_hold(), sig_pri_handle_subcmds(), sig_ss7_queue_frame(), stream_monitor(), unistim_do_senddigit(), unistim_senddigit_end(), usbradio_read(), and wakeup_sub().
01520 { 01521 return __ast_queue_frame(chan, fin, 0, NULL); 01522 }
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 1524 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().
01525 { 01526 return __ast_queue_frame(chan, fin, 1, NULL); 01527 }
int ast_queue_hangup | ( | struct ast_channel * | chan | ) |
Queue a hangup frame.
Definition at line 1530 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().
01531 { 01532 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP }; 01533 /* Yeah, let's not change a lock-critical value without locking */ 01534 if (!ast_channel_trylock(chan)) { 01535 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01536 ast_channel_unlock(chan); 01537 } 01538 return ast_queue_frame(chan, &f); 01539 }
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 1542 of file channel.c.
References ast_channel::_softhangup, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), AST_SOFTHANGUP_DEV, chanlist::chan, f, and ast_channel::hangupcause.
Referenced by __analog_handle_event(), __oh323_update_info(), __sip_autodestruct(), close_call(), close_client(), console_hangup(), dahdi_handle_event(), dahdi_r2_on_call_disconnect(), handle_request_bye(), handle_response(), handle_response_invite(), HandleCallOutgoing(), hangup_chan(), hangup_connection(), misdn_answer(), retrans_pkt(), and TransferCallStep1().
01543 { 01544 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP }; 01545 01546 if (cause >= 0) 01547 f.data.uint32 = cause; 01548 01549 /* Yeah, let's not change a lock-critical value without locking */ 01550 if (!ast_channel_trylock(chan)) { 01551 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01552 if (cause < 0) 01553 f.data.uint32 = chan->hangupcause; 01554 01555 ast_channel_unlock(chan); 01556 } 01557 01558 return ast_queue_frame(chan, &f); 01559 }
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 2871 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().
02872 { 02873 int res = 0; 02874 02875 ast_channel_lock(chan); 02876 02877 /* You can't answer an outbound call */ 02878 if (ast_test_flag(chan, AST_FLAG_OUTGOING)) { 02879 ast_channel_unlock(chan); 02880 return 0; 02881 } 02882 02883 /* Stop if we're a zombie or need a soft hangup */ 02884 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02885 ast_channel_unlock(chan); 02886 return -1; 02887 } 02888 02889 ast_channel_unlock(chan); 02890 02891 switch (chan->_state) { 02892 case AST_STATE_RINGING: 02893 case AST_STATE_RING: 02894 ast_channel_lock(chan); 02895 if (chan->tech->answer) { 02896 res = chan->tech->answer(chan); 02897 } 02898 ast_setstate(chan, AST_STATE_UP); 02899 if (cdr_answer) { 02900 ast_cdr_answer(chan->cdr); 02901 } 02902 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 02903 ast_channel_unlock(chan); 02904 break; 02905 case AST_STATE_UP: 02906 ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL); 02907 /* Calling ast_cdr_answer when it it has previously been called 02908 * is essentially a no-op, so it is safe. 02909 */ 02910 if (cdr_answer) { 02911 ast_cdr_answer(chan->cdr); 02912 } 02913 break; 02914 default: 02915 break; 02916 } 02917 02918 ast_indicate(chan, -1); 02919 02920 return res; 02921 }
struct ast_frame* ast_read | ( | struct ast_channel * | chan | ) |
Reads a frame.
chan | channel to read a frame from |
Definition at line 4252 of file channel.c.
References __ast_read(), and chanlist::chan.
Referenced by __adsi_transmit_messages(), __analog_ss_thread(), __ast_answer(), __ast_play_and_record(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), agent_read(), analog_ss_thread(), ast_bridge_handle_trip(), ast_recvtext(), ast_safe_sleep_conditional(), ast_tonepair(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), async_agi_read_frame(), async_wait(), autoservice_run(), background_detect_exec(), channel_spy(), conf_flush(), conf_run(), dahdi_bridge(), dial_exec_full(), dictate_exec(), disa_exec(), disable_t38(), do_idle_thread(), do_waiting(), echo_exec(), eivr_comm(), feature_request_and_dial(), find_cache(), generic_fax_exec(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), jack_exec(), local_bridge_loop(), manage_parked_call(), measurenoise(), misdn_bridge(), monitor_dial(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), receivefax_t38_init(), recordthread(), remote_bridge_loop(), 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().
04253 { 04254 return __ast_read(chan, 0); 04255 }
static void ast_read_generator_actions | ( | struct ast_channel * | chan, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 3609 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().
03610 { 03611 if (chan->generator && chan->generator->generate && chan->generatordata && !ast_internal_timing_enabled(chan)) { 03612 void *tmp = chan->generatordata; 03613 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = chan->generator->generate; 03614 int res; 03615 int samples; 03616 03617 if (chan->timingfunc) { 03618 ast_debug(1, "Generator got voice, switching to phase locked mode\n"); 03619 ast_settimeout(chan, 0, NULL, NULL); 03620 } 03621 03622 chan->generatordata = NULL; /* reset, to let writes go through */ 03623 03624 if (f->subclass.codec != chan->writeformat) { 03625 float factor; 03626 factor = ((float) ast_format_rate(chan->writeformat)) / ((float) ast_format_rate(f->subclass.codec)); 03627 samples = (int) ( ((float) f->samples) * factor ); 03628 } else { 03629 samples = f->samples; 03630 } 03631 03632 /* This unlock is here based on two assumptions that hold true at this point in the 03633 * code. 1) this function is only called from within __ast_read() and 2) all generators 03634 * call ast_write() in their generate callback. 03635 * 03636 * The reason this is added is so that when ast_write is called, the lock that occurs 03637 * there will not recursively lock the channel. Doing this will cause intended deadlock 03638 * avoidance not to work in deeper functions 03639 */ 03640 ast_channel_unlock(chan); 03641 res = generate(chan, tmp, f->datalen, samples); 03642 ast_channel_lock(chan); 03643 chan->generatordata = tmp; 03644 if (res) { 03645 ast_debug(1, "Auto-deactivating generator\n"); 03646 ast_deactivate_generator(chan); 03647 } 03648 03649 } else if (f->frametype == AST_FRAME_CNG) { 03650 if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) { 03651 ast_debug(1, "Generator got CNG, switching to timed mode\n"); 03652 ast_settimeout(chan, 50, generator_force, chan); 03653 } 03654 } 03655 }
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 4257 of file channel.c.
References __ast_read(), and chanlist::chan.
Referenced by ast_bridge_handle_trip(), and conf_run().
04258 { 04259 return __ast_read(chan, 1); 04260 }
int ast_readstring | ( | struct ast_channel * | c, | |
char * | s, | |||
int | len, | |||
int | timeout, | |||
int | rtimeout, | |||
char * | enders | |||
) |
Reads multiple digits.
c | channel to read from | |
s | string to read in to. Must be at least the size of your length | |
len | how many digits to read (maximum) | |
timeout | how long to timeout between digits | |
rtimeout | timeout to wait on the first digit | |
enders | digits to end the string |
Definition at line 5686 of file channel.c.
References ast_readstring_full().
Referenced by ast_adsi_begin_download(), ast_adsi_get_cpeinfo(), ast_adsi_load_session(), ast_app_getdata(), dialout(), do_directory(), forward_message(), privacy_exec(), vm_authenticate(), vm_newuser(), and vm_options().
05687 { 05688 return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1); 05689 }
int ast_readstring_full | ( | struct ast_channel * | c, | |
char * | s, | |||
int | len, | |||
int | timeout, | |||
int | ftimeout, | |||
char * | enders, | |||
int | audiofd, | |||
int | ctrlfd | |||
) |
Definition at line 5691 of file channel.c.
References ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, AST_GETDATA_COMPLETE, AST_GETDATA_EMPTY_END_TERMINATED, AST_GETDATA_FAILED, AST_GETDATA_INTERRUPTED, AST_GETDATA_TIMEOUT, ast_opt_transmit_silence, ast_stopstream(), ast_test_flag, ast_waitfordigit_full(), ast_waitstream_full(), and ast_channel::stream.
Referenced by ast_app_getdata_full(), and ast_readstring().
05692 { 05693 int pos = 0; /* index in the buffer where we accumulate digits */ 05694 int to = ftimeout; 05695 05696 struct ast_silence_generator *silgen = NULL; 05697 05698 /* Stop if we're a zombie or need a soft hangup */ 05699 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 05700 return -1; 05701 if (!len) 05702 return -1; 05703 for (;;) { 05704 int d; 05705 if (c->stream) { 05706 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 05707 ast_stopstream(c); 05708 if (!silgen && ast_opt_transmit_silence) 05709 silgen = ast_channel_start_silence_generator(c); 05710 usleep(1000); 05711 if (!d) 05712 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 05713 } else { 05714 if (!silgen && ast_opt_transmit_silence) 05715 silgen = ast_channel_start_silence_generator(c); 05716 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 05717 } 05718 if (d < 0) { 05719 ast_channel_stop_silence_generator(c, silgen); 05720 return AST_GETDATA_FAILED; 05721 } 05722 if (d == 0) { 05723 s[pos] = '\0'; 05724 ast_channel_stop_silence_generator(c, silgen); 05725 return AST_GETDATA_TIMEOUT; 05726 } 05727 if (d == 1) { 05728 s[pos] = '\0'; 05729 ast_channel_stop_silence_generator(c, silgen); 05730 return AST_GETDATA_INTERRUPTED; 05731 } 05732 if (strchr(enders, d) && (pos == 0)) { 05733 s[pos] = '\0'; 05734 ast_channel_stop_silence_generator(c, silgen); 05735 return AST_GETDATA_EMPTY_END_TERMINATED; 05736 } 05737 if (!strchr(enders, d)) { 05738 s[pos++] = d; 05739 } 05740 if (strchr(enders, d) || (pos >= len)) { 05741 s[pos] = '\0'; 05742 ast_channel_stop_silence_generator(c, silgen); 05743 return AST_GETDATA_COMPLETE; 05744 } 05745 to = timeout; 05746 } 05747 /* Never reached */ 05748 return 0; 05749 }
int ast_recvchar | ( | struct ast_channel * | chan, | |
int | timeout | |||
) |
Receives a text character from a channel.
chan | channel to act upon | |
timeout | timeout in milliseconds (0 for infinite wait) |
Definition at line 4511 of file channel.c.
References ast_free, ast_recvtext(), and chanlist::chan.
Referenced by handle_recvchar().
04512 { 04513 int c; 04514 char *buf = ast_recvtext(chan, timeout); 04515 if (buf == NULL) 04516 return -1; /* error or timeout */ 04517 c = *(unsigned char *)buf; 04518 ast_free(buf); 04519 return c; 04520 }
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 4522 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().
04523 { 04524 int res, done = 0; 04525 char *buf = NULL; 04526 04527 while (!done) { 04528 struct ast_frame *f; 04529 if (ast_check_hangup(chan)) 04530 break; 04531 res = ast_waitfor(chan, timeout); 04532 if (res <= 0) /* timeout or error */ 04533 break; 04534 timeout = res; /* update timeout */ 04535 f = ast_read(chan); 04536 if (f == NULL) 04537 break; /* no frame */ 04538 if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP) 04539 done = 1; /* force a break */ 04540 else if (f->frametype == AST_FRAME_TEXT) { /* what we want */ 04541 buf = ast_strndup((char *) f->data.ptr, f->datalen); /* dup and break */ 04542 done = 1; 04543 } 04544 ast_frfree(f); 04545 } 04546 return buf; 04547 }
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 8865 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().
08866 { 08867 int32_t value; 08868 size_t pos = 0; 08869 int res; 08870 08871 static const struct ast_party_id_ies from_ies = { 08872 .name.str = AST_REDIRECTING_FROM_NAME, 08873 .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET, 08874 .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION, 08875 .name.valid = AST_REDIRECTING_FROM_NAME_VALID, 08876 08877 .number.str = AST_REDIRECTING_FROM_NUMBER, 08878 .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN, 08879 .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION, 08880 .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID, 08881 08882 .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS, 08883 .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE, 08884 .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, 08885 .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID, 08886 08887 .tag = AST_REDIRECTING_FROM_TAG, 08888 .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION, 08889 }; 08890 static const struct ast_party_id_ies to_ies = { 08891 .name.str = AST_REDIRECTING_TO_NAME, 08892 .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET, 08893 .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION, 08894 .name.valid = AST_REDIRECTING_TO_NAME_VALID, 08895 08896 .number.str = AST_REDIRECTING_TO_NUMBER, 08897 .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN, 08898 .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION, 08899 .number.valid = AST_REDIRECTING_TO_NUMBER_VALID, 08900 08901 .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS, 08902 .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE, 08903 .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, 08904 .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID, 08905 08906 .tag = AST_REDIRECTING_TO_TAG, 08907 .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION, 08908 }; 08909 08910 /* Redirecting frame version */ 08911 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08912 ast_log(LOG_WARNING, "No space left for redirecting frame version\n"); 08913 return -1; 08914 } 08915 data[pos++] = AST_REDIRECTING_VERSION; 08916 data[pos++] = 1; 08917 data[pos++] = 2;/* Version 1 did not have a version ie */ 08918 08919 res = party_id_build_data(data + pos, datalen - pos, &redirecting->from, 08920 "redirecting-from", &from_ies, update ? &update->from : NULL); 08921 if (res < 0) { 08922 return -1; 08923 } 08924 pos += res; 08925 08926 res = party_id_build_data(data + pos, datalen - pos, &redirecting->to, 08927 "redirecting-to", &to_ies, update ? &update->to : NULL); 08928 if (res < 0) { 08929 return -1; 08930 } 08931 pos += res; 08932 08933 /* Redirecting reason */ 08934 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 08935 ast_log(LOG_WARNING, "No space left for redirecting reason\n"); 08936 return -1; 08937 } 08938 data[pos++] = AST_REDIRECTING_REASON; 08939 data[pos++] = sizeof(value); 08940 value = htonl(redirecting->reason); 08941 memcpy(data + pos, &value, sizeof(value)); 08942 pos += sizeof(value); 08943 08944 /* Redirecting count */ 08945 if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { 08946 ast_log(LOG_WARNING, "No space left for redirecting count\n"); 08947 return -1; 08948 } 08949 data[pos++] = AST_REDIRECTING_COUNT; 08950 data[pos++] = sizeof(value); 08951 value = htonl(redirecting->count); 08952 memcpy(data + pos, &value, sizeof(value)); 08953 pos += sizeof(value); 08954 08955 return pos; 08956 }
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 8958 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().
08959 { 08960 size_t pos; 08961 unsigned char ie_len; 08962 unsigned char ie_id; 08963 int32_t value; 08964 int frame_version = 1; 08965 int from_combined_presentation = 0; 08966 int got_from_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 08967 int to_combined_presentation = 0; 08968 int got_to_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */ 08969 08970 for (pos = 0; pos < datalen; pos += ie_len) { 08971 if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) { 08972 ast_log(LOG_WARNING, "Invalid redirecting update\n"); 08973 return -1; 08974 } 08975 ie_id = data[pos++]; 08976 ie_len = data[pos++]; 08977 if (datalen < pos + ie_len) { 08978 ast_log(LOG_WARNING, "Invalid redirecting update\n"); 08979 return -1; 08980 } 08981 08982 switch (ie_id) { 08983 /* Redirecting frame version */ 08984 case AST_REDIRECTING_VERSION: 08985 if (ie_len != 1) { 08986 ast_log(LOG_WARNING, "Invalid redirecting frame version (%u)\n", 08987 (unsigned) ie_len); 08988 break; 08989 } 08990 frame_version = data[pos]; 08991 break; 08992 /* Redirecting-from party id name */ 08993 case AST_REDIRECTING_FROM_NAME: 08994 ast_free(redirecting->from.name.str); 08995 redirecting->from.name.str = ast_malloc(ie_len + 1); 08996 if (redirecting->from.name.str) { 08997 memcpy(redirecting->from.name.str, data + pos, ie_len); 08998 redirecting->from.name.str[ie_len] = 0; 08999 } 09000 break; 09001 case AST_REDIRECTING_FROM_NAME_CHAR_SET: 09002 if (ie_len != 1) { 09003 ast_log(LOG_WARNING, "Invalid redirecting-from name char set (%u)\n", 09004 (unsigned) ie_len); 09005 break; 09006 } 09007 redirecting->from.name.char_set = data[pos]; 09008 break; 09009 case AST_REDIRECTING_FROM_NAME_PRESENTATION: 09010 if (ie_len != 1) { 09011 ast_log(LOG_WARNING, "Invalid redirecting-from name presentation (%u)\n", 09012 (unsigned) ie_len); 09013 break; 09014 } 09015 redirecting->from.name.presentation = data[pos]; 09016 break; 09017 case AST_REDIRECTING_FROM_NAME_VALID: 09018 if (ie_len != 1) { 09019 ast_log(LOG_WARNING, "Invalid redirecting-from name valid (%u)\n", 09020 (unsigned) ie_len); 09021 break; 09022 } 09023 redirecting->from.name.valid = data[pos]; 09024 break; 09025 /* Redirecting-from party id number */ 09026 case AST_REDIRECTING_FROM_NUMBER: 09027 ast_free(redirecting->from.number.str); 09028 redirecting->from.number.str = ast_malloc(ie_len + 1); 09029 if (redirecting->from.number.str) { 09030 memcpy(redirecting->from.number.str, data + pos, ie_len); 09031 redirecting->from.number.str[ie_len] = 0; 09032 } 09033 break; 09034 case AST_REDIRECTING_FROM_NUMBER_PLAN: 09035 if (ie_len != 1) { 09036 ast_log(LOG_WARNING, "Invalid redirecting-from numbering plan (%u)\n", 09037 (unsigned) ie_len); 09038 break; 09039 } 09040 redirecting->from.number.plan = data[pos]; 09041 break; 09042 case AST_REDIRECTING_FROM_NUMBER_PRESENTATION: 09043 if (ie_len != 1) { 09044 ast_log(LOG_WARNING, "Invalid redirecting-from number presentation (%u)\n", 09045 (unsigned) ie_len); 09046 break; 09047 } 09048 redirecting->from.number.presentation = data[pos]; 09049 break; 09050 case AST_REDIRECTING_FROM_NUMBER_VALID: 09051 if (ie_len != 1) { 09052 ast_log(LOG_WARNING, "Invalid redirecting-from number valid (%u)\n", 09053 (unsigned) ie_len); 09054 break; 09055 } 09056 redirecting->from.number.valid = data[pos]; 09057 break; 09058 /* Redirecting-from party id combined presentation */ 09059 case AST_REDIRECTING_FROM_ID_PRESENTATION: 09060 if (ie_len != 1) { 09061 ast_log(LOG_WARNING, "Invalid redirecting-from combined presentation (%u)\n", 09062 (unsigned) ie_len); 09063 break; 09064 } 09065 from_combined_presentation = data[pos]; 09066 got_from_combined_presentation = 1; 09067 break; 09068 /* Redirecting-from party id subaddress */ 09069 case AST_REDIRECTING_FROM_SUBADDRESS: 09070 ast_free(redirecting->from.subaddress.str); 09071 redirecting->from.subaddress.str = ast_malloc(ie_len + 1); 09072 if (redirecting->from.subaddress.str) { 09073 memcpy(redirecting->from.subaddress.str, data + pos, ie_len); 09074 redirecting->from.subaddress.str[ie_len] = 0; 09075 } 09076 break; 09077 case AST_REDIRECTING_FROM_SUBADDRESS_TYPE: 09078 if (ie_len != 1) { 09079 ast_log(LOG_WARNING, "Invalid redirecting-from type of subaddress (%u)\n", 09080 (unsigned) ie_len); 09081 break; 09082 } 09083 redirecting->from.subaddress.type = data[pos]; 09084 break; 09085 case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN: 09086 if (ie_len != 1) { 09087 ast_log(LOG_WARNING, 09088 "Invalid redirecting-from subaddress odd-even indicator (%u)\n", 09089 (unsigned) ie_len); 09090 break; 09091 } 09092 redirecting->from.subaddress.odd_even_indicator = data[pos]; 09093 break; 09094 case AST_REDIRECTING_FROM_SUBADDRESS_VALID: 09095 if (ie_len != 1) { 09096 ast_log(LOG_WARNING, "Invalid redirecting-from subaddress valid (%u)\n", 09097 (unsigned) ie_len); 09098 break; 09099 } 09100 redirecting->from.subaddress.valid = data[pos]; 09101 break; 09102 /* Redirecting-from party id tag */ 09103 case AST_REDIRECTING_FROM_TAG: 09104 ast_free(redirecting->from.tag); 09105 redirecting->from.tag = ast_malloc(ie_len + 1); 09106 if (redirecting->from.tag) { 09107 memcpy(redirecting->from.tag, data + pos, ie_len); 09108 redirecting->from.tag[ie_len] = 0; 09109 } 09110 break; 09111 /* Redirecting-to party id name */ 09112 case AST_REDIRECTING_TO_NAME: 09113 ast_free(redirecting->to.name.str); 09114 redirecting->to.name.str = ast_malloc(ie_len + 1); 09115 if (redirecting->to.name.str) { 09116 memcpy(redirecting->to.name.str, data + pos, ie_len); 09117 redirecting->to.name.str[ie_len] = 0; 09118 } 09119 break; 09120 case AST_REDIRECTING_TO_NAME_CHAR_SET: 09121 if (ie_len != 1) { 09122 ast_log(LOG_WARNING, "Invalid redirecting-to name char set (%u)\n", 09123 (unsigned) ie_len); 09124 break; 09125 } 09126 redirecting->to.name.char_set = data[pos]; 09127 break; 09128 case AST_REDIRECTING_TO_NAME_PRESENTATION: 09129 if (ie_len != 1) { 09130 ast_log(LOG_WARNING, "Invalid redirecting-to name presentation (%u)\n", 09131 (unsigned) ie_len); 09132 break; 09133 } 09134 redirecting->to.name.presentation = data[pos]; 09135 break; 09136 case AST_REDIRECTING_TO_NAME_VALID: 09137 if (ie_len != 1) { 09138 ast_log(LOG_WARNING, "Invalid redirecting-to name valid (%u)\n", 09139 (unsigned) ie_len); 09140 break; 09141 } 09142 redirecting->to.name.valid = data[pos]; 09143 break; 09144 /* Redirecting-to party id number */ 09145 case AST_REDIRECTING_TO_NUMBER: 09146 ast_free(redirecting->to.number.str); 09147 redirecting->to.number.str = ast_malloc(ie_len + 1); 09148 if (redirecting->to.number.str) { 09149 memcpy(redirecting->to.number.str, data + pos, ie_len); 09150 redirecting->to.number.str[ie_len] = 0; 09151 } 09152 break; 09153 case AST_REDIRECTING_TO_NUMBER_PLAN: 09154 if (ie_len != 1) { 09155 ast_log(LOG_WARNING, "Invalid redirecting-to numbering plan (%u)\n", 09156 (unsigned) ie_len); 09157 break; 09158 } 09159 redirecting->to.number.plan = data[pos]; 09160 break; 09161 case AST_REDIRECTING_TO_NUMBER_PRESENTATION: 09162 if (ie_len != 1) { 09163 ast_log(LOG_WARNING, "Invalid redirecting-to number presentation (%u)\n", 09164 (unsigned) ie_len); 09165 break; 09166 } 09167 redirecting->to.number.presentation = data[pos]; 09168 break; 09169 case AST_REDIRECTING_TO_NUMBER_VALID: 09170 if (ie_len != 1) { 09171 ast_log(LOG_WARNING, "Invalid redirecting-to number valid (%u)\n", 09172 (unsigned) ie_len); 09173 break; 09174 } 09175 redirecting->to.number.valid = data[pos]; 09176 break; 09177 /* Redirecting-to party id combined presentation */ 09178 case AST_REDIRECTING_TO_ID_PRESENTATION: 09179 if (ie_len != 1) { 09180 ast_log(LOG_WARNING, "Invalid redirecting-to combined presentation (%u)\n", 09181 (unsigned) ie_len); 09182 break; 09183 } 09184 to_combined_presentation = data[pos]; 09185 got_to_combined_presentation = 1; 09186 break; 09187 /* Redirecting-to party id subaddress */ 09188 case AST_REDIRECTING_TO_SUBADDRESS: 09189 ast_free(redirecting->to.subaddress.str); 09190 redirecting->to.subaddress.str = ast_malloc(ie_len + 1); 09191 if (redirecting->to.subaddress.str) { 09192 memcpy(redirecting->to.subaddress.str, data + pos, ie_len); 09193 redirecting->to.subaddress.str[ie_len] = 0; 09194 } 09195 break; 09196 case AST_REDIRECTING_TO_SUBADDRESS_TYPE: 09197 if (ie_len != 1) { 09198 ast_log(LOG_WARNING, "Invalid redirecting-to type of subaddress (%u)\n", 09199 (unsigned) ie_len); 09200 break; 09201 } 09202 redirecting->to.subaddress.type = data[pos]; 09203 break; 09204 case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN: 09205 if (ie_len != 1) { 09206 ast_log(LOG_WARNING, 09207 "Invalid redirecting-to subaddress odd-even indicator (%u)\n", 09208 (unsigned) ie_len); 09209 break; 09210 } 09211 redirecting->to.subaddress.odd_even_indicator = data[pos]; 09212 break; 09213 case AST_REDIRECTING_TO_SUBADDRESS_VALID: 09214 if (ie_len != 1) { 09215 ast_log(LOG_WARNING, "Invalid redirecting-to subaddress valid (%u)\n", 09216 (unsigned) ie_len); 09217 break; 09218 } 09219 redirecting->to.subaddress.valid = data[pos]; 09220 break; 09221 /* Redirecting-to party id tag */ 09222 case AST_REDIRECTING_TO_TAG: 09223 ast_free(redirecting->to.tag); 09224 redirecting->to.tag = ast_malloc(ie_len + 1); 09225 if (redirecting->to.tag) { 09226 memcpy(redirecting->to.tag, data + pos, ie_len); 09227 redirecting->to.tag[ie_len] = 0; 09228 } 09229 break; 09230 /* Redirecting reason */ 09231 case AST_REDIRECTING_REASON: 09232 if (ie_len != sizeof(value)) { 09233 ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n", 09234 (unsigned) ie_len); 09235 break; 09236 } 09237 memcpy(&value, data + pos, sizeof(value)); 09238 redirecting->reason = ntohl(value); 09239 break; 09240 /* Redirecting count */ 09241 case AST_REDIRECTING_COUNT: 09242 if (ie_len != sizeof(value)) { 09243 ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n", 09244 (unsigned) ie_len); 09245 break; 09246 } 09247 memcpy(&value, data + pos, sizeof(value)); 09248 redirecting->count = ntohl(value); 09249 break; 09250 /* Redirecting unknown element */ 09251 default: 09252 ast_log(LOG_DEBUG, "Unknown redirecting element: %u (%u)\n", 09253 (unsigned) ie_id, (unsigned) ie_len); 09254 break; 09255 } 09256 } 09257 09258 switch (frame_version) { 09259 case 1: 09260 /* 09261 * The other end is an earlier version that we need to adjust 09262 * for compatibility. 09263 */ 09264 redirecting->from.name.valid = 1; 09265 redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 09266 redirecting->from.number.valid = 1; 09267 if (got_from_combined_presentation) { 09268 redirecting->from.name.presentation = from_combined_presentation; 09269 redirecting->from.number.presentation = from_combined_presentation; 09270 } 09271 09272 redirecting->to.name.valid = 1; 09273 redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; 09274 redirecting->to.number.valid = 1; 09275 if (got_to_combined_presentation) { 09276 redirecting->to.name.presentation = to_combined_presentation; 09277 redirecting->to.number.presentation = to_combined_presentation; 09278 } 09279 break; 09280 case 2: 09281 /* The other end is at the same level as we are. */ 09282 break; 09283 default: 09284 /* 09285 * The other end is newer than we are. 09286 * We need to assume that they are compatible with us. 09287 */ 09288 ast_log(LOG_DEBUG, "Redirecting frame has newer version: %u\n", 09289 (unsigned) frame_version); 09290 break; 09291 } 09292 09293 return 0; 09294 }
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 5544 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().
05545 { 05546 struct chanlist *chan; 05547 struct ast_channel *c; 05548 format_t capabilities; 05549 format_t fmt; 05550 int res; 05551 int foo; 05552 format_t videoformat = format & AST_FORMAT_VIDEO_MASK; 05553 format_t textformat = format & AST_FORMAT_TEXT_MASK; 05554 05555 if (!cause) 05556 cause = &foo; 05557 *cause = AST_CAUSE_NOTDEFINED; 05558 05559 if (AST_RWLIST_RDLOCK(&backends)) { 05560 ast_log(LOG_WARNING, "Unable to lock technology backend list\n"); 05561 return NULL; 05562 } 05563 05564 AST_RWLIST_TRAVERSE(&backends, chan, list) { 05565 if (strcasecmp(type, chan->tech->type)) 05566 continue; 05567 05568 capabilities = chan->tech->capabilities; 05569 fmt = format & AST_FORMAT_AUDIO_MASK; 05570 if (fmt) { 05571 /* We have audio - is it possible to connect the various calls to each other? 05572 (Avoid this check for calls without audio, like text+video calls) 05573 */ 05574 res = ast_translator_best_choice(&fmt, &capabilities); 05575 if (res < 0) { 05576 char tmp1[256], tmp2[256]; 05577 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %s) to %s\n", type, 05578 ast_getformatname_multiple(tmp1, sizeof(tmp1), chan->tech->capabilities), 05579 ast_getformatname_multiple(tmp2, sizeof(tmp2), format)); 05580 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05581 AST_RWLIST_UNLOCK(&backends); 05582 return NULL; 05583 } 05584 } 05585 AST_RWLIST_UNLOCK(&backends); 05586 if (!chan->tech->requester) 05587 return NULL; 05588 05589 if (!(c = chan->tech->requester(type, capabilities | videoformat | textformat, requestor, data, cause))) 05590 return NULL; 05591 05592 if (set_security_requirements(requestor, c)) { 05593 ast_log(LOG_WARNING, "Setting security requirements failed\n"); 05594 c = ast_channel_release(c); 05595 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05596 return NULL; 05597 } 05598 05599 /* no need to generate a Newchannel event here; it is done in the channel_alloc call */ 05600 return c; 05601 } 05602 05603 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 05604 *cause = AST_CAUSE_NOSUCHDRIVER; 05605 AST_RWLIST_UNLOCK(&backends); 05606 05607 return NULL; 05608 }
struct ast_channel* ast_request_and_dial | ( | const char * | type, | |
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 5499 of file channel.c.
References __ast_request_and_dial().
Referenced by ast_pbx_outgoing_exten(), and generic_recall().
05500 { 05501 return __ast_request_and_dial(type, format, requestor, data, timeout, outstate, cidnum, cidname, NULL); 05502 }
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 1873 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(), builtin_parkcall(), 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(), 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().
01874 { 01875 return ast_safe_sleep_conditional(chan, ms, NULL, NULL); 01876 }
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 1806 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().
01807 { 01808 struct ast_frame *f; 01809 struct ast_silence_generator *silgen = NULL; 01810 int res = 0; 01811 AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames; 01812 01813 AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames); 01814 01815 /* If no other generator is present, start silencegen while waiting */ 01816 if (ast_opt_transmit_silence && !chan->generatordata) { 01817 silgen = ast_channel_start_silence_generator(chan); 01818 } 01819 01820 while (ms > 0) { 01821 struct ast_frame *dup_f = NULL; 01822 if (cond && ((*cond)(data) == 0)) { 01823 break; 01824 } 01825 ms = ast_waitfor(chan, ms); 01826 if (ms < 0) { 01827 res = -1; 01828 break; 01829 } 01830 if (ms > 0) { 01831 f = ast_read(chan); 01832 if (!f) { 01833 res = -1; 01834 break; 01835 } 01836 01837 if (!ast_is_deferrable_frame(f)) { 01838 ast_frfree(f); 01839 continue; 01840 } 01841 01842 if ((dup_f = ast_frisolate(f))) { 01843 if (dup_f != f) { 01844 ast_frfree(f); 01845 } 01846 AST_LIST_INSERT_HEAD(&deferred_frames, dup_f, frame_list); 01847 } 01848 } 01849 } 01850 01851 /* stop silgen if present */ 01852 if (silgen) { 01853 ast_channel_stop_silence_generator(chan, silgen); 01854 } 01855 01856 /* We need to free all the deferred frames, but we only need to 01857 * queue the deferred frames if there was no error and no 01858 * hangup was received 01859 */ 01860 ast_channel_lock(chan); 01861 while ((f = AST_LIST_REMOVE_HEAD(&deferred_frames, frame_list))) { 01862 if (!res) { 01863 ast_queue_frame_head(chan, f); 01864 } 01865 ast_frfree(f); 01866 } 01867 ast_channel_unlock(chan); 01868 01869 return res; 01870 }
int ast_say_character_str | ( | struct ast_channel * | chan, | |
const char * | str, | |||
const char * | ints, | |||
const char * | lang | |||
) |
Definition at line 8125 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().
08127 { 08128 return ast_say_character_str_full(chan, str, ints, lang, -1, -1); 08129 }
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 8119 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().
08121 { 08122 return ast_say_digit_str_full(chan, str, ints, lang, -1, -1); 08123 }
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 8113 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().
08115 { 08116 return ast_say_digits_full(chan, num, ints, lang, -1, -1); 08117 }
int ast_say_digits_full | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | ints, | |||
const char * | lang, | |||
int | audiofd, | |||
int | ctrlfd | |||
) |
Definition at line 8137 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().
08139 { 08140 char buf[256]; 08141 08142 snprintf(buf, sizeof(buf), "%d", num); 08143 08144 return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd); 08145 }
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 8107 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().
08109 { 08110 return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1); 08111 }
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 8101 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().
08103 { 08104 return ast_say_number_full(chan, num, ints, language, options, -1, -1); 08105 }
int ast_say_phonetic_str | ( | struct ast_channel * | chan, | |
const char * | str, | |||
const char * | ints, | |||
const char * | lang | |||
) |
Definition at line 8131 of file channel.c.
References ast_say_phonetic_str_full.
Referenced by pbx_builtin_sayphonetic().
08133 { 08134 return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1); 08135 }
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 4625 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().
04626 { 04627 if (chan->tech->send_digit_begin) { 04628 ast_senddigit_begin(chan, digit); 04629 ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 04630 } 04631 04632 return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 04633 }
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 4567 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().
04568 { 04569 /* Device does not support DTMF tones, lets fake 04570 * it by doing our own generation. */ 04571 static const char * const dtmf_tones[] = { 04572 "941+1336", /* 0 */ 04573 "697+1209", /* 1 */ 04574 "697+1336", /* 2 */ 04575 "697+1477", /* 3 */ 04576 "770+1209", /* 4 */ 04577 "770+1336", /* 5 */ 04578 "770+1477", /* 6 */ 04579 "852+1209", /* 7 */ 04580 "852+1336", /* 8 */ 04581 "852+1477", /* 9 */ 04582 "697+1633", /* A */ 04583 "770+1633", /* B */ 04584 "852+1633", /* C */ 04585 "941+1633", /* D */ 04586 "941+1209", /* * */ 04587 "941+1477" /* # */ 04588 }; 04589 04590 if (!chan->tech->send_digit_begin) 04591 return 0; 04592 04593 if (!chan->tech->send_digit_begin(chan, digit)) 04594 return 0; 04595 04596 if (digit >= '0' && digit <='9') 04597 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0); 04598 else if (digit >= 'A' && digit <= 'D') 04599 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0); 04600 else if (digit == '*') 04601 ast_playtones_start(chan, 0, dtmf_tones[14], 0); 04602 else if (digit == '#') 04603 ast_playtones_start(chan, 0, dtmf_tones[15], 0); 04604 else { 04605 /* not handled */ 04606 ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name); 04607 } 04608 04609 return 0; 04610 }
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 4612 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().
04613 { 04614 int res = -1; 04615 04616 if (chan->tech->send_digit_end) 04617 res = chan->tech->send_digit_end(chan, digit, duration); 04618 04619 if (res && chan->generator) 04620 ast_playtones_stop(chan); 04621 04622 return 0; 04623 }
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 4549 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_test_flag, chanlist::chan, CHECK_BLOCKING, ast_channel_tech::send_text, and ast_channel::tech.
Referenced by action_sendtext(), agent_sendtext(), handle_sendtext(), send_newkey(), and sendtext_exec().
04550 { 04551 int res = 0; 04552 04553 ast_channel_lock(chan); 04554 /* Stop if we're a zombie or need a soft hangup */ 04555 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 04556 ast_channel_unlock(chan); 04557 return -1; 04558 } 04559 CHECK_BLOCKING(chan); 04560 if (chan->tech->send_text) 04561 res = chan->tech->send_text(chan, text); 04562 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04563 ast_channel_unlock(chan); 04564 return res; 04565 }
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 6811 of file channel.c.
References ast_party_caller::ani, ast_cdr_setcid(), ast_channel_lock, ast_channel_unlock, ast_free, ast_strdup, ast_channel::caller, ast_channel::cdr, chanlist::chan, ast_party_caller::id, ast_party_id::name, ast_party_id::number, report_new_callerid(), ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.
Referenced by __analog_ss_thread(), __ast_request_and_dial(), analog_ss_thread(), cb_events(), get_pai(), get_rpid(), handle_setcallerid(), mgcp_ss(), ring_entry(), rpt_exec(), skinny_newcall(), and socket_process().
06812 { 06813 ast_channel_lock(chan); 06814 06815 if (cid_num) { 06816 chan->caller.id.number.valid = 1; 06817 ast_free(chan->caller.id.number.str); 06818 chan->caller.id.number.str = ast_strdup(cid_num); 06819 } 06820 if (cid_name) { 06821 chan->caller.id.name.valid = 1; 06822 ast_free(chan->caller.id.name.str); 06823 chan->caller.id.name.str = ast_strdup(cid_name); 06824 } 06825 if (cid_ani) { 06826 chan->caller.ani.number.valid = 1; 06827 ast_free(chan->caller.ani.number.str); 06828 chan->caller.ani.number.str = ast_strdup(cid_ani); 06829 } 06830 if (chan->cdr) { 06831 ast_cdr_setcid(chan->cdr, chan); 06832 } 06833 06834 report_new_callerid(chan); 06835 06836 ast_channel_unlock(chan); 06837 }
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 2714 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().
02715 { 02716 struct ast_channel *bridge; 02717 02718 ast_channel_lock(chan); 02719 if (force || ast_strlen_zero(chan->hangupsource)) { 02720 ast_string_field_set(chan, hangupsource, source); 02721 } 02722 bridge = ast_bridged_channel(chan); 02723 ast_channel_unlock(chan); 02724 02725 if (bridge && (force || ast_strlen_zero(bridge->hangupsource))) { 02726 ast_channel_lock(bridge); 02727 ast_string_field_set(chan, hangupsource, source); 02728 ast_channel_unlock(bridge); 02729 } 02730 }
static void ast_set_owners_and_peers | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 6275 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().
06277 { 06278 if (!ast_strlen_zero(chan1->accountcode) && ast_strlen_zero(chan2->peeraccount)) { 06279 ast_log(LOG_DEBUG, "setting peeraccount to %s for %s from data on channel %s\n", 06280 chan1->accountcode, chan2->name, chan1->name); 06281 ast_string_field_set(chan2, peeraccount, chan1->accountcode); 06282 } 06283 if (!ast_strlen_zero(chan2->accountcode) && ast_strlen_zero(chan1->peeraccount)) { 06284 ast_log(LOG_DEBUG, "setting peeraccount to %s for %s from data on channel %s\n", 06285 chan2->accountcode, chan1->name, chan2->name); 06286 ast_string_field_set(chan1, peeraccount, chan2->accountcode); 06287 } 06288 if (!ast_strlen_zero(chan1->peeraccount) && ast_strlen_zero(chan2->accountcode)) { 06289 ast_log(LOG_DEBUG, "setting accountcode to %s for %s from data on channel %s\n", 06290 chan1->peeraccount, chan2->name, chan1->name); 06291 ast_string_field_set(chan2, accountcode, chan1->peeraccount); 06292 } 06293 if (!ast_strlen_zero(chan2->peeraccount) && ast_strlen_zero(chan1->accountcode)) { 06294 ast_log(LOG_DEBUG, "setting accountcode to %s for %s from data on channel %s\n", 06295 chan2->peeraccount, chan1->name, chan2->name); 06296 ast_string_field_set(chan1, accountcode, chan2->peeraccount); 06297 } 06298 if (0 != strcmp(chan1->accountcode, chan2->peeraccount)) { 06299 ast_log(LOG_DEBUG, "changing peeraccount from %s to %s on %s to match channel %s\n", 06300 chan2->peeraccount, chan1->peeraccount, chan2->name, chan1->name); 06301 ast_string_field_set(chan2, peeraccount, chan1->accountcode); 06302 } 06303 if (0 != strcmp(chan2->accountcode, chan1->peeraccount)) { 06304 ast_log(LOG_DEBUG, "changing peeraccount from %s to %s on %s to match channel %s\n", 06305 chan1->peeraccount, chan2->peeraccount, chan1->name, chan2->name); 06306 ast_string_field_set(chan1, peeraccount, chan2->accountcode); 06307 } 06308 }
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 5151 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().
05152 { 05153 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat, 05154 &chan->readtrans, 0); 05155 }
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 7988 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().
07989 { 07990 struct ast_variable *cur; 07991 07992 for (cur = vars; cur; cur = cur->next) 07993 pbx_builtin_setvar_helper(chan, cur->name, cur->value); 07994 }
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 5157 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(), ast_write(), 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().
05158 { 05159 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat, 05160 &chan->writetrans, 1); 05161 }
int ast_setstate | ( | struct ast_channel * | chan, | |
enum ast_channel_state | state | |||
) |
Change the state of a channel.
Definition at line 6879 of file channel.c.
References ast_channel::_state, AST_CHANNEL_NAME, ast_copy_string(), AST_DEVICE_UNKNOWN, ast_devstate_changed_literal(), ast_manager_event, ast_state2str(), ast_channel::caller, chanlist::chan, ast_channel::connected, EVENT_FLAG_CALL, ast_party_connected_line::id, ast_party_caller::id, ast_party_id::name, ast_channel::name, name, ast_party_id::number, S_COR, ast_party_name::str, ast_party_number::str, ast_channel::uniqueid, ast_party_name::valid, and ast_party_number::valid.
Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_read(), __dahdi_exception(), __oh323_update_info(), agent_call(), alsa_answer(), analog_answer(), analog_call(), analog_exception(), analog_ss_thread(), ast_raw_answer(), cb_events(), check_availability(), console_answer(), dahdi_answer(), dahdi_call(), dahdi_handle_event(), dahdi_indicate(), dahdi_read(), do_bridge_masquerade(), gtalk_call(), gtalk_newcall(), handle_invite_replaces(), handle_offhook_message(), handle_request_invite(), handle_response_invite(), handle_soft_key_event_message(), handle_stimulus_message(), iax2_call(), jingle_call(), jingle_newcall(), local_queue_frame(), mgcp_answer(), mgcp_call(), mgcp_ss(), misdn_call(), misdn_indication(), my_set_waitingfordt(), nbs_call(), nbs_hangup(), oh323_answer(), oss_answer(), pbx_builtin_busy(), pbx_builtin_congestion(), phone_answer(), phone_call(), phone_exception(), phone_hangup(), phone_write(), pri_ss_thread(), release_chan(), release_chan_early(), sig_pri_answer(), sig_pri_call(), sig_pri_indicate(), 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().
06880 { 06881 int oldstate = chan->_state; 06882 char name[AST_CHANNEL_NAME], *dashptr; 06883 06884 if (oldstate == state) 06885 return 0; 06886 06887 ast_copy_string(name, chan->name, sizeof(name)); 06888 if ((dashptr = strrchr(name, '-'))) { 06889 *dashptr = '\0'; 06890 } 06891 06892 chan->_state = state; 06893 06894 /* We have to pass AST_DEVICE_UNKNOWN here because it is entirely possible that the channel driver 06895 * for this channel is using the callback method for device state. If we pass in an actual state here 06896 * we override what they are saying the state is and things go amuck. */ 06897 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, name); 06898 06899 /* setstate used to conditionally report Newchannel; this is no more */ 06900 ast_manager_event(chan, EVENT_FLAG_CALL, "Newstate", 06901 "Channel: %s\r\n" 06902 "ChannelState: %d\r\n" 06903 "ChannelStateDesc: %s\r\n" 06904 "CallerIDNum: %s\r\n" 06905 "CallerIDName: %s\r\n" 06906 "ConnectedLineNum: %s\r\n" 06907 "ConnectedLineName: %s\r\n" 06908 "Uniqueid: %s\r\n", 06909 chan->name, chan->_state, ast_state2str(chan->_state), 06910 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""), 06911 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""), 06912 S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, ""), 06913 S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, ""), 06914 chan->uniqueid); 06915 06916 return 0; 06917 }
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 3479 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_debug, ast_timer_get_max_rate(), ast_timer_set_rate(), ast_channel::timer, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.
Referenced by ast_activate_generator(), ast_deactivate_generator(), ast_read_generator_actions(), ast_readaudio_callback(), and filestream_close().
03480 { 03481 int res; 03482 unsigned int real_rate = rate, max_rate; 03483 03484 ast_channel_lock(c); 03485 03486 if (c->timingfd == -1) { 03487 ast_channel_unlock(c); 03488 return -1; 03489 } 03490 03491 if (!func) { 03492 rate = 0; 03493 data = NULL; 03494 } 03495 03496 if (rate && rate > (max_rate = ast_timer_get_max_rate(c->timer))) { 03497 real_rate = max_rate; 03498 } 03499 03500 ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate); 03501 03502 res = ast_timer_set_rate(c->timer, real_rate); 03503 03504 c->timingfunc = func; 03505 c->timingdata = data; 03506 03507 ast_channel_unlock(c); 03508 03509 return res; 03510 }
int ast_shutting_down | ( | void | ) |
Returns non-zero if Asterisk is being shut down.
Definition at line 844 of file channel.c.
Referenced by handle_request_options().
00845 { 00846 return shutting_down; 00847 }
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 2691 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_softhangup_nolock(), and chanlist::chan.
Referenced by __analog_handle_event(), __ast_module_user_hangup_all(), __unload_module(), agent_hangup(), agent_logoff(), agent_read(), ast_bridge_call(), ast_channel_softhangup_cb(), ast_dial_join(), 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().
02692 { 02693 int res; 02694 02695 ast_channel_lock(chan); 02696 res = ast_softhangup_nolock(chan, cause); 02697 ast_channel_unlock(chan); 02698 02699 return res; 02700 }
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 2678 of file channel.c.
References ast_channel::_softhangup, ast_debug, AST_FLAG_BLOCKING, ast_null_frame, ast_queue_frame(), ast_test_flag, ast_channel::blocker, chanlist::chan, and ast_channel::name.
Referenced by __analog_handle_event(), action_hangup(), ast_async_goto(), ast_softhangup(), attempt_transfer(), check_pendings(), check_rtp_timeout(), dahdi_softhangup_all(), oh323_indicate(), proc_session_timer(), sig_pri_indicate(), sig_pri_send_aoce_termination_request(), sip_indicate(), and skinny_indicate().
02679 { 02680 ast_debug(1, "Soft-Hanging up channel '%s'\n", chan->name); 02681 /* Inform channel driver that we need to be hung up, if it cares */ 02682 chan->_softhangup |= cause; 02683 ast_queue_frame(chan, &ast_null_frame); 02684 /* Interrupt any poll call or such */ 02685 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) 02686 pthread_kill(chan->blocker, SIGURG); 02687 return 0; 02688 }
const char* ast_state2str | ( | enum ast_channel_state | state | ) |
Gives the string form of a given channel state.
Definition at line 986 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().
00987 { 00988 char *buf; 00989 00990 switch (state) { 00991 case AST_STATE_DOWN: 00992 return "Down"; 00993 case AST_STATE_RESERVED: 00994 return "Rsrvd"; 00995 case AST_STATE_OFFHOOK: 00996 return "OffHook"; 00997 case AST_STATE_DIALING: 00998 return "Dialing"; 00999 case AST_STATE_RING: 01000 return "Ring"; 01001 case AST_STATE_RINGING: 01002 return "Ringing"; 01003 case AST_STATE_UP: 01004 return "Up"; 01005 case AST_STATE_BUSY: 01006 return "Busy"; 01007 case AST_STATE_DIALING_OFFHOOK: 01008 return "Dialing Offhook"; 01009 case AST_STATE_PRERING: 01010 return "Pre-ring"; 01011 default: 01012 if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE))) 01013 return "Unknown"; 01014 snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state); 01015 return buf; 01016 } 01017 }
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 972 of file channel.c.
References ARRAY_LEN, and causes.
Referenced by pbx_builtin_hangup().
00973 { 00974 int x; 00975 00976 for (x = 0; x < ARRAY_LEN(causes); x++) 00977 if (!strncasecmp(causes[x].name, name, strlen(causes[x].name))) 00978 return causes[x].cause; 00979 00980 return -1; 00981 }
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 7708 of file channel.c.
References ast_frfree, ast_read(), ast_tonepair_start(), ast_waitfor(), f, and ast_channel::generatordata.
Referenced by zapateller_exec().
07709 { 07710 int res; 07711 07712 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 07713 return res; 07714 07715 /* Give us some wiggle room */ 07716 while (chan->generatordata && ast_waitfor(chan, 100) >= 0) { 07717 struct ast_frame *f = ast_read(chan); 07718 if (f) 07719 ast_frfree(f); 07720 else 07721 return -1; 07722 } 07723 return 0; 07724 }
int ast_tonepair_start | ( | struct ast_channel * | chan, | |
int | freq1, | |||
int | freq2, | |||
int | duration, | |||
int | vol | |||
) |
Start a tone going
Definition at line 7690 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().
07691 { 07692 struct tonepair_def d = { 0, }; 07693 07694 d.freq1 = freq1; 07695 d.freq2 = freq2; 07696 d.duration = duration; 07697 d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */ 07698 if (ast_activate_generator(chan, &tonepair, &d)) 07699 return -1; 07700 return 0; 07701 }
void ast_tonepair_stop | ( | struct ast_channel * | chan | ) |
Stop a tone from playing
Definition at line 7703 of file channel.c.
References ast_deactivate_generator().
Referenced by sendnoise().
07704 { 07705 ast_deactivate_generator(chan); 07706 }
int ast_transfer | ( | struct ast_channel * | chan, | |
char * | dest | |||
) |
Transfer a channel (if supported).
Called by:
Definition at line 5637 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_CONTROL_TRANSFER, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, ast_frfree, ast_read(), ast_test_flag, AST_TRANSFER_SUCCESS, ast_waitfor(), chanlist::chan, ast_channel::tech, and ast_channel_tech::transfer.
Referenced by transfer_exec().
05638 { 05639 int res = -1; 05640 05641 /* Stop if we're a zombie or need a soft hangup */ 05642 ast_channel_lock(chan); 05643 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 05644 if (chan->tech->transfer) { 05645 res = chan->tech->transfer(chan, dest); 05646 if (!res) 05647 res = 1; 05648 } else 05649 res = 0; 05650 } 05651 ast_channel_unlock(chan); 05652 05653 if (res <= 0) { 05654 return res; 05655 } 05656 05657 for (;;) { 05658 struct ast_frame *fr; 05659 05660 res = ast_waitfor(chan, -1); 05661 05662 if (res < 0 || !(fr = ast_read(chan))) { 05663 res = -1; 05664 break; 05665 } 05666 05667 if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_TRANSFER) { 05668 enum ast_control_transfer *message = fr->data.ptr; 05669 05670 if (*message == AST_TRANSFER_SUCCESS) { 05671 res = 1; 05672 } else { 05673 res = -1; 05674 } 05675 05676 ast_frfree(fr); 05677 break; 05678 } 05679 05680 ast_frfree(fr); 05681 } 05682 05683 return res; 05684 }
char* ast_transfercapability2str | ( | int | transfercapability | ) | const |
Gives the string form of a given transfer capability.
transfercapability | transfer capability to get the name of |
Definition at line 1020 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().
01021 { 01022 switch (transfercapability) { 01023 case AST_TRANS_CAP_SPEECH: 01024 return "SPEECH"; 01025 case AST_TRANS_CAP_DIGITAL: 01026 return "DIGITAL"; 01027 case AST_TRANS_CAP_RESTRICTED_DIGITAL: 01028 return "RESTRICTED_DIGITAL"; 01029 case AST_TRANS_CAP_3_1K_AUDIO: 01030 return "3K1AUDIO"; 01031 case AST_TRANS_CAP_DIGITAL_W_TONES: 01032 return "DIGITAL_W_TONES"; 01033 case AST_TRANS_CAP_VIDEO: 01034 return "VIDEO"; 01035 default: 01036 return "UNKNOWN"; 01037 } 01038 }
void ast_uninstall_music_functions | ( | void | ) |
Definition at line 7771 of file channel.c.
References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.
Referenced by unload_module().
07772 { 07773 ast_moh_start_ptr = NULL; 07774 ast_moh_stop_ptr = NULL; 07775 ast_moh_cleanup_ptr = NULL; 07776 }
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 3463 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().
03464 { 03465 int oldms = ms; /* -1 if no timeout */ 03466 03467 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms); 03468 if ((ms < 0) && (oldms < 0)) 03469 ms = 0; 03470 return ms; 03471 }
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 3458 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().
03459 { 03460 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 03461 }
int ast_waitfor_n_fd | ( | int * | fds, | |
int | n, | |||
int * | ms, | |||
int * | exception | |||
) |
Waits for input on an fd.
Definition at line 3099 of file channel.c.
References ast_waitfor_nandfds().
Referenced by dundi_lookup_internal(), dundi_precache_internal(), and softmix_bridge_thread().
03100 { 03101 int winner = -1; 03102 ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms); 03103 return winner; 03104 }
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 3111 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().
03114 { 03115 struct timeval start = { 0 , 0 }; 03116 struct pollfd *pfds = NULL; 03117 int res; 03118 long rms; 03119 int x, y, max; 03120 int sz; 03121 struct timeval now = { 0, 0 }; 03122 struct timeval whentohangup = { 0, 0 }, diff; 03123 struct ast_channel *winner = NULL; 03124 struct fdmap { 03125 int chan; 03126 int fdno; 03127 } *fdmap = NULL; 03128 03129 if ((sz = n * AST_MAX_FDS + nfds)) { 03130 pfds = alloca(sizeof(*pfds) * sz); 03131 fdmap = alloca(sizeof(*fdmap) * sz); 03132 } 03133 03134 if (outfd) 03135 *outfd = -99999; 03136 if (exception) 03137 *exception = 0; 03138 03139 /* Perform any pending masquerades */ 03140 for (x = 0; x < n; x++) { 03141 if (c[x]->masq && ast_do_masquerade(c[x])) { 03142 ast_log(LOG_WARNING, "Masquerade failed\n"); 03143 *ms = -1; 03144 return NULL; 03145 } 03146 03147 ast_channel_lock(c[x]); 03148 if (!ast_tvzero(c[x]->whentohangup)) { 03149 if (ast_tvzero(whentohangup)) 03150 now = ast_tvnow(); 03151 diff = ast_tvsub(c[x]->whentohangup, now); 03152 if (diff.tv_sec < 0 || ast_tvzero(diff)) { 03153 /* Should already be hungup */ 03154 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 03155 ast_channel_unlock(c[x]); 03156 return c[x]; 03157 } 03158 if (ast_tvzero(whentohangup) || ast_tvcmp(diff, whentohangup) < 0) 03159 whentohangup = diff; 03160 } 03161 ast_channel_unlock(c[x]); 03162 } 03163 /* Wait full interval */ 03164 rms = *ms; 03165 /* INT_MAX, not LONG_MAX, because it matters on 64-bit */ 03166 if (!ast_tvzero(whentohangup) && whentohangup.tv_sec < INT_MAX / 1000) { 03167 rms = whentohangup.tv_sec * 1000 + whentohangup.tv_usec / 1000; /* timeout in milliseconds */ 03168 if (*ms >= 0 && *ms < rms) { /* original *ms still smaller */ 03169 rms = *ms; 03170 } 03171 } else if (!ast_tvzero(whentohangup) && rms < 0) { 03172 /* Tiny corner case... call would need to last >24 days */ 03173 rms = INT_MAX; 03174 } 03175 /* 03176 * Build the pollfd array, putting the channels' fds first, 03177 * followed by individual fds. Order is important because 03178 * individual fd's must have priority over channel fds. 03179 */ 03180 max = 0; 03181 for (x = 0; x < n; x++) { 03182 for (y = 0; y < AST_MAX_FDS; y++) { 03183 fdmap[max].fdno = y; /* fd y is linked to this pfds */ 03184 fdmap[max].chan = x; /* channel x is linked to this pfds */ 03185 max += ast_add_fd(&pfds[max], c[x]->fds[y]); 03186 } 03187 CHECK_BLOCKING(c[x]); 03188 } 03189 /* Add the individual fds */ 03190 for (x = 0; x < nfds; x++) { 03191 fdmap[max].chan = -1; 03192 max += ast_add_fd(&pfds[max], fds[x]); 03193 } 03194 03195 if (*ms > 0) 03196 start = ast_tvnow(); 03197 03198 if (sizeof(int) == 4) { /* XXX fix timeout > 600000 on linux x86-32 */ 03199 do { 03200 int kbrms = rms; 03201 if (kbrms > 600000) 03202 kbrms = 600000; 03203 res = ast_poll(pfds, max, kbrms); 03204 if (!res) 03205 rms -= kbrms; 03206 } while (!res && (rms > 0)); 03207 } else { 03208 res = ast_poll(pfds, max, rms); 03209 } 03210 for (x = 0; x < n; x++) 03211 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 03212 if (res < 0) { /* Simulate a timeout if we were interrupted */ 03213 if (errno != EINTR) 03214 *ms = -1; 03215 return NULL; 03216 } 03217 if (!ast_tvzero(whentohangup)) { /* if we have a timeout, check who expired */ 03218 now = ast_tvnow(); 03219 for (x = 0; x < n; x++) { 03220 if (!ast_tvzero(c[x]->whentohangup) && ast_tvcmp(c[x]->whentohangup, now) <= 0) { 03221 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 03222 if (winner == NULL) 03223 winner = c[x]; 03224 } 03225 } 03226 } 03227 if (res == 0) { /* no fd ready, reset timeout and done */ 03228 *ms = 0; /* XXX use 0 since we may not have an exact timeout. */ 03229 return winner; 03230 } 03231 /* 03232 * Then check if any channel or fd has a pending event. 03233 * Remember to check channels first and fds last, as they 03234 * must have priority on setting 'winner' 03235 */ 03236 for (x = 0; x < max; x++) { 03237 res = pfds[x].revents; 03238 if (res == 0) 03239 continue; 03240 if (fdmap[x].chan >= 0) { /* this is a channel */ 03241 winner = c[fdmap[x].chan]; /* override previous winners */ 03242 if (res & POLLPRI) 03243 ast_set_flag(winner, AST_FLAG_EXCEPTION); 03244 else 03245 ast_clear_flag(winner, AST_FLAG_EXCEPTION); 03246 winner->fdno = fdmap[x].fdno; 03247 } else { /* this is an fd */ 03248 if (outfd) 03249 *outfd = pfds[x].fd; 03250 if (exception) 03251 *exception = (res & POLLPRI) ? -1 : 0; 03252 winner = NULL; 03253 } 03254 } 03255 if (*ms > 0) { 03256 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 03257 if (*ms < 0) 03258 *ms = 0; 03259 } 03260 return winner; 03261 }
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 3474 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().
03475 { 03476 return ast_waitfordigit_full(c, ms, -1, -1); 03477 }
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 3512 of file channel.c.
References ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UPDATE_RTP_PEER, AST_FLAG_END_DTMF_ONLY, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_set_flag, ast_test_flag, ast_waitfor_nandfds(), errno, f, and LOG_WARNING.
Referenced by ast_readstring_full(), ast_waitfordigit(), handle_getoption(), and handle_waitfordigit().
03513 { 03514 /* Stop if we're a zombie or need a soft hangup */ 03515 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 03516 return -1; 03517 03518 /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */ 03519 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY); 03520 03521 /* Wait for a digit, no more than ms milliseconds total. */ 03522 03523 while (ms) { 03524 struct ast_channel *rchan; 03525 int outfd=-1; 03526 03527 errno = 0; 03528 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 03529 03530 if (!rchan && outfd < 0 && ms) { 03531 if (errno == 0 || errno == EINTR) 03532 continue; 03533 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 03534 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03535 return -1; 03536 } else if (outfd > -1) { 03537 /* The FD we were watching has something waiting */ 03538 ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n"); 03539 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03540 return 1; 03541 } else if (rchan) { 03542 int res; 03543 struct ast_frame *f = ast_read(c); 03544 if (!f) 03545 return -1; 03546 03547 switch (f->frametype) { 03548 case AST_FRAME_DTMF_BEGIN: 03549 break; 03550 case AST_FRAME_DTMF_END: 03551 res = f->subclass.integer; 03552 ast_frfree(f); 03553 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03554 return res; 03555 case AST_FRAME_CONTROL: 03556 switch (f->subclass.integer) { 03557 case AST_CONTROL_HANGUP: 03558 ast_frfree(f); 03559 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03560 return -1; 03561 case AST_CONTROL_RINGING: 03562 case AST_CONTROL_ANSWER: 03563 case AST_CONTROL_SRCUPDATE: 03564 case AST_CONTROL_SRCCHANGE: 03565 case AST_CONTROL_CONNECTED_LINE: 03566 case AST_CONTROL_REDIRECTING: 03567 case AST_CONTROL_UPDATE_RTP_PEER: 03568 case -1: 03569 /* Unimportant */ 03570 break; 03571 default: 03572 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass.integer); 03573 break; 03574 } 03575 break; 03576 case AST_FRAME_VOICE: 03577 /* Write audio if appropriate */ 03578 if (audiofd > -1) { 03579 if (write(audiofd, f->data.ptr, f->datalen) < 0) { 03580 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 03581 } 03582 } 03583 default: 03584 /* Ignore */ 03585 break; 03586 } 03587 ast_frfree(f); 03588 } 03589 } 03590 03591 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 03592 03593 return 0; /* Time is up */ 03594 }
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 4767 of file channel.c.
References ast_channel::_softhangup, apply_plc(), ast_audiohook_detach_list(), AST_AUDIOHOOK_DIRECTION_WRITE, ast_audiohook_write_list(), ast_audiohook_write_list_empty(), ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_UNHOLD, ast_deactivate_generator(), ast_debug, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_WRITE_INT, AST_FLAG_ZOMBIE, AST_FORMAT_AUDIO_MASK, ast_format_rate(), AST_FORMAT_SLINEAR, AST_FORMAT_T140, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_frame_dump(), AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_framehook_list_write_event(), ast_frfree, ast_frisolate(), ast_getformatname(), ast_getformatname_multiple(), AST_LIST_NEXT, ast_log(), AST_MONITOR_RUNNING, ast_opt_generic_plc, ast_seekstream(), ast_senddigit_begin(), ast_senddigit_end(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_translate(), ast_writestream(), ast_channel::audiohooks, calc_monitor_jump(), chanlist::chan, CHECK_BLOCKING, ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, DEBUGCHAN_FLAG, f, ast_filestream::fmt, ast_format::format, ast_channel::fout, FRAMECOUNT_INC, ast_channel::framehooks, ast_frame::frametype, ast_channel::generatordata, ast_channel_tech::indicate, ast_channel::insmpl, ast_frame_subclass::integer, ast_frame::len, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, chanlist::next, ast_channel::outsmpl, ast_frame::ptr, ast_channel::rawwriteformat, ast_channel_monitor::read_stream, ast_frame::samples, SEEK_FORCECUR, send_dtmf_event(), ast_channel_tech::send_html, ast_channel_tech::send_text, ast_frame::src, ast_channel_monitor::state, ast_frame::subclass, ast_channel::tech, ast_channel_tech::write, ast_channel_monitor::write_stream, ast_channel_tech::write_text, ast_channel_tech::write_video, ast_channel::writeformat, and ast_channel::writetrans.
Referenced by adsi_careful_send(), agent_write(), ast_bridge_call(), ast_prod(), ast_readaudio_callback(), ast_readvideo_callback(), ast_udptl_bridge(), ast_write_video(), conf_queue_dtmf(), conf_run(), dahdi_bridge(), dictate_exec(), echo_exec(), fax_generator_generate(), feature_request_and_dial(), 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().
04768 { 04769 int res = -1; 04770 struct ast_frame *f = NULL; 04771 int count = 0; 04772 04773 /*Deadlock avoidance*/ 04774 while(ast_channel_trylock(chan)) { 04775 /*cannot goto done since the channel is not locked*/ 04776 if(count++ > 10) { 04777 ast_debug(1, "Deadlock avoided for write to channel '%s'\n", chan->name); 04778 return 0; 04779 } 04780 usleep(1); 04781 } 04782 /* Stop if we're a zombie or need a soft hangup */ 04783 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 04784 goto done; 04785 04786 /* Handle any pending masquerades */ 04787 if (chan->masq) { 04788 ast_channel_unlock(chan); 04789 if (ast_do_masquerade(chan)) { 04790 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 04791 return res; /* no need to goto done: chan is already unlocked for masq */ 04792 } 04793 ast_channel_lock(chan); 04794 } 04795 if (chan->masqr) { 04796 res = 0; /* XXX explain, why 0 ? */ 04797 goto done; 04798 } 04799 04800 /* Perform the framehook write event here. After the frame enters the framehook list 04801 * there is no telling what will happen, how awesome is that!!! */ 04802 if (!(fr = ast_framehook_list_write_event(chan->framehooks, fr))) { 04803 res = 0; 04804 goto done; 04805 } 04806 04807 if (chan->generatordata && (!fr->src || strcasecmp(fr->src, "ast_prod"))) { 04808 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) { 04809 ast_deactivate_generator(chan); 04810 } else { 04811 if (fr->frametype == AST_FRAME_DTMF_END) { 04812 /* There is a generator running while we're in the middle of a digit. 04813 * It's probably inband DTMF, so go ahead and pass it so it can 04814 * stop the generator */ 04815 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04816 ast_channel_unlock(chan); 04817 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len); 04818 ast_channel_lock(chan); 04819 CHECK_BLOCKING(chan); 04820 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass.integer == AST_CONTROL_UNHOLD) { 04821 /* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */ 04822 res = (chan->tech->indicate == NULL) ? 0 : 04823 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen); 04824 } 04825 res = 0; /* XXX explain, why 0 ? */ 04826 goto done; 04827 } 04828 } 04829 /* High bit prints debugging */ 04830 if (chan->fout & DEBUGCHAN_FLAG) 04831 ast_frame_dump(chan->name, fr, ">>"); 04832 CHECK_BLOCKING(chan); 04833 switch (fr->frametype) { 04834 case AST_FRAME_CONTROL: 04835 res = (chan->tech->indicate == NULL) ? 0 : 04836 chan->tech->indicate(chan, fr->subclass.integer, fr->data.ptr, fr->datalen); 04837 break; 04838 case AST_FRAME_DTMF_BEGIN: 04839 if (chan->audiohooks) { 04840 struct ast_frame *old_frame = fr; 04841 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 04842 if (old_frame != fr) 04843 f = fr; 04844 } 04845 send_dtmf_event(chan, "Sent", fr->subclass.integer, "Yes", "No"); 04846 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04847 ast_channel_unlock(chan); 04848 res = ast_senddigit_begin(chan, fr->subclass.integer); 04849 ast_channel_lock(chan); 04850 CHECK_BLOCKING(chan); 04851 break; 04852 case AST_FRAME_DTMF_END: 04853 if (chan->audiohooks) { 04854 struct ast_frame *new_frame = fr; 04855 04856 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 04857 if (new_frame != fr) { 04858 ast_frfree(new_frame); 04859 } 04860 } 04861 send_dtmf_event(chan, "Sent", fr->subclass.integer, "No", "Yes"); 04862 ast_clear_flag(chan, AST_FLAG_BLOCKING); 04863 ast_channel_unlock(chan); 04864 res = ast_senddigit_end(chan, fr->subclass.integer, fr->len); 04865 ast_channel_lock(chan); 04866 CHECK_BLOCKING(chan); 04867 break; 04868 case AST_FRAME_TEXT: 04869 if (fr->subclass.integer == AST_FORMAT_T140) { 04870 res = (chan->tech->write_text == NULL) ? 0 : 04871 chan->tech->write_text(chan, fr); 04872 } else { 04873 res = (chan->tech->send_text == NULL) ? 0 : 04874 chan->tech->send_text(chan, (char *) fr->data.ptr); 04875 } 04876 break; 04877 case AST_FRAME_HTML: 04878 res = (chan->tech->send_html == NULL) ? 0 : 04879 chan->tech->send_html(chan, fr->subclass.integer, (char *) fr->data.ptr, fr->datalen); 04880 break; 04881 case AST_FRAME_VIDEO: 04882 /* XXX Handle translation of video codecs one day XXX */ 04883 res = (chan->tech->write_video == NULL) ? 0 : 04884 chan->tech->write_video(chan, fr); 04885 break; 04886 case AST_FRAME_MODEM: 04887 res = (chan->tech->write == NULL) ? 0 : 04888 chan->tech->write(chan, fr); 04889 break; 04890 case AST_FRAME_VOICE: 04891 if (chan->tech->write == NULL) 04892 break; /*! \todo XXX should return 0 maybe ? */ 04893 04894 if (ast_opt_generic_plc && fr->subclass.codec == AST_FORMAT_SLINEAR) { 04895 apply_plc(chan, fr); 04896 } 04897 04898 /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */ 04899 if (fr->subclass.codec == chan->rawwriteformat) { 04900 f = fr; 04901 } else { 04902 /* XXX Something is not right we are not compatible with this frame bad things can happen 04903 * problems range from no/one-way audio to unexplained line hangups as a last resort try adjust the format 04904 * ideally we do not want to do this and this indicates a deeper problem for now we log these events to 04905 * eliminate user impact and help identify the problem areas 04906 * JIRA issues related to this :- 04907 * ASTERISK-14384, ASTERISK-17502, ASTERISK-17541, ASTERISK-18063, ASTERISK-18325, ASTERISK-18422*/ 04908 if ((!(fr->subclass.codec & chan->nativeformats)) && (chan->writeformat != fr->subclass.codec)) { 04909 char nf[512]; 04910 ast_log(LOG_WARNING, "Codec mismatch on channel %s setting write format to %s from %s native formats %s\n", 04911 chan->name, ast_getformatname(fr->subclass.codec), ast_getformatname(chan->writeformat), 04912 ast_getformatname_multiple(nf, sizeof(nf), chan->nativeformats & AST_FORMAT_AUDIO_MASK)); 04913 ast_set_write_format(chan, fr->subclass.codec); 04914 } 04915 04916 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr; 04917 } 04918 04919 if (!f) { 04920 res = 0; 04921 break; 04922 } 04923 04924 if (chan->audiohooks) { 04925 struct ast_frame *prev = NULL, *new_frame, *cur, *dup; 04926 int freeoldlist = 0; 04927 04928 if (f != fr) { 04929 freeoldlist = 1; 04930 } 04931 04932 /* Since ast_audiohook_write may return a new frame, and the cur frame is 04933 * an item in a list of frames, create a new list adding each cur frame back to it 04934 * regardless if the cur frame changes or not. */ 04935 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 04936 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, cur); 04937 04938 /* if this frame is different than cur, preserve the end of the list, 04939 * free the old frames, and set cur to be the new frame */ 04940 if (new_frame != cur) { 04941 04942 /* doing an ast_frisolate here seems silly, but we are not guaranteed the new_frame 04943 * isn't part of local storage, meaning if ast_audiohook_write is called multiple 04944 * times it may override the previous frame we got from it unless we dup it */ 04945 if ((dup = ast_frisolate(new_frame))) { 04946 AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list); 04947 if (freeoldlist) { 04948 AST_LIST_NEXT(cur, frame_list) = NULL; 04949 ast_frfree(cur); 04950 } 04951 if (new_frame != dup) { 04952 ast_frfree(new_frame); 04953 } 04954 cur = dup; 04955 } 04956 } 04957 04958 /* now, regardless if cur is new or not, add it to the new list, 04959 * if the new list has not started, cur will become the first item. */ 04960 if (prev) { 04961 AST_LIST_NEXT(prev, frame_list) = cur; 04962 } else { 04963 f = cur; /* set f to be the beginning of our new list */ 04964 } 04965 prev = cur; 04966 } 04967 } 04968 04969 /* If Monitor is running on this channel, then we have to write frames out there too */ 04970 /* the translator on chan->writetrans may have returned multiple frames 04971 from the single frame we passed in; if so, feed each one of them to the 04972 monitor */ 04973 if (chan->monitor && chan->monitor->write_stream) { 04974 struct ast_frame *cur; 04975 04976 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 04977 /* XXX must explain this code */ 04978 #ifndef MONITOR_CONSTANT_DELAY 04979 int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples; 04980 if (jump >= 0) { 04981 jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 04982 if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1) 04983 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 04984 chan->outsmpl += (chan->insmpl - chan->outsmpl) + cur->samples; 04985 } else { 04986 chan->outsmpl += cur->samples; 04987 } 04988 #else 04989 int jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format)); 04990 if (jump - MONITOR_DELAY >= 0) { 04991 if (ast_seekstream(chan->monitor->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1) 04992 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 04993 chan->outsmpl += chan->insmpl - chan->outsmpl; 04994 } else { 04995 chan->outsmpl += cur->samples; 04996 } 04997 #endif 04998 if (chan->monitor->state == AST_MONITOR_RUNNING) { 04999 if (ast_writestream(chan->monitor->write_stream, cur) < 0) 05000 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 05001 } 05002 } 05003 } 05004 05005 /* the translator on chan->writetrans may have returned multiple frames 05006 from the single frame we passed in; if so, feed each one of them to the 05007 channel, freeing each one after it has been written */ 05008 if ((f != fr) && AST_LIST_NEXT(f, frame_list)) { 05009 struct ast_frame *cur, *next; 05010 unsigned int skip = 0; 05011 05012 for (cur = f, next = AST_LIST_NEXT(cur, frame_list); 05013 cur; 05014 cur = next, next = cur ? AST_LIST_NEXT(cur, frame_list) : NULL) { 05015 if (!skip) { 05016 if ((res = chan->tech->write(chan, cur)) < 0) { 05017 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05018 skip = 1; 05019 } else if (next) { 05020 /* don't do this for the last frame in the list, 05021 as the code outside the loop will do it once 05022 */ 05023 chan->fout = FRAMECOUNT_INC(chan->fout); 05024 } 05025 } 05026 ast_frfree(cur); 05027 } 05028 05029 /* reset f so the code below doesn't attempt to free it */ 05030 f = NULL; 05031 } else { 05032 res = chan->tech->write(chan, f); 05033 } 05034 break; 05035 case AST_FRAME_NULL: 05036 case AST_FRAME_IAX: 05037 /* Ignore these */ 05038 res = 0; 05039 break; 05040 default: 05041 /* At this point, fr is the incoming frame and f is NULL. Channels do 05042 * not expect to get NULL as a frame pointer and will segfault. Hence, 05043 * we output the original frame passed in. */ 05044 res = chan->tech->write(chan, fr); 05045 break; 05046 } 05047 05048 if (f && f != fr) 05049 ast_frfree(f); 05050 ast_clear_flag(chan, AST_FLAG_BLOCKING); 05051 05052 /* Consider a write failure to force a soft hangup */ 05053 if (res < 0) { 05054 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05055 } else { 05056 chan->fout = FRAMECOUNT_INC(chan->fout); 05057 } 05058 done: 05059 if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) { 05060 /* The list gets recreated if audiohooks are added again later */ 05061 ast_audiohook_detach_list(chan->audiohooks); 05062 chan->audiohooks = NULL; 05063 } 05064 ast_channel_unlock(chan); 05065 return res; 05066 }
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 4652 of file channel.c.
References ast_write(), chanlist::chan, ast_channel::tech, and ast_channel_tech::write_video.
04653 { 04654 int res; 04655 if (!chan->tech->write_video) 04656 return 0; 04657 res = ast_write(chan, fr); 04658 if (!res) 04659 res = 1; 04660 return res; 04661 }
static void bridge_play_sounds | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1 | |||
) | [static] |
Definition at line 7235 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().
07236 { 07237 const char *s, *sound; 07238 07239 /* See if we need to play an audio file to any side of the bridge */ 07240 07241 ast_channel_lock(c0); 07242 if ((s = pbx_builtin_getvar_helper(c0, "BRIDGE_PLAY_SOUND"))) { 07243 sound = ast_strdupa(s); 07244 ast_channel_unlock(c0); 07245 bridge_playfile(c0, c1, sound, 0); 07246 pbx_builtin_setvar_helper(c0, "BRIDGE_PLAY_SOUND", NULL); 07247 } else { 07248 ast_channel_unlock(c0); 07249 } 07250 07251 ast_channel_lock(c1); 07252 if ((s = pbx_builtin_getvar_helper(c1, "BRIDGE_PLAY_SOUND"))) { 07253 sound = ast_strdupa(s); 07254 ast_channel_unlock(c1); 07255 bridge_playfile(c1, c0, sound, 0); 07256 pbx_builtin_setvar_helper(c1, "BRIDGE_PLAY_SOUND", NULL); 07257 } else { 07258 ast_channel_unlock(c1); 07259 } 07260 }
static void bridge_playfile | ( | struct ast_channel * | chan, | |
struct ast_channel * | peer, | |||
const char * | sound, | |||
int | remain | |||
) | [static] |
Definition at line 6929 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().
06930 { 06931 int min = 0, sec = 0, check; 06932 06933 check = ast_autoservice_start(peer); 06934 if (check) 06935 return; 06936 06937 if (remain > 0) { 06938 if (remain / 60 > 1) { 06939 min = remain / 60; 06940 sec = remain % 60; 06941 } else { 06942 sec = remain; 06943 } 06944 } 06945 06946 if (!strcmp(sound,"timeleft")) { /* Queue support */ 06947 ast_stream_and_wait(chan, "vm-youhave", ""); 06948 if (min) { 06949 ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, NULL); 06950 ast_stream_and_wait(chan, "queue-minutes", ""); 06951 } 06952 if (sec) { 06953 ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, NULL); 06954 ast_stream_and_wait(chan, "queue-seconds", ""); 06955 } 06956 } else { 06957 ast_stream_and_wait(chan, sound, ""); 06958 } 06959 06960 ast_autoservice_stop(peer); 06961 }
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 3702 of file channel.c.
Referenced by __ast_read(), and ast_write().
03703 { 03704 int diff = sample_rate - seek_rate; 03705 03706 if (diff > 0) { 03707 samples = samples / (float) (sample_rate / seek_rate); 03708 } else if (diff < 0) { 03709 samples = samples * (float) (seek_rate / sample_rate); 03710 } 03711 03712 return samples; 03713 }
static void call_forward_inherit | ( | struct ast_channel * | new_chan, | |
struct ast_channel * | parent, | |||
struct ast_channel * | orig | |||
) | [static] |
Definition at line 5209 of file channel.c.
References ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_lock_both, ast_channel_redirecting_macro(), ast_channel_unlock, ast_channel_update_redirecting(), ast_check_hangup(), AST_FLAG_ZOMBIE, ast_party_redirecting_copy(), ast_party_redirecting_free(), ast_party_redirecting_init(), ast_test_flag, and ast_channel::redirecting.
Referenced by ast_call_forward().
05210 { 05211 if (!ast_test_flag(parent, AST_FLAG_ZOMBIE) && !ast_check_hangup(parent)) { 05212 struct ast_party_redirecting redirecting; 05213 05214 /* 05215 * The parent is not a ZOMBIE or hungup so update it with the 05216 * original channel's redirecting information. 05217 */ 05218 ast_party_redirecting_init(&redirecting); 05219 ast_channel_lock(orig); 05220 ast_party_redirecting_copy(&redirecting, &orig->redirecting); 05221 ast_channel_unlock(orig); 05222 if (ast_channel_redirecting_macro(orig, parent, &redirecting, 1, 0)) { 05223 ast_channel_update_redirecting(parent, &redirecting, NULL); 05224 } 05225 ast_party_redirecting_free(&redirecting); 05226 } 05227 05228 /* Safely inherit variables and datastores from the parent channel. */ 05229 ast_channel_lock_both(parent, new_chan); 05230 ast_channel_inherit_variables(parent, new_chan); 05231 ast_channel_datastore_inherit(parent, new_chan); 05232 ast_channel_unlock(new_chan); 05233 ast_channel_unlock(parent); 05234 }
static void* channel_cc_params_copy | ( | void * | data | ) | [static] |
Definition at line 9401 of file channel.c.
References ast_cc_config_params_init, and ast_cc_copy_config_params().
09402 { 09403 const struct ast_cc_config_params *src = data; 09404 struct ast_cc_config_params *dest = ast_cc_config_params_init(); 09405 if (!dest) { 09406 return NULL; 09407 } 09408 ast_cc_copy_config_params(dest, src); 09409 return dest; 09410 }
static void channel_cc_params_destroy | ( | void * | data | ) | [static] |
Definition at line 9412 of file channel.c.
References ast_cc_config_params_destroy().
09413 { 09414 struct ast_cc_config_params *cc_params = data; 09415 ast_cc_config_params_destroy(cc_params); 09416 }
static void channel_data_add_flags | ( | struct ast_data * | tree, | |
struct ast_channel * | chan | |||
) | [static] |
Definition at line 267 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().
00269 { 00270 ast_data_add_bool(tree, "DEFER_DTMF", ast_test_flag(chan, AST_FLAG_DEFER_DTMF)); 00271 ast_data_add_bool(tree, "WRITE_INT", ast_test_flag(chan, AST_FLAG_WRITE_INT)); 00272 ast_data_add_bool(tree, "BLOCKING", ast_test_flag(chan, AST_FLAG_BLOCKING)); 00273 ast_data_add_bool(tree, "ZOMBIE", ast_test_flag(chan, AST_FLAG_ZOMBIE)); 00274 ast_data_add_bool(tree, "EXCEPTION", ast_test_flag(chan, AST_FLAG_EXCEPTION)); 00275 ast_data_add_bool(tree, "MOH", ast_test_flag(chan, AST_FLAG_MOH)); 00276 ast_data_add_bool(tree, "SPYING", ast_test_flag(chan, AST_FLAG_SPYING)); 00277 ast_data_add_bool(tree, "NBRIDGE", ast_test_flag(chan, AST_FLAG_NBRIDGE)); 00278 ast_data_add_bool(tree, "IN_AUTOLOOP", ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)); 00279 ast_data_add_bool(tree, "OUTGOING", ast_test_flag(chan, AST_FLAG_OUTGOING)); 00280 ast_data_add_bool(tree, "IN_DTMF", ast_test_flag(chan, AST_FLAG_IN_DTMF)); 00281 ast_data_add_bool(tree, "EMULATE_DTMF", ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)); 00282 ast_data_add_bool(tree, "END_DTMF_ONLY", ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)); 00283 ast_data_add_bool(tree, "ANSWERED_ELSEWHERE", ast_test_flag(chan, AST_FLAG_ANSWERED_ELSEWHERE)); 00284 ast_data_add_bool(tree, "MASQ_NOSTREAM", ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM)); 00285 ast_data_add_bool(tree, "BRIDGE_HANGUP_RUN", ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN)); 00286 ast_data_add_bool(tree, "BRIDGE_HANGUP_DONT", ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT)); 00287 ast_data_add_bool(tree, "DISABLE_WORKAROUNDS", ast_test_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS)); 00288 }
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 1618 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().
01621 { 01622 struct ast_channel_iterator *i; 01623 struct ast_channel tmp_chan = { 01624 .name = name, 01625 /* This is sort of a hack. Basically, we're using an arbitrary field 01626 * in ast_channel to pass the name_len for a prefix match. If this 01627 * gets changed, then the compare callback must be changed, too. */ 01628 .rings = name_len, 01629 }; 01630 01631 if (!(i = ast_calloc(1, sizeof(*i)))) { 01632 return NULL; 01633 } 01634 01635 if (exten) { 01636 ast_copy_string(tmp_chan.exten, exten, sizeof(tmp_chan.exten)); 01637 } 01638 01639 if (context) { 01640 ast_copy_string(tmp_chan.context, context, sizeof(tmp_chan.context)); 01641 } 01642 01643 if (!(i->active_iterator = ao2_find(channels, &tmp_chan, 01644 OBJ_MULTIPLE | ((!ast_strlen_zero(name) && (name_len == 0)) ? OBJ_POINTER : 0)))) { 01645 ast_free(i); 01646 return NULL; 01647 } 01648 01649 return i; 01650 }
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 8076 of file channel.c.
References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.
08077 { 08078 switch (reason) { 08079 case CHANNEL_MODULE_LOAD: 08080 return "LOAD (Channel module load)"; 08081 08082 case CHANNEL_MODULE_RELOAD: 08083 return "RELOAD (Channel module reload)"; 08084 08085 case CHANNEL_CLI_RELOAD: 08086 return "CLIRELOAD (Channel module reload by CLI command)"; 08087 08088 default: 08089 return "MANAGERRELOAD (Channel module reload by manager)"; 08090 } 08091 };
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 6137 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().
06138 { 06139 struct ast_var_t *current, *newvar; 06140 /* Append variables from clone channel into original channel */ 06141 /* XXX Is this always correct? We have to in order to keep MACROS working XXX */ 06142 if (AST_LIST_FIRST(&clonechan->varshead)) 06143 AST_LIST_APPEND_LIST(&original->varshead, &clonechan->varshead, entries); 06144 06145 /* then, dup the varshead list into the clone */ 06146 06147 AST_LIST_TRAVERSE(&original->varshead, current, entries) { 06148 newvar = ast_var_assign(current->name, current->value); 06149 if (newvar) 06150 AST_LIST_INSERT_TAIL(&clonechan->varshead, newvar, entries); 06151 } 06152 }
static char* complete_channeltypes | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 522 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().
00523 { 00524 struct chanlist *cl; 00525 int which = 0; 00526 int wordlen; 00527 char *ret = NULL; 00528 00529 if (a->pos != 3) 00530 return NULL; 00531 00532 wordlen = strlen(a->word); 00533 00534 AST_RWLIST_RDLOCK(&backends); 00535 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00536 if (!strncasecmp(a->word, cl->tech->type, wordlen) && ++which > a->n) { 00537 ret = ast_strdup(cl->tech->type); 00538 break; 00539 } 00540 } 00541 AST_RWLIST_UNLOCK(&backends); 00542 00543 return ret; 00544 }
static int data_channels_provider_handler | ( | const struct ast_data_search * | search, | |
struct ast_data * | root | |||
) | [static] |
Definition at line 7835 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.
07837 { 07838 struct ast_channel *c; 07839 struct ast_channel_iterator *iter = NULL; 07840 struct ast_data *data_channel; 07841 07842 for (iter = ast_channel_iterator_all_new(); 07843 iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) { 07844 ast_channel_lock(c); 07845 07846 data_channel = ast_data_add_node(root, "channel"); 07847 if (!data_channel) { 07848 ast_channel_unlock(c); 07849 continue; 07850 } 07851 07852 if (ast_channel_data_add_structure(data_channel, c, 1) < 0) { 07853 ast_log(LOG_ERROR, "Unable to add channel structure for channel: %s\n", c->name); 07854 } 07855 07856 ast_channel_unlock(c); 07857 07858 if (!ast_data_search_match(search, data_channel)) { 07859 ast_data_remove_node(root, data_channel); 07860 } 07861 } 07862 if (iter) { 07863 ast_channel_iterator_destroy(iter); 07864 } 07865 07866 return 0; 07867 }
static int data_channeltypes_provider_handler | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 7873 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.
07875 { 07876 struct chanlist *cl; 07877 struct ast_data *data_type; 07878 07879 AST_RWLIST_RDLOCK(&backends); 07880 AST_RWLIST_TRAVERSE(&backends, cl, list) { 07881 data_type = ast_data_add_node(data_root, "type"); 07882 if (!data_type) { 07883 continue; 07884 } 07885 ast_data_add_str(data_type, "name", cl->tech->type); 07886 ast_data_add_str(data_type, "description", cl->tech->description); 07887 ast_data_add_bool(data_type, "devicestate", cl->tech->devicestate ? 1 : 0); 07888 ast_data_add_bool(data_type, "indications", cl->tech->indicate ? 1 : 0); 07889 ast_data_add_bool(data_type, "transfer", cl->tech->transfer ? 1 : 0); 07890 ast_data_add_bool(data_type, "send_digit_begin", cl->tech->send_digit_begin ? 1 : 0); 07891 ast_data_add_bool(data_type, "send_digit_end", cl->tech->send_digit_end ? 1 : 0); 07892 ast_data_add_bool(data_type, "call", cl->tech->call ? 1 : 0); 07893 ast_data_add_bool(data_type, "hangup", cl->tech->hangup ? 1 : 0); 07894 ast_data_add_bool(data_type, "answer", cl->tech->answer ? 1 : 0); 07895 ast_data_add_bool(data_type, "read", cl->tech->read ? 1 : 0); 07896 ast_data_add_bool(data_type, "write", cl->tech->write ? 1 : 0); 07897 ast_data_add_bool(data_type, "send_text", cl->tech->send_text ? 1 : 0); 07898 ast_data_add_bool(data_type, "send_image", cl->tech->send_image ? 1 : 0); 07899 ast_data_add_bool(data_type, "send_html", cl->tech->send_html ? 1 : 0); 07900 ast_data_add_bool(data_type, "exception", cl->tech->exception ? 1 : 0); 07901 ast_data_add_bool(data_type, "bridge", cl->tech->bridge ? 1 : 0); 07902 ast_data_add_bool(data_type, "early_bridge", cl->tech->early_bridge ? 1 : 0); 07903 ast_data_add_bool(data_type, "fixup", cl->tech->fixup ? 1 : 0); 07904 ast_data_add_bool(data_type, "setoption", cl->tech->setoption ? 1 : 0); 07905 ast_data_add_bool(data_type, "queryoption", cl->tech->queryoption ? 1 : 0); 07906 ast_data_add_bool(data_type, "write_video", cl->tech->write_video ? 1 : 0); 07907 ast_data_add_bool(data_type, "write_text", cl->tech->write_text ? 1 : 0); 07908 ast_data_add_bool(data_type, "bridged_channel", cl->tech->bridged_channel ? 1 : 0); 07909 ast_data_add_bool(data_type, "func_channel_read", cl->tech->func_channel_read ? 1 : 0); 07910 ast_data_add_bool(data_type, "func_channel_write", cl->tech->func_channel_write ? 1 : 0); 07911 ast_data_add_bool(data_type, "get_base_channel", cl->tech->get_base_channel ? 1 : 0); 07912 ast_data_add_bool(data_type, "set_base_channel", cl->tech->set_base_channel ? 1 : 0); 07913 ast_data_add_bool(data_type, "get_pvt_uniqueid", cl->tech->get_pvt_uniqueid ? 1 : 0); 07914 ast_data_add_bool(data_type, "cc_callback", cl->tech->cc_callback ? 1 : 0); 07915 07916 ast_data_add_codecs(data_type, "capabilities", cl->tech->capabilities); 07917 07918 if (!ast_data_search_match(search, data_type)) { 07919 ast_data_remove_node(data_root, data_type); 07920 } 07921 } 07922 AST_RWLIST_UNLOCK(&backends); 07923 07924 return 0; 07925 }
static void free_translation | ( | struct ast_channel * | clonechan | ) | [static] |
Definition at line 2702 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().
02703 { 02704 if (clonechan->writetrans) 02705 ast_translator_free_path(clonechan->writetrans); 02706 if (clonechan->readtrans) 02707 ast_translator_free_path(clonechan->readtrans); 02708 clonechan->writetrans = NULL; 02709 clonechan->readtrans = NULL; 02710 clonechan->rawwriteformat = clonechan->nativeformats; 02711 clonechan->rawreadformat = clonechan->nativeformats; 02712 }
static int generator_force | ( | const void * | data | ) | [static] |
Definition at line 3044 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().
03045 { 03046 /* Called if generator doesn't have data */ 03047 void *tmp; 03048 int res; 03049 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL; 03050 struct ast_channel *chan = (struct ast_channel *)data; 03051 03052 ast_channel_lock(chan); 03053 tmp = chan->generatordata; 03054 chan->generatordata = NULL; 03055 if (chan->generator) 03056 generate = chan->generator->generate; 03057 ast_channel_unlock(chan); 03058 03059 if (!tmp || !generate) 03060 return 0; 03061 03062 res = generate(chan, tmp, 0, ast_format_rate(chan->writeformat & AST_FORMAT_AUDIO_MASK) / 50); 03063 03064 chan->generatordata = tmp; 03065 03066 if (res) { 03067 ast_debug(1, "Auto-deactivating generator\n"); 03068 ast_deactivate_generator(chan); 03069 } 03070 03071 return 0; 03072 }
static void handle_cause | ( | int | cause, | |
int * | outstate | |||
) | [static] |
Definition at line 5186 of file channel.c.
References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CONTROL_BUSY, and AST_CONTROL_CONGESTION.
05187 { 05188 if (outstate) { 05189 /* compute error and return */ 05190 if (cause == AST_CAUSE_BUSY) 05191 *outstate = AST_CONTROL_BUSY; 05192 else if (cause == AST_CAUSE_CONGESTION) 05193 *outstate = AST_CONTROL_CONGESTION; 05194 else 05195 *outstate = 0; 05196 } 05197 }
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 547 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.
00548 { 00549 struct chanlist *cl = NULL; 00550 char buf[512]; 00551 00552 switch (cmd) { 00553 case CLI_INIT: 00554 e->command = "core show channeltype"; 00555 e->usage = 00556 "Usage: core show channeltype <name>\n" 00557 " Show details about the specified channel type, <name>.\n"; 00558 return NULL; 00559 case CLI_GENERATE: 00560 return complete_channeltypes(a); 00561 } 00562 00563 if (a->argc != 4) 00564 return CLI_SHOWUSAGE; 00565 00566 AST_RWLIST_RDLOCK(&backends); 00567 00568 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00569 if (!strncasecmp(cl->tech->type, a->argv[3], strlen(cl->tech->type))) 00570 break; 00571 } 00572 00573 00574 if (!cl) { 00575 ast_cli(a->fd, "\n%s is not a registered channel driver.\n", a->argv[3]); 00576 AST_RWLIST_UNLOCK(&backends); 00577 return CLI_FAILURE; 00578 } 00579 00580 ast_cli(a->fd, 00581 "-- Info about channel driver: %s --\n" 00582 " Device State: %s\n" 00583 " Indication: %s\n" 00584 " Transfer : %s\n" 00585 " Capabilities: %s\n" 00586 " Digit Begin: %s\n" 00587 " Digit End: %s\n" 00588 " Send HTML : %s\n" 00589 " Image Support: %s\n" 00590 " Text Support: %s\n", 00591 cl->tech->type, 00592 (cl->tech->devicestate) ? "yes" : "no", 00593 (cl->tech->indicate) ? "yes" : "no", 00594 (cl->tech->transfer) ? "yes" : "no", 00595 ast_getformatname_multiple(buf, sizeof(buf), (cl->tech->capabilities) ? cl->tech->capabilities : -1), 00596 (cl->tech->send_digit_begin) ? "yes" : "no", 00597 (cl->tech->send_digit_end) ? "yes" : "no", 00598 (cl->tech->send_html) ? "yes" : "no", 00599 (cl->tech->send_image) ? "yes" : "no", 00600 (cl->tech->send_text) ? "yes" : "no" 00601 00602 ); 00603 00604 AST_RWLIST_UNLOCK(&backends); 00605 00606 return CLI_SUCCESS; 00607 }
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 481 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.
00482 { 00483 #define FORMAT "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\n" 00484 struct chanlist *cl; 00485 int count_chan = 0; 00486 00487 switch (cmd) { 00488 case CLI_INIT: 00489 e->command = "core show channeltypes"; 00490 e->usage = 00491 "Usage: core show channeltypes\n" 00492 " Lists available channel types registered in your\n" 00493 " Asterisk server.\n"; 00494 return NULL; 00495 case CLI_GENERATE: 00496 return NULL; 00497 } 00498 00499 if (a->argc != 3) 00500 return CLI_SHOWUSAGE; 00501 00502 ast_cli(a->fd, FORMAT, "Type", "Description", "Devicestate", "Indications", "Transfer"); 00503 ast_cli(a->fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------"); 00504 00505 AST_RWLIST_RDLOCK(&backends); 00506 AST_RWLIST_TRAVERSE(&backends, cl, list) { 00507 ast_cli(a->fd, FORMAT, cl->tech->type, cl->tech->description, 00508 (cl->tech->devicestate) ? "yes" : "no", 00509 (cl->tech->indicate) ? "yes" : "no", 00510 (cl->tech->transfer) ? "yes" : "no"); 00511 count_chan++; 00512 } 00513 AST_RWLIST_UNLOCK(&backends); 00514 00515 ast_cli(a->fd, "----------\n%d channel drivers registered.\n", count_chan); 00516 00517 return CLI_SUCCESS; 00518 00519 #undef FORMAT 00520 }
static int attribute_const is_visible_indication | ( | enum ast_control_frame_type | condition | ) | [static] |
Definition at line 4267 of file channel.c.
References _XXX_AST_CONTROL_T38, AST_CONTROL_ANSWER, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_END_OF_Q, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_READ_ACTION, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_TRANSFER, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, and AST_CONTROL_WINK.
Referenced by ast_indicate_data().
04268 { 04269 /* Don't include a default case here so that we get compiler warnings 04270 * when a new type is added. */ 04271 04272 switch (condition) { 04273 case AST_CONTROL_PROGRESS: 04274 case AST_CONTROL_PROCEEDING: 04275 case AST_CONTROL_VIDUPDATE: 04276 case AST_CONTROL_SRCUPDATE: 04277 case AST_CONTROL_SRCCHANGE: 04278 case AST_CONTROL_RADIO_KEY: 04279 case AST_CONTROL_RADIO_UNKEY: 04280 case AST_CONTROL_OPTION: 04281 case AST_CONTROL_WINK: 04282 case AST_CONTROL_FLASH: 04283 case AST_CONTROL_OFFHOOK: 04284 case AST_CONTROL_TAKEOFFHOOK: 04285 case AST_CONTROL_ANSWER: 04286 case AST_CONTROL_HANGUP: 04287 case AST_CONTROL_CONNECTED_LINE: 04288 case AST_CONTROL_REDIRECTING: 04289 case AST_CONTROL_TRANSFER: 04290 case AST_CONTROL_T38_PARAMETERS: 04291 case _XXX_AST_CONTROL_T38: 04292 case AST_CONTROL_CC: 04293 case AST_CONTROL_READ_ACTION: 04294 case AST_CONTROL_AOC: 04295 case AST_CONTROL_END_OF_Q: 04296 case AST_CONTROL_UPDATE_RTP_PEER: 04297 break; 04298 04299 case AST_CONTROL_INCOMPLETE: 04300 case AST_CONTROL_CONGESTION: 04301 case AST_CONTROL_BUSY: 04302 case AST_CONTROL_RINGING: 04303 case AST_CONTROL_RING: 04304 case AST_CONTROL_HOLD: 04305 /* You can hear these */ 04306 return 1; 04307 04308 case AST_CONTROL_UNHOLD: 04309 /* This is a special case. You stop hearing this. */ 04310 break; 04311 } 04312 04313 return 0; 04314 }
static struct ast_frame* kill_exception | ( | struct ast_channel * | chan | ) | [static] |
static int kill_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
static int kill_hangup | ( | struct ast_channel * | chan | ) | [static] |
static struct ast_frame* kill_read | ( | struct ast_channel * | chan | ) | [static] |
static int kill_write | ( | struct ast_channel * | chan, | |
struct ast_frame * | frame | |||
) | [static] |
static void manager_bridge_event | ( | int | onoff, | |
int | type, | |||
struct ast_channel * | c0, | |||
struct ast_channel * | c1 | |||
) | [static] |
Send manager event for bridge link and unlink events.
onoff | Link/Unlinked | |
type | 1 for core, 2 for native | |
c0 | first channel in bridge | |
c1 | second channel in bridge |
Definition at line 7178 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().
07179 { 07180 struct ast_channel *chans[2] = { c0, c1 }; 07181 ast_manager_event_multichan(EVENT_FLAG_CALL, "Bridge", 2, chans, 07182 "Bridgestate: %s\r\n" 07183 "Bridgetype: %s\r\n" 07184 "Channel1: %s\r\n" 07185 "Channel2: %s\r\n" 07186 "Uniqueid1: %s\r\n" 07187 "Uniqueid2: %s\r\n" 07188 "CallerID1: %s\r\n" 07189 "CallerID2: %s\r\n", 07190 onoff ? "Link" : "Unlink", 07191 type == 1 ? "core" : "native", 07192 c0->name, c1->name, 07193 c0->uniqueid, c1->uniqueid, 07194 S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, ""), 07195 S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "")); 07196 }
static void masquerade_colp_transfer | ( | struct ast_channel * | transferee, | |
struct xfer_masquerade_ds * | colp | |||
) | [static] |
Definition at line 6343 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().
06344 { 06345 struct ast_control_read_action_payload *frame_payload; 06346 int payload_size; 06347 int frame_size; 06348 unsigned char connected_line_data[1024]; 06349 06350 /* Release any hold on the target. */ 06351 if (colp->target_held) { 06352 ast_queue_control(transferee, AST_CONTROL_UNHOLD); 06353 } 06354 06355 /* 06356 * Since transferee may not actually be bridged to another channel, 06357 * there is no way for us to queue a frame so that its connected 06358 * line status will be updated. Instead, we use the somewhat 06359 * hackish approach of using a special control frame type that 06360 * instructs ast_read() to perform a specific action. In this 06361 * case, the frame we queue tells ast_read() to call the 06362 * connected line interception macro configured for transferee. 06363 */ 06364 payload_size = ast_connected_line_build_data(connected_line_data, 06365 sizeof(connected_line_data), &colp->target_id, NULL); 06366 if (payload_size != -1) { 06367 frame_size = payload_size + sizeof(*frame_payload); 06368 frame_payload = alloca(frame_size); 06369 frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO; 06370 frame_payload->payload_size = payload_size; 06371 memcpy(frame_payload->payload, connected_line_data, payload_size); 06372 ast_queue_control_data(transferee, AST_CONTROL_READ_ACTION, frame_payload, 06373 frame_size); 06374 } 06375 /* 06376 * In addition to queueing the read action frame so that the 06377 * connected line info on transferee will be updated, we also are 06378 * going to queue a plain old connected line update on transferee to 06379 * update the target. 06380 */ 06381 ast_channel_queue_connected_line_update(transferee, &colp->transferee_id, NULL); 06382 }
static const char* oldest_linkedid | ( | const char * | a, | |
const char * | b | |||
) | [static] |
Definition at line 6167 of file channel.c.
References ast_strlen_zero().
Referenced by ast_channel_set_linkgroup().
06168 { 06169 const char *satime, *saseq; 06170 const char *sbtime, *sbseq; 06171 const char *dash; 06172 06173 unsigned int atime, aseq, btime, bseq; 06174 06175 if (ast_strlen_zero(a)) 06176 return b; 06177 06178 if (ast_strlen_zero(b)) 06179 return a; 06180 06181 satime = a; 06182 sbtime = b; 06183 06184 /* jump over the system name */ 06185 if ((dash = strrchr(satime, '-'))) { 06186 satime = dash+1; 06187 } 06188 if ((dash = strrchr(sbtime, '-'))) { 06189 sbtime = dash+1; 06190 } 06191 06192 /* the sequence comes after the '.' */ 06193 saseq = strchr(satime, '.'); 06194 sbseq = strchr(sbtime, '.'); 06195 if (!saseq || !sbseq) 06196 return NULL; 06197 saseq++; 06198 sbseq++; 06199 06200 /* convert it all to integers */ 06201 atime = atoi(satime); /* note that atoi is ignoring the '.' after the time string */ 06202 btime = atoi(sbtime); /* note that atoi is ignoring the '.' after the time string */ 06203 aseq = atoi(saseq); 06204 bseq = atoi(sbseq); 06205 06206 /* and finally compare */ 06207 if (atime == btime) { 06208 return (aseq < bseq) ? a : b; 06209 } 06210 else { 06211 return (atime < btime) ? a : b; 06212 } 06213 }
static void party_connected_line_copy_transfer | ( | struct ast_party_connected_line * | dest, | |
const struct ast_party_connected_line * | src | |||
) | [static] |
Definition at line 5974 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().
05975 { 05976 struct ast_party_connected_line connected; 05977 05978 connected = *((struct ast_party_connected_line *) src); 05979 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; 05980 05981 /* Make sure empty strings will be erased. */ 05982 if (!connected.id.name.str) { 05983 connected.id.name.str = ""; 05984 } 05985 if (!connected.id.number.str) { 05986 connected.id.number.str = ""; 05987 } 05988 if (!connected.id.subaddress.str) { 05989 connected.id.subaddress.str = ""; 05990 } 05991 if (!connected.id.tag) { 05992 connected.id.tag = ""; 05993 } 05994 05995 ast_party_connected_line_copy(dest, &connected); 05996 }
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 8426 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().
08429 { 08430 size_t length; 08431 size_t pos = 0; 08432 int res; 08433 08434 /* 08435 * The size of integer values must be fixed in case the frame is 08436 * shipped to another machine. 08437 */ 08438 08439 if (!update || update->name) { 08440 res = party_name_build_data(data + pos, datalen - pos, &id->name, label, 08441 &ies->name); 08442 if (res < 0) { 08443 return -1; 08444 } 08445 pos += res; 08446 } 08447 08448 if (!update || update->number) { 08449 res = party_number_build_data(data + pos, datalen - pos, &id->number, label, 08450 &ies->number); 08451 if (res < 0) { 08452 return -1; 08453 } 08454 pos += res; 08455 } 08456 08457 if (!update || update->subaddress) { 08458 res = party_subaddress_build_data(data + pos, datalen - pos, &id->subaddress, 08459 label, &ies->subaddress); 08460 if (res < 0) { 08461 return -1; 08462 } 08463 pos += res; 08464 } 08465 08466 /* *************** Party id user tag **************************** */ 08467 if (id->tag) { 08468 length = strlen(id->tag); 08469 if (datalen < pos + (sizeof(data[0]) * 2) + length) { 08470 ast_log(LOG_WARNING, "No space left for %s tag\n", label); 08471 return -1; 08472 } 08473 data[pos++] = ies->tag; 08474 data[pos++] = length; 08475 memcpy(data + pos, id->tag, length); 08476 pos += length; 08477 } 08478 08479 /* *************** Party id combined presentation *************** */ 08480 if (!update || update->number) { 08481 int presentation; 08482 08483 if (!update || update->name) { 08484 presentation = ast_party_id_presentation(id); 08485 } else { 08486 /* 08487 * We must compromise because not all the information is available 08488 * to determine a combined presentation value. 08489 * We will only send the number presentation instead. 08490 */ 08491 presentation = id->number.presentation; 08492 } 08493 08494 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08495 ast_log(LOG_WARNING, "No space left for %s combined presentation\n", label); 08496 return -1; 08497 } 08498 data[pos++] = ies->combined_presentation; 08499 data[pos++] = 1; 08500 data[pos++] = presentation; 08501 } 08502 08503 return pos; 08504 }
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 8200 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().
08201 { 08202 size_t length; 08203 size_t pos = 0; 08204 08205 /* 08206 * The size of integer values must be fixed in case the frame is 08207 * shipped to another machine. 08208 */ 08209 if (name->str) { 08210 length = strlen(name->str); 08211 if (datalen < pos + (sizeof(data[0]) * 2) + length) { 08212 ast_log(LOG_WARNING, "No space left for %s name\n", label); 08213 return -1; 08214 } 08215 data[pos++] = ies->str; 08216 data[pos++] = length; 08217 memcpy(data + pos, name->str, length); 08218 pos += length; 08219 } 08220 08221 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08222 ast_log(LOG_WARNING, "No space left for %s name char set\n", label); 08223 return -1; 08224 } 08225 data[pos++] = ies->char_set; 08226 data[pos++] = 1; 08227 data[pos++] = name->char_set; 08228 08229 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08230 ast_log(LOG_WARNING, "No space left for %s name presentation\n", label); 08231 return -1; 08232 } 08233 data[pos++] = ies->presentation; 08234 data[pos++] = 1; 08235 data[pos++] = name->presentation; 08236 08237 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08238 ast_log(LOG_WARNING, "No space left for %s name valid\n", label); 08239 return -1; 08240 } 08241 data[pos++] = ies->valid; 08242 data[pos++] = 1; 08243 data[pos++] = name->valid; 08244 08245 return pos; 08246 }
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 8274 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().
08275 { 08276 size_t length; 08277 size_t pos = 0; 08278 08279 /* 08280 * The size of integer values must be fixed in case the frame is 08281 * shipped to another machine. 08282 */ 08283 if (number->str) { 08284 length = strlen(number->str); 08285 if (datalen < pos + (sizeof(data[0]) * 2) + length) { 08286 ast_log(LOG_WARNING, "No space left for %s number\n", label); 08287 return -1; 08288 } 08289 data[pos++] = ies->str; 08290 data[pos++] = length; 08291 memcpy(data + pos, number->str, length); 08292 pos += length; 08293 } 08294 08295 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08296 ast_log(LOG_WARNING, "No space left for %s numbering plan\n", label); 08297 return -1; 08298 } 08299 data[pos++] = ies->plan; 08300 data[pos++] = 1; 08301 data[pos++] = number->plan; 08302 08303 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08304 ast_log(LOG_WARNING, "No space left for %s number presentation\n", label); 08305 return -1; 08306 } 08307 data[pos++] = ies->presentation; 08308 data[pos++] = 1; 08309 data[pos++] = number->presentation; 08310 08311 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08312 ast_log(LOG_WARNING, "No space left for %s number valid\n", label); 08313 return -1; 08314 } 08315 data[pos++] = ies->valid; 08316 data[pos++] = 1; 08317 data[pos++] = number->valid; 08318 08319 return pos; 08320 }
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 8348 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().
08349 { 08350 size_t length; 08351 size_t pos = 0; 08352 08353 /* 08354 * The size of integer values must be fixed in case the frame is 08355 * shipped to another machine. 08356 */ 08357 if (subaddress->str) { 08358 length = strlen(subaddress->str); 08359 if (datalen < pos + (sizeof(data[0]) * 2) + length) { 08360 ast_log(LOG_WARNING, "No space left for %s subaddress\n", label); 08361 return -1; 08362 } 08363 data[pos++] = ies->str; 08364 data[pos++] = length; 08365 memcpy(data + pos, subaddress->str, length); 08366 pos += length; 08367 } 08368 08369 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08370 ast_log(LOG_WARNING, "No space left for %s type of subaddress\n", label); 08371 return -1; 08372 } 08373 data[pos++] = ies->type; 08374 data[pos++] = 1; 08375 data[pos++] = subaddress->type; 08376 08377 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08378 ast_log(LOG_WARNING, 08379 "No space left for %s subaddress odd-even indicator\n", label); 08380 return -1; 08381 } 08382 data[pos++] = ies->odd_even_indicator; 08383 data[pos++] = 1; 08384 data[pos++] = subaddress->odd_even_indicator; 08385 08386 if (datalen < pos + (sizeof(data[0]) * 2) + 1) { 08387 ast_log(LOG_WARNING, "No space left for %s subaddress valid\n", label); 08388 return -1; 08389 } 08390 data[pos++] = ies->valid; 08391 data[pos++] = 1; 08392 data[pos++] = subaddress->valid; 08393 08394 return pos; 08395 }
static void plc_ds_destroy | ( | void * | data | ) | [static] |
Definition at line 4676 of file channel.c.
References ast_free, and plc_ds::samples_buf.
04677 { 04678 struct plc_ds *plc = data; 04679 ast_free(plc->samples_buf); 04680 ast_free(plc); 04681 }
static void queue_dtmf_readq | ( | struct ast_channel * | chan, | |
struct ast_frame * | f | |||
) | [inline, static] |
Definition at line 3657 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().
03658 { 03659 struct ast_frame *fr = &chan->dtmff; 03660 03661 fr->frametype = AST_FRAME_DTMF_END; 03662 fr->subclass.integer = f->subclass.integer; 03663 fr->len = f->len; 03664 03665 /* The only time this function will be called is for a frame that just came 03666 * out of the channel driver. So, we want to stick it on the tail of the 03667 * readq. */ 03668 03669 ast_queue_frame(chan, fr); 03670 }
static void report_new_callerid | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6313 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().
06314 { 06315 int pres; 06316 06317 pres = ast_party_id_presentation(&chan->caller.id); 06318 ast_manager_event(chan, EVENT_FLAG_CALL, "NewCallerid", 06319 "Channel: %s\r\n" 06320 "CallerIDNum: %s\r\n" 06321 "CallerIDName: %s\r\n" 06322 "Uniqueid: %s\r\n" 06323 "CID-CallingPres: %d (%s)\r\n", 06324 chan->name, 06325 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""), 06326 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""), 06327 chan->uniqueid, 06328 pres, 06329 ast_describe_caller_presentation(pres) 06330 ); 06331 }
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 3596 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().
03597 { 03598 ast_manager_event(chan, EVENT_FLAG_DTMF, 03599 "DTMF", 03600 "Channel: %s\r\n" 03601 "Uniqueid: %s\r\n" 03602 "Digit: %c\r\n" 03603 "Direction: %s\r\n" 03604 "Begin: %s\r\n" 03605 "End: %s\r\n", 03606 chan->name, chan->uniqueid, digit, direction, begin, end); 03607 }
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 5068 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().
05070 { 05071 format_t native, native_fmt = ast_best_codec(fmt); 05072 int res; 05073 char from[200], to[200]; 05074 05075 /* Make sure we only consider audio */ 05076 fmt &= AST_FORMAT_AUDIO_MASK; 05077 05078 native = chan->nativeformats; 05079 05080 if (!fmt || !native) /* No audio requested */ 05081 return 0; /* Let's try a call without any sounds (video, text) */ 05082 05083 /* See if the underlying channel driver is capable of performing transcoding for us */ 05084 if (!ast_channel_setoption(chan, direction ? AST_OPTION_FORMAT_WRITE : AST_OPTION_FORMAT_READ, &native_fmt, sizeof(int*), 0)) { 05085 ast_debug(1, "Channel driver natively set channel %s to %s format %s\n", chan->name, 05086 direction ? "write" : "read", ast_getformatname(native_fmt)); 05087 chan->nativeformats = *rawformat = *format = native_fmt; 05088 if (*trans) { 05089 ast_translator_free_path(*trans); 05090 } 05091 *trans = NULL; 05092 return 0; 05093 } 05094 05095 /* Find a translation path from the native format to one of the desired formats */ 05096 if (!direction) 05097 /* reading */ 05098 res = ast_translator_best_choice(&fmt, &native); 05099 else 05100 /* writing */ 05101 res = ast_translator_best_choice(&native, &fmt); 05102 05103 if (res < 0) { 05104 ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n", 05105 ast_getformatname_multiple(from, sizeof(from), native), 05106 ast_getformatname_multiple(to, sizeof(to), fmt)); 05107 return -1; 05108 } 05109 05110 /* Now we have a good choice for both. */ 05111 ast_channel_lock(chan); 05112 05113 if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) { 05114 /* the channel is already in these formats, so nothing to do */ 05115 ast_channel_unlock(chan); 05116 return 0; 05117 } 05118 05119 *rawformat = native; 05120 /* User perspective is fmt */ 05121 *format = fmt; 05122 /* Free any read translation we have right now */ 05123 if (*trans) { 05124 ast_translator_free_path(*trans); 05125 *trans = NULL; 05126 } 05127 /* Build a translation path from the raw format to the desired format */ 05128 if (*format == *rawformat) { 05129 /* 05130 * If we were able to swap the native format to the format that 05131 * has been requested, then there is no need to try to build 05132 * a translation path. 05133 */ 05134 res = 0; 05135 } else { 05136 if (!direction) { 05137 /* reading */ 05138 *trans = ast_translator_build_path(*format, *rawformat); 05139 } else { 05140 /* writing */ 05141 *trans = ast_translator_build_path(*rawformat, *format); 05142 } 05143 res = *trans ? 0 : -1; 05144 } 05145 ast_channel_unlock(chan); 05146 ast_debug(1, "Set channel %s to %s format %s\n", chan->name, 05147 direction ? "write" : "read", ast_getformatname(fmt)); 05148 return res; 05149 }
static int set_security_requirements | ( | const struct ast_channel * | requestor, | |
struct ast_channel * | out | |||
) | [static] |
Definition at line 5504 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().
05505 { 05506 int ops[2][2] = { 05507 {AST_OPTION_SECURE_SIGNALING, 0}, 05508 {AST_OPTION_SECURE_MEDIA, 0}, 05509 }; 05510 int i; 05511 struct ast_channel *r = (struct ast_channel *) requestor; /* UGLY */ 05512 struct ast_datastore *ds; 05513 05514 if (!requestor || !out) { 05515 return 0; 05516 } 05517 05518 ast_channel_lock(r); 05519 if ((ds = ast_channel_datastore_find(r, &secure_call_info, NULL))) { 05520 struct ast_secure_call_store *encrypt = ds->data; 05521 ops[0][1] = encrypt->signaling; 05522 ops[1][1] = encrypt->media; 05523 } else { 05524 ast_channel_unlock(r); 05525 return 0; 05526 } 05527 ast_channel_unlock(r); 05528 05529 for (i = 0; i < 2; i++) { 05530 if (ops[i][1]) { 05531 if (ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0)) { 05532 /* We require a security feature, but the channel won't provide it */ 05533 return -1; 05534 } 05535 } else { 05536 /* We don't care if we can't clear the option on a channel that doesn't support it */ 05537 ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0); 05538 } 05539 } 05540 05541 return 0; 05542 }
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 3675 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().
03676 { 03677 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)) { 03678 /* We're in the middle of emulating a digit, or DTMF has been 03679 * explicitly deferred. Skip this digit, then. */ 03680 return 1; 03681 } 03682 03683 if (!ast_tvzero(chan->dtmf_tv) && 03684 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) { 03685 /* We're not in the middle of a digit, but it hasn't been long enough 03686 * since the last digit, so we'll have to skip DTMF for now. */ 03687 return 1; 03688 } 03689 03690 return 0; 03691 }
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 8007 of file channel.c.
References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_write(), and ast_frame::frametype.
08008 { 08009 short buf[samples]; 08010 struct ast_frame frame = { 08011 .frametype = AST_FRAME_VOICE, 08012 .subclass.codec = AST_FORMAT_SLINEAR, 08013 .data.ptr = buf, 08014 .samples = samples, 08015 .datalen = sizeof(buf), 08016 }; 08017 08018 memset(buf, 0, sizeof(buf)); 08019 08020 if (ast_write(chan, &frame)) 08021 return -1; 08022 08023 return 0; 08024 }
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 7608 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.
07609 { 07610 struct tonepair_state *ts; 07611 struct tonepair_def *td = params; 07612 07613 if (!(ts = ast_calloc(1, sizeof(*ts)))) 07614 return NULL; 07615 ts->origwfmt = chan->writeformat; 07616 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) { 07617 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name); 07618 tonepair_release(NULL, ts); 07619 ts = NULL; 07620 } else { 07621 ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0; 07622 ts->v1_1 = 0; 07623 ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol; 07624 ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol; 07625 ts->v2_1 = 0; 07626 ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0; 07627 ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol; 07628 ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol; 07629 ts->duration = td->duration; 07630 ts->modulate = 0; 07631 } 07632 /* Let interrupts interrupt :) */ 07633 ast_set_flag(chan, AST_FLAG_WRITE_INT); 07634 return ts; 07635 }
static int tonepair_generator | ( | struct ast_channel * | chan, | |
void * | data, | |||
int | len, | |||
int | samples | |||
) | [static] |
Definition at line 7637 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.
07638 { 07639 struct tonepair_state *ts = data; 07640 int x; 07641 07642 /* we need to prepare a frame with 16 * timelen samples as we're 07643 * generating SLIN audio 07644 */ 07645 len = samples * 2; 07646 07647 if (len > sizeof(ts->data) / 2 - 1) { 07648 ast_log(LOG_WARNING, "Can't generate that much data!\n"); 07649 return -1; 07650 } 07651 memset(&ts->f, 0, sizeof(ts->f)); 07652 for (x=0;x<len/2;x++) { 07653 ts->v1_1 = ts->v2_1; 07654 ts->v2_1 = ts->v3_1; 07655 ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1; 07656 07657 ts->v1_2 = ts->v2_2; 07658 ts->v2_2 = ts->v3_2; 07659 ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2; 07660 if (ts->modulate) { 07661 int p; 07662 p = ts->v3_2 - 32768; 07663 if (p < 0) p = -p; 07664 p = ((p * 9) / 10) + 1; 07665 ts->data[x] = (ts->v3_1 * p) >> 15; 07666 } else 07667 ts->data[x] = ts->v3_1 + ts->v3_2; 07668 } 07669 ts->f.frametype = AST_FRAME_VOICE; 07670 ts->f.subclass.codec = AST_FORMAT_SLINEAR; 07671 ts->f.datalen = len; 07672 ts->f.samples = samples; 07673 ts->f.offset = AST_FRIENDLY_OFFSET; 07674 ts->f.data.ptr = ts->data; 07675 ast_write(chan, &ts->f); 07676 ts->pos += x; 07677 if (ts->duration > 0) { 07678 if (ts->pos >= ts->duration * 8) 07679 return -1; 07680 } 07681 return 0; 07682 }
static void tonepair_release | ( | struct ast_channel * | chan, | |
void * | params | |||
) | [static] |
Definition at line 7599 of file channel.c.
References ast_free, ast_set_write_format(), chanlist::chan, and tonepair_state::origwfmt.
Referenced by tonepair_alloc().
07600 { 07601 struct tonepair_state *ts = params; 07602 07603 if (chan) 07604 ast_set_write_format(chan, ts->origwfmt); 07605 ast_free(ts); 07606 }
static void update_bridge_vars | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1 | |||
) | [static] |
Definition at line 7198 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().
07199 { 07200 const char *c0_name; 07201 const char *c1_name; 07202 const char *c0_pvtid = NULL; 07203 const char *c1_pvtid = NULL; 07204 07205 ast_channel_lock(c1); 07206 c1_name = ast_strdupa(c1->name); 07207 if (c1->tech->get_pvt_uniqueid) { 07208 c1_pvtid = ast_strdupa(c1->tech->get_pvt_uniqueid(c1)); 07209 } 07210 ast_channel_unlock(c1); 07211 07212 ast_channel_lock(c0); 07213 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER"))) { 07214 pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1_name); 07215 } 07216 if (c1_pvtid) { 07217 pbx_builtin_setvar_helper(c0, "BRIDGEPVTCALLID", c1_pvtid); 07218 } 07219 c0_name = ast_strdupa(c0->name); 07220 if (c0->tech->get_pvt_uniqueid) { 07221 c0_pvtid = ast_strdupa(c0->tech->get_pvt_uniqueid(c0)); 07222 } 07223 ast_channel_unlock(c0); 07224 07225 ast_channel_lock(c1); 07226 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER"))) { 07227 pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0_name); 07228 } 07229 if (c0_pvtid) { 07230 pbx_builtin_setvar_helper(c1, "BRIDGEPVTCALLID", c0_pvtid); 07231 } 07232 ast_channel_unlock(c1); 07233 }
static void xfer_ds_destroy | ( | void * | data | ) | [static] |
Definition at line 6019 of file channel.c.
References ast_free, ast_party_connected_line_free(), xfer_masquerade_ds::target_id, and xfer_masquerade_ds::transferee_id.
06020 { 06021 struct xfer_masquerade_ds *ds = data; 06022 06023 ast_party_connected_line_free(&ds->target_id); 06024 ast_party_connected_line_free(&ds->transferee_id); 06025 ast_free(ds); 06026 }
struct ast_channel_tech ast_kill_tech |
Kill the channel channel driver technology descriptor.
The purpose of this channel technology is to encourage the channel to hangup as quickly as possible.
Definition at line 653 of file channel.c.
Referenced by ast_do_masquerade().
void(*) ast_moh_cleanup_ptr(struct ast_channel *) = NULL [static] |
Definition at line 7760 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 7758 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 7759 of file channel.c.
Referenced by ast_install_music_functions(), ast_moh_stop(), and ast_uninstall_music_functions().
int cause |
Definition at line 197 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 9418 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 7945 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 609 of file channel.c.
Referenced by ast_channels_init().
unsigned long global_fin |
The current value of the debug flags is stored in the two variables global_fin and global_fout (declared in main/channel.c)
Definition at line 97 of file channel.c.
Referenced by handle_core_set_debug_channel().
unsigned long global_fout |
struct ast_channel_tech null_tech [static] |
Initial value:
{ .type = "NULL", .description = "Null channel (should not see this)", }
Definition at line 1099 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 4683 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 8026 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 7684 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 6028 of file channel.c.
Referenced by ast_channel_transfer_masquerade(), and ast_do_masquerade().