#include "asterisk.h"
#include "asterisk/_private.h"
#include <sys/time.h>
#include <signal.h>
#include <math.h>
#include <sys/ioctl.h>
#include <dahdi/user.h>
#include "asterisk/paths.h"
#include "asterisk/pbx.h"
#include "asterisk/frame.h"
#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include "asterisk/musiconhold.h"
#include "asterisk/say.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/manager.h"
#include "asterisk/chanvars.h"
#include "asterisk/linkedlists.h"
#include "asterisk/indications.h"
#include "asterisk/monitor.h"
#include "asterisk/causes.h"
#include "asterisk/callerid.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/app.h"
#include "asterisk/transcap.h"
#include "asterisk/devicestate.h"
#include "asterisk/sha1.h"
#include "asterisk/threadstorage.h"
#include "asterisk/slinfactory.h"
#include "asterisk/audiohook.h"
Go to the source code of this file.
Data Structures | |
struct | ast_cause |
map AST_CAUSE's to readable string representations More... | |
struct | ast_epoll_data |
struct | ast_silence_generator |
struct | backends |
the list of registered channel types More... | |
struct | chanlist |
List of channel drivers. More... | |
struct | channels |
the list of channels we have. Note that the lock for this list is used for both the channels list and the backends list. More... | |
struct | tonepair_def |
struct | tonepair_state |
Defines | |
#define | AST_DEFAULT_EMULATE_DTMF_DURATION 100 |
#define | AST_MIN_DTMF_DURATION 80 |
#define | AST_MIN_DTMF_GAP 45 |
#define | FORMAT "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\n" |
#define | STATE2STR_BUFSIZE 32 |
Functions | |
int | __ast_answer (struct ast_channel *chan, unsigned int delay, int cdr_answer) |
Answer a channel, with a selectable delay before returning. | |
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 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 int amaflag, const char *file, int line, const char *function, const char *name_fmt, va_list ap1, va_list ap2) |
Create a new channel structure. | |
static int | __ast_queue_frame (struct ast_channel *chan, struct ast_frame *fin, int head, struct ast_frame *after) |
static struct ast_frame * | __ast_read (struct ast_channel *chan, int dropaudio) |
ast_channel * | __ast_request_and_dial (const char *type, int format, 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) |
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) |
Initiate system shutdown. | |
int | ast_best_codec (int 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, int format, struct outgoing_helper *oh, int *outstate) |
Forwards a call to a new channel specified by the original channel's call_forward str. If possible, the new forwarded channel is created and returned while the original one is terminated. | |
void | ast_cancel_shutdown (void) |
Cancel a shutdown in progress. | |
const char * | ast_cause2str (int cause) |
Gives the string form of a given hangup cause. | |
void | ast_change_name (struct ast_channel *chan, 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 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. | |
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_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 datastore structure. | |
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 datastore structure. | |
int | ast_channel_datastore_inherit (struct ast_channel *from, struct ast_channel *to) |
Inherit datastores from a parent to a child. | |
int | ast_channel_datastore_remove (struct ast_channel *chan, struct ast_datastore *datastore) |
Remove a datastore from a channel. | |
int | ast_channel_defer_dtmf (struct ast_channel *chan) |
Set defer DTMF flag on channel. | |
int | ast_channel_early_bridge (struct ast_channel *c0, struct ast_channel *c1) |
Bridge two channels together (early). | |
void | ast_channel_free (struct ast_channel *chan) |
Free a channel structure. | |
void | ast_channel_inherit_variables (const struct ast_channel *parent, struct ast_channel *child) |
Inherits channel variable from parent to child channel. | |
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) |
const char * | ast_channel_reason2str (int reason) |
return an english explanation of the code returned thru __ast_request_and_dial's 'outstate' argument | |
int | ast_channel_register (const struct ast_channel_tech *tech) |
Register a channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports. | |
int | ast_channel_sendhtml (struct ast_channel *chan, int subclass, const char *data, int datalen) |
int | ast_channel_sendurl (struct ast_channel *chan, const char *url) |
void | ast_channel_set_fd (struct ast_channel *chan, int which, int fd) |
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. | |
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) |
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. | |
ast_channel * | ast_channel_walk_locked (const struct ast_channel *prev) |
Browse channels in use Browse the channels currently in use. | |
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. | |
static int | ast_check_hangup_locked (struct ast_channel *chan) |
void | ast_deactivate_generator (struct ast_channel *chan) |
int | ast_do_masquerade (struct ast_channel *original) |
Start masquerading a channel XXX This is a seriously whacked out operation. We're essentially putting the guts of the clone channel into the original channel. Start by killing off the original channel's backend. I'm not sure we're going to keep this function, because while the features are nice, the cost is very high in terms of pure nastiness. XXX. | |
static enum ast_bridge_result | ast_generic_bridge (struct ast_channel *c0, struct ast_channel *c1, struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc, struct timeval bridge_end) |
ast_channel * | ast_get_channel_by_exten_locked (const char *exten, const char *context) |
Get channel by exten (and optionally context) and lock it. | |
ast_channel * | ast_get_channel_by_name_locked (const char *name) |
Get channel by name or uniqueid (locks channel). | |
ast_channel * | ast_get_channel_by_name_prefix_locked (const char *name, const int namelen) |
Get channel by name or uniqueid prefix (locks channel). | |
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. | |
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_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_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) |
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. | |
ast_channel * | ast_request (const char *type, int format, void *data, int *cause) |
Requests a channel. | |
ast_channel * | ast_request_and_dial (const char *type, int format, 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) |
int | ast_say_digits (struct ast_channel *chan, int num, const char *ints, const char *lang) |
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) |
int | ast_say_number (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options) |
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 Send a DTMF digit to a channel. | |
int | ast_senddigit_begin (struct ast_channel *chan, char digit) |
Send a DTMF digit to a channel 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. | |
int | ast_set_read_format (struct ast_channel *chan, int fmt) |
Sets read format on channel chan Set read format for channel to whichever component of "format" is best. | |
void | ast_set_variables (struct ast_channel *chan, struct ast_variable *vars) |
adds a list of channel variables to a channel | |
int | ast_set_write_format (struct ast_channel *chan, int fmt) |
Sets write format on channel chan Set write format for channel to whichever component of "format" is best. | |
int | ast_setstate (struct ast_channel *chan, enum ast_channel_state state) |
Change the state of a channel. | |
int | ast_settimeout (struct ast_channel *c, int samples, int(*func)(const void *data), void *data) |
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 a symbolic hangup cause to number. | |
int | ast_tonepair (struct ast_channel *chan, int freq1, int freq2, int duration, int vol) |
int | ast_tonepair_start (struct ast_channel *chan, int freq1, int freq2, int duration, int vol) |
void | ast_tonepair_stop (struct ast_channel *chan) |
int | ast_transfer (struct ast_channel *chan, char *dest) |
Transfer a channel (if supported). Returns -1 on error, 0 if not supported and 1 if supported and requested. | |
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 This version works on fd's only. Be careful with it. | |
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. | |
ast_channel * | ast_walk_channel_by_exten_locked (const struct ast_channel *chan, const char *exten, const char *context) |
Get next channel by exten (and optionally context) and lock it. | |
ast_channel * | ast_walk_channel_by_name_prefix_locked (const struct ast_channel *chan, const char *name, const int namelen) |
Get channel by name or uniqueid prefix (locks channel). | |
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_playfile (struct ast_channel *chan, struct ast_channel *peer, const char *sound, int remain) |
static struct ast_channel * | channel_find_locked (const struct ast_channel *prev, const char *name, const int namelen, const char *context, const char *exten) |
Helper function to find channels. | |
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 *clone) |
Clone channel variables from 'clone' channel into 'original' channel. | |
static char * | complete_channeltypes (struct ast_cli_args *a) |
static void | free_cid (struct ast_callerid *cid) |
static void | free_translation (struct ast_channel *clone) |
static int | generator_force (const void *data) |
static void | handle_cause (int cause, int *outstate) |
static char * | handle_cli_core_show_channeltype (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show details about a channel driver - CLI command. | |
static char * | handle_cli_core_show_channeltypes (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show channel types - CLI command. | |
static int attribute_const | is_visible_indication (enum ast_control_frame_type condition) |
static void | manager_bridge_event (int onoff, int type, struct ast_channel *c0, struct ast_channel *c1) |
Send manager event for bridge link and unlink events. | |
static void | queue_dtmf_readq (struct ast_channel *chan, struct ast_frame *f) |
static void | report_new_callerid (const struct ast_channel *chan) |
static void | send_dtmf_event (const struct ast_channel *chan, const char *direction, const char digit, const char *begin, const char *end) |
static int | set_format (struct ast_channel *chan, int fmt, int *rawformat, int *format, struct ast_trans_pvt **trans, const int direction) |
static int | should_skip_dtmf (struct ast_channel *chan) |
Determine whether or not we should ignore DTMF in the readq. | |
static void * | silence_generator_alloc (struct ast_channel *chan, void *data) |
static int | silence_generator_generate (struct ast_channel *chan, void *data, int len, int samples) |
static void | silence_generator_release (struct ast_channel *chan, void *data) |
static void * | tonepair_alloc (struct ast_channel *chan, void *params) |
static int | tonepair_generator (struct ast_channel *chan, void *data, int len, int samples) |
static void | tonepair_release (struct ast_channel *chan, void *params) |
static void | update_bridge_vars (struct ast_channel *c0, struct ast_channel *c1) |
Variables | |
static void(*) | ast_moh_cleanup_ptr (struct ast_channel *) = NULL |
static int(*) | ast_moh_start_ptr (struct ast_channel *, const char *, const char *) = NULL |
static void(*) | ast_moh_stop_ptr (struct ast_channel *) = NULL |
ast_cause | causes [] |
map AST_CAUSE's to readable string representations | |
static struct ast_cli_entry | cli_channel [] |
unsigned long | global_fin |
unsigned long | global_fout |
static struct ast_channel_tech | null_tech |
static int | shutting_down |
Prevent new channel allocation if shutting down. | |
static struct ast_generator | silence_generator |
static struct ast_threadstorage | state2str_threadbuf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_state2str_threadbuf , .custom_init = NULL , } |
static struct ast_generator | tonepair |
static int | uniqueint |
Definition in file channel.c.
#define AST_DEFAULT_EMULATE_DTMF_DURATION 100 |
Default amount of time to use when emulating a digit as a begin and end 100ms
Definition at line 95 of file channel.c.
Referenced by __ast_read(), and ast_senddigit().
#define AST_MIN_DTMF_DURATION 80 |
Minimum allowed digit length - 80ms
Definition at line 98 of file channel.c.
Referenced by __ast_read().
#define AST_MIN_DTMF_GAP 45 |
Minimum amount of time between the end of the last digit and the beginning of a new one - 45ms
Definition at line 102 of file channel.c.
Referenced by __ast_read(), and should_skip_dtmf().
#define FORMAT "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\n" |
#define STATE2STR_BUFSIZE 32 |
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 1791 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, ast_frame::frame_list, frames, ast_frame::frametype, LOG_WARNING, MAX, ast_channel::name, and ast_frame::subclass.
Referenced by ast_answer(), dial_exec_full(), and pbx_builtin_answer().
01792 { 01793 int res = 0; 01794 enum ast_channel_state old_state; 01795 01796 old_state = chan->_state; 01797 if ((res = ast_raw_answer(chan, cdr_answer))) { 01798 return res; 01799 } 01800 01801 switch (old_state) { 01802 case AST_STATE_RINGING: 01803 case AST_STATE_RING: 01804 /* wait for media to start flowing, but don't wait any longer 01805 * than 'delay' or 500 milliseconds, whichever is longer 01806 */ 01807 do { 01808 AST_LIST_HEAD_NOLOCK(, ast_frame) frames; 01809 struct ast_frame *cur, *new; 01810 int ms = MAX(delay, 500); 01811 unsigned int done = 0; 01812 01813 AST_LIST_HEAD_INIT_NOLOCK(&frames); 01814 01815 for (;;) { 01816 ms = ast_waitfor(chan, ms); 01817 if (ms < 0) { 01818 ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", chan->name, strerror(errno)); 01819 res = -1; 01820 break; 01821 } 01822 if (ms == 0) { 01823 ast_debug(2, "Didn't receive a media frame from %s within %d ms of answering. Continuing anyway\n", chan->name, MAX(delay, 500)); 01824 break; 01825 } 01826 cur = ast_read(chan); 01827 if (!cur || ((cur->frametype == AST_FRAME_CONTROL) && 01828 (cur->subclass == AST_CONTROL_HANGUP))) { 01829 if (cur) { 01830 ast_frfree(cur); 01831 } 01832 res = -1; 01833 ast_debug(2, "Hangup of channel %s detected in answer routine\n", chan->name); 01834 break; 01835 } 01836 01837 if ((new = ast_frisolate(cur)) != cur) { 01838 ast_frfree(cur); 01839 } 01840 01841 AST_LIST_INSERT_HEAD(&frames, new, frame_list); 01842 01843 /* if a specific delay period was requested, continue 01844 * until that delay has passed. don't stop just because 01845 * incoming media has arrived. 01846 */ 01847 if (delay) { 01848 continue; 01849 } 01850 01851 switch (new->frametype) { 01852 /* all of these frametypes qualify as 'media' */ 01853 case AST_FRAME_VOICE: 01854 case AST_FRAME_VIDEO: 01855 case AST_FRAME_TEXT: 01856 case AST_FRAME_DTMF_BEGIN: 01857 case AST_FRAME_DTMF_END: 01858 case AST_FRAME_IMAGE: 01859 case AST_FRAME_HTML: 01860 case AST_FRAME_MODEM: 01861 done = 1; 01862 break; 01863 case AST_FRAME_CONTROL: 01864 case AST_FRAME_IAX: 01865 case AST_FRAME_NULL: 01866 case AST_FRAME_CNG: 01867 break; 01868 } 01869 01870 if (done) { 01871 break; 01872 } 01873 } 01874 01875 if (res == 0) { 01876 ast_channel_lock(chan); 01877 while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list))) { 01878 ast_queue_frame_head(chan, cur); 01879 ast_frfree(cur); 01880 } 01881 ast_channel_unlock(chan); 01882 } 01883 } while (0); 01884 break; 01885 default: 01886 break; 01887 } 01888 01889 return res; 01890 }
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 int | amaflag, | |||
const char * | file, | |||
int | line, | |||
const char * | function, | |||
const char * | name_fmt, | |||
... | ||||
) |
Create a channel structure.
NULL | failure | |
non-NULL | successfully allocated channel |
Definition at line 965 of file channel.c.
References __ast_channel_alloc_ap().
00970 { 00971 va_list ap1, ap2; 00972 struct ast_channel *result; 00973 00974 va_start(ap1, name_fmt); 00975 va_start(ap2, name_fmt); 00976 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context, 00977 amaflag, file, line, function, name_fmt, ap1, ap2); 00978 va_end(ap1); 00979 va_end(ap2); 00980 00981 return result; 00982 }
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 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 765 of file channel.c.
References __ast_calloc(), accountcode, AST_ALERT_FD, ast_atomic_fetchadd_int(), ast_calloc, ast_cdr_alloc(), ast_cdr_init(), ast_cdr_start(), ast_channel_set_fd(), ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_default_accountcode, ast_default_amaflags, ast_free, AST_LIST_HEAD_INIT_NOLOCK, ast_log(), AST_MAX_FDS, ast_mutex_init(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_state2str(), ast_strdup, ast_string_field_build, ast_string_field_build_va, ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), AST_TIMING_FD, defaultlanguage, errno, EVENT_FLAG_CALL, chanlist::flags, language, LOG_WARNING, manager_event, name, null_tech, S_OR, sched_context_create(), and sched_context_destroy().
Referenced by __ast_channel_alloc(), and ast_channel_alloc().
00769 { 00770 struct ast_channel *tmp; 00771 int x; 00772 int flags; 00773 struct varshead *headp; 00774 00775 /* If shutting down, don't allocate any new channels */ 00776 if (shutting_down) { 00777 ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n"); 00778 return NULL; 00779 } 00780 00781 #if defined(__AST_DEBUG_MALLOC) 00782 if (!(tmp = __ast_calloc(1, sizeof(*tmp), file, line, function))) { 00783 return NULL; 00784 } 00785 #else 00786 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { 00787 return NULL; 00788 } 00789 #endif 00790 00791 if (!(tmp->sched = sched_context_create())) { 00792 ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n"); 00793 ast_free(tmp); 00794 return NULL; 00795 } 00796 00797 if ((ast_string_field_init(tmp, 128))) { 00798 sched_context_destroy(tmp->sched); 00799 ast_free(tmp); 00800 return NULL; 00801 } 00802 00803 #ifdef HAVE_EPOLL 00804 tmp->epfd = epoll_create(25); 00805 #endif 00806 00807 for (x = 0; x < AST_MAX_FDS; x++) { 00808 tmp->fds[x] = -1; 00809 #ifdef HAVE_EPOLL 00810 tmp->epfd_data[x] = NULL; 00811 #endif 00812 } 00813 00814 #ifdef HAVE_DAHDI 00815 tmp->timingfd = open("/dev/dahdi/timer", O_RDWR); 00816 if (tmp->timingfd > -1) { 00817 /* Check if timing interface supports new 00818 ping/pong scheme */ 00819 flags = 1; 00820 if (!ioctl(tmp->timingfd, DAHDI_TIMERPONG, &flags)) 00821 needqueue = 0; 00822 } 00823 #else 00824 tmp->timingfd = -1; 00825 #endif 00826 00827 if (needqueue) { 00828 if (pipe(tmp->alertpipe)) { 00829 ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n"); 00830 alertpipe_failed: 00831 #ifdef HAVE_DAHDI 00832 if (tmp->timingfd > -1) 00833 close(tmp->timingfd); 00834 #endif 00835 sched_context_destroy(tmp->sched); 00836 ast_string_field_free_memory(tmp); 00837 ast_free(tmp); 00838 return NULL; 00839 } else { 00840 flags = fcntl(tmp->alertpipe[0], F_GETFL); 00841 if (fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) { 00842 ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno)); 00843 close(tmp->alertpipe[0]); 00844 close(tmp->alertpipe[1]); 00845 goto alertpipe_failed; 00846 } 00847 flags = fcntl(tmp->alertpipe[1], F_GETFL); 00848 if (fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK) < 0) { 00849 ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno)); 00850 close(tmp->alertpipe[0]); 00851 close(tmp->alertpipe[1]); 00852 goto alertpipe_failed; 00853 } 00854 } 00855 } else /* Make sure we've got it done right if they don't */ 00856 tmp->alertpipe[0] = tmp->alertpipe[1] = -1; 00857 00858 /* Always watch the alertpipe */ 00859 ast_channel_set_fd(tmp, AST_ALERT_FD, tmp->alertpipe[0]); 00860 /* And timing pipe */ 00861 ast_channel_set_fd(tmp, AST_TIMING_FD, tmp->timingfd); 00862 ast_string_field_set(tmp, name, "**Unknown**"); 00863 00864 /* Initial state */ 00865 tmp->_state = state; 00866 00867 tmp->streamid = -1; 00868 00869 tmp->fin = global_fin; 00870 tmp->fout = global_fout; 00871 00872 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) { 00873 ast_string_field_build(tmp, uniqueid, "%li.%d", (long) time(NULL), 00874 ast_atomic_fetchadd_int(&uniqueint, 1)); 00875 } else { 00876 ast_string_field_build(tmp, uniqueid, "%s-%li.%d", ast_config_AST_SYSTEM_NAME, 00877 (long) time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1)); 00878 } 00879 00880 tmp->cid.cid_name = ast_strdup(cid_name); 00881 tmp->cid.cid_num = ast_strdup(cid_num); 00882 00883 if (!ast_strlen_zero(name_fmt)) { 00884 /* Almost every channel is calling this function, and setting the name via the ast_string_field_build() call. 00885 * And they all use slightly different formats for their name string. 00886 * This means, to set the name here, we have to accept variable args, and call the string_field_build from here. 00887 * This means, that the stringfields must have a routine that takes the va_lists directly, and 00888 * uses them to build the string, instead of forming the va_lists internally from the vararg ... list. 00889 * This new function was written so this can be accomplished. 00890 */ 00891 ast_string_field_build_va(tmp, name, name_fmt, ap1, ap2); 00892 } 00893 00894 /* Reminder for the future: under what conditions do we NOT want to track cdrs on channels? */ 00895 00896 /* These 4 variables need to be set up for the cdr_init() to work right */ 00897 if (amaflag) 00898 tmp->amaflags = amaflag; 00899 else 00900 tmp->amaflags = ast_default_amaflags; 00901 00902 if (!ast_strlen_zero(acctcode)) 00903 ast_string_field_set(tmp, accountcode, acctcode); 00904 else 00905 ast_string_field_set(tmp, accountcode, ast_default_accountcode); 00906 00907 if (!ast_strlen_zero(context)) 00908 ast_copy_string(tmp->context, context, sizeof(tmp->context)); 00909 else 00910 strcpy(tmp->context, "default"); 00911 00912 if (!ast_strlen_zero(exten)) 00913 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); 00914 else 00915 strcpy(tmp->exten, "s"); 00916 00917 tmp->priority = 1; 00918 00919 tmp->cdr = ast_cdr_alloc(); 00920 ast_cdr_init(tmp->cdr, tmp); 00921 ast_cdr_start(tmp->cdr); 00922 00923 headp = &tmp->varshead; 00924 AST_LIST_HEAD_INIT_NOLOCK(headp); 00925 00926 ast_mutex_init(&tmp->lock_dont_use); 00927 00928 AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores); 00929 00930 ast_string_field_set(tmp, language, defaultlanguage); 00931 00932 tmp->tech = &null_tech; 00933 00934 AST_RWLIST_WRLOCK(&channels); 00935 AST_RWLIST_INSERT_HEAD(&channels, tmp, chan_list); 00936 AST_RWLIST_UNLOCK(&channels); 00937 00938 /*\!note 00939 * and now, since the channel structure is built, and has its name, let's 00940 * call the manager event generator with this Newchannel event. This is the 00941 * proper and correct place to make this call, but you sure do have to pass 00942 * a lot of data into this func to do it here! 00943 */ 00944 if (!ast_strlen_zero(name_fmt)) { 00945 manager_event(EVENT_FLAG_CALL, "Newchannel", 00946 "Channel: %s\r\n" 00947 "ChannelState: %d\r\n" 00948 "ChannelStateDesc: %s\r\n" 00949 "CallerIDNum: %s\r\n" 00950 "CallerIDName: %s\r\n" 00951 "AccountCode: %s\r\n" 00952 "Uniqueid: %s\r\n", 00953 tmp->name, 00954 state, 00955 ast_state2str(state), 00956 S_OR(cid_num, ""), 00957 S_OR(cid_name, ""), 00958 tmp->accountcode, 00959 tmp->uniqueid); 00960 } 00961 00962 return tmp; 00963 }
static int __ast_queue_frame | ( | struct ast_channel * | chan, | |
struct ast_frame * | fin, | |||
int | head, | |||
struct ast_frame * | after | |||
) | [static] |
Definition at line 984 of file channel.c.
References ast_channel::alertpipe, ast_channel_lock, ast_channel_unlock, AST_CONTROL_HANGUP, AST_FLAG_BLOCKING, AST_FRAME_CONTROL, AST_FRAME_VOICE, ast_frdup(), ast_frfree, AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_LIST_AFTER, AST_LIST_INSERT_TAIL, AST_LIST_LAST, AST_LIST_NEXT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, ast_log(), ast_test_flag, ast_channel::blocker, chanlist::chan, errno, f, ast_frame::frame_list, frames, ast_frame::frametype, LOG_WARNING, ast_channel::name, ast_channel::readq, ast_frame::subclass, and ast_channel::timingfd.
Referenced by __ast_read(), ast_queue_frame(), and ast_queue_frame_head().
00985 { 00986 struct ast_frame *f; 00987 struct ast_frame *cur; 00988 int blah = 1; 00989 unsigned int new_frames = 0; 00990 unsigned int new_voice_frames = 0; 00991 unsigned int queued_frames = 0; 00992 unsigned int queued_voice_frames = 0; 00993 AST_LIST_HEAD_NOLOCK(, ast_frame) frames; 00994 00995 ast_channel_lock(chan); 00996 00997 /* See if the last frame on the queue is a hangup, if so don't queue anything */ 00998 if ((cur = AST_LIST_LAST(&chan->readq)) && 00999 (cur->frametype == AST_FRAME_CONTROL) && 01000 (cur->subclass == AST_CONTROL_HANGUP)) { 01001 ast_channel_unlock(chan); 01002 return 0; 01003 } 01004 01005 /* Build copies of all the frames and count them */ 01006 AST_LIST_HEAD_INIT_NOLOCK(&frames); 01007 for (cur = fin; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 01008 if (!(f = ast_frdup(cur))) { 01009 ast_frfree(AST_LIST_FIRST(&frames)); 01010 return -1; 01011 } 01012 01013 AST_LIST_INSERT_TAIL(&frames, f, frame_list); 01014 new_frames++; 01015 if (f->frametype == AST_FRAME_VOICE) { 01016 new_voice_frames++; 01017 } 01018 } 01019 01020 /* Count how many frames exist on the queue */ 01021 AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) { 01022 queued_frames++; 01023 if (cur->frametype == AST_FRAME_VOICE) { 01024 queued_voice_frames++; 01025 } 01026 } 01027 01028 if ((queued_frames + new_frames) > 128) { 01029 ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name); 01030 while ((f = AST_LIST_REMOVE_HEAD(&frames, frame_list))) { 01031 ast_frfree(f); 01032 } 01033 ast_channel_unlock(chan); 01034 return 0; 01035 } 01036 01037 if ((queued_voice_frames + new_voice_frames) > 96) { 01038 ast_log(LOG_WARNING, "Exceptionally long voice queue length queuing to %s\n", chan->name); 01039 while ((f = AST_LIST_REMOVE_HEAD(&frames, frame_list))) { 01040 ast_frfree(f); 01041 } 01042 ast_channel_unlock(chan); 01043 return 0; 01044 } 01045 01046 if (after) { 01047 AST_LIST_INSERT_LIST_AFTER(&chan->readq, &frames, after, frame_list); 01048 } else { 01049 if (head) { 01050 AST_LIST_APPEND_LIST(&frames, &chan->readq, frame_list); 01051 AST_LIST_HEAD_INIT_NOLOCK(&chan->readq); 01052 } 01053 AST_LIST_APPEND_LIST(&chan->readq, &frames, frame_list); 01054 } 01055 01056 if (chan->alertpipe[1] > -1) { 01057 if (write(chan->alertpipe[1], &blah, new_frames * sizeof(blah)) != (new_frames * sizeof(blah))) { 01058 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s (qlen = %d): %s!\n", 01059 chan->name, queued_frames, strerror(errno)); 01060 } 01061 #ifdef HAVE_DAHDI 01062 } else if (chan->timingfd > -1) { 01063 ioctl(chan->timingfd, DAHDI_TIMERPING, &blah); 01064 #endif 01065 } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 01066 pthread_kill(chan->blocker, SIGURG); 01067 } 01068 01069 ast_channel_unlock(chan); 01070 01071 return 0; 01072 }
static struct ast_frame* __ast_read | ( | struct ast_channel * | chan, | |
int | dropaudio | |||
) | [static] |
Definition at line 2552 of file channel.c.
References __ast_queue_frame(), ast_channel::_softhangup, ast_channel::_state, ast_channel::alertpipe, AST_AUDIOHOOK_DIRECTION_READ, ast_audiohook_write_list(), ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, ast_deactivate_generator(), ast_debug, AST_DEFAULT_EMULATE_DTMF_DURATION, ast_do_masquerade(), AST_FLAG_DEFER_DTMF, AST_FLAG_EMULATE_DTMF, AST_FLAG_END_DTMF_ONLY, AST_FLAG_EXCEPTION, AST_FLAG_IN_DTMF, AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_frame_dump(), AST_FRAME_NULL, AST_FRAME_VOICE, ast_frfree, AST_GENERATOR_FD, ast_getformatname(), ast_getformatname_multiple(), AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_LAST, AST_LIST_NEXT, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), AST_MIN_DTMF_DURATION, AST_MIN_DTMF_GAP, AST_MONITOR_RUNNING, ast_null_frame, ast_queue_frame(), ast_queue_frame_head(), ast_read_generator_actions(), ast_seekstream(), ast_set_flag, ast_setstate(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_test_flag, AST_TIMING_FD, ast_translate(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_writestream(), ast_channel::audiohooks, ast_channel::blocker, chanlist::chan, DEBUGCHAN_FLAG, ast_generator::digit, ast_channel::dtmf_tv, ast_channel::dtmff, ast_channel::emulate_dtmf_digit, ast_channel::emulate_dtmf_duration, errno, ast_channel_tech::exception, f, ast_channel::fdno, ast_channel::fds, ast_channel::fin, chanlist::flags, ast_frame::frame_list, FRAMECOUNT_INC, ast_generator::generate, ast_channel::generator, ast_channel::generatordata, 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, 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::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.
Referenced by ast_read(), and ast_read_noaudio().
02553 { 02554 struct ast_frame *f = NULL; /* the return value */ 02555 int blah; 02556 int prestate; 02557 int count = 0; 02558 02559 /* this function is very long so make sure there is only one return 02560 * point at the end (there are only two exceptions to this). 02561 */ 02562 while(ast_channel_trylock(chan)) { 02563 if(count++ > 10) 02564 /*cannot goto done since the channel is not locked*/ 02565 return &ast_null_frame; 02566 usleep(1); 02567 } 02568 02569 if (chan->masq) { 02570 if (ast_do_masquerade(chan)) 02571 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 02572 else 02573 f = &ast_null_frame; 02574 goto done; 02575 } 02576 02577 /* Stop if we're a zombie or need a soft hangup */ 02578 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02579 if (chan->generator) 02580 ast_deactivate_generator(chan); 02581 goto done; 02582 } 02583 02584 if (chan->fdno == -1) { 02585 #ifdef AST_DEVMODE 02586 ast_log(LOG_ERROR, "ast_read() called with no recorded file descriptor.\n"); 02587 #else 02588 ast_debug(2, "ast_read() called with no recorded file descriptor.\n"); 02589 #endif 02590 f = &ast_null_frame; 02591 goto done; 02592 } 02593 prestate = chan->_state; 02594 02595 /* Read and ignore anything on the alertpipe, but read only 02596 one sizeof(blah) per frame that we send from it */ 02597 if (chan->alertpipe[0] > -1) { 02598 int flags = fcntl(chan->alertpipe[0], F_GETFL); 02599 /* For some odd reason, the alertpipe occasionally loses nonblocking status, 02600 * which immediately causes a deadlock scenario. Detect and prevent this. */ 02601 if ((flags & O_NONBLOCK) == 0) { 02602 ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", chan->name); 02603 if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) { 02604 ast_log(LOG_WARNING, "Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno)); 02605 f = &ast_null_frame; 02606 goto done; 02607 } 02608 } 02609 if (read(chan->alertpipe[0], &blah, sizeof(blah)) < 0) { 02610 if (errno != EINTR && errno != EAGAIN) { 02611 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 02612 } 02613 } 02614 } 02615 02616 #ifdef HAVE_DAHDI 02617 if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD && ast_test_flag(chan, AST_FLAG_EXCEPTION)) { 02618 int res; 02619 02620 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 02621 blah = -1; 02622 /* IF we can't get event, assume it's an expired as-per the old interface */ 02623 res = ioctl(chan->timingfd, DAHDI_GETEVENT, &blah); 02624 if (res) 02625 blah = DAHDI_EVENT_TIMER_EXPIRED; 02626 02627 if (blah == DAHDI_EVENT_TIMER_PING) { 02628 if (AST_LIST_EMPTY(&chan->readq) || !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) { 02629 /* Acknowledge PONG unless we need it again */ 02630 if (ioctl(chan->timingfd, DAHDI_TIMERPONG, &blah)) { 02631 ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno)); 02632 } 02633 } 02634 } else if (blah == DAHDI_EVENT_TIMER_EXPIRED) { 02635 ioctl(chan->timingfd, DAHDI_TIMERACK, &blah); 02636 if (chan->timingfunc) { 02637 /* save a copy of func/data before unlocking the channel */ 02638 int (*func)(const void *) = chan->timingfunc; 02639 void *data = chan->timingdata; 02640 chan->fdno = -1; 02641 ast_channel_unlock(chan); 02642 func(data); 02643 } else { 02644 blah = 0; 02645 ioctl(chan->timingfd, DAHDI_TIMERCONFIG, &blah); 02646 chan->timingdata = NULL; 02647 chan->fdno = -1; 02648 ast_channel_unlock(chan); 02649 } 02650 /* cannot 'goto done' because the channel is already unlocked */ 02651 return &ast_null_frame; 02652 } else 02653 ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name); 02654 } else 02655 #endif 02656 if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) { 02657 /* if the AST_GENERATOR_FD is set, call the generator with args 02658 * set to -1 so it can do whatever it needs to. 02659 */ 02660 void *tmp = chan->generatordata; 02661 chan->generatordata = NULL; /* reset to let ast_write get through */ 02662 chan->generator->generate(chan, tmp, -1, -1); 02663 chan->generatordata = tmp; 02664 f = &ast_null_frame; 02665 chan->fdno = -1; 02666 goto done; 02667 } 02668 02669 /* Check for pending read queue */ 02670 if (!AST_LIST_EMPTY(&chan->readq)) { 02671 int skip_dtmf = should_skip_dtmf(chan); 02672 02673 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, f, frame_list) { 02674 /* We have to be picky about which frame we pull off of the readq because 02675 * there are cases where we want to leave DTMF frames on the queue until 02676 * some later time. */ 02677 02678 if ( (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && skip_dtmf) { 02679 continue; 02680 } 02681 02682 AST_LIST_REMOVE_CURRENT(frame_list); 02683 break; 02684 } 02685 AST_LIST_TRAVERSE_SAFE_END 02686 02687 if (!f) { 02688 /* There were no acceptable frames on the readq. */ 02689 f = &ast_null_frame; 02690 if (chan->alertpipe[0] > -1) { 02691 int poke = 0; 02692 /* Restore the state of the alertpipe since we aren't ready for any 02693 * of the frames in the readq. */ 02694 if (write(chan->alertpipe[1], &poke, sizeof(poke)) != sizeof(poke)) { 02695 ast_log(LOG_ERROR, "Failed to write to alertpipe: %s\n", strerror(errno)); 02696 } 02697 } 02698 } 02699 02700 /* Interpret hangup and return NULL */ 02701 /* XXX why not the same for frames from the channel ? */ 02702 if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) { 02703 ast_frfree(f); 02704 f = NULL; 02705 } 02706 } else { 02707 chan->blocker = pthread_self(); 02708 if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) { 02709 if (chan->tech->exception) 02710 f = chan->tech->exception(chan); 02711 else { 02712 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name); 02713 f = &ast_null_frame; 02714 } 02715 /* Clear the exception flag */ 02716 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 02717 } else if (chan->tech->read) 02718 f = chan->tech->read(chan); 02719 else 02720 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name); 02721 } 02722 02723 /* 02724 * Reset the recorded file descriptor that triggered this read so that we can 02725 * easily detect when ast_read() is called without properly using ast_waitfor(). 02726 */ 02727 chan->fdno = -1; 02728 02729 if (f) { 02730 struct ast_frame *readq_tail = AST_LIST_LAST(&chan->readq); 02731 02732 /* if the channel driver returned more than one frame, stuff the excess 02733 into the readq for the next ast_read call 02734 */ 02735 if (AST_LIST_NEXT(f, frame_list)) { 02736 ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list)); 02737 ast_frfree(AST_LIST_NEXT(f, frame_list)); 02738 AST_LIST_NEXT(f, frame_list) = NULL; 02739 } 02740 02741 switch (f->frametype) { 02742 case AST_FRAME_CONTROL: 02743 if (f->subclass == AST_CONTROL_ANSWER) { 02744 if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) { 02745 ast_debug(1, "Ignoring answer on an inbound call!\n"); 02746 ast_frfree(f); 02747 f = &ast_null_frame; 02748 } else if (prestate == AST_STATE_UP) { 02749 ast_debug(1, "Dropping duplicate answer!\n"); 02750 ast_frfree(f); 02751 f = &ast_null_frame; 02752 } else { 02753 /* Answer the CDR */ 02754 ast_setstate(chan, AST_STATE_UP); 02755 /* removed a call to ast_cdr_answer(chan->cdr) from here. */ 02756 } 02757 } 02758 break; 02759 case AST_FRAME_DTMF_END: 02760 send_dtmf_event(chan, "Received", f->subclass, "No", "Yes"); 02761 ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass, chan->name, f->len); 02762 /* Queue it up if DTMF is deferred, or if DTMF emulation is forced. */ 02763 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) || ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) { 02764 queue_dtmf_readq(chan, f); 02765 ast_frfree(f); 02766 f = &ast_null_frame; 02767 } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) { 02768 if (!ast_tvzero(chan->dtmf_tv) && 02769 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) { 02770 /* If it hasn't been long enough, defer this digit */ 02771 queue_dtmf_readq(chan, f); 02772 ast_frfree(f); 02773 f = &ast_null_frame; 02774 } else { 02775 /* There was no begin, turn this into a begin and send the end later */ 02776 f->frametype = AST_FRAME_DTMF_BEGIN; 02777 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF); 02778 chan->emulate_dtmf_digit = f->subclass; 02779 chan->dtmf_tv = ast_tvnow(); 02780 if (f->len) { 02781 if (f->len > AST_MIN_DTMF_DURATION) 02782 chan->emulate_dtmf_duration = f->len; 02783 else 02784 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION; 02785 } else 02786 chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION; 02787 ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass, chan->emulate_dtmf_duration, chan->name); 02788 } 02789 if (chan->audiohooks) { 02790 struct ast_frame *old_frame = f; 02791 /*! 02792 * \todo XXX It is possible to write a digit to the audiohook twice 02793 * if the digit was originally read while the channel was in autoservice. */ 02794 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 02795 if (old_frame != f) 02796 ast_frfree(old_frame); 02797 } 02798 } else { 02799 struct timeval now = ast_tvnow(); 02800 if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) { 02801 ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass, chan->name); 02802 ast_clear_flag(chan, AST_FLAG_IN_DTMF); 02803 if (!f->len) 02804 f->len = ast_tvdiff_ms(now, chan->dtmf_tv); 02805 } else if (!f->len) { 02806 ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass, chan->name); 02807 f->len = AST_MIN_DTMF_DURATION; 02808 } 02809 if (f->len < AST_MIN_DTMF_DURATION && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) { 02810 ast_log(LOG_DTMF, "DTMF end '%c' has duration %ld but want minimum %d, emulating on %s\n", f->subclass, f->len, AST_MIN_DTMF_DURATION, chan->name); 02811 ast_set_flag(chan, AST_FLAG_EMULATE_DTMF); 02812 chan->emulate_dtmf_digit = f->subclass; 02813 chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len; 02814 ast_frfree(f); 02815 f = &ast_null_frame; 02816 } else { 02817 ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass, chan->name); 02818 if (f->len < AST_MIN_DTMF_DURATION) { 02819 f->len = AST_MIN_DTMF_DURATION; 02820 } 02821 chan->dtmf_tv = now; 02822 } 02823 if (chan->audiohooks) { 02824 struct ast_frame *old_frame = f; 02825 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 02826 if (old_frame != f) 02827 ast_frfree(old_frame); 02828 } 02829 } 02830 break; 02831 case AST_FRAME_DTMF_BEGIN: 02832 send_dtmf_event(chan, "Received", f->subclass, "Yes", "No"); 02833 ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass, chan->name); 02834 if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) || 02835 (!ast_tvzero(chan->dtmf_tv) && 02836 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) { 02837 ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass, chan->name); 02838 ast_frfree(f); 02839 f = &ast_null_frame; 02840 } else { 02841 ast_set_flag(chan, AST_FLAG_IN_DTMF); 02842 chan->dtmf_tv = ast_tvnow(); 02843 ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass, chan->name); 02844 } 02845 break; 02846 case AST_FRAME_NULL: 02847 /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration 02848 * is reached , because we want to make sure we pass at least one 02849 * voice frame through before starting the next digit, to ensure a gap 02850 * between DTMF digits. */ 02851 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) { 02852 struct timeval now = ast_tvnow(); 02853 if (!chan->emulate_dtmf_duration) { 02854 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF); 02855 chan->emulate_dtmf_digit = 0; 02856 } else if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) { 02857 chan->emulate_dtmf_duration = 0; 02858 ast_frfree(f); 02859 f = &chan->dtmff; 02860 f->frametype = AST_FRAME_DTMF_END; 02861 f->subclass = chan->emulate_dtmf_digit; 02862 f->len = ast_tvdiff_ms(now, chan->dtmf_tv); 02863 chan->dtmf_tv = now; 02864 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF); 02865 chan->emulate_dtmf_digit = 0; 02866 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name); 02867 if (chan->audiohooks) { 02868 struct ast_frame *old_frame = f; 02869 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 02870 if (old_frame != f) { 02871 ast_frfree(old_frame); 02872 } 02873 } 02874 } 02875 } 02876 break; 02877 case AST_FRAME_VOICE: 02878 /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration 02879 * is reached , because we want to make sure we pass at least one 02880 * voice frame through before starting the next digit, to ensure a gap 02881 * between DTMF digits. */ 02882 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) { 02883 ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF); 02884 chan->emulate_dtmf_digit = 0; 02885 } 02886 02887 if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) { 02888 if (dropaudio) 02889 ast_read_generator_actions(chan, f); 02890 ast_frfree(f); 02891 f = &ast_null_frame; 02892 } 02893 02894 if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_IN_DTMF)) { 02895 struct timeval now = ast_tvnow(); 02896 if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) { 02897 chan->emulate_dtmf_duration = 0; 02898 ast_frfree(f); 02899 f = &chan->dtmff; 02900 f->frametype = AST_FRAME_DTMF_END; 02901 f->subclass = chan->emulate_dtmf_digit; 02902 f->len = ast_tvdiff_ms(now, chan->dtmf_tv); 02903 chan->dtmf_tv = now; 02904 if (chan->audiohooks) { 02905 struct ast_frame *old_frame = f; 02906 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 02907 if (old_frame != f) 02908 ast_frfree(old_frame); 02909 } 02910 ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name); 02911 } else { 02912 /* Drop voice frames while we're still in the middle of the digit */ 02913 ast_frfree(f); 02914 f = &ast_null_frame; 02915 } 02916 } else if ((f->frametype == AST_FRAME_VOICE) && !(f->subclass & chan->nativeformats)) { 02917 /* This frame is not one of the current native formats -- drop it on the floor */ 02918 char to[200]; 02919 ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n", 02920 chan->name, ast_getformatname(f->subclass), ast_getformatname_multiple(to, sizeof(to), chan->nativeformats)); 02921 ast_frfree(f); 02922 f = &ast_null_frame; 02923 } else if ((f->frametype == AST_FRAME_VOICE)) { 02924 /* Send frame to audiohooks if present */ 02925 if (chan->audiohooks) { 02926 struct ast_frame *old_frame = f; 02927 f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f); 02928 if (old_frame != f) 02929 ast_frfree(old_frame); 02930 } 02931 if (chan->monitor && chan->monitor->read_stream ) { 02932 /* XXX what does this do ? */ 02933 #ifndef MONITOR_CONSTANT_DELAY 02934 int jump = chan->outsmpl - chan->insmpl - 4 * f->samples; 02935 if (jump >= 0) { 02936 jump = chan->outsmpl - chan->insmpl; 02937 if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1) 02938 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 02939 chan->insmpl += jump + f->samples; 02940 } else 02941 chan->insmpl+= f->samples; 02942 #else 02943 int jump = chan->outsmpl - chan->insmpl; 02944 if (jump - MONITOR_DELAY >= 0) { 02945 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1) 02946 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 02947 chan->insmpl += jump; 02948 } else 02949 chan->insmpl += f->samples; 02950 #endif 02951 if (chan->monitor->state == AST_MONITOR_RUNNING) { 02952 if (ast_writestream(chan->monitor->read_stream, f) < 0) 02953 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n"); 02954 } 02955 } 02956 02957 if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL) { 02958 f = &ast_null_frame; 02959 } 02960 02961 /* it is possible for the translation process on chan->readtrans to have 02962 produced multiple frames from the single input frame we passed it; if 02963 this happens, queue the additional frames *before* the frames we may 02964 have queued earlier. if the readq was empty, put them at the head of 02965 the queue, and if it was not, put them just after the frame that was 02966 at the end of the queue. 02967 */ 02968 if (AST_LIST_NEXT(f, frame_list)) { 02969 if (!readq_tail) { 02970 ast_queue_frame_head(chan, AST_LIST_NEXT(f, frame_list)); 02971 } else { 02972 __ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list), 0, readq_tail); 02973 } 02974 ast_frfree(AST_LIST_NEXT(f, frame_list)); 02975 AST_LIST_NEXT(f, frame_list) = NULL; 02976 } 02977 02978 /* Run generator sitting on the line if timing device not available 02979 * and synchronous generation of outgoing frames is necessary */ 02980 ast_read_generator_actions(chan, f); 02981 } 02982 default: 02983 /* Just pass it on! */ 02984 break; 02985 } 02986 } else { 02987 /* Make sure we always return NULL in the future */ 02988 chan->_softhangup |= AST_SOFTHANGUP_DEV; 02989 if (chan->generator) 02990 ast_deactivate_generator(chan); 02991 /* We no longer End the CDR here */ 02992 } 02993 02994 /* High bit prints debugging */ 02995 if (chan->fin & DEBUGCHAN_FLAG) 02996 ast_frame_dump(chan->name, f, "<<"); 02997 chan->fin = FRAMECOUNT_INC(chan->fin); 02998 02999 done: 03000 if (chan->music_state && chan->generator && chan->generator->digit && f && f->frametype == AST_FRAME_DTMF_END) 03001 chan->generator->digit(chan, f->subclass); 03002 03003 ast_channel_unlock(chan); 03004 return f; 03005 }
struct ast_channel* __ast_request_and_dial | ( | const char * | type, | |
int | format, | |||
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 | |
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 3722 of file channel.c.
References ast_channel::_state, outgoing_helper::account, ast_call(), ast_call_forward(), AST_CAUSE_NO_ANSWER, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_end(), ast_cdr_failed(), AST_CDR_FLAG_ORIGINATED, ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_setapp(), ast_cdr_start(), ast_cdr_update(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_copy_string(), AST_FRAME_CONTROL, ast_frfree, ast_hangup(), ast_log(), ast_read(), ast_request(), ast_set_callerid(), ast_set_flag, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_waitfor(), ast_channel::call_forward, ast_channel::cdr, chanlist::chan, outgoing_helper::cid_name, outgoing_helper::cid_num, outgoing_helper::context, ast_channel::context, outgoing_helper::exten, ast_channel::exten, f, handle_cause(), ast_channel::hangupcause, LOG_NOTICE, outgoing_helper::parent_channel, outgoing_helper::priority, ast_channel::priority, and outgoing_helper::vars.
Referenced by ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_request_and_dial(), and parkandannounce_exec().
03723 { 03724 int dummy_outstate; 03725 int cause = 0; 03726 struct ast_channel *chan; 03727 int res = 0; 03728 int last_subclass = 0; 03729 03730 if (outstate) 03731 *outstate = 0; 03732 else 03733 outstate = &dummy_outstate; /* make outstate always a valid pointer */ 03734 03735 chan = ast_request(type, format, data, &cause); 03736 if (!chan) { 03737 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 03738 handle_cause(cause, outstate); 03739 return NULL; 03740 } 03741 03742 if (oh) { 03743 if (oh->vars) 03744 ast_set_variables(chan, oh->vars); 03745 /* XXX why is this necessary, for the parent_channel perhaps ? */ 03746 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) 03747 ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num); 03748 if (oh->parent_channel) { 03749 ast_channel_inherit_variables(oh->parent_channel, chan); 03750 ast_channel_datastore_inherit(oh->parent_channel, chan); 03751 } 03752 if (oh->account) 03753 ast_cdr_setaccount(chan, oh->account); 03754 } 03755 ast_set_callerid(chan, cid_num, cid_name, cid_num); 03756 ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED); 03757 03758 if (ast_call(chan, data, 0)) { /* ast_call failed... */ 03759 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data); 03760 } else { 03761 res = 1; /* mark success in case chan->_state is already AST_STATE_UP */ 03762 while (timeout && chan->_state != AST_STATE_UP) { 03763 struct ast_frame *f; 03764 res = ast_waitfor(chan, timeout); 03765 if (res <= 0) /* error, timeout, or done */ 03766 break; 03767 if (timeout > -1) 03768 timeout = res; 03769 if (!ast_strlen_zero(chan->call_forward)) { 03770 if (!(chan = ast_call_forward(NULL, chan, &timeout, format, oh, outstate))) { 03771 return NULL; 03772 } 03773 continue; 03774 } 03775 03776 f = ast_read(chan); 03777 if (!f) { 03778 *outstate = AST_CONTROL_HANGUP; 03779 res = 0; 03780 break; 03781 } 03782 if (f->frametype == AST_FRAME_CONTROL) { 03783 switch (f->subclass) { 03784 case AST_CONTROL_RINGING: /* record but keep going */ 03785 *outstate = f->subclass; 03786 break; 03787 03788 case AST_CONTROL_BUSY: 03789 case AST_CONTROL_CONGESTION: 03790 case AST_CONTROL_ANSWER: 03791 *outstate = f->subclass; 03792 timeout = 0; /* trick to force exit from the while() */ 03793 break; 03794 03795 /* Ignore these */ 03796 case AST_CONTROL_PROGRESS: 03797 case AST_CONTROL_PROCEEDING: 03798 case AST_CONTROL_HOLD: 03799 case AST_CONTROL_UNHOLD: 03800 case AST_CONTROL_VIDUPDATE: 03801 case AST_CONTROL_SRCUPDATE: 03802 case -1: /* Ignore -- just stopping indications */ 03803 break; 03804 03805 default: 03806 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass); 03807 } 03808 last_subclass = f->subclass; 03809 } 03810 ast_frfree(f); 03811 } 03812 } 03813 03814 /* Final fixups */ 03815 if (oh) { 03816 if (!ast_strlen_zero(oh->context)) 03817 ast_copy_string(chan->context, oh->context, sizeof(chan->context)); 03818 if (!ast_strlen_zero(oh->exten)) 03819 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten)); 03820 if (oh->priority) 03821 chan->priority = oh->priority; 03822 } 03823 if (chan->_state == AST_STATE_UP) 03824 *outstate = AST_CONTROL_ANSWER; 03825 03826 if (res <= 0) { 03827 if ( AST_CONTROL_RINGING == last_subclass ) 03828 chan->hangupcause = AST_CAUSE_NO_ANSWER; 03829 if (!chan->cdr && (chan->cdr = ast_cdr_alloc())) 03830 ast_cdr_init(chan->cdr, chan); 03831 if (chan->cdr) { 03832 char tmp[256]; 03833 snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data); 03834 ast_cdr_setapp(chan->cdr,"Dial",tmp); 03835 ast_cdr_update(chan); 03836 ast_cdr_start(chan->cdr); 03837 ast_cdr_end(chan->cdr); 03838 /* If the cause wasn't handled properly */ 03839 if (ast_cdr_disposition(chan->cdr,chan->hangupcause)) 03840 ast_cdr_failed(chan->cdr); 03841 } 03842 ast_hangup(chan); 03843 chan = NULL; 03844 } 03845 return chan; 03846 }
static void __init_state2str_threadbuf | ( | void | ) | [static] |
int ast_activate_generator | ( | struct ast_channel * | chan, | |
struct ast_generator * | gen, | |||
void * | params | |||
) |
Activate a given generator
Definition at line 1942 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 app_exec(), ast_channel_start_silence_generator(), ast_linear_stream(), ast_playtones_start(), ast_tonepair_start(), channel_spy(), old_milliwatt_exec(), and transmit_audio().
01943 { 01944 int res = 0; 01945 01946 ast_channel_lock(chan); 01947 01948 if (chan->generatordata) { 01949 if (chan->generator && chan->generator->release) 01950 chan->generator->release(chan, chan->generatordata); 01951 chan->generatordata = NULL; 01952 } 01953 01954 ast_prod(chan); 01955 if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) { 01956 res = -1; 01957 } 01958 01959 if (!res) { 01960 ast_settimeout(chan, 160, generator_force, chan); 01961 chan->generator = gen; 01962 } 01963 01964 ast_channel_unlock(chan); 01965 01966 return res; 01967 }
int ast_active_channels | ( | void | ) |
returns number of active/allocated channels
Returns number of active/allocated channels
Definition at line 499 of file channel.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, and AST_RWLIST_UNLOCK.
Referenced by action_corestatus(), dahdi_restart(), handle_show_settings(), and quit_handler().
00500 { 00501 struct ast_channel *c; 00502 int cnt = 0; 00503 AST_RWLIST_RDLOCK(&channels); 00504 AST_RWLIST_TRAVERSE(&channels, c, chan_list) 00505 cnt++; 00506 AST_RWLIST_UNLOCK(&channels); 00507 return cnt; 00508 }
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 1892 of file channel.c.
References __ast_answer(), and chanlist::chan.
Referenced by action_bridge(), agi_exec_full(), alarmreceiver_exec(), answer_trunk_chan(), app_exec(), ast_control_streamfile(), ast_pickup_call(), auth_exec(), background_detect_exec(), bridge_exec(), builtin_parkcall(), common_exec(), conf_exec(), count_exec(), dahdiras_exec(), dictate_exec(), directory_exec(), disa_exec(), features_answer(), handle_answer(), ices_exec(), login_exec(), minivm_accmess_exec(), minivm_greet_exec(), minivm_record_exec(), old_milliwatt_exec(), park_call_exec(), park_exec(), pbx_builtin_background(), pickup_do(), playback_exec(), privacy_exec(), read_exec(), readexten_exec(), sayunixtime_exec(), send_waveform_to_channel(), setup_privacy_args(), skel_exec(), sla_station_exec(), speech_background(), testclient_exec(), testserver_exec(), transmit(), vm_exec(), vm_execmain(), waitforsilence_exec(), and zapateller_exec().
01893 { 01894 return __ast_answer(chan, 0, 1); 01895 }
void ast_begin_shutdown | ( | int | hangup | ) |
Initiate system shutdown.
Initiate system shutdown -- prevents new channels from being allocated. If "hangup" is non-zero, all existing channels will receive soft hangups
Definition at line 486 of file channel.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_softhangup(), and AST_SOFTHANGUP_SHUTDOWN.
Referenced by quit_handler().
00487 { 00488 struct ast_channel *c; 00489 shutting_down = 1; 00490 if (hangup) { 00491 AST_RWLIST_RDLOCK(&channels); 00492 AST_RWLIST_TRAVERSE(&channels, c, chan_list) 00493 ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN); 00494 AST_RWLIST_UNLOCK(&channels); 00495 } 00496 }
int ast_best_codec | ( | int | fmts | ) |
Pick the best audio codec.
Pick the best codec
Okay, ulaw is used by all telephony equipment, so start with it
Unless of course, you're a silly European, so then prefer ALAW
G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority
Okay, well, signed linear is easy to translate into other stuff
G.726 is standard ADPCM, in RFC3551 packing order
G.726 is standard ADPCM, in AAL2 packing order
ADPCM has great sound quality and is still pretty easy to translate
Okay, we're down to vocoders now, so pick GSM because it's small and easier to translate and sounds pretty good
iLBC is not too bad
Speex is free, but computationally more expensive than GSM
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 706 of file channel.c.
References ARRAY_LEN, AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_AUDIO_MASK, AST_FORMAT_G722, AST_FORMAT_G723_1, AST_FORMAT_G726, AST_FORMAT_G726_AAL2, AST_FORMAT_G729A, AST_FORMAT_GSM, AST_FORMAT_ILBC, AST_FORMAT_LPC10, AST_FORMAT_SLINEAR, AST_FORMAT_SLINEAR16, AST_FORMAT_SPEEX, AST_FORMAT_ULAW, ast_log(), LOG_WARNING, and prefs.
Referenced by __oh323_new(), agent_call(), ast_codec_choose(), ast_iax2_new(), ast_speech_new(), builtin_atxfer(), echo_exec(), findmeexec(), gtalk_new(), handle_open_receive_channel_ack_message(), iax2_request(), jingle_new(), local_new(), login_exec(), mgcp_new(), sip_new(), skinny_new(), skinny_set_rtp_peer(), socket_process(), start_rtp(), transmit_connect(), and unistim_new().
00707 { 00708 /* This just our opinion, expressed in code. We are asked to choose 00709 the best codec to use, given no information */ 00710 int x; 00711 static const int prefs[] = 00712 { 00713 /*! Okay, ulaw is used by all telephony equipment, so start with it */ 00714 AST_FORMAT_ULAW, 00715 /*! Unless of course, you're a silly European, so then prefer ALAW */ 00716 AST_FORMAT_ALAW, 00717 /*! G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority */ 00718 AST_FORMAT_G722, 00719 /*! Okay, well, signed linear is easy to translate into other stuff */ 00720 AST_FORMAT_SLINEAR16, 00721 AST_FORMAT_SLINEAR, 00722 /*! G.726 is standard ADPCM, in RFC3551 packing order */ 00723 AST_FORMAT_G726, 00724 /*! G.726 is standard ADPCM, in AAL2 packing order */ 00725 AST_FORMAT_G726_AAL2, 00726 /*! ADPCM has great sound quality and is still pretty easy to translate */ 00727 AST_FORMAT_ADPCM, 00728 /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to 00729 translate and sounds pretty good */ 00730 AST_FORMAT_GSM, 00731 /*! iLBC is not too bad */ 00732 AST_FORMAT_ILBC, 00733 /*! Speex is free, but computationally more expensive than GSM */ 00734 AST_FORMAT_SPEEX, 00735 /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough 00736 to use it */ 00737 AST_FORMAT_LPC10, 00738 /*! G.729a is faster than 723 and slightly less expensive */ 00739 AST_FORMAT_G729A, 00740 /*! Down to G.723.1 which is proprietary but at least designed for voice */ 00741 AST_FORMAT_G723_1, 00742 }; 00743 00744 /* Strip out video */ 00745 fmts &= AST_FORMAT_AUDIO_MASK; 00746 00747 /* Find the first preferred codec in the format given */ 00748 for (x = 0; x < ARRAY_LEN(prefs); x++) { 00749 if (fmts & prefs[x]) 00750 return prefs[x]; 00751 } 00752 00753 ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts); 00754 00755 return 0; 00756 }
struct ast_channel* ast_bridged_channel | ( | struct ast_channel * | chan | ) |
Find bridged channel.
chan | Current channel |
Definition at line 4593 of file channel.c.
References ast_channel::_bridge, ast_channel_tech::bridged_channel, chanlist::chan, and ast_channel::tech.
Referenced by __dahdi_exception(), action_agents(), action_coreshowchannels(), agents_show(), agents_show_online(), ast_bridge_call(), ast_channel_masquerade(), attempt_transfer(), cb_events(), check_bridge(), common_exec(), console_transfer(), create_jb(), dahdi_handle_event(), dahdi_hangup(), export_aoc_vars(), get_refer_info(), handle_chanlist(), handle_hd_hf(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_refer(), handle_showchan(), key_call(), key_dial_page(), local_attended_transfer(), mgcp_hangup(), mgcp_ss(), misdn_transfer_bc(), mixmonitor_thread(), park_call_full(), schedule_delivery(), sip_read(), sip_set_rtp_peer(), socket_process(), ss_thread(), start_spying(), startmon(), TransferCallStep1(), and unistim_hangup().
04594 { 04595 struct ast_channel *bridged; 04596 bridged = chan->_bridge; 04597 if (bridged && bridged->tech->bridged_channel) 04598 bridged = bridged->tech->bridged_channel(chan, bridged); 04599 return bridged; 04600 }
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 Place a call, take no longer than timeout ms. |
Definition at line 3909 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(), agent_call(), ast_call_forward(), ast_feature_request_and_dial(), attempt_reconnect(), begin_dial_channel(), dial_exec_full(), do_forward(), do_idle_thread(), features_call(), findmeexec(), function_ilink(), ring_entry(), and rpt().
03910 { 03911 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 03912 If the remote end does not answer within the timeout, then do NOT hang up, but 03913 return anyway. */ 03914 int res = -1; 03915 /* Stop if we're a zombie or need a soft hangup */ 03916 ast_channel_lock(chan); 03917 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 03918 if (chan->cdr) 03919 ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED); 03920 if (chan->tech->call) 03921 res = chan->tech->call(chan, addr, timeout); 03922 ast_set_flag(chan, AST_FLAG_OUTGOING); 03923 } 03924 ast_channel_unlock(chan); 03925 return res; 03926 }
struct ast_channel* ast_call_forward | ( | struct ast_channel * | caller, | |
struct ast_channel * | orig, | |||
int * | timeout, | |||
int | format, | |||
struct outgoing_helper * | oh, | |||
int * | outstate | |||
) |
Forwards a call to a new channel specified by the original channel's call_forward str. If possible, the new forwarded channel is created and returned while the original one is terminated.
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 3650 of file channel.c.
References outgoing_helper::account, accountcode, ast_channel::accountcode, ast_call(), AST_CDR_FLAG_ORIGINATED, ast_cdr_setaccount(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_copy_flags, ast_copy_string(), ast_hangup(), ast_log(), ast_request(), ast_set_callerid(), ast_set_variables(), ast_string_field_set, ast_strlen_zero(), ast_channel::call_forward, ast_channel::cdr, CHANNEL_DEADLOCK_AVOIDANCE, ast_channel::cid, outgoing_helper::cid_name, ast_callerid::cid_name, outgoing_helper::cid_num, ast_callerid::cid_num, ast_channel::context, handle_cause(), LOG_NOTICE, outgoing_helper::parent_channel, pbx_builtin_getvar_helper(), S_OR, type, and outgoing_helper::vars.
Referenced by __ast_request_and_dial(), and ast_feature_request_and_dial().
03651 { 03652 char tmpchan[256]; 03653 struct ast_channel *new = NULL; 03654 char *data, *type; 03655 int cause = 0; 03656 03657 /* gather data and request the new forward channel */ 03658 ast_copy_string(tmpchan, orig->call_forward, sizeof(tmpchan)); 03659 if ((data = strchr(tmpchan, '/'))) { 03660 *data++ = '\0'; 03661 type = tmpchan; 03662 } else { 03663 const char *forward_context; 03664 ast_channel_lock(orig); 03665 forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT"); 03666 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", orig->call_forward, S_OR(forward_context, orig->context)); 03667 ast_channel_unlock(orig); 03668 data = tmpchan; 03669 type = "Local"; 03670 } 03671 if (!(new = ast_request(type, format, data, &cause))) { 03672 ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause); 03673 handle_cause(cause, outstate); 03674 ast_hangup(orig); 03675 return NULL; 03676 } 03677 03678 /* Copy/inherit important information into new channel */ 03679 if (oh) { 03680 if (oh->vars) { 03681 ast_set_variables(new, oh->vars); 03682 } 03683 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) { 03684 ast_set_callerid(new, oh->cid_num, oh->cid_name, oh->cid_num); 03685 } 03686 if (oh->parent_channel) { 03687 ast_channel_inherit_variables(oh->parent_channel, new); 03688 ast_channel_datastore_inherit(oh->parent_channel, new); 03689 } 03690 if (oh->account) { 03691 ast_cdr_setaccount(new, oh->account); 03692 } 03693 } else if (caller) { /* no outgoing helper so use caller if avaliable */ 03694 ast_channel_inherit_variables(caller, new); 03695 ast_channel_datastore_inherit(caller, new); 03696 } 03697 03698 ast_channel_lock(orig); 03699 while (ast_channel_trylock(new)) { 03700 CHANNEL_DEADLOCK_AVOIDANCE(orig); 03701 } 03702 ast_copy_flags(new->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED); 03703 ast_string_field_set(new, accountcode, orig->accountcode); 03704 if (!ast_strlen_zero(orig->cid.cid_num) && !ast_strlen_zero(new->cid.cid_name)) { 03705 ast_set_callerid(new, orig->cid.cid_num, orig->cid.cid_name, orig->cid.cid_num); 03706 } 03707 ast_channel_unlock(new); 03708 ast_channel_unlock(orig); 03709 03710 /* call new channel */ 03711 if ((*timeout = ast_call(new, data, 0))) { 03712 ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data); 03713 ast_hangup(orig); 03714 ast_hangup(new); 03715 return NULL; 03716 } 03717 ast_hangup(orig); 03718 03719 return new; 03720 }
void ast_cancel_shutdown | ( | void | ) |
Cancel a shutdown in progress.
Cancels an existing shutdown and returns to normal operation
Definition at line 511 of file channel.c.
Referenced by handle_abort_shutdown().
00512 { 00513 shutting_down = 0; 00514 }
const char* ast_cause2str | ( | int | state | ) |
Gives the string form of a given hangup cause.
state | cause to get the description of Give a name to a cause code Returns the text form of the binary cause code given |
Definition at line 624 of file channel.c.
References ARRAY_LEN, causes, and ast_cause::desc.
Referenced by __transmit_response(), ast_do_masquerade(), ast_hangup(), dial_exec_full(), findmeexec(), sip_hangup(), and transmit_request_with_auth().
00625 { 00626 int x; 00627 00628 for (x = 0; x < ARRAY_LEN(causes); x++) { 00629 if (causes[x].cause == cause) 00630 return causes[x].desc; 00631 } 00632 00633 return "Unknown"; 00634 }
void ast_change_name | ( | struct ast_channel * | chan, | |
char * | newname | |||
) |
Change channel name.
Definition at line 4161 of file channel.c.
References ast_string_field_set, chanlist::chan, EVENT_FLAG_CALL, manager_event, ast_channel::name, name, and ast_channel::uniqueid.
04162 { 04163 manager_event(EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid); 04164 ast_string_field_set(chan, name, newname); 04165 }
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 int | amaflag, | |||
const char * | name_fmt, | |||
... | ||||
) |
Definition at line 5707 of file channel.c.
References __ast_channel_alloc_ap().
05711 { 05712 va_list ap1, ap2; 05713 struct ast_channel *result; 05714 05715 05716 va_start(ap1, name_fmt); 05717 va_start(ap2, name_fmt); 05718 result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context, 05719 amaflag, __FILE__, __LINE__, __FUNCTION__, name_fmt, ap1, ap2); 05720 va_end(ap1); 05721 va_end(ap2); 05722 05723 return result; 05724 }
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.
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(?) Bridge two channels (c0 and c1) together. If an important frame occurs, we return that frame in rf (remember, it could be NULL) and which channel (0 or 1) in rc |
Definition at line 4888 of file channel.c.
References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_RETRY, ast_channel_make_compatible(), ast_check_hangup(), ast_check_hangup_locked(), ast_clear_flag, AST_CONTROL_SRCUPDATE, ast_debug, AST_FEATURE_PLAY_WARNING, AST_FEATURE_WARNING_ACTIVE, AST_FLAG_END_DTMF_ONLY, AST_FLAG_NBRIDGE, AST_FLAG_ZOMBIE, ast_generic_bridge(), ast_indicate(), ast_log(), ast_samp2tv(), ast_set_flag, AST_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_playfile(), ast_channel::cid, ast_callerid::cid_num, config, EVENT_FLAG_CALL, ast_channel::generator, LOG_WARNING, manager_bridge_event(), manager_event, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, ast_channel::readformat, ast_channel_tech::send_digit_begin, ast_channel::tech, ast_channel::uniqueid, update_bridge_vars(), and ast_channel::writeformat.
Referenced by ast_bridge_call().
04890 { 04891 struct ast_channel *who = NULL; 04892 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 04893 int nativefailed=0; 04894 int firstpass; 04895 int o0nativeformats; 04896 int o1nativeformats; 04897 long time_left_ms=0; 04898 char caller_warning = 0; 04899 char callee_warning = 0; 04900 04901 if (c0->_bridge) { 04902 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 04903 c0->name, c0->_bridge->name); 04904 return -1; 04905 } 04906 if (c1->_bridge) { 04907 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 04908 c1->name, c1->_bridge->name); 04909 return -1; 04910 } 04911 04912 /* Stop if we're a zombie or need a soft hangup */ 04913 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 04914 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 04915 return -1; 04916 04917 *fo = NULL; 04918 firstpass = config->firstpass; 04919 config->firstpass = 0; 04920 04921 if (ast_tvzero(config->start_time)) 04922 config->start_time = ast_tvnow(); 04923 time_left_ms = config->timelimit; 04924 04925 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING); 04926 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING); 04927 04928 if (config->start_sound && firstpass) { 04929 if (caller_warning) 04930 bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000); 04931 if (callee_warning) 04932 bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000); 04933 } 04934 04935 /* Keep track of bridge */ 04936 c0->_bridge = c1; 04937 c1->_bridge = c0; 04938 04939 04940 o0nativeformats = c0->nativeformats; 04941 o1nativeformats = c1->nativeformats; 04942 04943 if (config->feature_timer && !ast_tvzero(config->nexteventts)) { 04944 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000)); 04945 } else if (config->timelimit && firstpass) { 04946 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 04947 if (caller_warning || callee_warning) 04948 config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(config->play_warning, 1000)); 04949 } 04950 04951 if (!c0->tech->send_digit_begin) 04952 ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY); 04953 if (!c1->tech->send_digit_begin) 04954 ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY); 04955 manager_bridge_event(1, 1, c0, c1); 04956 04957 /* Before we enter in and bridge these two together tell them both the source of audio has changed */ 04958 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 04959 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 04960 04961 for (/* ever */;;) { 04962 struct timeval now = { 0, }; 04963 int to; 04964 04965 to = -1; 04966 04967 if (!ast_tvzero(config->nexteventts)) { 04968 now = ast_tvnow(); 04969 to = ast_tvdiff_ms(config->nexteventts, now); 04970 if (to <= 0) { 04971 if (!config->timelimit) { 04972 res = AST_BRIDGE_COMPLETE; 04973 break; 04974 } 04975 to = 0; 04976 } 04977 } 04978 04979 if (config->timelimit) { 04980 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time); 04981 if (time_left_ms < to) 04982 to = time_left_ms; 04983 04984 if (time_left_ms <= 0) { 04985 if (caller_warning && config->end_sound) 04986 bridge_playfile(c0, c1, config->end_sound, 0); 04987 if (callee_warning && config->end_sound) 04988 bridge_playfile(c1, c0, config->end_sound, 0); 04989 *fo = NULL; 04990 if (who) 04991 *rc = who; 04992 res = 0; 04993 break; 04994 } 04995 04996 if (!to) { 04997 if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) { 04998 int t = (time_left_ms + 500) / 1000; /* round to nearest second */ 04999 if (caller_warning) 05000 bridge_playfile(c0, c1, config->warning_sound, t); 05001 if (callee_warning) 05002 bridge_playfile(c1, c0, config->warning_sound, t); 05003 } 05004 if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) 05005 config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000)); 05006 else 05007 config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 05008 } 05009 ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE); 05010 } 05011 05012 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) { 05013 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 05014 c0->_softhangup = 0; 05015 if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 05016 c1->_softhangup = 0; 05017 c0->_bridge = c1; 05018 c1->_bridge = c0; 05019 ast_debug(1, "Unbridge signal received. Ending native bridge.\n"); 05020 continue; 05021 } 05022 05023 /* Stop if we're a zombie or need a soft hangup */ 05024 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 05025 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) { 05026 *fo = NULL; 05027 if (who) 05028 *rc = who; 05029 res = 0; 05030 ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n", 05031 c0->name, c1->name, 05032 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No", 05033 ast_check_hangup(c0) ? "Yes" : "No", 05034 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No", 05035 ast_check_hangup(c1) ? "Yes" : "No"); 05036 break; 05037 } 05038 05039 update_bridge_vars(c0, c1); 05040 05041 if (c0->tech->bridge && 05042 (c0->tech->bridge == c1->tech->bridge) && 05043 !nativefailed && !c0->monitor && !c1->monitor && 05044 !c0->audiohooks && !c1->audiohooks && 05045 !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) { 05046 /* Looks like they share a bridge method and nothing else is in the way */ 05047 ast_set_flag(c0, AST_FLAG_NBRIDGE); 05048 ast_set_flag(c1, AST_FLAG_NBRIDGE); 05049 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) { 05050 /* \todo XXX here should check that cid_num is not NULL */ 05051 manager_event(EVENT_FLAG_CALL, "Unlink", 05052 "Channel1: %s\r\n" 05053 "Channel2: %s\r\n" 05054 "Uniqueid1: %s\r\n" 05055 "Uniqueid2: %s\r\n" 05056 "CallerID1: %s\r\n" 05057 "CallerID2: %s\r\n", 05058 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 05059 ast_debug(1, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name); 05060 05061 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 05062 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 05063 05064 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 05065 continue; 05066 05067 c0->_bridge = NULL; 05068 c1->_bridge = NULL; 05069 05070 return res; 05071 } else { 05072 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 05073 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 05074 } 05075 switch (res) { 05076 case AST_BRIDGE_RETRY: 05077 if (config->play_warning) { 05078 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE); 05079 } 05080 continue; 05081 default: 05082 ast_verb(3, "Native bridging %s and %s ended\n", c0->name, c1->name); 05083 /* fallthrough */ 05084 case AST_BRIDGE_FAILED_NOWARN: 05085 nativefailed++; 05086 break; 05087 } 05088 } 05089 05090 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) || 05091 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) && 05092 !(c0->generator || c1->generator)) { 05093 if (ast_channel_make_compatible(c0, c1)) { 05094 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 05095 manager_bridge_event(0, 1, c0, c1); 05096 return AST_BRIDGE_FAILED; 05097 } 05098 o0nativeformats = c0->nativeformats; 05099 o1nativeformats = c1->nativeformats; 05100 } 05101 05102 update_bridge_vars(c0, c1); 05103 05104 res = ast_generic_bridge(c0, c1, config, fo, rc, config->nexteventts); 05105 if (res != AST_BRIDGE_RETRY) { 05106 break; 05107 } else if (config->feature_timer) { 05108 /* feature timer expired but has not been updated, sending to ast_bridge_call to do so */ 05109 break; 05110 } 05111 } 05112 05113 ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY); 05114 ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY); 05115 05116 /* Now that we have broken the bridge the source will change yet again */ 05117 ast_indicate(c0, AST_CONTROL_SRCUPDATE); 05118 ast_indicate(c1, AST_CONTROL_SRCUPDATE); 05119 05120 c0->_bridge = NULL; 05121 c1->_bridge = NULL; 05122 05123 /* \todo XXX here should check that cid_num is not NULL */ 05124 manager_event(EVENT_FLAG_CALL, "Unlink", 05125 "Channel1: %s\r\n" 05126 "Channel2: %s\r\n" 05127 "Uniqueid1: %s\r\n" 05128 "Uniqueid2: %s\r\n" 05129 "CallerID1: %s\r\n" 05130 "CallerID2: %s\r\n", 05131 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 05132 ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name); 05133 05134 return res; 05135 }
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 531 of file channel.c.
References chanlist::chan, and ast_channel::whentohangup.
00532 { 00533 time_t whentohangup; 00534 00535 if (!chan->whentohangup) 00536 return (offset == 0) ? 0 : -1; 00537 00538 if (!offset) /* XXX why is this special? */ 00539 return 1; 00540 00541 whentohangup = offset + time(NULL); 00542 00543 if (chan->whentohangup < whentohangup) 00544 return 1; 00545 else if (chan->whentohangup == whentohangup) 00546 return 0; 00547 else 00548 return -1; 00549 }
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 1491 of file channel.c.
References AST_LIST_INSERT_HEAD, chanlist::chan, ast_channel::datastores, and ast_datastore::entry.
Referenced by _macro_exec(), acf_iaxvar_write(), add_features_datastores(), add_to_agi(), ast_iax2_new(), authenticate_reply(), dial_exec_full(), dundi_query_read(), enable_jack_hook(), enum_query_read(), get_lock(), gosub_exec(), lua_get_state(), pbx_builtin_raise_exception(), setup_chanspy_ds(), setup_inheritance_datastore(), setup_mixmonitor_ds(), setup_transfer_datastore(), shared_write(), smdi_msg_retrieve_read(), socket_process(), speech_create(), try_calling(), and volume_write().
01492 { 01493 int res = 0; 01494 01495 AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry); 01496 01497 return res; 01498 }
struct ast_datastore* ast_channel_datastore_alloc | ( | const struct ast_datastore_info * | info, | |
const char * | uid | |||
) |
Create a channel datastore structure.
Definition at line 1430 of file channel.c.
References ast_calloc, ast_strdup, and ast_datastore::info.
Referenced by _macro_exec(), acf_iaxvar_write(), add_features_datastores(), add_to_agi(), ast_channel_datastore_inherit(), ast_iax2_new(), authenticate_reply(), dial_exec_full(), dundi_query_read(), enable_jack_hook(), enum_query_read(), get_lock(), gosub_exec(), lua_get_state(), pbx_builtin_raise_exception(), setup_chanspy_ds(), setup_inheritance_datastore(), setup_mixmonitor_ds(), setup_transfer_datastore(), shared_write(), smdi_msg_retrieve_read(), socket_process(), speech_create(), try_calling(), and volume_write().
01431 { 01432 struct ast_datastore *datastore = NULL; 01433 01434 /* Make sure we at least have type so we can identify this */ 01435 if (!info) { 01436 return NULL; 01437 } 01438 01439 /* Allocate memory for datastore and clear it */ 01440 datastore = ast_calloc(1, sizeof(*datastore)); 01441 if (!datastore) { 01442 return NULL; 01443 } 01444 01445 datastore->info = info; 01446 01447 datastore->uid = ast_strdup(uid); 01448 01449 return datastore; 01450 }
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.
Definition at line 1505 of file channel.c.
References AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, chanlist::chan, ast_channel::datastores, ast_datastore::entry, ast_datastore::info, and ast_datastore::uid.
Referenced by _macro_exec(), acf_exception_read(), acf_fetch(), acf_iaxvar_read(), acf_iaxvar_write(), add_agi_cmd(), add_features_datastores(), add_to_agi(), attended_transfer_occurred(), builtin_atxfer(), chanspy_ds_free(), dial_exec_full(), disable_jack_hook(), do_parking_thread(), dundi_result_read(), enable_jack_hook(), enum_result_read(), exec_odbcfinish(), find_speech(), func_inheritance_write(), get_agi_cmd(), get_lock(), gosub_exec(), iax2_call(), jack_hook_callback(), local_read(), local_write(), lua_get_state(), park_exec(), pbx_builtin_raise_exception(), pop_exec(), queue_transfer_fixup(), return_exec(), shared_read(), shared_write(), smdi_msg_read(), speech_background(), speech_destroy(), stop_mixmonitor_exec(), try_calling(), unlock_read(), volume_callback(), and volume_write().
01506 { 01507 struct ast_datastore *datastore = NULL; 01508 01509 if (info == NULL) 01510 return NULL; 01511 01512 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) { 01513 if (datastore->info == info) { 01514 if (uid != NULL && datastore->uid != NULL) { 01515 if (!strcasecmp(uid, datastore->uid)) { 01516 /* Matched by type AND uid */ 01517 break; 01518 } 01519 } else { 01520 /* Matched by type at least */ 01521 break; 01522 } 01523 } 01524 } 01525 AST_LIST_TRAVERSE_SAFE_END 01526 01527 return datastore; 01528 }
int ast_channel_datastore_free | ( | struct ast_datastore * | datastore | ) |
Free a channel datastore structure.
Definition at line 1452 of file channel.c.
References ast_free, ast_datastore::data, ast_datastore_info::destroy, ast_datastore::info, and ast_datastore::uid.
Referenced by acf_fetch(), add_features_datastores(), add_to_agi(), ast_channel_free(), ast_iax2_new(), authenticate_reply(), chanspy_ds_free(), dial_exec_full(), disable_jack_hook(), exec_odbcfinish(), get_lock(), gosub_exec(), lua_get_state(), pbx_builtin_raise_exception(), setup_inheritance_datastore(), shared_write(), socket_process(), try_calling(), and volume_write().
01453 { 01454 int res = 0; 01455 01456 /* Using the destroy function (if present) destroy the data */ 01457 if (datastore->info->destroy != NULL && datastore->data != NULL) { 01458 datastore->info->destroy(datastore->data); 01459 datastore->data = NULL; 01460 } 01461 01462 /* Free allocated UID memory */ 01463 if (datastore->uid != NULL) { 01464 ast_free((void *) datastore->uid); 01465 datastore->uid = NULL; 01466 } 01467 01468 /* Finally free memory used by ourselves */ 01469 ast_free(datastore); 01470 01471 return res; 01472 }
int ast_channel_datastore_inherit | ( | struct ast_channel * | from, | |
struct ast_channel * | to | |||
) |
Inherit datastores from a parent to a child.
Definition at line 1474 of file channel.c.
References ast_channel_datastore_alloc(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_channel::datastores, ast_datastore_info::duplicate, ast_datastore::entry, ast_datastore::info, ast_datastore::inheritance, and ast_datastore::uid.
Referenced by __ast_request_and_dial(), ast_call_forward(), dial_exec_full(), do_forward(), and local_call().
01475 { 01476 struct ast_datastore *datastore = NULL, *datastore2; 01477 01478 AST_LIST_TRAVERSE(&from->datastores, datastore, entry) { 01479 if (datastore->inheritance > 0) { 01480 datastore2 = ast_channel_datastore_alloc(datastore->info, datastore->uid); 01481 if (datastore2) { 01482 datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL; 01483 datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1; 01484 AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry); 01485 } 01486 } 01487 } 01488 return 0; 01489 }
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 1500 of file channel.c.
References AST_LIST_REMOVE, chanlist::chan, ast_channel::datastores, and ast_datastore::entry.
Referenced by acf_fetch(), chanspy_ds_free(), dial_exec_full(), disable_jack_hook(), exec_odbcfinish(), lua_get_state(), queue_transfer_fixup(), speech_background(), speech_destroy(), and try_calling().
01501 { 01502 return AST_LIST_REMOVE(&chan->datastores, datastore, entry) ? 0 : -1; 01503 }
int ast_channel_defer_dtmf | ( | struct ast_channel * | chan | ) |
Set defer DTMF flag on channel.
Defer DTMF so that you only read things like hangups and audio. Returns non-zero if channel was already DTMF-deferred or 0 if channel is just now being DTMF-deferred
Definition at line 1120 of file channel.c.
References AST_FLAG_DEFER_DTMF, ast_set_flag, ast_test_flag, and chanlist::chan.
Referenced by find_cache().
01121 { 01122 int pre = 0; 01123 01124 if (chan) { 01125 pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF); 01126 ast_set_flag(chan, AST_FLAG_DEFER_DTMF); 01127 } 01128 return pre; 01129 }
int ast_channel_early_bridge | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1 | |||
) |
Bridge two channels together (early).
Bridge two channels together (early)
c0 | first channel to bridge | |
c1 | second channel to bridge Bridge two channels (c0 and c1) together early. This implies either side may not be answered yet. |
Definition at line 4817 of file channel.c.
References ast_channel_tech::early_bridge, and ast_channel::tech.
Referenced by dial_exec_full(), and wait_for_answer().
04818 { 04819 /* Make sure we can early bridge, if not error out */ 04820 if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge))) 04821 return -1; 04822 04823 return c0->tech->early_bridge(c0, c1); 04824 }
void ast_channel_free | ( | struct ast_channel * | chan | ) |
Free a channel structure.
Definition at line 1326 of file channel.c.
References ast_channel::alertpipe, ast_app_group_discard(), ast_cdr_discard(), ast_channel_datastore_free(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_unlock, ast_copy_string(), ast_device_state_changed_literal(), ast_free, ast_frfree, ast_jb_destroy(), AST_LIST_REMOVE_HEAD, ast_log(), AST_MAX_FDS, ast_moh_cleanup(), ast_mutex_destroy(), AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_string_field_free_memory, ast_translator_free_path(), ast_var_delete(), ast_channel::cdr, chanlist::chan, ast_channel::cid, ast_channel::datastores, ast_datastore::entry, f, free, free_cid(), ast_channel::lock_dont_use, LOG_ERROR, LOG_WARNING, ast_channel::monitor, ast_channel::music_state, name, ast_channel::name, ast_channel::pbx, ast_channel::readq, ast_channel::readtrans, ast_channel::sched, sched_context_destroy(), ast_channel_monitor::stop, ast_channel::tech_pvt, ast_channel::timingfd, ast_channel::varshead, and ast_channel::writetrans.
Referenced by acf_odbc_write(), action_getvar(), agent_cleanup(), agent_new(), ast_do_masquerade(), ast_hangup(), ast_iax2_new(), ast_pbx_outgoing_cdr_failed(), gtalk_newcall(), local_new(), make_email_file(), pbx_substitute_variables_helper_full(), rotate_file(), sendmail(), and sendpage().
01327 { 01328 int fd; 01329 #ifdef HAVE_EPOLL 01330 int i; 01331 #endif 01332 struct ast_var_t *vardata; 01333 struct ast_frame *f; 01334 struct varshead *headp; 01335 struct ast_datastore *datastore = NULL; 01336 char name[AST_CHANNEL_NAME], *dashptr; 01337 01338 headp=&chan->varshead; 01339 01340 AST_RWLIST_WRLOCK(&channels); 01341 if (!AST_RWLIST_REMOVE(&channels, chan, chan_list)) { 01342 ast_log(LOG_ERROR, "Unable to find channel in list to free. Assuming it has already been done.\n"); 01343 } 01344 /* Lock and unlock the channel just to be sure nobody has it locked still 01345 due to a reference retrieved from the channel list. */ 01346 ast_channel_lock(chan); 01347 ast_channel_unlock(chan); 01348 01349 /* Get rid of each of the data stores on the channel */ 01350 while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry))) 01351 /* Free the data store */ 01352 ast_channel_datastore_free(datastore); 01353 01354 /* Lock and unlock the channel just to be sure nobody has it locked still 01355 due to a reference that was stored in a datastore. (i.e. app_chanspy) */ 01356 ast_channel_lock(chan); 01357 ast_channel_unlock(chan); 01358 01359 if (chan->tech_pvt) { 01360 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name); 01361 ast_free(chan->tech_pvt); 01362 } 01363 01364 if (chan->sched) 01365 sched_context_destroy(chan->sched); 01366 01367 ast_copy_string(name, chan->name, sizeof(name)); 01368 if ((dashptr = strrchr(name, '-'))) { 01369 *dashptr = '\0'; 01370 } 01371 01372 /* Stop monitoring */ 01373 if (chan->monitor) 01374 chan->monitor->stop( chan, 0 ); 01375 01376 /* If there is native format music-on-hold state, free it */ 01377 if (chan->music_state) 01378 ast_moh_cleanup(chan); 01379 01380 /* Free translators */ 01381 if (chan->readtrans) 01382 ast_translator_free_path(chan->readtrans); 01383 if (chan->writetrans) 01384 ast_translator_free_path(chan->writetrans); 01385 if (chan->pbx) 01386 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name); 01387 free_cid(&chan->cid); 01388 /* Close pipes if appropriate */ 01389 if ((fd = chan->alertpipe[0]) > -1) 01390 close(fd); 01391 if ((fd = chan->alertpipe[1]) > -1) 01392 close(fd); 01393 if ((fd = chan->timingfd) > -1) 01394 close(fd); 01395 #ifdef HAVE_EPOLL 01396 for (i = 0; i < AST_MAX_FDS; i++) { 01397 if (chan->epfd_data[i]) 01398 free(chan->epfd_data[i]); 01399 } 01400 close(chan->epfd); 01401 #endif 01402 while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list))) 01403 ast_frfree(f); 01404 01405 /* loop over the variables list, freeing all data and deleting list items */ 01406 /* no need to lock the list, as the channel is already locked */ 01407 01408 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) 01409 ast_var_delete(vardata); 01410 01411 ast_app_group_discard(chan); 01412 01413 /* Destroy the jitterbuffer */ 01414 ast_jb_destroy(chan); 01415 01416 if (chan->cdr) { 01417 ast_cdr_discard(chan->cdr); 01418 chan->cdr = NULL; 01419 } 01420 01421 ast_mutex_destroy(&chan->lock_dont_use); 01422 01423 ast_string_field_free_memory(chan); 01424 ast_free(chan); 01425 AST_RWLIST_UNLOCK(&channels); 01426 01427 ast_device_state_changed_literal(name); 01428 }
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 4167 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(), agent_call(), ast_call_forward(), ast_feature_request_and_dial(), begin_dial_channel(), dial_exec_full(), do_forward(), findmeexec(), and ring_entry().
04168 { 04169 struct ast_var_t *current, *newvar; 04170 const char *varname; 04171 04172 AST_LIST_TRAVERSE(&parent->varshead, current, entries) { 04173 int vartype = 0; 04174 04175 varname = ast_var_full_name(current); 04176 if (!varname) 04177 continue; 04178 04179 if (varname[0] == '_') { 04180 vartype = 1; 04181 if (varname[1] == '_') 04182 vartype = 2; 04183 } 04184 04185 switch (vartype) { 04186 case 1: 04187 newvar = ast_var_assign(&varname[1], ast_var_value(current)); 04188 if (newvar) { 04189 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 04190 ast_debug(1, "Copying soft-transferable variable %s.\n", ast_var_name(newvar)); 04191 } 04192 break; 04193 case 2: 04194 newvar = ast_var_assign(varname, ast_var_value(current)); 04195 if (newvar) { 04196 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 04197 ast_debug(1, "Copying hard-transferable variable %s.\n", ast_var_name(newvar)); 04198 } 04199 break; 04200 default: 04201 ast_debug(1, "Not copying variable %s.\n", ast_var_name(current)); 04202 break; 04203 } 04204 } 04205 }
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 Set two channels to compatible formats -- call before ast_channel_bridge in general . |
Definition at line 4065 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(), park_exec(), and wait_for_answer().
04066 { 04067 /* Some callers do not check return code, and we must try to set all call legs correctly */ 04068 int rc = 0; 04069 04070 /* Set up translation from the chan to the peer */ 04071 rc = ast_channel_make_compatible_helper(chan, peer); 04072 04073 if (rc < 0) 04074 return rc; 04075 04076 /* Set up translation from the peer to the chan */ 04077 rc = ast_channel_make_compatible_helper(peer, chan); 04078 04079 return rc; 04080 }
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 4024 of file channel.c.
References AST_FORMAT_AUDIO_MASK, AST_FORMAT_SLINEAR, ast_log(), ast_opt_transcode_via_slin, ast_set_read_format(), ast_set_write_format(), ast_translate_path_steps(), ast_translator_best_choice(), LOG_WARNING, ast_channel::name, ast_channel::nativeformats, ast_channel::readformat, and ast_channel::writeformat.
Referenced by ast_channel_make_compatible().
04025 { 04026 int src; 04027 int dst; 04028 04029 if (from->readformat == to->writeformat && from->writeformat == to->readformat) { 04030 /* Already compatible! Moving on ... */ 04031 return 0; 04032 } 04033 04034 /* Set up translation from the 'from' channel to the 'to' channel */ 04035 src = from->nativeformats; 04036 dst = to->nativeformats; 04037 04038 /* If there's no audio in this call, don't bother with trying to find a translation path */ 04039 if ((src & AST_FORMAT_AUDIO_MASK) == 0 || (dst & AST_FORMAT_AUDIO_MASK) == 0) 04040 return 0; 04041 04042 if (ast_translator_best_choice(&dst, &src) < 0) { 04043 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", from->name, src, to->name, dst); 04044 return -1; 04045 } 04046 04047 /* if the best path is not 'pass through', then 04048 transcoding is needed; if desired, force transcode path 04049 to use SLINEAR between channels, but only if there is 04050 no direct conversion available */ 04051 if ((src != dst) && ast_opt_transcode_via_slin && 04052 (ast_translate_path_steps(dst, src) != 1)) 04053 dst = AST_FORMAT_SLINEAR; 04054 if (ast_set_read_format(from, dst) < 0) { 04055 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", from->name, dst); 04056 return -1; 04057 } 04058 if (ast_set_write_format(to, dst) < 0) { 04059 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", to->name, dst); 04060 return -1; 04061 } 04062 return 0; 04063 }
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 4082 of file channel.c.
References ast_channel::_bridge, ast_bridged_channel(), ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_log(), ast_null_frame, ast_queue_frame(), ast_channel_tech::get_base_channel, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::name, and ast_channel::tech.
Referenced by ast_async_goto(), ast_pickup_call(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), masq_park_call(), misdn_transfer_bc(), pickup_do(), and sip_park().
04083 { 04084 int res = -1; 04085 struct ast_channel *final_orig, *final_clone, *base; 04086 04087 retrymasq: 04088 final_orig = original; 04089 final_clone = clone; 04090 04091 ast_channel_lock(original); 04092 while (ast_channel_trylock(clone)) { 04093 ast_channel_unlock(original); 04094 usleep(1); 04095 ast_channel_lock(original); 04096 } 04097 04098 /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent) 04099 and if so, we don't really want to masquerade it, but its proxy */ 04100 if (original->_bridge && (original->_bridge != ast_bridged_channel(original)) && (original->_bridge->_bridge != original)) 04101 final_orig = original->_bridge; 04102 04103 if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone)) && (clone->_bridge->_bridge != clone)) 04104 final_clone = clone->_bridge; 04105 04106 if (final_clone->tech->get_base_channel && (base = final_clone->tech->get_base_channel(final_clone))) { 04107 final_clone = base; 04108 } 04109 04110 if ((final_orig != original) || (final_clone != clone)) { 04111 /* Lots and lots of deadlock avoidance. The main one we're competing with 04112 * is ast_write(), which locks channels recursively, when working with a 04113 * proxy channel. */ 04114 if (ast_channel_trylock(final_orig)) { 04115 ast_channel_unlock(clone); 04116 ast_channel_unlock(original); 04117 goto retrymasq; 04118 } 04119 if (ast_channel_trylock(final_clone)) { 04120 ast_channel_unlock(final_orig); 04121 ast_channel_unlock(clone); 04122 ast_channel_unlock(original); 04123 goto retrymasq; 04124 } 04125 ast_channel_unlock(clone); 04126 ast_channel_unlock(original); 04127 original = final_orig; 04128 clone = final_clone; 04129 } 04130 04131 if (original == clone) { 04132 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name); 04133 ast_channel_unlock(clone); 04134 ast_channel_unlock(original); 04135 return -1; 04136 } 04137 04138 ast_debug(1, "Planning to masquerade channel %s into the structure of %s\n", 04139 clone->name, original->name); 04140 if (original->masq) { 04141 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 04142 original->masq->name, original->name); 04143 } else if (clone->masqr) { 04144 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 04145 clone->name, clone->masqr->name); 04146 } else { 04147 original->masq = clone; 04148 clone->masqr = original; 04149 ast_queue_frame(original, &ast_null_frame); 04150 ast_queue_frame(clone, &ast_null_frame); 04151 ast_debug(1, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name); 04152 res = 0; 04153 } 04154 04155 ast_channel_unlock(clone); 04156 ast_channel_unlock(original); 04157 04158 return res; 04159 }
int ast_channel_queryoption | ( | struct ast_channel * | channel, | |
int | option, | |||
void * | data, | |||
int * | datalen, | |||
int | block | |||
) |
Query the value of an option Works similarly to setoption except only reads the options.
Definition at line 5151 of file channel.c.
References ast_log(), chan, errno, LOG_ERROR, ast_channel_tech::queryoption, and ast_channel::tech.
Referenced by ast_channel_get_t38_state().
05152 { 05153 if (!chan->tech->queryoption) { 05154 errno = ENOSYS; 05155 return -1; 05156 } 05157 05158 if (block) 05159 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 05160 05161 return chan->tech->queryoption(chan, option, data, datalen); 05162 }
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 3614 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().
03615 { 03616 switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */ 03617 { 03618 case 0: 03619 return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)"; 03620 case AST_CONTROL_HANGUP: 03621 return "Hangup"; 03622 case AST_CONTROL_RING: 03623 return "Local Ring"; 03624 case AST_CONTROL_RINGING: 03625 return "Remote end Ringing"; 03626 case AST_CONTROL_ANSWER: 03627 return "Remote end has Answered"; 03628 case AST_CONTROL_BUSY: 03629 return "Remote end is Busy"; 03630 case AST_CONTROL_CONGESTION: 03631 return "Congestion (circuits busy)"; 03632 default: 03633 return "Unknown Reason!!"; 03634 } 03635 }
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 552 of file channel.c.
References ast_calloc, ast_debug, AST_LIST_INSERT_HEAD, AST_LIST_TRAVERSE, ast_log(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, chanlist::chan, chanlist::list, LOG_WARNING, chanlist::tech, ast_channel::tech, and ast_channel_tech::type.
Referenced by load_module(), and unload_module().
00553 { 00554 struct chanlist *chan; 00555 00556 AST_RWLIST_WRLOCK(&channels); 00557 00558 AST_LIST_TRAVERSE(&backends, chan, list) { 00559 if (!strcasecmp(tech->type, chan->tech->type)) { 00560 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type); 00561 AST_RWLIST_UNLOCK(&channels); 00562 return -1; 00563 } 00564 } 00565 00566 if (!(chan = ast_calloc(1, sizeof(*chan)))) { 00567 AST_RWLIST_UNLOCK(&channels); 00568 return -1; 00569 } 00570 chan->tech = tech; 00571 AST_LIST_INSERT_HEAD(&backends, chan, list); 00572 00573 ast_debug(1, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description); 00574 00575 ast_verb(2, "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description); 00576 00577 AST_RWLIST_UNLOCK(&channels); 00578 return 0; 00579 }
int ast_channel_sendhtml | ( | struct ast_channel * | channel, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) |
Send HTML or URL on link. Returns 0 on success or -1 on failure
Definition at line 4011 of file channel.c.
References chanlist::chan, ast_channel_tech::send_html, and ast_channel::tech.
Referenced by agent_sendhtml(), ast_channel_sendurl(), and wait_for_answer().
04012 { 04013 if (chan->tech->send_html) 04014 return chan->tech->send_html(chan, subclass, data, datalen); 04015 return -1; 04016 }
int ast_channel_sendurl | ( | struct ast_channel * | channel, | |
const char * | url | |||
) |
Send URL on link. Returns 0 on success or -1 on failure
Definition at line 4018 of file channel.c.
References ast_channel_sendhtml(), AST_HTML_URL, and chanlist::chan.
Referenced by dial_exec_full(), and sendurl_exec().
04019 { 04020 return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1); 04021 }
void ast_channel_set_fd | ( | struct ast_channel * | chan, | |
int | which, | |||
int | fd | |||
) |
Set the file descriptor on the channel
Definition at line 1531 of file channel.c.
References ast_calloc, chanlist::chan, ast_channel::data, ast_channel::fds, and free.
Referenced by __ast_channel_alloc_ap(), __oh323_new(), __oh323_rtp_create(), __oh323_update_info(), alsa_new(), ast_deactivate_generator(), ast_do_masquerade(), dahdi_new(), gtalk_new(), jingle_new(), mgcp_new(), misdn_new(), nbs_new(), oss_new(), phone_new(), pri_assign_bearer(), pri_fixup_principle(), restore_channel(), setformat(), sip_new(), skinny_new(), start_rtp(), swap_subs(), and update_features().
01532 { 01533 #ifdef HAVE_EPOLL 01534 struct epoll_event ev; 01535 struct ast_epoll_data *aed = NULL; 01536 01537 if (chan->fds[which] > -1) { 01538 epoll_ctl(chan->epfd, EPOLL_CTL_DEL, chan->fds[which], &ev); 01539 aed = chan->epfd_data[which]; 01540 } 01541 01542 /* If this new fd is valid, add it to the epoll */ 01543 if (fd > -1) { 01544 if (!aed && (!(aed = ast_calloc(1, sizeof(*aed))))) 01545 return; 01546 01547 chan->epfd_data[which] = aed; 01548 aed->chan = chan; 01549 aed->which = which; 01550 01551 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 01552 ev.data.ptr = aed; 01553 epoll_ctl(chan->epfd, EPOLL_CTL_ADD, fd, &ev); 01554 } else if (aed) { 01555 /* We don't have to keep around this epoll data structure now */ 01556 free(aed); 01557 chan->epfd_data[which] = NULL; 01558 } 01559 #endif 01560 chan->fds[which] = fd; 01561 return; 01562 }
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 Set an option on a channel (see frame.h), optionally blocking awaiting the reply Returns 0 on success and -1 on failure |
Definition at line 5138 of file channel.c.
References ast_log(), chan, errno, LOG_ERROR, ast_channel_tech::setoption, and ast_channel::tech.
Referenced by ast_bridge_call(), common_exec(), conf_run(), dahdi_hangup(), dial_exec_full(), func_channel_write(), handle_tddmode(), play_record_review(), reset_volumes(), rpt(), set_listen_volume(), set_talk_volume(), and vm_forwardoptions().
05139 { 05140 if (!chan->tech->setoption) { 05141 errno = ENOSYS; 05142 return -1; 05143 } 05144 05145 if (block) 05146 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 05147 05148 return chan->tech->setoption(chan, option, data, datalen); 05149 }
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 from current time of when to hang up |
Definition at line 523 of file channel.c.
References ast_null_frame, ast_queue_frame(), chanlist::chan, and ast_channel::whentohangup.
Referenced by action_timeout(), and timeout_write().
00524 { 00525 chan->whentohangup = offset ? time(NULL) + offset : 0; 00526 ast_queue_frame(chan, &ast_null_frame); 00527 return; 00528 }
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 |
The pointer returned by this function must be preserved and passed to ast_channel_stop_silence_generator when you wish to stop the silence generation.
Definition at line 5471 of file channel.c.
References ast_activate_generator(), ast_calloc, ast_debug, AST_FORMAT_SLINEAR, ast_free, ast_log(), ast_set_write_format(), chan, LOG_ERROR, ast_channel::name, ast_silence_generator::old_write_format, silence_generator, and ast_channel::writeformat.
Referenced by __ast_play_and_record(), ast_dtmf_stream(), channel_spy(), and TransferCallStep1().
05472 { 05473 struct ast_silence_generator *state; 05474 05475 if (!(state = ast_calloc(1, sizeof(*state)))) { 05476 return NULL; 05477 } 05478 05479 state->old_write_format = chan->writeformat; 05480 05481 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) { 05482 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n"); 05483 ast_free(state); 05484 return NULL; 05485 } 05486 05487 ast_activate_generator(chan, &silence_generator, state); 05488 05489 ast_debug(1, "Started silence generator on '%s'\n", chan->name); 05490 05491 return state; 05492 }
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 5494 of file channel.c.
References ast_deactivate_generator(), ast_debug, ast_free, ast_log(), ast_set_write_format(), chan, LOG_ERROR, ast_channel::name, and ast_silence_generator::old_write_format.
Referenced by __ast_play_and_record(), ast_dtmf_stream(), channel_spy(), HandleCallOutgoing(), key_dial_page(), and unistim_hangup().
05495 { 05496 if (!state) 05497 return; 05498 05499 ast_deactivate_generator(chan); 05500 05501 ast_debug(1, "Stopped silence generator on '%s'\n", chan->name); 05502 05503 if (ast_set_write_format(chan, state->old_write_format) < 0) 05504 ast_log(LOG_ERROR, "Could not return write format to its original state\n"); 05505 05506 ast_free(state); 05507 }
int ast_channel_supports_html | ( | struct ast_channel * | channel | ) |
Returns 0 if channel does not support HTML or non-zero if it does
Definition at line 4006 of file channel.c.
References chanlist::chan, ast_channel_tech::send_html, and ast_channel::tech.
Referenced by dial_exec_full(), and sendurl_exec().
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 1132 of file channel.c.
References ast_clear_flag, AST_FLAG_DEFER_DTMF, and chanlist::chan.
Referenced by find_cache(), and rpt_call().
01133 { 01134 if (chan) 01135 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF); 01136 }
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 582 of file channel.c.
References ast_debug, ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, chanlist::chan, chanlist::list, chanlist::tech, ast_channel::tech, and ast_channel_tech::type.
Referenced by __unload_module(), load_module(), and unload_module().
00583 { 00584 struct chanlist *chan; 00585 00586 ast_debug(1, "Unregistering channel type '%s'\n", tech->type); 00587 00588 AST_RWLIST_WRLOCK(&channels); 00589 00590 AST_LIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) { 00591 if (chan->tech == tech) { 00592 AST_LIST_REMOVE_CURRENT(list); 00593 ast_free(chan); 00594 ast_verb(2, "Unregistered channel type '%s'\n", tech->type); 00595 break; 00596 } 00597 } 00598 AST_LIST_TRAVERSE_SAFE_END; 00599 00600 AST_RWLIST_UNLOCK(&channels); 00601 }
struct ast_channel* ast_channel_walk_locked | ( | const struct ast_channel * | prev | ) |
Browse channels in use Browse the channels currently in use.
prev | where you want to start in the channel list |
Definition at line 1246 of file channel.c.
References channel_find_locked().
Referenced by action_coreshowchannels(), action_status(), ast_complete_channels(), ast_pickup_call(), conf_exec(), handle_chanlist(), handle_core_set_debug_channel(), next_channel(), pickup_by_exten(), and pickup_by_mark().
01247 { 01248 return channel_find_locked(prev, NULL, 0, NULL, NULL); 01249 }
void ast_channels_init | ( | void | ) |
Provided by channel.c
Definition at line 5392 of file channel.c.
References ARRAY_LEN, ast_cli_register_multiple(), and cli_channel.
Referenced by main().
05393 { 05394 ast_cli_register_multiple(cli_channel, ARRAY_LEN(cli_channel)); 05395 }
struct ast_variable* ast_channeltype_list | ( | void | ) |
return an ast_variable list of channeltypes
Definition at line 188 of file channel.c.
References AST_LIST_TRAVERSE, ast_variable_new(), ast_channel_tech::description, chanlist::list, chanlist::tech, ast_channel_tech::type, and var.
00189 { 00190 struct chanlist *cl; 00191 struct ast_variable *var=NULL, *prev = NULL; 00192 AST_LIST_TRAVERSE(&backends, cl, list) { 00193 if (prev) { 00194 if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description, ""))) 00195 prev = prev->next; 00196 } else { 00197 var = ast_variable_new(cl->tech->type, cl->tech->description, ""); 00198 prev = var; 00199 } 00200 } 00201 return var; 00202 }
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 464 of file channel.c.
References ast_channel::_softhangup, AST_SOFTHANGUP_TIMEOUT, chanlist::chan, and ast_channel::whentohangup.
Referenced by __ast_read(), _macro_exec(), action_redirect(), agent_indicate(), agi_exec(), agi_handle_command(), announce_thread(), ast_bridge_call(), ast_bridge_call_thread(), ast_call(), ast_channel_bridge(), ast_check_hangup_locked(), ast_feature_request_and_dial(), ast_indicate_data(), ast_raw_answer(), ast_readstring_full(), ast_recvtext(), ast_rtp_bridge(), ast_sendtext(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), ast_write(), autoservice_run(), bridge_exec(), bridge_native_loop(), builtin_atxfer(), channel_spy(), check_bridge(), common_exec(), conf_play(), conf_run(), dahdi_sendtext(), dahdi_setoption(), dial_exec_full(), dundi_lookup_internal(), eagi_exec(), eivr_comm(), findmeexec(), handle_sendimage(), launch_asyncagi(), lua_check_hangup(), ospfinished_exec(), pbx_exec(), read_exec(), readexten_exec(), rpt(), and run_ras().
00465 { 00466 if (chan->_softhangup) /* yes if soft hangup flag set */ 00467 return 1; 00468 if (!chan->whentohangup) /* no if no hangup scheduled */ 00469 return 0; 00470 if (chan->whentohangup > time(NULL)) /* no if hangup time has not come yet. */ 00471 return 0; 00472 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */ 00473 return 1; 00474 }
static int ast_check_hangup_locked | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 476 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), and chanlist::chan.
Referenced by ast_channel_bridge().
00477 { 00478 int res; 00479 ast_channel_lock(chan); 00480 res = ast_check_hangup(chan); 00481 ast_channel_unlock(chan); 00482 return res; 00483 }
void ast_deactivate_generator | ( | struct ast_channel * | chan | ) |
Deactivate an active generator
Definition at line 1897 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().
01898 { 01899 ast_channel_lock(chan); 01900 if (chan->generatordata) { 01901 if (chan->generator && chan->generator->release) 01902 chan->generator->release(chan, chan->generatordata); 01903 chan->generatordata = NULL; 01904 chan->generator = NULL; 01905 ast_channel_set_fd(chan, AST_GENERATOR_FD, -1); 01906 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 01907 ast_settimeout(chan, 0, NULL, NULL); 01908 } 01909 ast_channel_unlock(chan); 01910 }
int ast_do_masquerade | ( | struct ast_channel * | original | ) |
Start masquerading a channel XXX This is a seriously whacked out operation. We're essentially putting the guts of the clone channel into the original channel. Start by killing off the original channel's backend. I'm not sure we're going to keep this function, because while the features are nice, the cost is very high in terms of pure nastiness. XXX.
Definition at line 4258 of file channel.c.
References ast_channel::_softhangup, ast_channel::_state, ast_channel::adsicpe, ast_channel::alertpipe, ast_app_group_update(), ast_cause2str(), ast_channel_free(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_set_fd(), ast_channel_unlock, ast_copy_string(), ast_debug, AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, AST_GENERATOR_FD, ast_indicate(), AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_HEAD_NOLOCK, AST_LIST_HEAD_SET_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), AST_MAX_FDS, ast_null_frame, ast_queue_frame(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_state2str(), ast_string_field_set, ast_test_flag, AST_TIMING_FD, ast_channel::blocker, ast_channel::cdr, ast_datastore_info::chan_fixup, ast_channel::cid, clone_variables(), ast_datastore::data, ast_channel::datastores, 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, language, ast_channel::language, ast_channel::lock_dont_use, LOG_WARNING, manager_event, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, musicclass, ast_channel::name, name, ast_channel::nativeformats, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::readq, report_new_callerid(), ast_channel::tech, ast_channel::tech_pvt, ast_channel::timingfd, ast_channel_tech::type, ast_channel::uniqueid, ast_channel::visible_indication, and ast_channel::writeformat.
Referenced by __ast_read(), ast_async_goto(), ast_hangup(), ast_waitfor_nandfds(), ast_write(), do_bridge_masquerade(), iax_park(), sip_park(), and sip_park_thread().
04259 { 04260 int x,i; 04261 int res=0; 04262 int origstate; 04263 struct ast_frame *cur; 04264 const struct ast_channel_tech *t; 04265 void *t_pvt; 04266 struct ast_callerid tmpcid; 04267 struct ast_channel *clone = original->masq; 04268 struct ast_cdr *cdr; 04269 int rformat = original->readformat; 04270 int wformat = original->writeformat; 04271 char newn[AST_CHANNEL_NAME]; 04272 char orig[AST_CHANNEL_NAME]; 04273 char masqn[AST_CHANNEL_NAME]; 04274 char zombn[AST_CHANNEL_NAME]; 04275 04276 ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", 04277 clone->name, clone->_state, original->name, original->_state); 04278 04279 manager_event(EVENT_FLAG_CALL, "Masquerade", "Clone: %s\r\nCloneState: %s\r\nOriginal: %s\r\nOriginalState: %s\r\n", 04280 clone->name, ast_state2str(clone->_state), original->name, ast_state2str(original->_state)); 04281 04282 /* XXX This is a seriously wacked out operation. We're essentially putting the guts of 04283 the clone channel into the original channel. Start by killing off the original 04284 channel's backend. I'm not sure we're going to keep this function, because 04285 while the features are nice, the cost is very high in terms of pure nastiness. XXX */ 04286 04287 /* We need the clone's lock, too */ 04288 ast_channel_lock(clone); 04289 04290 ast_debug(2, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock_dont_use); 04291 04292 /* Having remembered the original read/write formats, we turn off any translation on either 04293 one */ 04294 free_translation(clone); 04295 free_translation(original); 04296 04297 04298 /* Unlink the masquerade */ 04299 original->masq = NULL; 04300 clone->masqr = NULL; 04301 04302 /* Save the original name */ 04303 ast_copy_string(orig, original->name, sizeof(orig)); 04304 /* Save the new name */ 04305 ast_copy_string(newn, clone->name, sizeof(newn)); 04306 /* Create the masq name */ 04307 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn); 04308 04309 /* Copy the name from the clone channel */ 04310 ast_string_field_set(original, name, newn); 04311 04312 /* Mangle the name of the clone channel */ 04313 ast_string_field_set(clone, name, masqn); 04314 04315 /* Notify any managers of the change, first the masq then the other */ 04316 manager_event(EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid); 04317 manager_event(EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid); 04318 04319 /* Swap the technologies */ 04320 t = original->tech; 04321 original->tech = clone->tech; 04322 clone->tech = t; 04323 04324 /* Swap the cdrs */ 04325 cdr = original->cdr; 04326 original->cdr = clone->cdr; 04327 clone->cdr = cdr; 04328 04329 t_pvt = original->tech_pvt; 04330 original->tech_pvt = clone->tech_pvt; 04331 clone->tech_pvt = t_pvt; 04332 04333 /* Swap the alertpipes */ 04334 for (i = 0; i < 2; i++) { 04335 x = original->alertpipe[i]; 04336 original->alertpipe[i] = clone->alertpipe[i]; 04337 clone->alertpipe[i] = x; 04338 } 04339 04340 /* 04341 * Swap the readq's. The end result should be this: 04342 * 04343 * 1) All frames should be on the new (original) channel. 04344 * 2) Any frames that were already on the new channel before this 04345 * masquerade need to be at the end of the readq, after all of the 04346 * frames on the old (clone) channel. 04347 * 3) The alertpipe needs to get poked for every frame that was already 04348 * on the new channel, since we are now using the alert pipe from the 04349 * old (clone) channel. 04350 */ 04351 { 04352 AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq; 04353 AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL); 04354 04355 AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list); 04356 AST_LIST_APPEND_LIST(&original->readq, &clone->readq, frame_list); 04357 04358 while ((cur = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) { 04359 AST_LIST_INSERT_TAIL(&original->readq, cur, frame_list); 04360 if (original->alertpipe[1] > -1) { 04361 int poke = 0; 04362 04363 if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) { 04364 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 04365 } 04366 } 04367 } 04368 } 04369 04370 /* Swap the raw formats */ 04371 x = original->rawreadformat; 04372 original->rawreadformat = clone->rawreadformat; 04373 clone->rawreadformat = x; 04374 x = original->rawwriteformat; 04375 original->rawwriteformat = clone->rawwriteformat; 04376 clone->rawwriteformat = x; 04377 04378 clone->_softhangup = AST_SOFTHANGUP_DEV; 04379 04380 /* And of course, so does our current state. Note we need not 04381 call ast_setstate since the event manager doesn't really consider 04382 these separate. We do this early so that the clone has the proper 04383 state of the original channel. */ 04384 origstate = original->_state; 04385 original->_state = clone->_state; 04386 clone->_state = origstate; 04387 04388 if (clone->tech->fixup){ 04389 res = clone->tech->fixup(original, clone); 04390 if (res) 04391 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name); 04392 } 04393 04394 /* Start by disconnecting the original's physical side */ 04395 if (clone->tech->hangup) 04396 res = clone->tech->hangup(clone); 04397 if (res) { 04398 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n"); 04399 ast_channel_unlock(clone); 04400 return -1; 04401 } 04402 04403 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); 04404 /* Mangle the name of the clone channel */ 04405 ast_string_field_set(clone, name, zombn); 04406 manager_event(EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid); 04407 04408 /* Update the type. */ 04409 t_pvt = original->monitor; 04410 original->monitor = clone->monitor; 04411 clone->monitor = t_pvt; 04412 04413 /* Keep the same language. */ 04414 ast_string_field_set(original, language, clone->language); 04415 /* Copy the FD's other than the generator fd */ 04416 for (x = 0; x < AST_MAX_FDS; x++) { 04417 if (x != AST_GENERATOR_FD) 04418 ast_channel_set_fd(original, x, clone->fds[x]); 04419 } 04420 04421 ast_app_group_update(clone, original); 04422 04423 /* Move data stores over */ 04424 if (AST_LIST_FIRST(&clone->datastores)) { 04425 struct ast_datastore *ds; 04426 /* We use a safe traversal here because some fixup routines actually 04427 * remove the datastore from the list and free them. 04428 */ 04429 AST_LIST_TRAVERSE_SAFE_BEGIN(&clone->datastores, ds, entry) { 04430 if (ds->info->chan_fixup) 04431 ds->info->chan_fixup(ds->data, clone, original); 04432 } 04433 AST_LIST_TRAVERSE_SAFE_END; 04434 AST_LIST_APPEND_LIST(&original->datastores, &clone->datastores, entry); 04435 } 04436 04437 clone_variables(original, clone); 04438 /* Presense of ADSI capable CPE follows clone */ 04439 original->adsicpe = clone->adsicpe; 04440 /* Bridge remains the same */ 04441 /* CDR fields remain the same */ 04442 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 04443 /* Application and data remain the same */ 04444 /* Clone exception becomes real one, as with fdno */ 04445 ast_set_flag(original, ast_test_flag(clone, AST_FLAG_OUTGOING | AST_FLAG_EXCEPTION)); 04446 original->fdno = clone->fdno; 04447 /* Schedule context remains the same */ 04448 /* Stream stuff stays the same */ 04449 /* Keep the original state. The fixup code will need to work with it most likely */ 04450 04451 /* Just swap the whole structures, nevermind the allocations, they'll work themselves 04452 out. */ 04453 tmpcid = original->cid; 04454 original->cid = clone->cid; 04455 clone->cid = tmpcid; 04456 report_new_callerid(original); 04457 04458 /* Restore original timing file descriptor */ 04459 ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd); 04460 04461 /* Our native formats are different now */ 04462 original->nativeformats = clone->nativeformats; 04463 04464 /* Context, extension, priority, app data, jump table, remain the same */ 04465 /* pvt switches. pbx stays the same, as does next */ 04466 04467 /* Set the write format */ 04468 ast_set_write_format(original, wformat); 04469 04470 /* Set the read format */ 04471 ast_set_read_format(original, rformat); 04472 04473 /* Copy the music class */ 04474 ast_string_field_set(original, musicclass, clone->musicclass); 04475 04476 ast_debug(1, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat); 04477 04478 /* Okay. Last thing is to let the channel driver know about all this mess, so he 04479 can fix up everything as best as possible */ 04480 if (original->tech->fixup) { 04481 res = original->tech->fixup(clone, original); 04482 if (res) { 04483 ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n", 04484 original->tech->type, original->name); 04485 ast_channel_unlock(clone); 04486 return -1; 04487 } 04488 } else 04489 ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)! Bad things may happen.\n", 04490 original->tech->type, original->name); 04491 04492 /* 04493 * If an indication is currently playing, maintain it on the channel 04494 * that is taking the place of original 04495 * 04496 * This is needed because the masquerade is swapping out in the internals 04497 * of this channel, and the new channel private data needs to be made 04498 * aware of the current visible indication (RINGING, CONGESTION, etc.) 04499 */ 04500 if (original->visible_indication) { 04501 ast_indicate(original, original->visible_indication); 04502 } 04503 04504 /* Now, at this point, the "clone" channel is totally F'd up. We mark it as 04505 a zombie so nothing tries to touch it. If it's already been marked as a 04506 zombie, then free it now (since it already is considered invalid). */ 04507 if (ast_test_flag(clone, AST_FLAG_ZOMBIE)) { 04508 ast_debug(1, "Destroying channel clone '%s'\n", clone->name); 04509 ast_channel_unlock(clone); 04510 manager_event(EVENT_FLAG_CALL, "Hangup", 04511 "Channel: %s\r\n" 04512 "Uniqueid: %s\r\n" 04513 "Cause: %d\r\n" 04514 "Cause-txt: %s\r\n", 04515 clone->name, 04516 clone->uniqueid, 04517 clone->hangupcause, 04518 ast_cause2str(clone->hangupcause) 04519 ); 04520 ast_channel_free(clone); 04521 } else { 04522 ast_debug(1, "Released clone lock on '%s'\n", clone->name); 04523 ast_set_flag(clone, AST_FLAG_ZOMBIE); 04524 ast_queue_frame(clone, &ast_null_frame); 04525 ast_channel_unlock(clone); 04526 } 04527 04528 /* Signal any blocker */ 04529 if (ast_test_flag(original, AST_FLAG_BLOCKING)) 04530 pthread_kill(original->blocker, SIGURG); 04531 ast_debug(1, "Done Masquerading %s (%d)\n", original->name, original->_state); 04532 return 0; 04533 }
static enum ast_bridge_result ast_generic_bridge | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1, | |||
struct ast_bridge_config * | config, | |||
struct ast_frame ** | fo, | |||
struct ast_channel ** | rc, | |||
struct timeval | bridge_end | |||
) | [static] |
Definition at line 4636 of file channel.c.
References AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_RETRY, AST_FEATURE_WARNING_ACTIVE, ast_jb_do_usecheck(), ast_jb_empty_and_reset(), ast_poll_channel_add(), ast_samp2tv(), ast_set_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().
04639 { 04640 /* Copy voice back and forth between the two channels. */ 04641 struct ast_channel *cs[3]; 04642 struct ast_frame *f; 04643 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 04644 int o0nativeformats; 04645 int o1nativeformats; 04646 int watch_c0_dtmf; 04647 int watch_c1_dtmf; 04648 void *pvt0, *pvt1; 04649 /* Indicates whether a frame was queued into a jitterbuffer */ 04650 int frame_put_in_jb = 0; 04651 int jb_in_use; 04652 int to; 04653 04654 cs[0] = c0; 04655 cs[1] = c1; 04656 pvt0 = c0->tech_pvt; 04657 pvt1 = c1->tech_pvt; 04658 o0nativeformats = c0->nativeformats; 04659 o1nativeformats = c1->nativeformats; 04660 watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0; 04661 watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1; 04662 04663 /* Check the need of a jitterbuffer for each channel */ 04664 jb_in_use = ast_jb_do_usecheck(c0, c1); 04665 if (jb_in_use) 04666 ast_jb_empty_and_reset(c0, c1); 04667 04668 ast_poll_channel_add(c0, c1); 04669 04670 if (config->feature_timer > 0 && ast_tvzero(config->nexteventts)) { 04671 /* calculate when the bridge should possibly break 04672 * if a partial feature match timed out */ 04673 config->partialfeature_timer = ast_tvadd(ast_tvnow(), ast_samp2tv(config->feature_timer, 1000)); 04674 } else { 04675 memset(&config->partialfeature_timer, 0, sizeof(config->partialfeature_timer)); 04676 } 04677 04678 for (;;) { 04679 struct ast_channel *who, *other; 04680 04681 if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) || 04682 (o0nativeformats != c0->nativeformats) || 04683 (o1nativeformats != c1->nativeformats)) { 04684 /* Check for Masquerade, codec changes, etc */ 04685 res = AST_BRIDGE_RETRY; 04686 break; 04687 } 04688 if (bridge_end.tv_sec) { 04689 to = ast_tvdiff_ms(bridge_end, ast_tvnow()); 04690 if (to <= 0) { 04691 if (config->timelimit) { 04692 res = AST_BRIDGE_RETRY; 04693 /* generic bridge ending to play warning */ 04694 ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE); 04695 } else { 04696 res = AST_BRIDGE_COMPLETE; 04697 } 04698 break; 04699 } 04700 } else { 04701 /* If a feature has been started and the bridge is configured to 04702 * to not break, leave the channel bridge when the feature timer 04703 * time has elapsed so the DTMF will be sent to the other side. 04704 */ 04705 if (!ast_tvzero(config->partialfeature_timer)) { 04706 int diff = ast_tvdiff_ms(config->partialfeature_timer, ast_tvnow()); 04707 if (diff <= 0) { 04708 res = AST_BRIDGE_RETRY; 04709 break; 04710 } 04711 } 04712 to = -1; 04713 } 04714 /* Calculate the appropriate max sleep interval - in general, this is the time, 04715 left to the closest jb delivery moment */ 04716 if (jb_in_use) 04717 to = ast_jb_get_when_to_wakeup(c0, c1, to); 04718 who = ast_waitfor_n(cs, 2, &to); 04719 if (!who) { 04720 /* No frame received within the specified timeout - check if we have to deliver now */ 04721 if (jb_in_use) 04722 ast_jb_get_and_deliver(c0, c1); 04723 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) { 04724 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 04725 c0->_softhangup = 0; 04726 if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 04727 c1->_softhangup = 0; 04728 c0->_bridge = c1; 04729 c1->_bridge = c0; 04730 } 04731 continue; 04732 } 04733 f = ast_read(who); 04734 if (!f) { 04735 *fo = NULL; 04736 *rc = who; 04737 ast_debug(1, "Didn't get a frame from channel: %s\n",who->name); 04738 break; 04739 } 04740 04741 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 04742 /* Try add the frame info the who's bridged channel jitterbuff */ 04743 if (jb_in_use) 04744 frame_put_in_jb = !ast_jb_put(other, f); 04745 04746 if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) { 04747 int bridge_exit = 0; 04748 04749 switch (f->subclass) { 04750 case AST_CONTROL_HOLD: 04751 case AST_CONTROL_UNHOLD: 04752 case AST_CONTROL_VIDUPDATE: 04753 case AST_CONTROL_SRCUPDATE: 04754 case AST_CONTROL_T38: 04755 ast_indicate_data(other, f->subclass, f->data, f->datalen); 04756 if (jb_in_use) { 04757 ast_jb_empty_and_reset(c0, c1); 04758 } 04759 break; 04760 default: 04761 *fo = f; 04762 *rc = who; 04763 bridge_exit = 1; 04764 ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name); 04765 break; 04766 } 04767 if (bridge_exit) 04768 break; 04769 } 04770 if ((f->frametype == AST_FRAME_VOICE) || 04771 (f->frametype == AST_FRAME_DTMF_BEGIN) || 04772 (f->frametype == AST_FRAME_DTMF) || 04773 (f->frametype == AST_FRAME_VIDEO) || 04774 (f->frametype == AST_FRAME_IMAGE) || 04775 (f->frametype == AST_FRAME_HTML) || 04776 (f->frametype == AST_FRAME_MODEM) || 04777 (f->frametype == AST_FRAME_TEXT)) { 04778 /* monitored dtmf causes exit from bridge */ 04779 int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf; 04780 04781 if (monitored_source && 04782 (f->frametype == AST_FRAME_DTMF_END || 04783 f->frametype == AST_FRAME_DTMF_BEGIN)) { 04784 *fo = f; 04785 *rc = who; 04786 ast_debug(1, "Got DTMF %s on channel (%s)\n", 04787 f->frametype == AST_FRAME_DTMF_END ? "end" : "begin", 04788 who->name); 04789 04790 break; 04791 } 04792 /* Write immediately frames, not passed through jb */ 04793 if (!frame_put_in_jb) 04794 ast_write(other, f); 04795 04796 /* Check if we have to deliver now */ 04797 if (jb_in_use) 04798 ast_jb_get_and_deliver(c0, c1); 04799 } 04800 /* XXX do we want to pass on also frames not matched above ? */ 04801 ast_frfree(f); 04802 04803 #ifndef HAVE_EPOLL 04804 /* Swap who gets priority */ 04805 cs[2] = cs[0]; 04806 cs[0] = cs[1]; 04807 cs[1] = cs[2]; 04808 #endif 04809 } 04810 04811 ast_poll_channel_del(c0, c1); 04812 04813 return res; 04814 }
struct ast_channel* ast_get_channel_by_exten_locked | ( | const char * | exten, | |
const char * | context | |||
) |
Get channel by exten (and optionally context) and lock it.
Definition at line 1271 of file channel.c.
References channel_find_locked().
01272 { 01273 return channel_find_locked(NULL, NULL, 0, context, exten); 01274 }
struct ast_channel* ast_get_channel_by_name_locked | ( | const char * | name | ) |
Get channel by name or uniqueid (locks channel).
Definition at line 1252 of file channel.c.
References channel_find_locked().
Referenced by acf_import(), action_add_agi_cmd(), 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(), get_dahdi_channel_locked(), handle_channelstatus(), handle_cli_agi_add_cmd(), handle_core_set_debug_channel(), handle_getvariablefull(), handle_hangup(), handle_set_chanvar(), handle_showchan(), handle_softhangup(), manager_park(), manager_play_dtmf(), park_call_full(), pbx_builtin_importvar(), shared_read(), shared_write(), start_monitor_action(), and stop_monitor_action().
01253 { 01254 return channel_find_locked(NULL, name, 0, NULL, NULL); 01255 }
struct ast_channel* ast_get_channel_by_name_prefix_locked | ( | const char * | name, | |
const int | namelen | |||
) |
Get channel by name or uniqueid prefix (locks channel).
Definition at line 1258 of file channel.c.
References channel_find_locked().
Referenced by action_bridge(), ast_parse_device_state(), bridge_exec(), common_exec(), handle_cli_mixmonitor(), shared_read(), and shared_write().
01259 { 01260 return channel_find_locked(NULL, name, namelen, NULL, NULL); 01261 }
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 604 of file channel.c.
References AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, chanlist::list, chanlist::tech, and ast_channel_tech::type.
Referenced by _ast_device_state().
00605 { 00606 struct chanlist *chanls; 00607 const struct ast_channel_tech *ret = NULL; 00608 00609 AST_RWLIST_RDLOCK(&channels); 00610 00611 AST_LIST_TRAVERSE(&backends, chanls, list) { 00612 if (!strcasecmp(name, chanls->tech->type)) { 00613 ret = chanls->tech; 00614 break; 00615 } 00616 } 00617 00618 AST_RWLIST_UNLOCK(&channels); 00619 00620 return ret; 00621 }
ast_group_t ast_get_group | ( | const char * | s | ) |
Definition at line 5316 of file channel.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_ERROR, LOG_WARNING, and strsep().
Referenced by _parse(), build_device(), build_gateway(), build_peer(), build_user(), func_channel_write(), process_dahdi(), and read_agent_config().
05317 { 05318 char *piece; 05319 char *c; 05320 int start=0, finish=0, x; 05321 ast_group_t group = 0; 05322 05323 if (ast_strlen_zero(s)) 05324 return 0; 05325 05326 c = ast_strdupa(s); 05327 05328 while ((piece = strsep(&c, ","))) { 05329 if (sscanf(piece, "%d-%d", &start, &finish) == 2) { 05330 /* Range */ 05331 } else if (sscanf(piece, "%d", &start)) { 05332 /* Just one */ 05333 finish = start; 05334 } else { 05335 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece); 05336 continue; 05337 } 05338 for (x = start; x <= finish; x++) { 05339 if ((x > 63) || (x < 0)) { 05340 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x); 05341 } else 05342 group |= ((ast_group_t) 1 << x); 05343 } 05344 } 05345 return group; 05346 }
int ast_hangup | ( | struct ast_channel * | chan | ) |
Hang up a channel.
chan | channel to hang up |
Definition at line 1643 of file channel.c.
References ast_assert, ast_audiohook_detach_list(), ast_autoservice_stop(), ast_cause2str(), ast_cdr_detach(), ast_cdr_end(), AST_CDR_FLAG_BRIDGED, AST_CDR_FLAG_DIALED, AST_CDR_FLAG_POST_DISABLED, AST_CDR_NULL, ast_channel_free(), ast_channel_lock, ast_channel_unlock, ast_closestream(), ast_debug, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_log(), ast_set_flag, ast_test_flag, ast_channel::audiohooks, ast_channel::blocker, ast_channel::blockproc, ast_channel::cdr, chanlist::chan, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_cdr::disposition, EVENT_FLAG_CALL, free_translation(), ast_channel::generator, ast_channel::generatordata, ast_channel_tech::hangup, ast_channel::hangupcause, LOG_WARNING, manager_event, ast_channel::masq, ast_channel::masqr, ast_channel::name, ast_generator::release, S_OR, ast_channel::sched, sched_context_destroy(), ast_channel::stream, ast_channel::tech, ast_channel::uniqueid, and ast_channel::vstream.
Referenced by __ast_request_and_dial(), __oh323_new(), action_bridge(), agent_hangup(), agent_read(), alsa_new(), answer_exec_run(), app_exec(), ast_async_goto(), ast_bridge_call_thread(), ast_call_forward(), ast_dial_destroy(), ast_dial_hangup(), ast_feature_request_and_dial(), ast_iax2_new(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run_app(), async_wait(), begin_dial_channel(), bridge_exec(), build_conf(), builtin_atxfer(), chanavail_exec(), check_compat(), check_goto_on_transfer(), clear_caller(), conf_run(), console_new(), dahdi_handle_event(), dahdi_new(), dial_exec_full(), do_forward(), do_hang(), do_idle_thread(), do_parking_thread(), features_hangup(), findmeexec(), function_ilink(), 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(), HandleCallOutgoing(), hangup_chan(), hangupcalls(), hanguptree(), iax2_request(), iax_park(), iax_park_thread(), jingle_new(), local_hangup(), masq_park_call(), mgcp_new(), mgcp_ss(), monitor_dial(), mwi_thread(), nbs_new(), oss_new(), park_exec(), parkandannounce_exec(), phone_new(), rpt(), rpt_call(), rpt_tele_thread(), sip_new(), sip_park(), sip_park_thread(), skinny_new(), skinny_ss(), ss_thread(), unistim_new(), usbradio_new(), wait_for_answer(), and wait_for_winner().
01644 { 01645 int res = 0; 01646 01647 /* Don't actually hang up a channel that will masquerade as someone else, or 01648 if someone is going to masquerade as us */ 01649 ast_channel_lock(chan); 01650 01651 if (chan->audiohooks) { 01652 ast_audiohook_detach_list(chan->audiohooks); 01653 chan->audiohooks = NULL; 01654 } 01655 01656 ast_autoservice_stop(chan); 01657 01658 if (chan->masq) { 01659 if (ast_do_masquerade(chan)) 01660 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01661 } 01662 01663 if (chan->masq) { 01664 ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name); 01665 ast_channel_unlock(chan); 01666 return 0; 01667 } 01668 /* If this channel is one which will be masqueraded into something, 01669 mark it as a zombie already, so we know to free it later */ 01670 if (chan->masqr) { 01671 ast_set_flag(chan, AST_FLAG_ZOMBIE); 01672 ast_channel_unlock(chan); 01673 return 0; 01674 } 01675 free_translation(chan); 01676 /* Close audio stream */ 01677 if (chan->stream) { 01678 ast_closestream(chan->stream); 01679 chan->stream = NULL; 01680 } 01681 /* Close video stream */ 01682 if (chan->vstream) { 01683 ast_closestream(chan->vstream); 01684 chan->vstream = NULL; 01685 } 01686 if (chan->sched) { 01687 sched_context_destroy(chan->sched); 01688 chan->sched = NULL; 01689 } 01690 01691 if (chan->generatordata) /* Clear any tone stuff remaining */ 01692 if (chan->generator && chan->generator->release) 01693 chan->generator->release(chan, chan->generatordata); 01694 chan->generatordata = NULL; 01695 chan->generator = NULL; 01696 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 01697 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 01698 "is blocked by thread %ld in procedure %s! Expect a failure\n", 01699 (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 01700 ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0); 01701 } 01702 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) { 01703 ast_debug(1, "Hanging up channel '%s'\n", chan->name); 01704 if (chan->tech->hangup) 01705 res = chan->tech->hangup(chan); 01706 } else { 01707 ast_debug(1, "Hanging up zombie '%s'\n", chan->name); 01708 } 01709 01710 ast_channel_unlock(chan); 01711 manager_event(EVENT_FLAG_CALL, "Hangup", 01712 "Channel: %s\r\n" 01713 "Uniqueid: %s\r\n" 01714 "CallerIDNum: %s\r\n" 01715 "CallerIDName: %s\r\n" 01716 "Cause: %d\r\n" 01717 "Cause-txt: %s\r\n", 01718 chan->name, 01719 chan->uniqueid, 01720 S_OR(chan->cid.cid_num, "<unknown>"), 01721 S_OR(chan->cid.cid_name, "<unknown>"), 01722 chan->hangupcause, 01723 ast_cause2str(chan->hangupcause) 01724 ); 01725 01726 if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) && 01727 !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) && 01728 (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) { 01729 01730 ast_cdr_end(chan->cdr); 01731 ast_cdr_detach(chan->cdr); 01732 chan->cdr = NULL; 01733 } 01734 01735 ast_channel_free(chan); 01736 01737 return res; 01738 }
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 3024 of file channel.c.
References ast_indicate_data(), and chanlist::chan.
Referenced by __ast_play_and_record(), agent_new(), alsa_call(), answer_trunk_chan(), ast_bridge_call(), ast_channel_bridge(), ast_do_masquerade(), ast_dtmf_stream(), ast_feature_request_and_dial(), ast_raw_answer(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), cli_console_answer(), conf_run(), console_call(), dial_exec_full(), do_forward(), do_parking_thread(), features_indicate(), finishup(), function_remote(), handle_callforward_button(), handle_frame(), handle_recordfile(), handle_remote_data(), handle_remote_phone_dtmf(), mgcp_ss(), monitor_dial(), oss_call(), park_exec(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_proceeding(), pbx_builtin_progress(), pbx_builtin_ringing(), pbx_builtin_waitexten(), queue_exec(), rmt_telem_finish(), rmt_telem_start(), rpt(), say_periodic_announcement(), say_position(), send_waveform_to_channel(), skinny_ss(), sla_handle_hold_event(), sla_station_exec(), sla_trunk_exec(), and wait_for_answer().
03025 { 03026 return ast_indicate_data(chan, condition, NULL, 0); 03027 }
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 3063 of file channel.c.
References ast_channel::_state, ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_CONTROL_WINK, ast_debug, AST_FLAG_ZOMBIE, ast_get_indication_tone(), ast_log(), ast_playtones_start(), ast_playtones_stop(), AST_STATE_UP, ast_test_flag, chanlist::chan, tone_zone_sound::data, ast_channel_tech::indicate, is_visible_indication(), LOG_WARNING, ast_channel::name, ast_channel::tech, ast_channel::visible_indication, and ast_channel::zone.
Referenced by agent_hangup(), ast_bridge_call(), ast_indicate(), bridge_native_loop(), do_parking_thread(), login_exec(), park_call_full(), pbx_builtin_waitexten(), and transmit_audio().
03065 { 03066 /* By using an enum, we'll get compiler warnings for values not handled 03067 * in switch statements. */ 03068 enum ast_control_frame_type condition = _condition; 03069 const struct tone_zone_sound *ts = NULL; 03070 int res = -1; 03071 03072 ast_channel_lock(chan); 03073 03074 /* Don't bother if the channel is about to go away, anyway. */ 03075 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 03076 ast_channel_unlock(chan); 03077 return -1; 03078 } 03079 03080 if (chan->tech->indicate) { 03081 /* See if the channel driver can handle this condition. */ 03082 res = chan->tech->indicate(chan, condition, data, datalen); 03083 } 03084 03085 ast_channel_unlock(chan); 03086 03087 if (chan->tech->indicate && !res) { 03088 /* The channel driver successfully handled this indication */ 03089 if (is_visible_indication(condition)) { 03090 chan->visible_indication = condition; 03091 } 03092 return 0; 03093 } 03094 03095 /* The channel driver does not support this indication, let's fake 03096 * it by doing our own tone generation if applicable. */ 03097 03098 /*!\note If we compare the enumeration type, which does not have any 03099 * negative constants, the compiler may optimize this code away. 03100 * Therefore, we must perform an integer comparison here. */ 03101 if (_condition < 0) { 03102 /* Stop any tones that are playing */ 03103 ast_playtones_stop(chan); 03104 return 0; 03105 } 03106 03107 /* Handle conditions that we have tones for. */ 03108 switch (condition) { 03109 case AST_CONTROL_RINGING: 03110 ts = ast_get_indication_tone(chan->zone, "ring"); 03111 /* It is common practice for channel drivers to return -1 if trying 03112 * to indicate ringing on a channel which is up. The idea is to let the 03113 * core generate the ringing inband. However, we don't want the 03114 * warning message about not being able to handle the specific indication 03115 * to print nor do we want ast_indicate_data to return an "error" for this 03116 * condition 03117 */ 03118 if (chan->_state == AST_STATE_UP) { 03119 res = 0; 03120 } 03121 break; 03122 case AST_CONTROL_BUSY: 03123 ts = ast_get_indication_tone(chan->zone, "busy"); 03124 break; 03125 case AST_CONTROL_CONGESTION: 03126 ts = ast_get_indication_tone(chan->zone, "congestion"); 03127 break; 03128 case AST_CONTROL_PROGRESS: 03129 case AST_CONTROL_PROCEEDING: 03130 case AST_CONTROL_VIDUPDATE: 03131 case AST_CONTROL_SRCUPDATE: 03132 case AST_CONTROL_RADIO_KEY: 03133 case AST_CONTROL_RADIO_UNKEY: 03134 case AST_CONTROL_OPTION: 03135 case AST_CONTROL_WINK: 03136 case AST_CONTROL_FLASH: 03137 case AST_CONTROL_OFFHOOK: 03138 case AST_CONTROL_TAKEOFFHOOK: 03139 case AST_CONTROL_ANSWER: 03140 case AST_CONTROL_HANGUP: 03141 case AST_CONTROL_RING: 03142 case AST_CONTROL_HOLD: 03143 case AST_CONTROL_UNHOLD: 03144 case AST_CONTROL_T38: 03145 /* Nothing left to do for these. */ 03146 res = 0; 03147 break; 03148 } 03149 03150 if (ts && ts->data[0]) { 03151 /* We have a tone to play, yay. */ 03152 ast_debug(1, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition); 03153 ast_playtones_start(chan, 0, ts->data, 1); 03154 res = 0; 03155 chan->visible_indication = condition; 03156 } 03157 03158 if (res) { 03159 /* not handled */ 03160 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); 03161 } 03162 03163 return res; 03164 }
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 5352 of file channel.c.
References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.
Referenced by load_module().
05355 { 05356 ast_moh_start_ptr = start_ptr; 05357 ast_moh_stop_ptr = stop_ptr; 05358 ast_moh_cleanup_ptr = cleanup_ptr; 05359 }
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 3007 of file channel.c.
References ast_debug, ast_opt_internal_timing, chanlist::chan, and ast_channel::timingfd.
Referenced by add_sdp(), and ast_read_generator_actions().
03008 { 03009 int ret = ast_opt_internal_timing && chan->timingfd > -1; 03010 ast_debug(5, "Internal timing is %s (option_internal_timing=%d chan->timingfd=%d)\n", ret? "enabled": "disabled", ast_opt_internal_timing, chan->timingfd); 03011 return ret; 03012 }
void ast_moh_cleanup | ( | struct ast_channel * | chan | ) |
Definition at line 5386 of file channel.c.
References ast_moh_cleanup_ptr, and chan.
Referenced by ast_channel_free().
05387 { 05388 if (ast_moh_cleanup_ptr) 05389 ast_moh_cleanup_ptr(chan); 05390 }
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 5369 of file channel.c.
References ast_moh_start_ptr, ast_verb, and chan.
Referenced by alsa_indicate(), app_exec(), cb_events(), conf_start_moh(), console_indicate(), dahdi_indicate(), dial_exec_full(), feature_exec_app(), gtalk_indicate(), handle_setmusic(), iax2_indicate(), jingle_indicate(), key_call(), local_indicate(), mgcp_indicate(), misdn_indication(), moh_handle_digit(), monitor_dial(), oh323_indicate(), oss_indicate(), phone_indicate(), play_moh_exec(), queue_exec(), retrydial_exec(), say_periodic_announcement(), say_position(), sip_indicate(), skinny_indicate(), start_moh_exec(), TransferCallStep1(), unistim_indicate(), usbradio_indicate(), and wait_moh_exec().
05370 { 05371 if (ast_moh_start_ptr) 05372 return ast_moh_start_ptr(chan, mclass, interpclass); 05373 05374 ast_verb(3, "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : (interpclass ? interpclass : "default")); 05375 05376 return 0; 05377 }
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 5380 of file channel.c.
References ast_moh_stop_ptr, and chan.
Referenced by alsa_indicate(), app_exec(), ast_quiet_chan(), cb_events(), 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(), mgcp_indicate(), misdn_indication(), misdn_transfer_bc(), moh_handle_digit(), monitor_dial(), oh323_indicate(), oss_indicate(), phone_indicate(), play_moh_exec(), retrydial_exec(), say_periodic_announcement(), say_position(), sip_indicate(), skinny_indicate(), stop_moh_exec(), unistim_hangup(), unistim_indicate(), usbradio_indicate(), and wait_moh_exec().
05381 { 05382 if (ast_moh_stop_ptr) 05383 ast_moh_stop_ptr(chan); 05384 }
void ast_poll_channel_add | ( | struct ast_channel * | chan0, | |
struct ast_channel * | chan1 | |||
) |
Add a channel to an optimized waitfor
Definition at line 1565 of file channel.c.
References AST_MAX_FDS, and ast_channel::fds.
Referenced by ast_feature_request_and_dial(), ast_generic_bridge(), begin_dial_channel(), bridge_native_loop(), bridge_p2p_loop(), and wait_for_answer().
01566 { 01567 #ifdef HAVE_EPOLL 01568 struct epoll_event ev; 01569 int i = 0; 01570 01571 if (chan0->epfd == -1) 01572 return; 01573 01574 /* Iterate through the file descriptors on chan1, adding them to chan0 */ 01575 for (i = 0; i < AST_MAX_FDS; i++) { 01576 if (chan1->fds[i] == -1) 01577 continue; 01578 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; 01579 ev.data.ptr = chan1->epfd_data[i]; 01580 epoll_ctl(chan0->epfd, EPOLL_CTL_ADD, chan1->fds[i], &ev); 01581 } 01582 01583 #endif 01584 return; 01585 }
void ast_poll_channel_del | ( | struct ast_channel * | chan0, | |
struct ast_channel * | chan1 | |||
) |
Delete a channel from an optimized waitfor
Definition at line 1588 of file channel.c.
References AST_MAX_FDS, and ast_channel::fds.
Referenced by ast_feature_request_and_dial(), bridge_native_loop(), monitor_dial(), and wait_for_answer().
01589 { 01590 #ifdef HAVE_EPOLL 01591 struct epoll_event ev; 01592 int i = 0; 01593 01594 if (chan0->epfd == -1) 01595 return; 01596 01597 for (i = 0; i < AST_MAX_FDS; i++) { 01598 if (chan1->fds[i] == -1) 01599 continue; 01600 epoll_ctl(chan0->epfd, EPOLL_CTL_DEL, chan1->fds[i], &ev); 01601 } 01602 01603 #endif 01604 return; 01605 }
char* ast_print_group | ( | char * | buf, | |
int | buflen, | |||
ast_group_t | group | |||
) |
print call- and pickup groups into buffer
Definition at line 5398 of file channel.c.
Referenced by _sip_show_peer(), func_channel_read(), function_sippeer(), handle_skinny_show_line(), misdn_cfg_get_config_string(), print_group(), read_config(), and serialize_showchan().
05399 { 05400 unsigned int i; 05401 int first = 1; 05402 char num[3]; 05403 05404 buf[0] = '\0'; 05405 05406 if (!group) /* Return empty string if no group */ 05407 return buf; 05408 05409 for (i = 0; i <= 63; i++) { /* Max group is 63 */ 05410 if (group & ((ast_group_t) 1 << i)) { 05411 if (!first) { 05412 strncat(buf, ", ", buflen - strlen(buf) - 1); 05413 } else { 05414 first = 0; 05415 } 05416 snprintf(num, sizeof(num), "%u", i); 05417 strncat(buf, num, buflen - strlen(buf) - 1); 05418 } 05419 } 05420 return buf; 05421 }
int ast_prod | ( | struct ast_channel * | chan | ) |
Send empty audio to prime a channel driver.
Definition at line 3285 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::data, LOG_WARNING, ast_channel::name, ast_channel::rawwriteformat, ast_frame::src, and ast_frame::subclass.
Referenced by ast_activate_generator().
03286 { 03287 struct ast_frame a = { AST_FRAME_VOICE }; 03288 char nothing[128]; 03289 03290 /* Send an empty audio frame to get things moving */ 03291 if (chan->_state != AST_STATE_UP) { 03292 ast_debug(1, "Prodding channel '%s'\n", chan->name); 03293 a.subclass = chan->rawwriteformat; 03294 a.data = nothing + AST_FRIENDLY_OFFSET; 03295 a.src = "ast_prod"; 03296 if (ast_write(chan, &a)) 03297 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 03298 } 03299 return 0; 03300 }
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 1097 of file channel.c.
References AST_FRAME_CONTROL, ast_queue_frame(), chanlist::chan, and f.
Referenced by __dahdi_exception(), __oh323_update_info(), ast_pickup_call(), attempt_transfer(), auto_congest(), cb_events(), 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(), mgcp_call(), nbs_call(), phone_call(), pickup_do(), process_sdp(), receive_digit(), remote_hold(), send_cause2ast(), setup_rtp_connection(), skinny_call(), skinny_unhold(), ss_thread(), unistim_call(), and update_state().
01098 { 01099 struct ast_frame f = { AST_FRAME_CONTROL, }; 01100 01101 f.subclass = control; 01102 01103 return ast_queue_frame(chan, &f); 01104 }
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 1107 of file channel.c.
References AST_FRAME_CONTROL, ast_queue_frame(), chanlist::chan, and f.
Referenced by change_t38_state(), dahdi_handle_event(), dahdi_hangup(), iax2_queue_control_data(), process_sdp(), and skinny_hold().
01109 { 01110 struct ast_frame f = { AST_FRAME_CONTROL, }; 01111 01112 f.subclass = control; 01113 f.data = (void *) data; 01114 f.datalen = datalen; 01115 01116 return ast_queue_frame(chan, &f); 01117 }
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 1074 of file channel.c.
References __ast_queue_frame(), and chanlist::chan.
Referenced by __ast_read(), __oh323_rtp_create(), __oh323_update_info(), agent_new(), alsa_call(), ast_channel_masquerade(), ast_channel_setwhentohangup(), ast_do_masquerade(), ast_dsp_process(), ast_queue_control(), ast_queue_control_data(), ast_queue_hangup(), ast_softhangup_nolock(), cb_events(), cli_console_answer(), cli_console_dial(), cli_console_flash(), cli_console_sendtext(), console_answer(), console_call(), console_dial(), console_do_answer(), console_flash(), console_sendtext(), dahdi_queue_frame(), 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(), process_sdp(), queue_dtmf_readq(), receive_digit(), receive_message(), stream_monitor(), unistim_do_senddigit(), unistim_senddigit_end(), usbradio_read(), and wakeup_sub().
01075 { 01076 return __ast_queue_frame(chan, fin, 0, NULL); 01077 }
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 1079 of file channel.c.
References __ast_queue_frame(), and chanlist::chan.
Referenced by __ast_answer(), __ast_read(), and ast_autoservice_stop().
01080 { 01081 return __ast_queue_frame(chan, fin, 1, NULL); 01082 }
int ast_queue_hangup | ( | struct ast_channel * | chan | ) |
Queue a hangup frame.
Definition at line 1085 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 __oh323_update_info(), __sip_autodestruct(), cleanup_connection(), cli_console_hangup(), close_call(), close_client(), console_hangup(), dahdi_handle_event(), gtalk_hangup_farend(), gtalk_is_answered(), handle_onhook_message(), handle_request_bye(), handle_request_cancel(), handle_response(), handle_response_invite(), handle_soft_key_event_message(), HandleCallOutgoing(), hangup_chan(), hangup_connection(), iax2_destroy(), iax2_queue_hangup(), jingle_hangup_farend(), local_hangup(), mgcp_queue_hangup(), misdn_answer(), pri_hangup_all(), retrans_pkt(), and TransferCallStep1().
01086 { 01087 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP }; 01088 /* Yeah, let's not change a lock-critical value without locking */ 01089 if (!ast_channel_trylock(chan)) { 01090 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01091 ast_channel_unlock(chan); 01092 } 01093 return ast_queue_frame(chan, &f); 01094 }
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 1740 of file channel.c.
References ast_channel::_state, ast_channel_tech::answer, ast_cdr_answer(), 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, ast_channel::tech, and ast_channel::visible_indication.
Referenced by __ast_answer(), and ast_bridge_call().
01741 { 01742 int res = 0; 01743 01744 ast_channel_lock(chan); 01745 01746 /* You can't answer an outbound call */ 01747 if (ast_test_flag(chan, AST_FLAG_OUTGOING)) { 01748 ast_channel_unlock(chan); 01749 return 0; 01750 } 01751 01752 /* Stop if we're a zombie or need a soft hangup */ 01753 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 01754 ast_channel_unlock(chan); 01755 return -1; 01756 } 01757 01758 ast_channel_unlock(chan); 01759 01760 switch (chan->_state) { 01761 case AST_STATE_RINGING: 01762 case AST_STATE_RING: 01763 ast_channel_lock(chan); 01764 if (chan->tech->answer) { 01765 res = chan->tech->answer(chan); 01766 } 01767 ast_setstate(chan, AST_STATE_UP); 01768 if (cdr_answer) { 01769 ast_cdr_answer(chan->cdr); 01770 } 01771 ast_channel_unlock(chan); 01772 break; 01773 case AST_STATE_UP: 01774 /* Calling ast_cdr_answer when it it has previously been called 01775 * is essentially a no-op, so it is safe. 01776 */ 01777 if (cdr_answer) { 01778 ast_cdr_answer(chan->cdr); 01779 } 01780 break; 01781 default: 01782 break; 01783 } 01784 01785 ast_indicate(chan, -1); 01786 chan->visible_indication = 0; 01787 01788 return res; 01789 }
struct ast_frame* ast_read | ( | struct ast_channel * | chan | ) |
Reads a frame.
chan | channel to read a frame from |
Definition at line 3014 of file channel.c.
References __ast_read(), and chanlist::chan.
Referenced by __adsi_transmit_messages(), __ast_answer(), __ast_play_and_record(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), agent_read(), ast_feature_request_and_dial(), ast_recvtext(), ast_safe_sleep_conditional(), ast_tonepair(), ast_udptl_bridge(), ast_waitfordigit_full(), async_wait(), autoservice_run(), background_detect_exec(), bridge_native_loop(), bridge_p2p_loop(), builtin_atxfer(), channel_spy(), check_goto_on_transfer(), conf_exec(), conf_flush(), conf_run(), dahdi_bridge(), dictate_exec(), disa_exec(), do_idle_thread(), do_parking_thread(), do_waiting(), echo_exec(), eivr_comm(), features_read(), find_cache(), handle_invite_replaces(), handle_recordfile(), handle_speechrecognize(), iax_park_thread(), ices_exec(), isAnsweringMachine(), launch_asyncagi(), masq_park_call(), measurenoise(), misdn_bridge(), monitor_dial(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), recordthread(), rpt(), run_agi(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), speech_background(), ss_thread(), transmit_audio(), transmit_t38(), wait_for_answer(), wait_for_hangup(), wait_for_winner(), waitforring_exec(), and waitstream_core().
03015 { 03016 return __ast_read(chan, 0); 03017 }
static void ast_read_generator_actions | ( | struct ast_channel * | chan, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 2462 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_deactivate_generator(), ast_format_rate(), AST_FRAME_CNG, ast_internal_timing_enabled(), ast_log(), ast_settimeout(), chanlist::chan, f, ast_generator::generate, ast_channel::generator, generator_force(), ast_channel::generatordata, LOG_DEBUG, option_debug, ast_channel::timingfd, ast_channel::timingfunc, and ast_channel::writeformat.
Referenced by __ast_read().
02463 { 02464 if (chan->generatordata && !ast_internal_timing_enabled(chan)) { 02465 void *tmp = chan->generatordata; 02466 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL; 02467 int res; 02468 int samples; 02469 02470 if (chan->timingfunc) { 02471 if (option_debug > 1) 02472 ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n"); 02473 ast_settimeout(chan, 0, NULL, NULL); 02474 } 02475 02476 chan->generatordata = NULL; /* reset, to let writes go through */ 02477 02478 if (f->subclass != chan->writeformat) { 02479 float factor; 02480 factor = ((float) ast_format_rate(chan->writeformat)) / ((float) ast_format_rate(f->subclass)); 02481 samples = (int) ( ((float) f->samples) * factor ); 02482 } else { 02483 samples = f->samples; 02484 } 02485 02486 if (chan->generator->generate) { 02487 generate = chan->generator->generate; 02488 } 02489 /* This unlock is here based on two assumptions that hold true at this point in the 02490 * code. 1) this function is only called from within __ast_read() and 2) all generators 02491 * call ast_write() in their generate callback. 02492 * 02493 * The reason this is added is so that when ast_write is called, the lock that occurs 02494 * there will not recursively lock the channel. Doing this will cause intended deadlock 02495 * avoidance not to work in deeper functions 02496 */ 02497 ast_channel_unlock(chan); 02498 res = generate(chan, tmp, f->datalen, samples); 02499 ast_channel_lock(chan); 02500 chan->generatordata = tmp; 02501 if (res) { 02502 if (option_debug > 1) 02503 ast_log(LOG_DEBUG, "Auto-deactivating generator\n"); 02504 ast_deactivate_generator(chan); 02505 } 02506 02507 } else if (f->frametype == AST_FRAME_CNG) { 02508 if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) { 02509 if (option_debug > 1) 02510 ast_log(LOG_DEBUG, "Generator got CNG, switching to timed mode\n"); 02511 ast_settimeout(chan, 160, generator_force, chan); 02512 } 02513 } 02514 }
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 3019 of file channel.c.
References __ast_read(), and chanlist::chan.
Referenced by conf_run().
03020 { 03021 return __ast_read(chan, 1); 03022 }
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 Read in a digit string "s", max length "len", maximum timeout between digits "timeout" (-1 for none), terminated by anything in "enders". Give them rtimeout for the first digit. Returns 0 on normal return, or 1 on a timeout. In the case of a timeout, any digits that were read before the timeout will still be available in s. RETURNS 2 in full version when ctrlfd is available, NOT 1 |
Definition at line 3953 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().
03954 { 03955 return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1); 03956 }
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 3958 of file channel.c.
References 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_stopstream(), ast_test_flag, ast_waitfordigit_full(), ast_waitstream_full(), and ast_channel::stream.
Referenced by ast_app_getdata_full(), and ast_readstring().
03959 { 03960 int pos = 0; /* index in the buffer where we accumulate digits */ 03961 int to = ftimeout; 03962 03963 /* Stop if we're a zombie or need a soft hangup */ 03964 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 03965 return -1; 03966 if (!len) 03967 return -1; 03968 for (;;) { 03969 int d; 03970 if (c->stream) { 03971 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 03972 ast_stopstream(c); 03973 usleep(1000); 03974 if (!d) 03975 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 03976 } else { 03977 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 03978 } 03979 if (d < 0) 03980 return AST_GETDATA_FAILED; 03981 if (d == 0) { 03982 s[pos] = '\0'; 03983 return AST_GETDATA_TIMEOUT; 03984 } 03985 if (d == 1) { 03986 s[pos] = '\0'; 03987 return AST_GETDATA_INTERRUPTED; 03988 } 03989 if (strchr(enders, d) && (pos == 0)) { 03990 s[pos] = '\0'; 03991 return AST_GETDATA_EMPTY_END_TERMINATED; 03992 } 03993 if (!strchr(enders, d)) { 03994 s[pos++] = d; 03995 } 03996 if (strchr(enders, d) || (pos >= len)) { 03997 s[pos] = '\0'; 03998 return AST_GETDATA_COMPLETE; 03999 } 04000 to = timeout; 04001 } 04002 /* Never reached */ 04003 return 0; 04004 }
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) Read a char of text from a channel Returns 0 on success, -1 on failure |
Definition at line 3166 of file channel.c.
References ast_free, ast_recvtext(), buf, and chanlist::chan.
Referenced by handle_recvchar().
03167 { 03168 int c; 03169 char *buf = ast_recvtext(chan, timeout); 03170 if (buf == NULL) 03171 return -1; /* error or timeout */ 03172 c = *(unsigned char *)buf; 03173 ast_free(buf); 03174 return c; 03175 }
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 3177 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(), buf, chanlist::chan, and f.
Referenced by ast_recvchar(), and handle_recvtext().
03178 { 03179 int res, done = 0; 03180 char *buf = NULL; 03181 03182 while (!done) { 03183 struct ast_frame *f; 03184 if (ast_check_hangup(chan)) 03185 break; 03186 res = ast_waitfor(chan, timeout); 03187 if (res <= 0) /* timeout or error */ 03188 break; 03189 timeout = res; /* update timeout */ 03190 f = ast_read(chan); 03191 if (f == NULL) 03192 break; /* no frame */ 03193 if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) 03194 done = 1; /* force a break */ 03195 else if (f->frametype == AST_FRAME_TEXT) { /* what we want */ 03196 buf = ast_strndup((char *) f->data, f->datalen); /* dup and break */ 03197 done = 1; 03198 } 03199 ast_frfree(f); 03200 } 03201 return buf; 03202 }
struct ast_channel* ast_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | status | |||
) |
Requests a channel.
type | type of channel to request | |
format | requested channel format (codec) | |
data | data to pass to the channel requester | |
status | status |
NULL | failure | |
non-NULL | channel on success |
Definition at line 3853 of file channel.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_NOSUCHDRIVER, AST_CAUSE_NOTDEFINED, AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, AST_LIST_TRAVERSE, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_translator_best_choice(), capabilities, ast_channel_tech::capabilities, chanlist::chan, chanlist::list, LOG_WARNING, ast_channel_tech::requester, ast_channel::tech, and ast_channel_tech::type.
Referenced by __ast_request_and_dial(), agent_request(), ast_call_forward(), ast_feature_request_and_dial(), attempt_reconnect(), begin_dial_channel(), build_conf(), chanavail_exec(), conf_run(), dial_exec_full(), do_forward(), features_alloc(), findmeexec(), function_ilink(), ring_entry(), rpt(), rpt_call(), and rpt_tele_thread().
03854 { 03855 struct chanlist *chan; 03856 struct ast_channel *c; 03857 int capabilities; 03858 int fmt; 03859 int res; 03860 int foo; 03861 int videoformat = format & AST_FORMAT_VIDEO_MASK; 03862 int textformat = format & AST_FORMAT_TEXT_MASK; 03863 03864 if (!cause) 03865 cause = &foo; 03866 *cause = AST_CAUSE_NOTDEFINED; 03867 03868 if (AST_RWLIST_RDLOCK(&channels)) { 03869 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 03870 return NULL; 03871 } 03872 03873 AST_LIST_TRAVERSE(&backends, chan, list) { 03874 if (strcasecmp(type, chan->tech->type)) 03875 continue; 03876 03877 capabilities = chan->tech->capabilities; 03878 fmt = format & AST_FORMAT_AUDIO_MASK; 03879 if (fmt) { 03880 /* We have audio - is it possible to connect the various calls to each other? 03881 (Avoid this check for calls without audio, like text+video calls) 03882 */ 03883 res = ast_translator_best_choice(&fmt, &capabilities); 03884 if (res < 0) { 03885 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native 0x%x) to 0x%x\n", type, chan->tech->capabilities, format); 03886 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03887 AST_RWLIST_UNLOCK(&channels); 03888 return NULL; 03889 } 03890 } 03891 AST_RWLIST_UNLOCK(&channels); 03892 if (!chan->tech->requester) 03893 return NULL; 03894 03895 if (!(c = chan->tech->requester(type, capabilities | videoformat | textformat, data, cause))) 03896 return NULL; 03897 03898 /* no need to generate a Newchannel event here; it is done in the channel_alloc call */ 03899 return c; 03900 } 03901 03902 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 03903 *cause = AST_CAUSE_NOSUCHDRIVER; 03904 AST_RWLIST_UNLOCK(&channels); 03905 03906 return NULL; 03907 }
struct ast_channel* ast_request_and_dial | ( | const char * | type, | |
int | format, | |||
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 | |
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 3848 of file channel.c.
References __ast_request_and_dial().
Referenced by ast_pbx_outgoing_exten().
03849 { 03850 return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL); 03851 }
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 Waits for a specified amount of time, servicing the channel as required. |
Definition at line 1305 of file channel.c.
References ast_safe_sleep_conditional(), and chanlist::chan.
Referenced by _ast_adsi_transmit_message_full(), alarmreceiver_exec(), ast_dtmf_stream(), ast_senddigit(), builtin_atxfer(), builtin_parkcall(), conf_run(), dictate_exec(), flash_exec(), function_ilink(), function_remote(), handle_callforward_button(), handle_remote_data(), handle_remote_phone_dtmf(), 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(), rmt_telem_start(), rpt_call(), rpt_tele_thread(), send_morse(), send_tone_telemetry(), skinny_ss(), ss_thread(), testclient_exec(), testserver_exec(), wait_for_hangup(), wait_interval(), wait_moh_exec(), waituntil_exec(), and zapateller_exec().
01306 { 01307 return ast_safe_sleep_conditional(chan, ms, NULL, NULL); 01308 }
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 1284 of file channel.c.
References ast_frfree, ast_read(), ast_waitfor(), chanlist::chan, and f.
Referenced by ast_safe_sleep(), and login_exec().
01285 { 01286 struct ast_frame *f; 01287 01288 while (ms > 0) { 01289 if (cond && ((*cond)(data) == 0)) 01290 return 0; 01291 ms = ast_waitfor(chan, ms); 01292 if (ms < 0) 01293 return -1; 01294 if (ms > 0) { 01295 f = ast_read(chan); 01296 if (!f) 01297 return -1; 01298 ast_frfree(f); 01299 } 01300 } 01301 return 0; 01302 }
int ast_say_character_str | ( | struct ast_channel * | chan, | |
const char * | str, | |||
const char * | ints, | |||
const char * | lang | |||
) |
Definition at line 5670 of file channel.c.
References ast_say_character_str_full, and chan.
Referenced by common_exec(), pbx_builtin_saycharacters(), play_mailbox_owner(), rpt_tele_thread(), and saycharstr().
05672 { 05673 return ast_say_character_str_full(chan, str, ints, lang, -1, -1); 05674 }
int ast_say_digit_str | ( | struct ast_channel * | chan, | |
const char * | str, | |||
const char * | ints, | |||
const char * | lang | |||
) |
Definition at line 5664 of file channel.c.
References ast_say_digit_str_full, and chan.
Referenced by forward_message(), invent_message(), mgcp_ss(), pbx_builtin_saydigits(), play_message_callerid(), and ss_thread().
05666 { 05667 return ast_say_digit_str_full(chan, str, ints, lang, -1, -1); 05668 }
int ast_say_digits | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | ints, | |||
const char * | lang | |||
) |
Definition at line 5658 of file channel.c.
References ast_say_digits_full(), and chan.
Referenced by common_exec(), conf_exec(), conf_run(), park_call_full(), parkandannounce_exec(), rpt_tele_thread(), and saydigits().
05660 { 05661 return ast_say_digits_full(chan, num, ints, lang, -1, -1); 05662 }
int ast_say_digits_full | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | ints, | |||
const char * | lang, | |||
int | audiofd, | |||
int | ctrlfd | |||
) |
Definition at line 5682 of file channel.c.
References ast_say_digit_str_full, and chan.
Referenced by ast_say_digits(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_number_full_cz(), 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_ge(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_it(), 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_tw(), and say_init_mode().
05684 { 05685 char buf[256]; 05686 05687 snprintf(buf, sizeof(buf), "%d", num); 05688 05689 return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd); 05690 }
int ast_say_enumeration | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | ints, | |||
const char * | language, | |||
const char * | options | |||
) |
Definition at line 5652 of file channel.c.
References ast_say_enumeration_full, and chan.
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(), and ast_say_date_with_format_pl().
05654 { 05655 return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1); 05656 }
int ast_say_number | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | ints, | |||
const char * | language, | |||
const char * | options | |||
) |
Definition at line 5646 of file channel.c.
References ast_say_number_full, and chan.
Referenced by ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_ge(), ast_say_date_gr(), ast_say_date_he(), ast_say_date_hu(), 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_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_ge(), ast_say_datetime_from_now_he(), ast_say_datetime_from_now_pt(), ast_say_datetime_he(), ast_say_datetime_pt(), ast_say_datetime_th(), ast_say_datetime_tw(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_ge(), ast_say_time_gr(), ast_say_time_hu(), ast_say_time_nl(), ast_say_time_pt(), ast_say_time_pt_BR(), ast_say_time_th(), ast_say_time_tw(), bridge_playfile(), conf_exec(), 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_multilang(), vm_intro_pt(), and vm_intro_pt_BR().
05648 { 05649 return ast_say_number_full(chan, num, ints, language, options, -1, -1); 05650 }
int ast_say_phonetic_str | ( | struct ast_channel * | chan, | |
const char * | str, | |||
const char * | ints, | |||
const char * | lang | |||
) |
Definition at line 5676 of file channel.c.
References ast_say_phonetic_str_full, and chan.
Referenced by pbx_builtin_sayphonetic().
05678 { 05679 return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1); 05680 }
int ast_senddigit | ( | struct ast_channel * | chan, | |
char | digit, | |||
unsigned int | duration | |||
) |
Send a DTMF digit to a channel 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 3275 of file channel.c.
References AST_DEFAULT_EMULATE_DTMF_DURATION, ast_safe_sleep(), ast_senddigit_begin(), ast_senddigit_end(), chanlist::chan, ast_channel_tech::send_digit_begin, and ast_channel::tech.
Referenced by ast_dtmf_stream(), dial_exec_full(), and manager_play_dtmf().
03276 { 03277 if (chan->tech->send_digit_begin) { 03278 ast_senddigit_begin(chan, digit); 03279 ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 03280 } 03281 03282 return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); 03283 }
int ast_senddigit_begin | ( | struct ast_channel * | chan, | |
char | digit | |||
) |
Send a DTMF digit to a channel Send a DTMF digit to a channel.
chan | channel to act upon | |
digit | the DTMF digit to send, encoded in ASCII |
Definition at line 3217 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(), ast_write(), and features_digit_begin().
03218 { 03219 /* Device does not support DTMF tones, lets fake 03220 * it by doing our own generation. */ 03221 static const char* dtmf_tones[] = { 03222 "941+1336", /* 0 */ 03223 "697+1209", /* 1 */ 03224 "697+1336", /* 2 */ 03225 "697+1477", /* 3 */ 03226 "770+1209", /* 4 */ 03227 "770+1336", /* 5 */ 03228 "770+1477", /* 6 */ 03229 "852+1209", /* 7 */ 03230 "852+1336", /* 8 */ 03231 "852+1477", /* 9 */ 03232 "697+1633", /* A */ 03233 "770+1633", /* B */ 03234 "852+1633", /* C */ 03235 "941+1633", /* D */ 03236 "941+1209", /* * */ 03237 "941+1477" /* # */ 03238 }; 03239 03240 if (!chan->tech->send_digit_begin) 03241 return 0; 03242 03243 if (!chan->tech->send_digit_begin(chan, digit)) 03244 return 0; 03245 03246 if (digit >= '0' && digit <='9') 03247 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0); 03248 else if (digit >= 'A' && digit <= 'D') 03249 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0); 03250 else if (digit == '*') 03251 ast_playtones_start(chan, 0, dtmf_tones[14], 0); 03252 else if (digit == '#') 03253 ast_playtones_start(chan, 0, dtmf_tones[15], 0); 03254 else { 03255 /* not handled */ 03256 ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name); 03257 } 03258 03259 return 0; 03260 }
int ast_senddigit_end | ( | struct ast_channel * | chan, | |
char | digit, | |||
unsigned int | duration | |||
) |
Send a DTMF digit to a channel.
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 3262 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(), ast_write(), and features_digit_end().
03263 { 03264 int res = -1; 03265 03266 if (chan->tech->send_digit_end) 03267 res = chan->tech->send_digit_end(chan, digit, duration); 03268 03269 if (res && chan->generator) 03270 ast_playtones_stop(chan); 03271 03272 return 0; 03273 }
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 3204 of file channel.c.
References ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_test_flag, chanlist::chan, CHECK_BLOCKING, ast_channel_tech::send_text, and ast_channel::tech.
Referenced by action_sendtext(), agent_sendtext(), handle_sendtext(), and sendtext_exec().
03205 { 03206 int res = 0; 03207 /* Stop if we're a zombie or need a soft hangup */ 03208 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 03209 return -1; 03210 CHECK_BLOCKING(chan); 03211 if (chan->tech->send_text) 03212 res = chan->tech->send_text(chan, text); 03213 ast_clear_flag(chan, AST_FLAG_BLOCKING); 03214 return res; 03215 }
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.
Definition at line 4535 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_free, ast_strdup, chanlist::chan, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, and report_new_callerid().
Referenced by __ast_request_and_dial(), agent_call(), ast_call_forward(), ast_feature_request_and_dial(), callerid_write(), dahdi_read(), dial_exec_full(), do_forward(), findmeexec(), handle_setcallerid(), mgcp_ss(), privacy_exec(), read_config(), skinny_newcall(), and ss_thread().
04536 { 04537 ast_channel_lock(chan); 04538 04539 if (cid_num) { 04540 if (chan->cid.cid_num) 04541 ast_free(chan->cid.cid_num); 04542 chan->cid.cid_num = ast_strdup(cid_num); 04543 } 04544 if (cid_name) { 04545 if (chan->cid.cid_name) 04546 ast_free(chan->cid.cid_name); 04547 chan->cid.cid_name = ast_strdup(cid_name); 04548 } 04549 if (cid_ani) { 04550 if (chan->cid.cid_ani) 04551 ast_free(chan->cid.cid_ani); 04552 chan->cid.cid_ani = ast_strdup(cid_ani); 04553 } 04554 04555 report_new_callerid(chan); 04556 04557 ast_channel_unlock(chan); 04558 }
int ast_set_read_format | ( | struct ast_channel * | chan, | |
int | 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 3602 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(), _ast_adsi_transmit_message_full(), agent_call(), alarmreceiver_exec(), ast_channel_make_compatible_helper(), ast_do_masquerade(), attempt_reconnect(), background_detect_exec(), build_conf(), conf_run(), dictate_exec(), do_waiting(), eagi_exec(), echo_exec(), function_ilink(), gtalk_rtp_read(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), jingle_rtp_read(), login_exec(), measurenoise(), mgcp_rtp_read(), oh323_rtp_read(), old_milliwatt_exec(), process_sdp(), rpt(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), speech_background(), transmit_audio(), unistim_rtp_read(), and update_features().
03603 { 03604 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat, 03605 &chan->readtrans, 0); 03606 }
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 5423 of file channel.c.
References chan, 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().
05424 { 05425 struct ast_variable *cur; 05426 05427 for (cur = vars; cur; cur = cur->next) 05428 pbx_builtin_setvar_helper(chan, cur->name, cur->value); 05429 }
int ast_set_write_format | ( | struct ast_channel * | chan, | |
int | 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 3608 of file channel.c.
References chanlist::chan, ast_channel::rawwriteformat, set_format(), ast_channel::writeformat, and ast_channel::writetrans.
Referenced by __oh323_update_info(), _ast_adsi_transmit_message_full(), agent_call(), alarmreceiver_exec(), ast_channel_make_compatible_helper(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_do_masquerade(), ast_openstream_full(), ast_stopstream(), attempt_reconnect(), build_conf(), chanspy_exec(), conf_run(), echo_exec(), extenspy_exec(), function_ilink(), gtalk_rtp_read(), 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(), send_waveform_to_channel(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), tonepair_alloc(), tonepair_release(), transmit_audio(), unistim_rtp_read(), and update_features().
03609 { 03610 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat, 03611 &chan->writetrans, 1); 03612 }
int ast_setstate | ( | struct ast_channel * | chan, | |
enum ast_channel_state | state | |||
) |
Change the state of a channel.
Definition at line 4560 of file channel.c.
References ast_channel::_state, AST_CHANNEL_NAME, ast_copy_string(), ast_device_state_changed_literal(), ast_state2str(), chanlist::chan, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, EVENT_FLAG_CALL, manager_event, name, ast_channel::name, S_OR, and ast_channel::uniqueid.
Referenced by __ast_read(), __dahdi_exception(), __oh323_update_info(), agent_call(), alsa_answer(), 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(), mgcp_answer(), mgcp_call(), mgcp_ss(), misdn_call(), misdn_indication(), nbs_call(), nbs_hangup(), oh323_answer(), oss_answer(), pbx_builtin_busy(), pbx_builtin_congestion(), phone_answer(), phone_call(), phone_exception(), phone_hangup(), phone_write(), release_chan(), sip_answer(), skinny_answer(), skinny_call(), skinny_newcall(), ss_thread(), unistim_answer(), unistim_call(), unistim_new(), unistim_ss(), update_state(), usbradio_answer(), and usbradio_call().
04561 { 04562 int oldstate = chan->_state; 04563 char name[AST_CHANNEL_NAME], *dashptr; 04564 04565 if (oldstate == state) 04566 return 0; 04567 04568 ast_copy_string(name, chan->name, sizeof(name)); 04569 if ((dashptr = strrchr(name, '-'))) { 04570 *dashptr = '\0'; 04571 } 04572 04573 chan->_state = state; 04574 ast_device_state_changed_literal(name); 04575 /* setstate used to conditionally report Newchannel; this is no more */ 04576 manager_event(EVENT_FLAG_CALL, 04577 "Newstate", 04578 "Channel: %s\r\n" 04579 "ChannelState: %d\r\n" 04580 "ChannelStateDesc: %s\r\n" 04581 "CallerIDNum: %s\r\n" 04582 "CallerIDName: %s\r\n" 04583 "Uniqueid: %s\r\n", 04584 chan->name, chan->_state, ast_state2str(chan->_state), 04585 S_OR(chan->cid.cid_num, ""), 04586 S_OR(chan->cid.cid_name, ""), 04587 chan->uniqueid); 04588 04589 return 0; 04590 }
int ast_settimeout | ( | struct ast_channel * | c, | |
int | samples, | |||
int(*)(const void *data) | func, | |||
void * | data | |||
) |
Definition at line 2350 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_debug, 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_destructor().
02351 { 02352 int res = -1; 02353 #ifdef HAVE_DAHDI 02354 ast_channel_lock(c); 02355 if (c->timingfd > -1) { 02356 if (!func) { 02357 samples = 0; 02358 data = 0; 02359 } 02360 ast_debug(1, "Scheduling timer at %d sample intervals\n", samples); 02361 res = ioctl(c->timingfd, DAHDI_TIMERCONFIG, &samples); 02362 c->timingfunc = func; 02363 c->timingdata = data; 02364 } 02365 ast_channel_unlock(c); 02366 #endif 02367 return res; 02368 }
int ast_shutting_down | ( | void | ) |
Returns non-zero if Asterisk is being shut down.
Returns non-zero if Asterisk is being shut down
Definition at line 517 of file channel.c.
Referenced by handle_request_options().
00518 { 00519 return shutting_down; 00520 }
int ast_softhangup | ( | struct ast_channel * | chan, | |
int | cause | |||
) |
Softly hangup up a channel.
chan | channel to be soft-hung-up | |
cause | Ast hangupcause for hangup |
Definition at line 1621 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_softhangup_nolock(), and chanlist::chan.
Referenced by __ast_module_user_hangup_all(), __unload_module(), action_hangup(), agent_hangup(), agent_logoff(), ast_begin_shutdown(), ast_dial_join(), conf_free(), dahdi_handle_event(), function_ilink(), handle_cli_rpt_restart(), handle_hangup(), handle_link_data(), handle_softhangup(), login_exec(), manager_park(), read_agent_config(), rpt(), rpt_call(), sla_handle_hold_event(), softhangup_exec(), start_spying(), startmon(), and unload_module().
01622 { 01623 int res; 01624 ast_channel_lock(chan); 01625 res = ast_softhangup_nolock(chan, cause); 01626 ast_channel_unlock(chan); 01627 return res; 01628 }
int ast_softhangup_nolock | ( | struct ast_channel * | chan, | |
int | cause | |||
) |
Softly hangup up a channel (no channel lock).
chan | channel to be soft-hung-up | |
cause | Ast hangupcause for hangup (see cause.h) |
Definition at line 1608 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 ast_async_goto(), ast_softhangup(), attempt_transfer(), check_rtp_timeout(), dahdi_softhangup_all(), oh323_indicate(), proc_session_timer(), sip_indicate(), and skinny_indicate().
01609 { 01610 ast_debug(1, "Soft-Hanging up channel '%s'\n", chan->name); 01611 /* Inform channel driver that we need to be hung up, if it cares */ 01612 chan->_softhangup |= cause; 01613 ast_queue_frame(chan, &ast_null_frame); 01614 /* Interrupt any poll call or such */ 01615 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) 01616 pthread_kill(chan->blocker, SIGURG); 01617 return 0; 01618 }
const char* ast_state2str | ( | enum ast_channel_state | state | ) |
Gives the string form of a given channel state.
Definition at line 651 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(), buf, STATE2STR_BUFSIZE, and state2str_threadbuf.
Referenced by __ast_channel_alloc_ap(), action_coreshowchannels(), action_status(), agent_hangup(), ast_do_masquerade(), ast_setstate(), attempt_transfer(), can_pickup(), func_channel_read(), handle_chanlist(), handle_invite_replaces(), handle_showchan(), local_attended_transfer(), mgcp_new(), serialize_showchan(), and sip_hangup().
00652 { 00653 char *buf; 00654 00655 switch (state) { 00656 case AST_STATE_DOWN: 00657 return "Down"; 00658 case AST_STATE_RESERVED: 00659 return "Rsrvd"; 00660 case AST_STATE_OFFHOOK: 00661 return "OffHook"; 00662 case AST_STATE_DIALING: 00663 return "Dialing"; 00664 case AST_STATE_RING: 00665 return "Ring"; 00666 case AST_STATE_RINGING: 00667 return "Ringing"; 00668 case AST_STATE_UP: 00669 return "Up"; 00670 case AST_STATE_BUSY: 00671 return "Busy"; 00672 case AST_STATE_DIALING_OFFHOOK: 00673 return "Dialing Offhook"; 00674 case AST_STATE_PRERING: 00675 return "Pre-ring"; 00676 default: 00677 if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE))) 00678 return "Unknown"; 00679 snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state); 00680 return buf; 00681 } 00682 }
int ast_str2cause | ( | const char * | name | ) |
Convert a symbolic hangup cause to number.
name | string form of the cause Returns the cause code |
Definition at line 637 of file channel.c.
References ARRAY_LEN, ast_cause::cause, and causes.
Referenced by pbx_builtin_hangup().
00638 { 00639 int x; 00640 00641 for (x = 0; x < ARRAY_LEN(causes); x++) 00642 if (!strncasecmp(causes[x].name, name, strlen(causes[x].name))) 00643 return causes[x].cause; 00644 00645 return -1; 00646 }
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 5298 of file channel.c.
References ast_frfree, ast_read(), ast_tonepair_start(), ast_waitfor(), chan, f, and ast_channel::generatordata.
Referenced by zapateller_exec().
05299 { 05300 int res; 05301 05302 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 05303 return res; 05304 05305 /* Give us some wiggle room */ 05306 while (chan->generatordata && ast_waitfor(chan, 100) >= 0) { 05307 struct ast_frame *f = ast_read(chan); 05308 if (f) 05309 ast_frfree(f); 05310 else 05311 return -1; 05312 } 05313 return 0; 05314 }
int ast_tonepair_start | ( | struct ast_channel * | chan, | |
int | freq1, | |||
int | freq2, | |||
int | duration, | |||
int | vol | |||
) |
Start a tone going
Definition at line 5280 of file channel.c.
References ast_activate_generator(), chan, 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().
05281 { 05282 struct tonepair_def d = { 0, }; 05283 05284 d.freq1 = freq1; 05285 d.freq2 = freq2; 05286 d.duration = duration; 05287 d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */ 05288 if (ast_activate_generator(chan, &tonepair, &d)) 05289 return -1; 05290 return 0; 05291 }
void ast_tonepair_stop | ( | struct ast_channel * | chan | ) |
Stop a tone from playing
Definition at line 5293 of file channel.c.
References ast_deactivate_generator(), and chan.
Referenced by sendnoise().
05294 { 05295 ast_deactivate_generator(chan); 05296 }
int ast_transfer | ( | struct ast_channel * | chan, | |
char * | dest | |||
) |
Transfer a channel (if supported). Returns -1 on error, 0 if not supported and 1 if supported and requested.
Called by:
Definition at line 3935 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_FLAG_ZOMBIE, ast_test_flag, chanlist::chan, ast_channel::tech, and ast_channel_tech::transfer.
Referenced by transfer_exec().
03936 { 03937 int res = -1; 03938 03939 /* Stop if we're a zombie or need a soft hangup */ 03940 ast_channel_lock(chan); 03941 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 03942 if (chan->tech->transfer) { 03943 res = chan->tech->transfer(chan, dest); 03944 if (!res) 03945 res = 1; 03946 } else 03947 res = 0; 03948 } 03949 ast_channel_unlock(chan); 03950 return res; 03951 }
char* ast_transfercapability2str | ( | int | transfercapability | ) | const |
Gives the string form of a given transfer capability.
transfercapability | transfercapabilty to get the name of Give a name to a transfercapbility See above Returns the text form of the binary transfer capability |
Definition at line 685 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 cb_events(), dahdi_call(), dahdi_new(), misdn_call(), and oh323_call().
00686 { 00687 switch (transfercapability) { 00688 case AST_TRANS_CAP_SPEECH: 00689 return "SPEECH"; 00690 case AST_TRANS_CAP_DIGITAL: 00691 return "DIGITAL"; 00692 case AST_TRANS_CAP_RESTRICTED_DIGITAL: 00693 return "RESTRICTED_DIGITAL"; 00694 case AST_TRANS_CAP_3_1K_AUDIO: 00695 return "3K1AUDIO"; 00696 case AST_TRANS_CAP_DIGITAL_W_TONES: 00697 return "DIGITAL_W_TONES"; 00698 case AST_TRANS_CAP_VIDEO: 00699 return "VIDEO"; 00700 default: 00701 return "UNKNOWN"; 00702 } 00703 }
void ast_uninstall_music_functions | ( | void | ) |
Definition at line 5361 of file channel.c.
References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.
Referenced by unload_module().
05362 { 05363 ast_moh_start_ptr = NULL; 05364 ast_moh_stop_ptr = NULL; 05365 ast_moh_cleanup_ptr = NULL; 05366 }
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 Wait for input on a channel for a given # of milliseconds (<0 for indefinite). |
Definition at line 2334 of file channel.c.
References ast_waitfor_nandfds().
Referenced by __adsi_transmit_messages(), __ast_answer(), __ast_play_and_record(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), ast_dtmf_stream(), ast_recvtext(), ast_safe_sleep_conditional(), ast_tonepair(), async_wait(), background_detect_exec(), channel_spy(), conf_exec(), conf_flush(), dictate_exec(), disa_exec(), do_idle_thread(), do_waiting(), echo_exec(), handle_recordfile(), handle_speechrecognize(), ices_exec(), isAnsweringMachine(), launch_asyncagi(), measurenoise(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), recordthread(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), speech_background(), ss_thread(), transmit_audio(), transmit_t38(), wait_for_hangup(), waitforring_exec(), and waitstream_core().
02335 { 02336 int oldms = ms; /* -1 if no timeout */ 02337 02338 ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms); 02339 if ((ms < 0) && (oldms < 0)) 02340 ms = 0; 02341 return ms; 02342 }
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 2329 of file channel.c.
References ast_waitfor_nandfds().
Referenced by ast_feature_request_and_dial(), ast_udptl_bridge(), autoservice_run(), bridge_native_loop(), dahdi_bridge(), misdn_bridge(), monitor_dial(), rpt(), wait_for_answer(), and wait_for_winner().
02330 { 02331 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 02332 }
int ast_waitfor_n_fd | ( | int * | fds, | |
int | n, | |||
int * | ms, | |||
int * | exception | |||
) |
Waits for input on an fd This version works on fd's only. Be careful with it.
Definition at line 1970 of file channel.c.
References ast_waitfor_nandfds().
Referenced by dundi_lookup_internal(), and dundi_precache_internal().
01971 { 01972 int winner = -1; 01973 ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms); 01974 return winner; 01975 }
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 Big momma function here. Wait for activity on any of the n channels, or any of the nfds file descriptors. |
Definition at line 1982 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_tvdiff_ms(), ast_tvnow(), chanlist::chan, CHECK_BLOCKING, errno, LOG_WARNING, and ast_channel::whentohangup.
Referenced by ast_waitfor(), ast_waitfor_n(), ast_waitfor_n_fd(), ast_waitfordigit_full(), conf_run(), eivr_comm(), find_cache(), run_agi(), and waitstream_core().
01985 { 01986 struct timeval start = { 0 , 0 }; 01987 struct pollfd *pfds = NULL; 01988 int res; 01989 long rms; 01990 int x, y, max; 01991 int sz; 01992 time_t now = 0; 01993 long whentohangup = 0, diff; 01994 struct ast_channel *winner = NULL; 01995 struct fdmap { 01996 int chan; 01997 int fdno; 01998 } *fdmap = NULL; 01999 02000 if ((sz = n * AST_MAX_FDS + nfds)) { 02001 pfds = alloca(sizeof(*pfds) * sz); 02002 fdmap = alloca(sizeof(*fdmap) * sz); 02003 } 02004 02005 if (outfd) 02006 *outfd = -99999; 02007 if (exception) 02008 *exception = 0; 02009 02010 /* Perform any pending masquerades */ 02011 for (x = 0; x < n; x++) { 02012 ast_channel_lock(c[x]); 02013 if (c[x]->masq && ast_do_masquerade(c[x])) { 02014 ast_log(LOG_WARNING, "Masquerade failed\n"); 02015 *ms = -1; 02016 ast_channel_unlock(c[x]); 02017 return NULL; 02018 } 02019 if (c[x]->whentohangup) { 02020 if (!whentohangup) 02021 time(&now); 02022 diff = c[x]->whentohangup - now; 02023 if (diff < 1) { 02024 /* Should already be hungup */ 02025 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 02026 ast_channel_unlock(c[x]); 02027 return c[x]; 02028 } 02029 if (!whentohangup || (diff < whentohangup)) 02030 whentohangup = diff; 02031 } 02032 ast_channel_unlock(c[x]); 02033 } 02034 /* Wait full interval */ 02035 rms = *ms; 02036 if (whentohangup) { 02037 rms = whentohangup * 1000; /* timeout in milliseconds */ 02038 if (*ms >= 0 && *ms < rms) /* original *ms still smaller */ 02039 rms = *ms; 02040 } 02041 /* 02042 * Build the pollfd array, putting the channels' fds first, 02043 * followed by individual fds. Order is important because 02044 * individual fd's must have priority over channel fds. 02045 */ 02046 max = 0; 02047 for (x = 0; x < n; x++) { 02048 for (y = 0; y < AST_MAX_FDS; y++) { 02049 fdmap[max].fdno = y; /* fd y is linked to this pfds */ 02050 fdmap[max].chan = x; /* channel x is linked to this pfds */ 02051 max += ast_add_fd(&pfds[max], c[x]->fds[y]); 02052 } 02053 CHECK_BLOCKING(c[x]); 02054 } 02055 /* Add the individual fds */ 02056 for (x = 0; x < nfds; x++) { 02057 fdmap[max].chan = -1; 02058 max += ast_add_fd(&pfds[max], fds[x]); 02059 } 02060 02061 if (*ms > 0) 02062 start = ast_tvnow(); 02063 02064 if (sizeof(int) == 4) { /* XXX fix timeout > 600000 on linux x86-32 */ 02065 do { 02066 int kbrms = rms; 02067 if (kbrms > 600000) 02068 kbrms = 600000; 02069 res = ast_poll(pfds, max, kbrms); 02070 if (!res) 02071 rms -= kbrms; 02072 } while (!res && (rms > 0)); 02073 } else { 02074 res = ast_poll(pfds, max, rms); 02075 } 02076 for (x = 0; x < n; x++) 02077 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 02078 if (res < 0) { /* Simulate a timeout if we were interrupted */ 02079 if (errno != EINTR) 02080 *ms = -1; 02081 return NULL; 02082 } 02083 if (whentohangup) { /* if we have a timeout, check who expired */ 02084 time(&now); 02085 for (x = 0; x < n; x++) { 02086 if (c[x]->whentohangup && now >= c[x]->whentohangup) { 02087 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 02088 if (winner == NULL) 02089 winner = c[x]; 02090 } 02091 } 02092 } 02093 if (res == 0) { /* no fd ready, reset timeout and done */ 02094 *ms = 0; /* XXX use 0 since we may not have an exact timeout. */ 02095 return winner; 02096 } 02097 /* 02098 * Then check if any channel or fd has a pending event. 02099 * Remember to check channels first and fds last, as they 02100 * must have priority on setting 'winner' 02101 */ 02102 for (x = 0; x < max; x++) { 02103 res = pfds[x].revents; 02104 if (res == 0) 02105 continue; 02106 if (fdmap[x].chan >= 0) { /* this is a channel */ 02107 winner = c[fdmap[x].chan]; /* override previous winners */ 02108 if (res & POLLPRI) 02109 ast_set_flag(winner, AST_FLAG_EXCEPTION); 02110 else 02111 ast_clear_flag(winner, AST_FLAG_EXCEPTION); 02112 winner->fdno = fdmap[x].fdno; 02113 } else { /* this is an fd */ 02114 if (outfd) 02115 *outfd = pfds[x].fd; 02116 if (exception) 02117 *exception = (res & POLLPRI) ? -1 : 0; 02118 winner = NULL; 02119 } 02120 } 02121 if (*ms > 0) { 02122 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 02123 if (*ms < 0) 02124 *ms = 0; 02125 } 02126 return winner; 02127 }
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 2345 of file channel.c.
References ast_waitfordigit_full().
Referenced by _ast_adsi_get_cpeid(), _ast_adsi_get_cpeinfo(), _ast_adsi_print(), _ast_adsi_read_encoded_dtmf(), _ast_adsi_transmit_message_full(), _while_exec(), advanced_options(), ast_app_dtget(), ast_control_streamfile(), ast_record_review(), builtin_atxfer(), collect_digits(), common_exec(), cpeid_exec(), dialout(), directory_exec(), forward_message(), get_folder(), ivr_dispatch(), mgcp_ss(), my_getsigstr(), pbx_builtin_waitexten(), play_record_review(), read_exec(), read_newoption(), readexten_exec(), retrydial_exec(), select_item_menu(), select_item_seq(), sendnoise(), ss_thread(), testclient_exec(), testserver_exec(), vm_execmain(), vm_forwardoptions(), vm_instructions_en(), vm_options(), vm_tempgreeting(), wait_a_bit(), and wait_our_turn().
02346 { 02347 return ast_waitfordigit_full(c, ms, -1, -1); 02348 }
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 2370 of file channel.c.
References ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_FLAG_END_DTMF_ONLY, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_set_flag, ast_test_flag, ast_waitfor_nandfds(), errno, f, and LOG_WARNING.
Referenced by ast_readstring_full(), ast_waitfordigit(), handle_getoption(), and handle_waitfordigit().
02371 { 02372 /* Stop if we're a zombie or need a soft hangup */ 02373 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 02374 return -1; 02375 02376 /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */ 02377 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY); 02378 02379 /* Wait for a digit, no more than ms milliseconds total. */ 02380 02381 while (ms) { 02382 struct ast_channel *rchan; 02383 int outfd=-1; 02384 02385 errno = 0; 02386 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 02387 02388 if (!rchan && outfd < 0 && ms) { 02389 if (errno == 0 || errno == EINTR) 02390 continue; 02391 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 02392 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 02393 return -1; 02394 } else if (outfd > -1) { 02395 /* The FD we were watching has something waiting */ 02396 ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n"); 02397 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 02398 return 1; 02399 } else if (rchan) { 02400 int res; 02401 struct ast_frame *f = ast_read(c); 02402 if (!f) 02403 return -1; 02404 02405 switch (f->frametype) { 02406 case AST_FRAME_DTMF_BEGIN: 02407 break; 02408 case AST_FRAME_DTMF_END: 02409 res = f->subclass; 02410 ast_frfree(f); 02411 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 02412 return res; 02413 case AST_FRAME_CONTROL: 02414 switch (f->subclass) { 02415 case AST_CONTROL_HANGUP: 02416 ast_frfree(f); 02417 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 02418 return -1; 02419 case AST_CONTROL_RINGING: 02420 case AST_CONTROL_ANSWER: 02421 case AST_CONTROL_SRCUPDATE: 02422 /* Unimportant */ 02423 break; 02424 default: 02425 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass); 02426 break; 02427 } 02428 break; 02429 case AST_FRAME_VOICE: 02430 /* Write audio if appropriate */ 02431 if (audiofd > -1) { 02432 if (write(audiofd, f->data, f->datalen) < 0) { 02433 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 02434 } 02435 } 02436 default: 02437 /* Ignore */ 02438 break; 02439 } 02440 ast_frfree(f); 02441 } 02442 } 02443 02444 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 02445 02446 return 0; /* Time is up */ 02447 }
struct ast_channel* ast_walk_channel_by_exten_locked | ( | const struct ast_channel * | chan, | |
const char * | exten, | |||
const char * | context | |||
) |
Get next channel by exten (and optionally context) and lock it.
Definition at line 1277 of file channel.c.
References chanlist::chan, and channel_find_locked().
Referenced by next_channel().
01279 { 01280 return channel_find_locked(chan, NULL, 0, context, exten); 01281 }
struct ast_channel* ast_walk_channel_by_name_prefix_locked | ( | const struct ast_channel * | chan, | |
const char * | name, | |||
const int | namelen | |||
) |
Get channel by name or uniqueid prefix (locks channel).
Definition at line 1264 of file channel.c.
References chanlist::chan, and channel_find_locked().
Referenced by my_ast_get_channel_by_name_locked(), next_channel(), and softhangup_exec().
01266 { 01267 return channel_find_locked(chan, name, namelen, NULL, NULL); 01268 }
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 3313 of file channel.c.
References ast_channel::_softhangup, AST_AUDIOHOOK_DIRECTION_WRITE, ast_audiohook_write_list(), 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_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_frfree, AST_LIST_NEXT, ast_log(), AST_MONITOR_RUNNING, ast_seekstream(), ast_senddigit_begin(), ast_senddigit_end(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_translate(), ast_writestream(), ast_channel::audiohooks, chanlist::chan, CHECK_BLOCKING, ast_frame::data, ast_frame::datalen, DEBUGCHAN_FLAG, f, ast_channel::fout, ast_frame::frame_list, FRAMECOUNT_INC, ast_frame::frametype, ast_channel::generatordata, ast_channel_tech::indicate, ast_channel::insmpl, ast_frame::len, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, chanlist::next, ast_channel::outsmpl, ast_channel::rawwriteformat, ast_frame::samples, SEEK_FORCECUR, send_dtmf_event(), ast_channel_tech::send_html, ast_channel_tech::send_text, ast_channel_monitor::state, ast_frame::subclass, ast_channel::tech, ast_channel_tech::write, ast_channel_monitor::write_stream, ast_channel_tech::write_text, ast_channel_tech::write_video, and ast_channel::writetrans.
Referenced by adsi_careful_send(), agent_write(), ast_prod(), ast_readaudio_callback(), ast_readvideo_callback(), ast_udptl_bridge(), ast_write_video(), bridge_native_loop(), conf_queue_dtmf(), conf_run(), dahdi_bridge(), dictate_exec(), echo_exec(), fax_generator_generate(), features_write(), function_ilink(), gen_generate(), handle_jack_audio(), handle_link_data(), jb_get_and_deliver(), linear_generator(), milliwatt_generate(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), NBScat_exec(), rpt(), rpt_call(), send_link_dtmf(), send_tone_burst(), send_waveform_to_channel(), silence_generator_generate(), spy_generate(), t38_tx_packet_handler(), and wait_for_answer().
03314 { 03315 int res = -1; 03316 struct ast_frame *f = NULL; 03317 int count = 0; 03318 03319 /*Deadlock avoidance*/ 03320 while(ast_channel_trylock(chan)) { 03321 /*cannot goto done since the channel is not locked*/ 03322 if(count++ > 10) { 03323 ast_debug(1, "Deadlock avoided for write to channel '%s'\n", chan->name); 03324 return 0; 03325 } 03326 usleep(1); 03327 } 03328 /* Stop if we're a zombie or need a soft hangup */ 03329 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 03330 goto done; 03331 03332 /* Handle any pending masquerades */ 03333 if (chan->masq && ast_do_masquerade(chan)) { 03334 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 03335 goto done; 03336 } 03337 if (chan->masqr) { 03338 res = 0; /* XXX explain, why 0 ? */ 03339 goto done; 03340 } 03341 if (chan->generatordata) { 03342 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) 03343 ast_deactivate_generator(chan); 03344 else { 03345 if (fr->frametype == AST_FRAME_DTMF_END) { 03346 /* There is a generator running while we're in the middle of a digit. 03347 * It's probably inband DTMF, so go ahead and pass it so it can 03348 * stop the generator */ 03349 ast_clear_flag(chan, AST_FLAG_BLOCKING); 03350 ast_channel_unlock(chan); 03351 res = ast_senddigit_end(chan, fr->subclass, fr->len); 03352 ast_channel_lock(chan); 03353 CHECK_BLOCKING(chan); 03354 } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass == AST_CONTROL_UNHOLD) { 03355 /* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */ 03356 res = (chan->tech->indicate == NULL) ? 0 : 03357 chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen); 03358 } 03359 res = 0; /* XXX explain, why 0 ? */ 03360 goto done; 03361 } 03362 } 03363 /* High bit prints debugging */ 03364 if (chan->fout & DEBUGCHAN_FLAG) 03365 ast_frame_dump(chan->name, fr, ">>"); 03366 CHECK_BLOCKING(chan); 03367 switch (fr->frametype) { 03368 case AST_FRAME_CONTROL: 03369 res = (chan->tech->indicate == NULL) ? 0 : 03370 chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen); 03371 break; 03372 case AST_FRAME_DTMF_BEGIN: 03373 if (chan->audiohooks) { 03374 struct ast_frame *old_frame = fr; 03375 fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 03376 if (old_frame != fr) 03377 f = fr; 03378 } 03379 send_dtmf_event(chan, "Sent", fr->subclass, "Yes", "No"); 03380 ast_clear_flag(chan, AST_FLAG_BLOCKING); 03381 ast_channel_unlock(chan); 03382 res = ast_senddigit_begin(chan, fr->subclass); 03383 ast_channel_lock(chan); 03384 CHECK_BLOCKING(chan); 03385 break; 03386 case AST_FRAME_DTMF_END: 03387 if (chan->audiohooks) { 03388 struct ast_frame *new_frame = fr; 03389 03390 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr); 03391 if (new_frame != fr) { 03392 ast_frfree(new_frame); 03393 } 03394 } 03395 send_dtmf_event(chan, "Sent", fr->subclass, "No", "Yes"); 03396 ast_clear_flag(chan, AST_FLAG_BLOCKING); 03397 ast_channel_unlock(chan); 03398 res = ast_senddigit_end(chan, fr->subclass, fr->len); 03399 ast_channel_lock(chan); 03400 CHECK_BLOCKING(chan); 03401 break; 03402 case AST_FRAME_TEXT: 03403 if (fr->subclass == AST_FORMAT_T140) { 03404 res = (chan->tech->write_text == NULL) ? 0 : 03405 chan->tech->write_text(chan, fr); 03406 } else { 03407 res = (chan->tech->send_text == NULL) ? 0 : 03408 chan->tech->send_text(chan, (char *) fr->data); 03409 } 03410 break; 03411 case AST_FRAME_HTML: 03412 res = (chan->tech->send_html == NULL) ? 0 : 03413 chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen); 03414 break; 03415 case AST_FRAME_VIDEO: 03416 /* XXX Handle translation of video codecs one day XXX */ 03417 res = (chan->tech->write_video == NULL) ? 0 : 03418 chan->tech->write_video(chan, fr); 03419 break; 03420 case AST_FRAME_MODEM: 03421 res = (chan->tech->write == NULL) ? 0 : 03422 chan->tech->write(chan, fr); 03423 break; 03424 case AST_FRAME_VOICE: 03425 if (chan->tech->write == NULL) 03426 break; /*! \todo XXX should return 0 maybe ? */ 03427 03428 /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */ 03429 if (fr->subclass == chan->rawwriteformat) 03430 f = fr; 03431 else 03432 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr; 03433 03434 if (!f) { 03435 res = 0; 03436 break; 03437 } 03438 03439 if (chan->audiohooks) { 03440 struct ast_frame *new_frame, *cur; 03441 03442 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 03443 new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, cur); 03444 if (new_frame != cur) { 03445 ast_frfree(new_frame); 03446 } 03447 } 03448 } 03449 03450 /* If Monitor is running on this channel, then we have to write frames out there too */ 03451 /* the translator on chan->writetrans may have returned multiple frames 03452 from the single frame we passed in; if so, feed each one of them to the 03453 monitor */ 03454 if (chan->monitor && chan->monitor->write_stream) { 03455 struct ast_frame *cur; 03456 03457 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 03458 /* XXX must explain this code */ 03459 #ifndef MONITOR_CONSTANT_DELAY 03460 int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples; 03461 if (jump >= 0) { 03462 jump = chan->insmpl - chan->outsmpl; 03463 if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1) 03464 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 03465 chan->outsmpl += jump + cur->samples; 03466 } else { 03467 chan->outsmpl += cur->samples; 03468 } 03469 #else 03470 int jump = chan->insmpl - chan->outsmpl; 03471 if (jump - MONITOR_DELAY >= 0) { 03472 if (ast_seekstream(chan->monitor->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1) 03473 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 03474 chan->outsmpl += jump; 03475 } else { 03476 chan->outsmpl += cur->samples; 03477 } 03478 #endif 03479 if (chan->monitor->state == AST_MONITOR_RUNNING) { 03480 if (ast_writestream(chan->monitor->write_stream, cur) < 0) 03481 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 03482 } 03483 } 03484 } 03485 03486 /* the translator on chan->writetrans may have returned multiple frames 03487 from the single frame we passed in; if so, feed each one of them to the 03488 channel, freeing each one after it has been written */ 03489 if ((f != fr) && AST_LIST_NEXT(f, frame_list)) { 03490 struct ast_frame *cur, *next; 03491 unsigned int skip = 0; 03492 03493 for (cur = f, next = AST_LIST_NEXT(cur, frame_list); 03494 cur; 03495 cur = next, next = cur ? AST_LIST_NEXT(cur, frame_list) : NULL) { 03496 if (!skip) { 03497 if ((res = chan->tech->write(chan, cur)) < 0) { 03498 chan->_softhangup |= AST_SOFTHANGUP_DEV; 03499 skip = 1; 03500 } else if (next) { 03501 /* don't do this for the last frame in the list, 03502 as the code outside the loop will do it once 03503 */ 03504 chan->fout = FRAMECOUNT_INC(chan->fout); 03505 } 03506 } 03507 ast_frfree(cur); 03508 } 03509 03510 /* reset f so the code below doesn't attempt to free it */ 03511 f = NULL; 03512 } else { 03513 res = chan->tech->write(chan, f); 03514 } 03515 break; 03516 case AST_FRAME_NULL: 03517 case AST_FRAME_IAX: 03518 /* Ignore these */ 03519 res = 0; 03520 break; 03521 default: 03522 /* At this point, fr is the incoming frame and f is NULL. Channels do 03523 * not expect to get NULL as a frame pointer and will segfault. Hence, 03524 * we output the original frame passed in. */ 03525 res = chan->tech->write(chan, fr); 03526 break; 03527 } 03528 03529 if (f && f != fr) 03530 ast_frfree(f); 03531 ast_clear_flag(chan, AST_FLAG_BLOCKING); 03532 03533 /* Consider a write failure to force a soft hangup */ 03534 if (res < 0) { 03535 chan->_softhangup |= AST_SOFTHANGUP_DEV; 03536 } else { 03537 chan->fout = FRAMECOUNT_INC(chan->fout); 03538 } 03539 done: 03540 ast_channel_unlock(chan); 03541 return res; 03542 }
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 3302 of file channel.c.
References ast_write(), chanlist::chan, ast_channel::tech, and ast_channel_tech::write_video.
03303 { 03304 int res; 03305 if (!chan->tech->write_video) 03306 return 0; 03307 res = ast_write(chan, fr); 03308 if (!res) 03309 res = 1; 03310 return res; 03311 }
static void bridge_playfile | ( | struct ast_channel * | chan, | |
struct ast_channel * | peer, | |||
const char * | sound, | |||
int | remain | |||
) | [static] |
Definition at line 4602 of file channel.c.
References ast_autoservice_start(), ast_autoservice_stop(), AST_DIGIT_ANY, ast_say_number(), ast_stream_and_wait(), chanlist::chan, and sec.
Referenced by ast_channel_bridge().
04603 { 04604 int min = 0, sec = 0, check; 04605 04606 check = ast_autoservice_start(peer); 04607 if (check) 04608 return; 04609 04610 if (remain > 0) { 04611 if (remain / 60 > 1) { 04612 min = remain / 60; 04613 sec = remain % 60; 04614 } else { 04615 sec = remain; 04616 } 04617 } 04618 04619 if (!strcmp(sound,"timeleft")) { /* Queue support */ 04620 ast_stream_and_wait(chan, "vm-youhave", ""); 04621 if (min) { 04622 ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, NULL); 04623 ast_stream_and_wait(chan, "queue-minutes", ""); 04624 } 04625 if (sec) { 04626 ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, NULL); 04627 ast_stream_and_wait(chan, "queue-seconds", ""); 04628 } 04629 } else { 04630 ast_stream_and_wait(chan, sound, ""); 04631 } 04632 04633 ast_autoservice_stop(peer); 04634 }
static struct ast_channel* channel_find_locked | ( | const struct ast_channel * | prev, | |
const char * | name, | |||
const int | namelen, | |||
const char * | context, | |||
const char * | exten | |||
) | [static] |
Helper function to find channels.
It supports these modes:
prev != NULL : get channel next in list after prev name != NULL : get channel with matching name name != NULL && namelen != 0 : get channel whose name starts with prefix exten != NULL : get channel whose exten or macroexten matches context != NULL && exten != NULL : get channel whose context or macrocontext
It returns with the channel's lock held. If getting the individual lock fails, unlock and retry quickly up to 10 times, then give up.
XXX also note that accessing fields (e.g. c->name in ast_log()) can only be done with the lock held or someone could delete the object while we work on it. This causes some ugliness in the code. Note that removing the first ast_log() may be harmful, as it would shorten the retry period and possibly cause failures. We should definitely go for a better scheme that is deadlock-free.
Definition at line 1162 of file channel.c.
References ast_channel_trylock, ast_debug, AST_RWLIST_NEXT, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_channel::context, ast_channel::exten, ast_channel::macrocontext, ast_channel::macroexten, msg, ast_channel::name, and ast_channel::uniqueid.
Referenced by ast_channel_walk_locked(), ast_get_channel_by_exten_locked(), ast_get_channel_by_name_locked(), ast_get_channel_by_name_prefix_locked(), ast_walk_channel_by_exten_locked(), and ast_walk_channel_by_name_prefix_locked().
01165 { 01166 const char *msg = prev ? "deadlock" : "initial deadlock"; 01167 int retries; 01168 struct ast_channel *c; 01169 const struct ast_channel *_prev = prev; 01170 01171 for (retries = 0; retries < 200; retries++) { 01172 int done; 01173 /* Reset prev on each retry. See note below for the reason. */ 01174 prev = _prev; 01175 AST_RWLIST_RDLOCK(&channels); 01176 AST_RWLIST_TRAVERSE(&channels, c, chan_list) { 01177 if (prev) { /* look for last item, first, before any evaluation */ 01178 if (c != prev) /* not this one */ 01179 continue; 01180 /* found, prepare to return c->next */ 01181 if ((c = AST_RWLIST_NEXT(c, chan_list)) == NULL) break; 01182 /*!\note 01183 * We're done searching through the list for the previous item. 01184 * Any item after this point, we want to evaluate for a match. 01185 * If we didn't set prev to NULL here, then we would only 01186 * return matches for the first matching item (since the above 01187 * "if (c != prev)" would not permit any other potential 01188 * matches to reach the additional matching logic, below). 01189 * Instead, it would just iterate until it once again found the 01190 * original match, then iterate down to the end of the list and 01191 * quit. 01192 */ 01193 prev = NULL; 01194 } 01195 if (name) { /* want match by name */ 01196 if ((!namelen && strcasecmp(c->name, name) && strcmp(c->uniqueid, name)) || 01197 (namelen && strncasecmp(c->name, name, namelen))) 01198 continue; /* name match failed */ 01199 } else if (exten) { 01200 if (context && strcasecmp(c->context, context) && 01201 strcasecmp(c->macrocontext, context)) 01202 continue; /* context match failed */ 01203 if (strcasecmp(c->exten, exten) && 01204 strcasecmp(c->macroexten, exten)) 01205 continue; /* exten match failed */ 01206 } 01207 /* if we get here, c points to the desired record */ 01208 break; 01209 } 01210 /* exit if chan not found or mutex acquired successfully */ 01211 /* this is slightly unsafe, as we _should_ hold the lock to access c->name */ 01212 done = c == NULL || ast_channel_trylock(c) == 0; 01213 if (!done) { 01214 ast_debug(1, "Avoiding %s for channel '%p'\n", msg, c); 01215 if (retries == 199) { 01216 /* We are about to fail due to a deadlock, so report this 01217 * while we still have the list lock. 01218 */ 01219 ast_debug(1, "Failure, could not lock '%p' after %d retries!\n", c, retries); 01220 /* As we have deadlocked, we will skip this channel and 01221 * see if there is another match. 01222 * NOTE: No point doing this for a full-name match, 01223 * as there can be no more matches. 01224 */ 01225 if (!(name && !namelen)) { 01226 prev = c; 01227 retries = -1; 01228 } 01229 } 01230 } 01231 AST_RWLIST_UNLOCK(&channels); 01232 if (done) 01233 return c; 01234 /* If we reach this point we basically tried to lock a channel and failed. Instead of 01235 * starting from the beginning of the list we can restore our saved pointer to the previous 01236 * channel and start from there. 01237 */ 01238 prev = _prev; 01239 usleep(1); /* give other threads a chance before retrying */ 01240 } 01241 01242 return NULL; 01243 }
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 5511 of file channel.c.
References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.
05512 { 05513 switch (reason) { 05514 case CHANNEL_MODULE_LOAD: 05515 return "LOAD (Channel module load)"; 05516 05517 case CHANNEL_MODULE_RELOAD: 05518 return "RELOAD (Channel module reload)"; 05519 05520 case CHANNEL_CLI_RELOAD: 05521 return "CLIRELOAD (Channel module reload by CLI command)"; 05522 05523 default: 05524 return "MANAGERRELOAD (Channel module reload by manager)"; 05525 } 05526 };
static void clone_variables | ( | struct ast_channel * | original, | |
struct ast_channel * | clone | |||
) | [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 4216 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().
04217 { 04218 struct ast_var_t *current, *newvar; 04219 /* Append variables from clone channel into original channel */ 04220 /* XXX Is this always correct? We have to in order to keep MACROS working XXX */ 04221 if (AST_LIST_FIRST(&clone->varshead)) 04222 AST_LIST_APPEND_LIST(&original->varshead, &clone->varshead, entries); 04223 04224 /* then, dup the varshead list into the clone */ 04225 04226 AST_LIST_TRAVERSE(&original->varshead, current, entries) { 04227 newvar = ast_var_assign(current->name, current->value); 04228 if (newvar) 04229 AST_LIST_INSERT_TAIL(&clone->varshead, newvar, entries); 04230 } 04231 }
static char* complete_channeltypes | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 248 of file channel.c.
References AST_LIST_TRAVERSE, 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().
00249 { 00250 struct chanlist *cl; 00251 int which = 0; 00252 int wordlen; 00253 char *ret = NULL; 00254 00255 if (a->pos != 3) 00256 return NULL; 00257 00258 wordlen = strlen(a->word); 00259 00260 AST_LIST_TRAVERSE(&backends, cl, list) { 00261 if (!strncasecmp(a->word, cl->tech->type, wordlen) && ++which > a->n) { 00262 ret = ast_strdup(cl->tech->type); 00263 break; 00264 } 00265 } 00266 00267 return ret; 00268 }
static void free_cid | ( | struct ast_callerid * | cid | ) | [static] |
Definition at line 1310 of file channel.c.
References ast_free, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, and ast_callerid::cid_rdnis.
Referenced by ast_channel_free().
01311 { 01312 if (cid->cid_dnid) 01313 ast_free(cid->cid_dnid); 01314 if (cid->cid_num) 01315 ast_free(cid->cid_num); 01316 if (cid->cid_name) 01317 ast_free(cid->cid_name); 01318 if (cid->cid_ani) 01319 ast_free(cid->cid_ani); 01320 if (cid->cid_rdnis) 01321 ast_free(cid->cid_rdnis); 01322 cid->cid_dnid = cid->cid_num = cid->cid_name = cid->cid_ani = cid->cid_rdnis = NULL; 01323 }
static void free_translation | ( | struct ast_channel * | clone | ) | [static] |
Definition at line 1630 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().
01631 { 01632 if (clone->writetrans) 01633 ast_translator_free_path(clone->writetrans); 01634 if (clone->readtrans) 01635 ast_translator_free_path(clone->readtrans); 01636 clone->writetrans = NULL; 01637 clone->readtrans = NULL; 01638 clone->rawwriteformat = clone->nativeformats; 01639 clone->rawreadformat = clone->nativeformats; 01640 }
static int generator_force | ( | const void * | data | ) | [static] |
Definition at line 1912 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().
01913 { 01914 /* Called if generator doesn't have data */ 01915 void *tmp; 01916 int res; 01917 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL; 01918 struct ast_channel *chan = (struct ast_channel *)data; 01919 01920 ast_channel_lock(chan); 01921 tmp = chan->generatordata; 01922 chan->generatordata = NULL; 01923 if (chan->generator) 01924 generate = chan->generator->generate; 01925 ast_channel_unlock(chan); 01926 01927 if (!tmp || !generate) 01928 return 0; 01929 01930 res = generate(chan, tmp, 0, ast_format_rate(chan->writeformat & AST_FORMAT_AUDIO_MASK) / 50); 01931 01932 chan->generatordata = tmp; 01933 01934 if (res) { 01935 ast_debug(1, "Auto-deactivating generator\n"); 01936 ast_deactivate_generator(chan); 01937 } 01938 01939 return 0; 01940 }
static void handle_cause | ( | int | cause, | |
int * | outstate | |||
) | [static] |
Definition at line 3637 of file channel.c.
References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CONTROL_BUSY, and AST_CONTROL_CONGESTION.
Referenced by __ast_request_and_dial(), ast_call_forward(), dial_exec_full(), do_forward(), and wait_for_answer().
03638 { 03639 if (outstate) { 03640 /* compute error and return */ 03641 if (cause == AST_CAUSE_BUSY) 03642 *outstate = AST_CONTROL_BUSY; 03643 else if (cause == AST_CAUSE_CONGESTION) 03644 *outstate = AST_CONTROL_CONGESTION; 03645 else 03646 *outstate = 0; 03647 } 03648 }
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 271 of file channel.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, 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.
00272 { 00273 struct chanlist *cl = NULL; 00274 00275 switch (cmd) { 00276 case CLI_INIT: 00277 e->command = "core show channeltype"; 00278 e->usage = 00279 "Usage: core show channeltype <name>\n" 00280 " Show details about the specified channel type, <name>.\n"; 00281 return NULL; 00282 case CLI_GENERATE: 00283 return complete_channeltypes(a); 00284 } 00285 00286 if (a->argc != 4) 00287 return CLI_SHOWUSAGE; 00288 00289 AST_RWLIST_RDLOCK(&channels); 00290 00291 AST_LIST_TRAVERSE(&backends, cl, list) { 00292 if (!strncasecmp(cl->tech->type, a->argv[3], strlen(cl->tech->type))) 00293 break; 00294 } 00295 00296 00297 if (!cl) { 00298 ast_cli(a->fd, "\n%s is not a registered channel driver.\n", a->argv[3]); 00299 AST_RWLIST_UNLOCK(&channels); 00300 return CLI_FAILURE; 00301 } 00302 00303 ast_cli(a->fd, 00304 "-- Info about channel driver: %s --\n" 00305 " Device State: %s\n" 00306 " Indication: %s\n" 00307 " Transfer : %s\n" 00308 " Capabilities: %d\n" 00309 " Digit Begin: %s\n" 00310 " Digit End: %s\n" 00311 " Send HTML : %s\n" 00312 " Image Support: %s\n" 00313 " Text Support: %s\n", 00314 cl->tech->type, 00315 (cl->tech->devicestate) ? "yes" : "no", 00316 (cl->tech->indicate) ? "yes" : "no", 00317 (cl->tech->transfer) ? "yes" : "no", 00318 (cl->tech->capabilities) ? cl->tech->capabilities : -1, 00319 (cl->tech->send_digit_begin) ? "yes" : "no", 00320 (cl->tech->send_digit_end) ? "yes" : "no", 00321 (cl->tech->send_html) ? "yes" : "no", 00322 (cl->tech->send_image) ? "yes" : "no", 00323 (cl->tech->send_text) ? "yes" : "no" 00324 00325 ); 00326 00327 AST_RWLIST_UNLOCK(&channels); 00328 return CLI_SUCCESS; 00329 }
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 205 of file channel.c.
References ast_cli_args::argc, ast_cli(), AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, 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.
00206 { 00207 #define FORMAT "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\n" 00208 struct chanlist *cl; 00209 int count_chan = 0; 00210 00211 switch (cmd) { 00212 case CLI_INIT: 00213 e->command = "core show channeltypes"; 00214 e->usage = 00215 "Usage: core show channeltypes\n" 00216 " Lists available channel types registered in your\n" 00217 " Asterisk server.\n"; 00218 return NULL; 00219 case CLI_GENERATE: 00220 return NULL; 00221 } 00222 00223 if (a->argc != 3) 00224 return CLI_SHOWUSAGE; 00225 00226 ast_cli(a->fd, FORMAT, "Type", "Description", "Devicestate", "Indications", "Transfer"); 00227 ast_cli(a->fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------"); 00228 00229 AST_RWLIST_RDLOCK(&channels); 00230 00231 AST_LIST_TRAVERSE(&backends, cl, list) { 00232 ast_cli(a->fd, FORMAT, cl->tech->type, cl->tech->description, 00233 (cl->tech->devicestate) ? "yes" : "no", 00234 (cl->tech->indicate) ? "yes" : "no", 00235 (cl->tech->transfer) ? "yes" : "no"); 00236 count_chan++; 00237 } 00238 00239 AST_RWLIST_UNLOCK(&channels); 00240 00241 ast_cli(a->fd, "----------\n%d channel drivers registered.\n", count_chan); 00242 00243 return CLI_SUCCESS; 00244 00245 #undef FORMAT 00246 }
static int attribute_const is_visible_indication | ( | enum ast_control_frame_type | condition | ) | [static] |
Definition at line 3029 of file channel.c.
References AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, and AST_CONTROL_WINK.
Referenced by ast_indicate_data().
03030 { 03031 /* Don't include a default case here so that we get compiler warnings 03032 * when a new type is added. */ 03033 03034 switch (condition) { 03035 case AST_CONTROL_PROGRESS: 03036 case AST_CONTROL_PROCEEDING: 03037 case AST_CONTROL_VIDUPDATE: 03038 case AST_CONTROL_SRCUPDATE: 03039 case AST_CONTROL_RADIO_KEY: 03040 case AST_CONTROL_RADIO_UNKEY: 03041 case AST_CONTROL_OPTION: 03042 case AST_CONTROL_WINK: 03043 case AST_CONTROL_FLASH: 03044 case AST_CONTROL_OFFHOOK: 03045 case AST_CONTROL_TAKEOFFHOOK: 03046 case AST_CONTROL_ANSWER: 03047 case AST_CONTROL_HANGUP: 03048 case AST_CONTROL_T38: 03049 return 0; 03050 03051 case AST_CONTROL_CONGESTION: 03052 case AST_CONTROL_BUSY: 03053 case AST_CONTROL_RINGING: 03054 case AST_CONTROL_RING: 03055 case AST_CONTROL_HOLD: 03056 case AST_CONTROL_UNHOLD: 03057 return 1; 03058 } 03059 03060 return 0; 03061 }
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 4832 of file channel.c.
References ast_channel::cid, ast_callerid::cid_num, EVENT_FLAG_CALL, manager_event, ast_channel::name, S_OR, and ast_channel::uniqueid.
Referenced by ast_channel_bridge().
04833 { 04834 manager_event(EVENT_FLAG_CALL, "Bridge", 04835 "Bridgestate: %s\r\n" 04836 "Bridgetype: %s\r\n" 04837 "Channel1: %s\r\n" 04838 "Channel2: %s\r\n" 04839 "Uniqueid1: %s\r\n" 04840 "Uniqueid2: %s\r\n" 04841 "CallerID1: %s\r\n" 04842 "CallerID2: %s\r\n", 04843 onoff ? "Link" : "Unlink", 04844 type == 1 ? "core" : "native", 04845 c0->name, c1->name, c0->uniqueid, c1->uniqueid, 04846 S_OR(c0->cid.cid_num, ""), 04847 S_OR(c1->cid.cid_num, "")); 04848 }
static void queue_dtmf_readq | ( | struct ast_channel * | chan, | |
struct ast_frame * | f | |||
) | [inline, static] |
Definition at line 2516 of file channel.c.
References AST_FRAME_DTMF_END, ast_queue_frame(), chanlist::chan, ast_channel::dtmff, f, ast_frame::frametype, ast_frame::len, and ast_frame::subclass.
Referenced by __ast_read().
02517 { 02518 struct ast_frame *fr = &chan->dtmff; 02519 02520 fr->frametype = AST_FRAME_DTMF_END; 02521 fr->subclass = f->subclass; 02522 fr->len = f->len; 02523 02524 /* The only time this function will be called is for a frame that just came 02525 * out of the channel driver. So, we want to stick it on the tail of the 02526 * readq. */ 02527 02528 ast_queue_frame(chan, fr); 02529 }
static void report_new_callerid | ( | const struct ast_channel * | chan | ) | [static] |
Definition at line 4236 of file channel.c.
References ast_describe_caller_presentation(), chanlist::chan, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, EVENT_FLAG_CALL, manager_event, ast_channel::name, S_OR, and ast_channel::uniqueid.
Referenced by ast_do_masquerade(), and ast_set_callerid().
04237 { 04238 manager_event(EVENT_FLAG_CALL, "NewCallerid", 04239 "Channel: %s\r\n" 04240 "CallerIDNum: %s\r\n" 04241 "CallerIDName: %s\r\n" 04242 "Uniqueid: %s\r\n" 04243 "CID-CallingPres: %d (%s)\r\n", 04244 chan->name, 04245 S_OR(chan->cid.cid_num, ""), 04246 S_OR(chan->cid.cid_name, ""), 04247 chan->uniqueid, 04248 chan->cid.cid_pres, 04249 ast_describe_caller_presentation(chan->cid.cid_pres) 04250 ); 04251 }
static void send_dtmf_event | ( | const struct ast_channel * | chan, | |
const char * | direction, | |||
const char | digit, | |||
const char * | begin, | |||
const char * | end | |||
) | [static] |
Definition at line 2449 of file channel.c.
References chanlist::chan, EVENT_FLAG_DTMF, manager_event, ast_channel::name, and ast_channel::uniqueid.
Referenced by __ast_read(), and ast_write().
02450 { 02451 manager_event(EVENT_FLAG_DTMF, 02452 "DTMF", 02453 "Channel: %s\r\n" 02454 "Uniqueid: %s\r\n" 02455 "Digit: %c\r\n" 02456 "Direction: %s\r\n" 02457 "Begin: %s\r\n" 02458 "End: %s\r\n", 02459 chan->name, chan->uniqueid, digit, direction, begin, end); 02460 }
static int set_format | ( | struct ast_channel * | chan, | |
int | fmt, | |||
int * | rawformat, | |||
int * | format, | |||
struct ast_trans_pvt ** | trans, | |||
const int | direction | |||
) | [static] |
Definition at line 3544 of file channel.c.
References ast_channel_lock, ast_channel_unlock, ast_debug, AST_FORMAT_AUDIO_MASK, ast_getformatname(), ast_getformatname_multiple(), ast_log(), 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().
03546 { 03547 int native; 03548 int res; 03549 char from[200], to[200]; 03550 03551 /* Make sure we only consider audio */ 03552 fmt &= AST_FORMAT_AUDIO_MASK; 03553 03554 native = chan->nativeformats; 03555 03556 if (!fmt || !native) /* No audio requested */ 03557 return 0; /* Let's try a call without any sounds (video, text) */ 03558 03559 /* Find a translation path from the native format to one of the desired formats */ 03560 if (!direction) 03561 /* reading */ 03562 res = ast_translator_best_choice(&fmt, &native); 03563 else 03564 /* writing */ 03565 res = ast_translator_best_choice(&native, &fmt); 03566 03567 if (res < 0) { 03568 ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n", 03569 ast_getformatname_multiple(from, sizeof(from), native), 03570 ast_getformatname_multiple(to, sizeof(to), fmt)); 03571 return -1; 03572 } 03573 03574 /* Now we have a good choice for both. */ 03575 ast_channel_lock(chan); 03576 03577 if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) { 03578 /* the channel is already in these formats, so nothing to do */ 03579 ast_channel_unlock(chan); 03580 return 0; 03581 } 03582 03583 *rawformat = native; 03584 /* User perspective is fmt */ 03585 *format = fmt; 03586 /* Free any read translation we have right now */ 03587 if (*trans) 03588 ast_translator_free_path(*trans); 03589 /* Build a translation path from the raw format to the desired format */ 03590 if (!direction) 03591 /* reading */ 03592 *trans = ast_translator_build_path(*format, *rawformat); 03593 else 03594 /* writing */ 03595 *trans = ast_translator_build_path(*rawformat, *format); 03596 ast_channel_unlock(chan); 03597 ast_debug(1, "Set channel %s to %s format %s\n", chan->name, 03598 direction ? "write" : "read", ast_getformatname(fmt)); 03599 return 0; 03600 }
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 2534 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().
02535 { 02536 if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)) { 02537 /* We're in the middle of emulating a digit, or DTMF has been 02538 * explicitly deferred. Skip this digit, then. */ 02539 return 1; 02540 } 02541 02542 if (!ast_tvzero(chan->dtmf_tv) && 02543 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) { 02544 /* We're not in the middle of a digit, but it hasn't been long enough 02545 * since the last digit, so we'll have to skip DTMF for now. */ 02546 return 1; 02547 } 02548 02549 return 0; 02550 }
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 5442 of file channel.c.
References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_write(), buf, chan, and ast_frame::frametype.
05443 { 05444 short buf[samples]; 05445 struct ast_frame frame = { 05446 .frametype = AST_FRAME_VOICE, 05447 .subclass = AST_FORMAT_SLINEAR, 05448 .data = buf, 05449 .samples = samples, 05450 .datalen = sizeof(buf), 05451 }; 05452 05453 memset(buf, 0, sizeof(buf)); 05454 05455 if (ast_write(chan, &frame)) 05456 return -1; 05457 05458 return 0; 05459 }
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 5198 of file channel.c.
References ast_calloc, AST_FLAG_WRITE_INT, AST_FORMAT_SLINEAR, ast_log(), ast_set_flag, ast_set_write_format(), chan, cos, tonepair_def::duration, tonepair_def::freq1, tonepair_def::freq2, LOG_WARNING, ast_channel::name, tonepair_release(), tonepair_def::vol, and ast_channel::writeformat.
05199 { 05200 struct tonepair_state *ts; 05201 struct tonepair_def *td = params; 05202 05203 if (!(ts = ast_calloc(1, sizeof(*ts)))) 05204 return NULL; 05205 ts->origwfmt = chan->writeformat; 05206 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) { 05207 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name); 05208 tonepair_release(NULL, ts); 05209 ts = NULL; 05210 } else { 05211 ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0; 05212 ts->v1_1 = 0; 05213 ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol; 05214 ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol; 05215 ts->v2_1 = 0; 05216 ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0; 05217 ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol; 05218 ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol; 05219 ts->duration = td->duration; 05220 ts->modulate = 0; 05221 } 05222 /* Let interrupts interrupt :) */ 05223 ast_set_flag(chan, AST_FLAG_WRITE_INT); 05224 return ts; 05225 }
static int tonepair_generator | ( | struct ast_channel * | chan, | |
void * | data, | |||
int | len, | |||
int | samples | |||
) | [static] |
Definition at line 5227 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.
05228 { 05229 struct tonepair_state *ts = data; 05230 int x; 05231 05232 /* we need to prepare a frame with 16 * timelen samples as we're 05233 * generating SLIN audio 05234 */ 05235 len = samples * 2; 05236 05237 if (len > sizeof(ts->data) / 2 - 1) { 05238 ast_log(LOG_WARNING, "Can't generate that much data!\n"); 05239 return -1; 05240 } 05241 memset(&ts->f, 0, sizeof(ts->f)); 05242 for (x=0;x<len/2;x++) { 05243 ts->v1_1 = ts->v2_1; 05244 ts->v2_1 = ts->v3_1; 05245 ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1; 05246 05247 ts->v1_2 = ts->v2_2; 05248 ts->v2_2 = ts->v3_2; 05249 ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2; 05250 if (ts->modulate) { 05251 int p; 05252 p = ts->v3_2 - 32768; 05253 if (p < 0) p = -p; 05254 p = ((p * 9) / 10) + 1; 05255 ts->data[x] = (ts->v3_1 * p) >> 15; 05256 } else 05257 ts->data[x] = ts->v3_1 + ts->v3_2; 05258 } 05259 ts->f.frametype = AST_FRAME_VOICE; 05260 ts->f.subclass = AST_FORMAT_SLINEAR; 05261 ts->f.datalen = len; 05262 ts->f.samples = samples; 05263 ts->f.offset = AST_FRIENDLY_OFFSET; 05264 ts->f.data = ts->data; 05265 ast_write(chan, &ts->f); 05266 ts->pos += x; 05267 if (ts->duration > 0) { 05268 if (ts->pos >= ts->duration * 8) 05269 return -1; 05270 } 05271 return 0; 05272 }
static void tonepair_release | ( | struct ast_channel * | chan, | |
void * | params | |||
) | [static] |
Definition at line 5189 of file channel.c.
References ast_free, ast_set_write_format(), chan, and tonepair_state::origwfmt.
Referenced by tonepair_alloc().
05190 { 05191 struct tonepair_state *ts = params; 05192 05193 if (chan) 05194 ast_set_write_format(chan, ts->origwfmt); 05195 ast_free(ts); 05196 }
static void update_bridge_vars | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1 | |||
) | [static] |
Definition at line 4850 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().
04851 { 04852 const char *c0_name; 04853 const char *c1_name; 04854 const char *c0_pvtid = NULL; 04855 const char *c1_pvtid = NULL; 04856 04857 ast_channel_lock(c1); 04858 c1_name = ast_strdupa(c1->name); 04859 if (c1->tech->get_pvt_uniqueid) { 04860 c1_pvtid = ast_strdupa(c1->tech->get_pvt_uniqueid(c1)); 04861 } 04862 ast_channel_unlock(c1); 04863 04864 ast_channel_lock(c0); 04865 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER"))) { 04866 pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1_name); 04867 } 04868 if (c1_pvtid) { 04869 pbx_builtin_setvar_helper(c0, "BRIDGEPVTCALLID", c1_pvtid); 04870 } 04871 c0_name = ast_strdupa(c0->name); 04872 if (c0->tech->get_pvt_uniqueid) { 04873 c0_pvtid = ast_strdupa(c0->tech->get_pvt_uniqueid(c0)); 04874 } 04875 ast_channel_unlock(c0); 04876 04877 ast_channel_lock(c1); 04878 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER"))) { 04879 pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0_name); 04880 } 04881 if (c0_pvtid) { 04882 pbx_builtin_setvar_helper(c1, "BRIDGEPVTCALLID", c0_pvtid); 04883 } 04884 ast_channel_unlock(c1); 04885 }
void(*) ast_moh_cleanup_ptr(struct ast_channel *) = NULL [static] |
Definition at line 5350 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 5348 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 5349 of file channel.c.
Referenced by ast_install_music_functions(), ast_moh_stop(), and ast_uninstall_music_functions().
map AST_CAUSE's to readable string representations
Referenced by ast_cause2str(), ast_str2cause(), and dump_cause().
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 331 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 88 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 758 of file channel.c.
Referenced by __ast_channel_alloc_ap().
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 5461 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 5274 of file channel.c.
Referenced by ast_tonepair_start().