#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <math.h>
#include "asterisk.h"
#include "asterisk/pbx.h"
#include "asterisk/frame.h"
#include "asterisk/sched.h"
#include "asterisk/options.h"
#include "asterisk/channel.h"
#include "asterisk/chanspy.h"
#include "asterisk/musiconhold.h"
#include "asterisk/logger.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"

Go to the source code of this file.
Data Structures | |
| struct | ast_cause |
| struct | ast_channel_spy_list |
| struct | ast_silence_generator |
| struct | chanlist |
| struct | channel_spy_trans |
| struct | tonepair_def |
| struct | tonepair_state |
Defines | |
| #define | FORMAT "%-10.10s %-30.30s %-12.12s %-12.12s %-12.12s\n" |
| #define | SPY_QUEUE_SAMPLE_LIMIT 4000 |
Enumerations | |
| enum | spy_direction { SPY_READ, SPY_WRITE } |
Functions | |
| struct 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) |
| int | ast_activate_generator (struct ast_channel *chan, struct ast_generator *gen, void *params) |
| int | ast_active_channels (void) |
| int | ast_answer (struct ast_channel *chan) |
| Answer a ringing call. | |
| void | ast_begin_shutdown (int hangup) |
| int | ast_best_codec (int fmts) |
| struct 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. | |
| void | ast_cancel_shutdown (void) |
| const char * | ast_cause2str (int cause) |
| void | ast_change_name (struct ast_channel *chan, char *newname) |
| Change channel name. | |
| struct ast_channel * | ast_channel_alloc (int needqueue) |
| Create a channel structure. | |
| 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) |
| 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_defer_dtmf (struct ast_channel *chan) |
| 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) |
| int | ast_channel_masquerade (struct ast_channel *original, struct ast_channel *clone) |
| 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) |
| int | ast_channel_setoption (struct ast_channel *chan, int option, void *data, int datalen, int block) |
| void | ast_channel_setwhentohangup (struct ast_channel *chan, time_t offset) |
| Set when to hang a channel up. | |
| int | ast_channel_spy_add (struct ast_channel *chan, struct ast_channel_spy *spy) |
| Adds a spy to a channel, to begin receiving copies of the channel's audio frames. | |
| void | ast_channel_spy_free (struct ast_channel_spy *spy) |
| Free a spy. | |
| struct ast_frame * | ast_channel_spy_read_frame (struct ast_channel_spy *spy, unsigned int samples) |
| Read one (or more) frames of audio from a channel being spied upon. | |
| void | ast_channel_spy_remove (struct ast_channel *chan, struct ast_channel_spy *spy) |
| Remove a spy from a channel. | |
| void | ast_channel_spy_stop_by_type (struct ast_channel *chan, const char *type) |
| Find all spies of a particular type on a channel and stop them. | |
| void | ast_channel_spy_trigger_wait (struct ast_channel_spy *spy) |
| Efficiently wait until audio is available for a spy, or an exception occurs. | |
| struct ast_silence_generator * | ast_channel_start_silence_generator (struct ast_channel *chan) |
| Starts a silence generator on the given channel. | |
| void | ast_channel_stop_silence_generator (struct ast_channel *chan, struct ast_silence_generator *state) |
| Stops a previously-started silence generator on the given channel. | |
| int | ast_channel_supports_html (struct ast_channel *chan) |
| void | ast_channel_undefer_dtmf (struct ast_channel *chan) |
| void | ast_channel_unregister (const struct ast_channel_tech *tech) |
| Unregister a channel technology. | |
| struct ast_channel * | ast_channel_walk_locked (const struct ast_channel *prev) |
| void | ast_channels_init (void) |
| 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 wacked 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) |
| struct ast_channel * | ast_get_channel_by_exten_locked (const char *exten, const char *context) |
| struct ast_channel * | ast_get_channel_by_name_locked (const char *name) |
| struct ast_channel * | ast_get_channel_by_name_prefix_locked (const char *name, const int namelen) |
| struct ast_channel_tech * | ast_get_channel_tech (const char *name) |
| Get a channel technology structure by name. | |
| ast_group_t | ast_get_group (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. | |
| void | ast_install_music_functions (int(*start_ptr)(struct ast_channel *, char *), void(*stop_ptr)(struct ast_channel *), void(*cleanup_ptr)(struct ast_channel *)) |
| void | ast_moh_cleanup (struct ast_channel *chan) |
| int | ast_moh_start (struct ast_channel *chan, char *mclass) |
| void | ast_moh_stop (struct ast_channel *chan) |
| AST_MUTEX_DEFINE_STATIC (chlock) | |
| AST_MUTEX_DEFINE_STATIC (uniquelock) | |
| char * | ast_print_group (char *buf, int buflen, ast_group_t group) |
| int | ast_prod (struct ast_channel *chan) |
| int | ast_queue_control (struct ast_channel *chan, int control) |
| Queue a control frame. | |
| int | ast_queue_frame (struct ast_channel *chan, struct ast_frame *fin) |
| Queue an outgoing frame. | |
| int | ast_queue_hangup (struct ast_channel *chan) |
| Queue a hangup frame. | |
| struct ast_frame * | ast_read (struct ast_channel *chan) |
| 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) |
| char * | ast_recvtext (struct ast_channel *chan, int timeout) |
| struct ast_channel * | ast_request (const char *type, int format, void *data, int *cause) |
| Requests a channel. | |
| struct 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 specied 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 specied amount of time, looking for hangups and a condition argument. | |
| int | ast_senddigit (struct ast_channel *chan, char digit) |
| int | ast_sendtext (struct ast_channel *chan, const char *text) |
| void | ast_set_callerid (struct ast_channel *chan, const char *callerid, const char *calleridname, const char *ani) |
| int | ast_set_read_format (struct ast_channel *chan, int fmt) |
| 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) |
| int | ast_setstate (struct ast_channel *chan, int state) |
| Change the state of a channel. | |
| int | ast_settimeout (struct ast_channel *c, int samples, int(*func)(void *data), void *data) |
| int | ast_shutting_down (void) |
| 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). | |
| char * | ast_state2str (int state) |
| 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) |
| void | ast_uninstall_music_functions (void) |
| int | ast_waitfor (struct ast_channel *c, int ms) |
| Wait for input on a channel. | |
| struct ast_channel * | ast_waitfor_n (struct ast_channel **c, int n, int *ms) |
| int | ast_waitfor_n_fd (int *fds, int n, int *ms, int *exception) |
| struct 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) |
| int | ast_waitfordigit_full (struct ast_channel *c, int ms, int audiofd, int cmdfd) |
| struct ast_channel * | ast_walk_channel_by_name_prefix_locked (struct ast_channel *chan, const char *name, const int namelen) |
| int | ast_write (struct ast_channel *chan, struct ast_frame *fr) |
| int | ast_write_video (struct ast_channel *chan, struct ast_frame *fr) |
| static void | bridge_playfile (struct ast_channel *chan, struct ast_channel *peer, 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) |
| static void | clone_variables (struct ast_channel *original, struct ast_channel *clone) |
| static void | copy_data_from_queue (struct ast_channel_spy_queue *queue, short *buf, unsigned int samples) |
| static void | detach_spies (struct ast_channel *chan) |
| static int | do_senddigit (struct ast_channel *chan, char digit) |
| static void | free_cid (struct ast_callerid *cid) |
| static void | free_translation (struct ast_channel *clone) |
| static int | generator_force (void *data) |
| static void | queue_frame_to_spies (struct ast_channel *chan, struct ast_frame *f, enum spy_direction dir) |
| static int | set_format (struct ast_channel *chan, int fmt, int *rawformat, int *format, struct ast_trans_pvt **trans, const int direction) |
| static int | show_channeltypes (int fd, int argc, char *argv[]) |
| 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 | spy_cleanup (struct ast_channel *chan) |
| static void | spy_detach (struct ast_channel_spy *spy, struct ast_channel *chan) |
| 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) |
Variables | |
| static void(* | ast_moh_cleanup_ptr )(struct ast_channel *) = NULL |
| static int(* | ast_moh_start_ptr )(struct ast_channel *, char *) = NULL |
| static void(* | ast_moh_stop_ptr )(struct ast_channel *) = NULL |
| static struct chanlist * | backends = NULL |
| struct ast_cause | causes [] |
| static struct ast_channel * | channels = NULL |
| static struct ast_cli_entry | cli_show_channeltypes |
| unsigned long | global_fin = 0 |
| unsigned long | global_fout = 0 |
| static struct ast_channel_tech | null_tech |
| static char | show_channeltypes_usage [] |
| static int | shutting_down = 0 |
| static struct ast_generator | silence_generator |
| static struct ast_generator | tonepair |
| static int | uniqueint = 0 |
Definition in file channel.c.
| #define FORMAT "%-10.10s %-30.30s %-12.12s %-12.12s %-12.12s\n" |
| #define SPY_QUEUE_SAMPLE_LIMIT 4000 |
| enum spy_direction |
| struct 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 | |||
| ) | [read] |
Definition at line 2449 of file channel.c.
References ast_channel::_state, outgoing_helper::account, ast_call(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_setapp(), ast_cdr_start(), ast_cdr_update(), ast_channel_inherit_variables(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_FRAME_CONTROL, ast_frfree(), ast_hangup(), ast_log(), ast_read(), ast_request(), ast_set_callerid(), ast_set_variables(), AST_STATE_UP, ast_waitfor(), ast_channel::cdr, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_channel::context, outgoing_helper::context, ast_channel::exten, outgoing_helper::exten, ast_frame::frametype, ast_channel::hangupcause, LOG_NOTICE, LOG_WARNING, outgoing_helper::parent_channel, ast_channel::priority, outgoing_helper::priority, ast_frame::subclass, and outgoing_helper::vars.
Referenced by ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_request_and_dial(), and parkandannounce_exec().
02450 { 02451 int state = 0; 02452 int cause = 0; 02453 struct ast_channel *chan; 02454 struct ast_frame *f; 02455 int res = 0; 02456 02457 chan = ast_request(type, format, data, &cause); 02458 if (chan) { 02459 if (oh) { 02460 if (oh->vars) 02461 ast_set_variables(chan, oh->vars); 02462 if (oh->cid_num && *oh->cid_num && oh->cid_name && *oh->cid_name) 02463 ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num); 02464 if (oh->parent_channel) 02465 ast_channel_inherit_variables(oh->parent_channel, chan); 02466 if (oh->account) 02467 ast_cdr_setaccount(chan, oh->account); 02468 } 02469 ast_set_callerid(chan, cid_num, cid_name, cid_num); 02470 02471 if (!ast_call(chan, data, 0)) { 02472 res = 1; /* in case chan->_state is already AST_STATE_UP */ 02473 while (timeout && (chan->_state != AST_STATE_UP)) { 02474 res = ast_waitfor(chan, timeout); 02475 if (res < 0) { 02476 /* Something not cool, or timed out */ 02477 break; 02478 } 02479 /* If done, break out */ 02480 if (!res) 02481 break; 02482 if (timeout > -1) 02483 timeout = res; 02484 f = ast_read(chan); 02485 if (!f) { 02486 state = AST_CONTROL_HANGUP; 02487 res = 0; 02488 break; 02489 } 02490 if (f->frametype == AST_FRAME_CONTROL) { 02491 if (f->subclass == AST_CONTROL_RINGING) 02492 state = AST_CONTROL_RINGING; 02493 else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) { 02494 state = f->subclass; 02495 ast_frfree(f); 02496 break; 02497 } else if (f->subclass == AST_CONTROL_ANSWER) { 02498 state = f->subclass; 02499 ast_frfree(f); 02500 break; 02501 } else if (f->subclass == AST_CONTROL_PROGRESS || f->subclass == AST_CONTROL_PROCEEDING) { 02502 /* Ignore */ 02503 } else if (f->subclass == -1) { 02504 /* Ignore -- just stopping indications */ 02505 } else { 02506 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass); 02507 } 02508 } 02509 ast_frfree(f); 02510 } 02511 } else 02512 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data); 02513 } else { 02514 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 02515 switch(cause) { 02516 case AST_CAUSE_BUSY: 02517 state = AST_CONTROL_BUSY; 02518 break; 02519 case AST_CAUSE_CONGESTION: 02520 state = AST_CONTROL_CONGESTION; 02521 break; 02522 } 02523 } 02524 if (chan) { 02525 /* Final fixups */ 02526 if (oh) { 02527 if (oh->context && *oh->context) 02528 ast_copy_string(chan->context, oh->context, sizeof(chan->context)); 02529 if (oh->exten && *oh->exten) 02530 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten)); 02531 if (oh->priority) 02532 chan->priority = oh->priority; 02533 } 02534 if (chan->_state == AST_STATE_UP) 02535 state = AST_CONTROL_ANSWER; 02536 } 02537 if (outstate) 02538 *outstate = state; 02539 if (chan && res <= 0) { 02540 if (!chan->cdr) { 02541 chan->cdr = ast_cdr_alloc(); 02542 if (chan->cdr) 02543 ast_cdr_init(chan->cdr, chan); 02544 } 02545 if (chan->cdr) { 02546 char tmp[256]; 02547 snprintf(tmp, 256, "%s/%s", type, (char *)data); 02548 ast_cdr_setapp(chan->cdr,"Dial",tmp); 02549 ast_cdr_update(chan); 02550 ast_cdr_start(chan->cdr); 02551 ast_cdr_end(chan->cdr); 02552 /* If the cause wasn't handled properly */ 02553 if (ast_cdr_disposition(chan->cdr,chan->hangupcause)) 02554 ast_cdr_failed(chan->cdr); 02555 } else 02556 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 02557 ast_hangup(chan); 02558 chan = NULL; 02559 } 02560 return chan; 02561 }
| int ast_activate_generator | ( | struct ast_channel * | chan, | |
| struct ast_generator * | gen, | |||
| void * | params | |||
| ) |
Activate a given generator
Definition at line 1476 of file channel.c.
References ast_generator::alloc, ast_mutex_lock(), ast_mutex_unlock(), ast_prod(), ast_settimeout(), ast_channel::generator, generator_force(), ast_channel::generatordata, ast_channel::lock, and ast_generator::release.
Referenced by app_exec(), ast_channel_start_silence_generator(), ast_linear_stream(), ast_playtones_start(), ast_tonepair_start(), channel_spy(), local_ast_moh_start(), milliwatt_exec(), and sms_exec().
01477 { 01478 int res = 0; 01479 01480 ast_mutex_lock(&chan->lock); 01481 01482 if (chan->generatordata) { 01483 if (chan->generator && chan->generator->release) 01484 chan->generator->release(chan, chan->generatordata); 01485 chan->generatordata = NULL; 01486 } 01487 01488 ast_prod(chan); 01489 if (gen->alloc) { 01490 if (!(chan->generatordata = gen->alloc(chan, params))) 01491 res = -1; 01492 } 01493 01494 if (!res) { 01495 ast_settimeout(chan, 160, generator_force, chan); 01496 chan->generator = gen; 01497 } 01498 01499 ast_mutex_unlock(&chan->lock); 01500 01501 return res; 01502 }
| int ast_active_channels | ( | void | ) |
Returns number of active/allocated channels
Definition at line 250 of file channel.c.
References ast_mutex_lock(), ast_mutex_unlock(), channels, and ast_channel::next.
Referenced by quit_handler().
00251 { 00252 struct ast_channel *c; 00253 int cnt = 0; 00254 ast_mutex_lock(&chlock); 00255 c = channels; 00256 while(c) { 00257 cnt++; 00258 c = c->next; 00259 } 00260 ast_mutex_unlock(&chlock); 00261 return cnt; 00262 }
| int ast_answer | ( | struct ast_channel * | chan | ) |
Answer a ringing call.
| chan | channel to answer This function answers a channel and handles all necessary call setup functions. |
Definition at line 1412 of file channel.c.
References ast_channel::_state, ast_channel_tech::answer, ast_cdr_answer(), ast_check_hangup(), AST_FLAG_ZOMBIE, ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_test_flag, ast_channel::cdr, ast_channel::lock, and ast_channel::tech.
Referenced by __login_exec(), agi_exec_full(), alarmreceiver_exec(), app_exec(), ast_bridge_call(), ast_control_streamfile(), ast_pickup_call(), auth_exec(), background_detect_exec(), chanspy_exec(), conf_exec(), count_exec(), datetime_exec(), dial_exec_full(), dictate_exec(), directory_exec(), disa_exec(), features_answer(), handle_answer(), ices_exec(), milliwatt_exec(), park_call_exec(), park_exec(), pbx_builtin_answer(), pbx_builtin_background(), pickup_exec(), playback_exec(), privacy_exec(), read_exec(), record_exec(), rpt_exec(), sayunixtime_exec(), send_waveform_to_channel(), skel_exec(), sms_exec(), testclient_exec(), testserver_exec(), vm_exec(), vm_execmain(), waitforsilence_exec(), zapateller_exec(), and zapras_exec().
01413 { 01414 int res = 0; 01415 ast_mutex_lock(&chan->lock); 01416 /* Stop if we're a zombie or need a soft hangup */ 01417 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 01418 ast_mutex_unlock(&chan->lock); 01419 return -1; 01420 } 01421 switch(chan->_state) { 01422 case AST_STATE_RINGING: 01423 case AST_STATE_RING: 01424 if (chan->tech->answer) 01425 res = chan->tech->answer(chan); 01426 ast_setstate(chan, AST_STATE_UP); 01427 if (chan->cdr) 01428 ast_cdr_answer(chan->cdr); 01429 ast_mutex_unlock(&chan->lock); 01430 return res; 01431 break; 01432 case AST_STATE_UP: 01433 if (chan->cdr) 01434 ast_cdr_answer(chan->cdr); 01435 break; 01436 } 01437 ast_mutex_unlock(&chan->lock); 01438 return 0; 01439 }
| void ast_begin_shutdown | ( | int | hangup | ) |
Initiate system shutdown -- prevents new channels from being allocated. If "hangup" is non-zero, all existing channels will receive soft hangups
Definition at line 234 of file channel.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_softhangup(), AST_SOFTHANGUP_SHUTDOWN, channels, ast_channel::next, and shutting_down.
Referenced by quit_handler().
00235 { 00236 struct ast_channel *c; 00237 shutting_down = 1; 00238 if (hangup) { 00239 ast_mutex_lock(&chlock); 00240 c = channels; 00241 while(c) { 00242 ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN); 00243 c = c->next; 00244 } 00245 ast_mutex_unlock(&chlock); 00246 } 00247 }
| int ast_best_codec | ( | int | fmts | ) |
Pick the best codec
Definition at line 471 of file channel.c.
References AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_G723_1, AST_FORMAT_G726, AST_FORMAT_G729A, AST_FORMAT_GSM, AST_FORMAT_ILBC, AST_FORMAT_LPC10, AST_FORMAT_SLINEAR, AST_FORMAT_SPEEX, AST_FORMAT_ULAW, ast_log(), LOG_WARNING, and prefs.
Referenced by __login_exec(), __oh323_new(), agent_call(), ast_codec_choose(), ast_iax2_new(), builtin_atxfer(), echo_exec(), iax2_request(), local_new(), mgcp_new(), sip_new(), skinny_new(), and socket_read().
00472 { 00473 /* This just our opinion, expressed in code. We are asked to choose 00474 the best codec to use, given no information */ 00475 int x; 00476 static int prefs[] = 00477 { 00478 /* Okay, ulaw is used by all telephony equipment, so start with it */ 00479 AST_FORMAT_ULAW, 00480 /* Unless of course, you're a silly European, so then prefer ALAW */ 00481 AST_FORMAT_ALAW, 00482 /* Okay, well, signed linear is easy to translate into other stuff */ 00483 AST_FORMAT_SLINEAR, 00484 /* G.726 is standard ADPCM */ 00485 AST_FORMAT_G726, 00486 /* ADPCM has great sound quality and is still pretty easy to translate */ 00487 AST_FORMAT_ADPCM, 00488 /* Okay, we're down to vocoders now, so pick GSM because it's small and easier to 00489 translate and sounds pretty good */ 00490 AST_FORMAT_GSM, 00491 /* iLBC is not too bad */ 00492 AST_FORMAT_ILBC, 00493 /* Speex is free, but computationally more expensive than GSM */ 00494 AST_FORMAT_SPEEX, 00495 /* Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough 00496 to use it */ 00497 AST_FORMAT_LPC10, 00498 /* G.729a is faster than 723 and slightly less expensive */ 00499 AST_FORMAT_G729A, 00500 /* Down to G.723.1 which is proprietary but at least designed for voice */ 00501 AST_FORMAT_G723_1, 00502 }; 00503 00504 00505 /* Find the first prefered codec in the format given */ 00506 for (x=0; x < (sizeof(prefs) / sizeof(prefs[0]) ); x++) 00507 if (fmts & prefs[x]) 00508 return prefs[x]; 00509 ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts); 00510 return 0; 00511 }
| struct ast_channel* ast_bridged_channel | ( | struct ast_channel * | chan | ) | [read] |
Find bridged channel.
| chan | Current channel |
Definition at line 3295 of file channel.c.
References ast_channel::_bridge, ast_channel_tech::bridged_channel, and ast_channel::tech.
Referenced by __zt_exception(), agents_show(), ast_channel_masquerade(), attempt_transfer(), chanspy_exec(), check_bridge(), console_transfer(), get_refer_info(), handle_chanlist(), handle_hd_hf(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_refer(), handle_showchan(), mgcp_hangup(), mgcp_ss(), mixmonitor_thread(), process_sdp(), schedule_delivery(), skinny_ss(), socket_read(), ss_thread(), start_spying(), startmon(), zt_handle_event(), and zt_hangup().
03296 { 03297 struct ast_channel *bridged; 03298 bridged = chan->_bridge; 03299 if (bridged && bridged->tech->bridged_channel) 03300 bridged = bridged->tech->bridged_channel(chan, bridged); 03301 return bridged; 03302 }
| 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 2628 of file channel.c.
References ast_check_hangup(), AST_FLAG_ZOMBIE, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_channel_tech::call, ast_channel::lock, and ast_channel::tech.
Referenced by __ast_request_and_dial(), agent_call(), ast_feature_request_and_dial(), attempt_reconnect(), dial_exec_full(), features_call(), function_ilink(), ring_entry(), rpt(), rpt_exec(), and wait_for_answer().
02629 { 02630 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 02631 If the remote end does not answer within the timeout, then do NOT hang up, but 02632 return anyway. */ 02633 int res = -1; 02634 /* Stop if we're a zombie or need a soft hangup */ 02635 ast_mutex_lock(&chan->lock); 02636 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) 02637 if (chan->tech->call) 02638 res = chan->tech->call(chan, addr, timeout); 02639 ast_mutex_unlock(&chan->lock); 02640 return res; 02641 }
| void ast_cancel_shutdown | ( | void | ) |
Cancels an existing shutdown and returns to normal operation
Definition at line 265 of file channel.c.
References shutting_down.
Referenced by handle_abort_halt().
00266 { 00267 shutting_down = 0; 00268 }
| const char* ast_cause2str | ( | int | state | ) |
Gives the string form of a given cause code
| 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 410 of file channel.c.
References causes, and ast_cause::desc.
Referenced by __transmit_response(), ast_do_masquerade(), ast_hangup(), dial_exec_full(), and transmit_request_with_auth().
00411 { 00412 int x; 00413 00414 for (x=0; x < sizeof(causes) / sizeof(causes[0]); x++) 00415 if (causes[x].cause == cause) 00416 return causes[x].desc; 00417 00418 return "Unknown"; 00419 }
| void ast_change_name | ( | struct ast_channel * | chan, | |
| char * | newname | |||
| ) |
Change channel name.
Definition at line 2886 of file channel.c.
References EVENT_FLAG_CALL, manager_event(), ast_channel::name, and ast_channel::uniqueid.
02887 { 02888 char tmp[256]; 02889 ast_copy_string(tmp, chan->name, sizeof(tmp)); 02890 ast_copy_string(chan->name, newname, sizeof(chan->name)); 02891 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid); 02892 }
| struct ast_channel* ast_channel_alloc | ( | int | needalertpipe | ) | [read] |
Create a channel structure.
Definition at line 519 of file channel.c.
References ast_channel::_state, ast_channel::accountcode, ast_channel::alertpipe, ast_channel::amaflags, ast_channel::appl, ast_default_accountcode, ast_default_amaflags, AST_LIST_HEAD_INIT_NOLOCK, ast_log(), AST_MAX_FDS, ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DOWN, channels, ast_channel::context, ast_channel::data, defaultlanguage, ast_channel::exten, ast_channel::fds, ast_channel::fin, ast_channel::flags, ast_channel::fout, free, global_fin, global_fout, ast_channel::language, ast_channel::lock, LOG_WARNING, malloc, ast_channel::name, ast_channel::next, null_tech, ast_channel::priority, ast_channel::sched, sched_context_create(), shutting_down, ast_channel::streamid, ast_channel::tech, ast_channel::timingfd, ast_channel::uniqueid, uniqueint, and ast_channel::varshead.
Referenced by __oh323_new(), agent_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_masq_park_call(), ast_modem_new(), ast_pbx_outgoing_cdr_failed(), ast_pbx_outgoing_exten(), builtin_atxfer(), check_goto_on_transfer(), features_new(), iax_park(), local_new(), mgcp_new(), misdn_new(), nbs_new(), oss_new(), phone_new(), sendmail(), sendpage(), sip_new(), sip_park(), skinny_new(), vpb_new(), and zt_new().
00520 { 00521 struct ast_channel *tmp; 00522 int x; 00523 int flags; 00524 struct varshead *headp; 00525 00526 00527 /* If shutting down, don't allocate any new channels */ 00528 if (shutting_down) { 00529 ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n"); 00530 return NULL; 00531 } 00532 00533 tmp = malloc(sizeof(struct ast_channel)); 00534 if (!tmp) { 00535 ast_log(LOG_WARNING, "Channel allocation failed: Out of memory\n"); 00536 return NULL; 00537 } 00538 00539 memset(tmp, 0, sizeof(struct ast_channel)); 00540 tmp->sched = sched_context_create(); 00541 if (!tmp->sched) { 00542 ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n"); 00543 free(tmp); 00544 return NULL; 00545 } 00546 00547 for (x=0; x<AST_MAX_FDS - 1; x++) 00548 tmp->fds[x] = -1; 00549 00550 #ifdef ZAPTEL_OPTIMIZATIONS 00551 tmp->timingfd = open("/dev/zap/timer", O_RDWR); 00552 if (tmp->timingfd > -1) { 00553 /* Check if timing interface supports new 00554 ping/pong scheme */ 00555 flags = 1; 00556 if (!ioctl(tmp->timingfd, ZT_TIMERPONG, &flags)) 00557 needqueue = 0; 00558 } 00559 #else 00560 tmp->timingfd = -1; 00561 #endif 00562 00563 if (needqueue) { 00564 if (pipe(tmp->alertpipe)) { 00565 ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n"); 00566 free(tmp); 00567 return NULL; 00568 } else { 00569 flags = fcntl(tmp->alertpipe[0], F_GETFL); 00570 fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK); 00571 flags = fcntl(tmp->alertpipe[1], F_GETFL); 00572 fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK); 00573 } 00574 } else 00575 /* Make sure we've got it done right if they don't */ 00576 tmp->alertpipe[0] = tmp->alertpipe[1] = -1; 00577 00578 /* Always watch the alertpipe */ 00579 tmp->fds[AST_MAX_FDS-1] = tmp->alertpipe[0]; 00580 /* And timing pipe */ 00581 tmp->fds[AST_MAX_FDS-2] = tmp->timingfd; 00582 strcpy(tmp->name, "**Unknown**"); 00583 /* Initial state */ 00584 tmp->_state = AST_STATE_DOWN; 00585 tmp->streamid = -1; 00586 tmp->appl = NULL; 00587 tmp->data = NULL; 00588 tmp->fin = global_fin; 00589 tmp->fout = global_fout; 00590 ast_mutex_lock(&uniquelock); 00591 snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long) time(NULL), uniqueint++); 00592 ast_mutex_unlock(&uniquelock); 00593 headp = &tmp->varshead; 00594 ast_mutex_init(&tmp->lock); 00595 AST_LIST_HEAD_INIT_NOLOCK(headp); 00596 strcpy(tmp->context, "default"); 00597 ast_copy_string(tmp->language, defaultlanguage, sizeof(tmp->language)); 00598 strcpy(tmp->exten, "s"); 00599 tmp->priority = 1; 00600 tmp->amaflags = ast_default_amaflags; 00601 ast_copy_string(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode)); 00602 00603 tmp->tech = &null_tech; 00604 00605 ast_mutex_lock(&chlock); 00606 tmp->next = channels; 00607 channels = tmp; 00608 00609 ast_mutex_unlock(&chlock); 00610 return tmp; 00611 }
| enum ast_bridge_result ast_channel_bridge | ( | struct ast_channel * | c0, | |
| struct ast_channel * | c1, | |||
| struct ast_bridge_config * | config, | |||
| struct ast_frame ** | fo, | |||
| struct ast_channel ** | rc | |||
| ) |
Bridge two channels together
| c0 | first channel to bridge | |
| c1 | second channel to bridge | |
| config | config for the channels | |
| fo | destination frame(?) | |
| rc | destination channel(?) 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 3459 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_FEATURE_PLAY_WARNING, AST_FEATURE_REDIRECT, AST_FLAG_NBRIDGE, AST_FLAG_ZOMBIE, ast_generic_bridge(), ast_log(), ast_set_flag, AST_SOFTHANGUP_UNBRIDGE, ast_strlen_zero(), ast_test_flag, ast_tvadd(), ast_tvsub(), ast_verbose(), ast_channel_tech::bridge, bridge_playfile(), ast_channel::cid, ast_callerid::cid_num, ast_bridge_config::end_sound, EVENT_FLAG_CALL, ast_bridge_config::feature_timer, ast_bridge_config::features_callee, ast_bridge_config::features_caller, ast_bridge_config::firstpass, ast_bridge_config::flags, ast_channel::generator, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, option_verbose, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), ast_bridge_config::play_warning, ast_channel::readformat, ast_channel::spies, ast_bridge_config::start_sound, ast_bridge_config::start_time, ast_channel::tech, ast_bridge_config::timelimit, ast_channel::uniqueid, VERBOSE_PREFIX_3, ast_bridge_config::warning_freq, ast_bridge_config::warning_sound, and ast_channel::writeformat.
Referenced by ast_bridge_call().
03461 { 03462 struct ast_channel *who = NULL; 03463 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 03464 int nativefailed=0; 03465 int firstpass; 03466 int o0nativeformats; 03467 int o1nativeformats; 03468 long time_left_ms=0; 03469 struct timeval nexteventts = { 0, }; 03470 char caller_warning = 0; 03471 char callee_warning = 0; 03472 03473 if (c0->_bridge) { 03474 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 03475 c0->name, c0->_bridge->name); 03476 return -1; 03477 } 03478 if (c1->_bridge) { 03479 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 03480 c1->name, c1->_bridge->name); 03481 return -1; 03482 } 03483 03484 /* Stop if we're a zombie or need a soft hangup */ 03485 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 03486 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 03487 return -1; 03488 03489 *fo = NULL; 03490 firstpass = config->firstpass; 03491 config->firstpass = 0; 03492 03493 if (ast_tvzero(config->start_time)) 03494 config->start_time = ast_tvnow(); 03495 time_left_ms = config->timelimit; 03496 03497 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING); 03498 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING); 03499 03500 if (config->start_sound && firstpass) { 03501 if (caller_warning) 03502 bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000); 03503 if (callee_warning) 03504 bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000); 03505 } 03506 03507 /* Keep track of bridge */ 03508 c0->_bridge = c1; 03509 c1->_bridge = c0; 03510 03511 manager_event(EVENT_FLAG_CALL, "Link", 03512 "Channel1: %s\r\n" 03513 "Channel2: %s\r\n" 03514 "Uniqueid1: %s\r\n" 03515 "Uniqueid2: %s\r\n" 03516 "CallerID1: %s\r\n" 03517 "CallerID2: %s\r\n", 03518 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03519 03520 o0nativeformats = c0->nativeformats; 03521 o1nativeformats = c1->nativeformats; 03522 03523 if (config->feature_timer) { 03524 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000)); 03525 } else if (config->timelimit) { 03526 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 03527 if (caller_warning || callee_warning) 03528 nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000)); 03529 } 03530 03531 for (/* ever */;;) { 03532 struct timeval now = { 0, }; 03533 int to; 03534 03535 to = -1; 03536 03537 if (!ast_tvzero(nexteventts)) { 03538 now = ast_tvnow(); 03539 to = ast_tvdiff_ms(nexteventts, now); 03540 if (to <= 0 && !config->timelimit) { 03541 res = AST_BRIDGE_COMPLETE; 03542 break; 03543 } 03544 03545 } 03546 03547 if (config->timelimit) { 03548 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time); 03549 if (time_left_ms < to) 03550 to = time_left_ms; 03551 03552 if (time_left_ms <= 0) { 03553 if (caller_warning && config->end_sound) 03554 bridge_playfile(c0, c1, config->end_sound, 0); 03555 if (callee_warning && config->end_sound) 03556 bridge_playfile(c1, c0, config->end_sound, 0); 03557 *fo = NULL; 03558 if (who) 03559 *rc = who; 03560 res = 0; 03561 break; 03562 } 03563 03564 if (to <= 0) { 03565 if (time_left_ms >= 5000) { 03566 /* force the time left to round up if appropriate */ 03567 if (caller_warning && config->warning_sound && config->play_warning) 03568 bridge_playfile(c0, c1, config->warning_sound, 03569 (time_left_ms + 500) / 1000); 03570 if (callee_warning && config->warning_sound && config->play_warning) 03571 bridge_playfile(c1, c0, config->warning_sound, 03572 (time_left_ms + 500) / 1000); 03573 } 03574 if (config->warning_freq) { 03575 nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000)); 03576 } 03577 03578 if ( (!config->warning_freq) || ( config->timelimit - ast_tvdiff_ms(nexteventts, config->start_time) < 0)) { 03579 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 03580 } 03581 } 03582 } 03583 03584 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) { 03585 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03586 c0->_softhangup = 0; 03587 if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03588 c1->_softhangup = 0; 03589 c0->_bridge = c1; 03590 c1->_bridge = c0; 03591 ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n"); 03592 continue; 03593 } 03594 03595 /* Stop if we're a zombie or need a soft hangup */ 03596 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 03597 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) { 03598 *fo = NULL; 03599 if (who) 03600 *rc = who; 03601 res = 0; 03602 ast_log(LOG_DEBUG, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n", 03603 c0->name, c1->name, 03604 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No", 03605 ast_check_hangup(c0) ? "Yes" : "No", 03606 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No", 03607 ast_check_hangup(c1) ? "Yes" : "No"); 03608 break; 03609 } 03610 03611 /* See if the BRIDGEPEER variable needs to be updated */ 03612 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER"))) 03613 pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1->name); 03614 if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER"))) 03615 pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0->name); 03616 03617 if (c0->tech->bridge && 03618 (config->timelimit == 0) && 03619 (c0->tech->bridge == c1->tech->bridge) && 03620 !nativefailed && !c0->monitor && !c1->monitor && 03621 !c0->spies && !c1->spies && !ast_test_flag(&(config->features_callee),AST_FEATURE_REDIRECT) && 03622 !ast_test_flag(&(config->features_caller),AST_FEATURE_REDIRECT) ) { 03623 /* Looks like they share a bridge method and nothing else is in the way */ 03624 if (option_verbose > 2) 03625 ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name); 03626 ast_set_flag(c0, AST_FLAG_NBRIDGE); 03627 ast_set_flag(c1, AST_FLAG_NBRIDGE); 03628 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) { 03629 manager_event(EVENT_FLAG_CALL, "Unlink", 03630 "Channel1: %s\r\n" 03631 "Channel2: %s\r\n" 03632 "Uniqueid1: %s\r\n" 03633 "Uniqueid2: %s\r\n" 03634 "CallerID1: %s\r\n" 03635 "CallerID2: %s\r\n", 03636 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03637 ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name); 03638 03639 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 03640 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 03641 03642 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03643 continue; 03644 03645 c0->_bridge = NULL; 03646 c1->_bridge = NULL; 03647 03648 return res; 03649 } else { 03650 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 03651 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 03652 } 03653 switch (res) { 03654 case AST_BRIDGE_RETRY: 03655 continue; 03656 default: 03657 ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name); 03658 /* fallthrough */ 03659 case AST_BRIDGE_FAILED_NOWARN: 03660 nativefailed++; 03661 break; 03662 } 03663 } 03664 03665 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) || 03666 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) && 03667 !(c0->generator || c1->generator)) { 03668 if (ast_channel_make_compatible(c0, c1)) { 03669 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 03670 manager_event(EVENT_FLAG_CALL, "Unlink", 03671 "Channel1: %s\r\n" 03672 "Channel2: %s\r\n" 03673 "Uniqueid1: %s\r\n" 03674 "Uniqueid2: %s\r\n" 03675 "CallerID1: %s\r\n" 03676 "CallerID2: %s\r\n", 03677 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03678 return AST_BRIDGE_FAILED; 03679 } 03680 o0nativeformats = c0->nativeformats; 03681 o1nativeformats = c1->nativeformats; 03682 } 03683 res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts); 03684 if (res != AST_BRIDGE_RETRY && fo) 03685 break; 03686 } 03687 03688 c0->_bridge = NULL; 03689 c1->_bridge = NULL; 03690 03691 manager_event(EVENT_FLAG_CALL, "Unlink", 03692 "Channel1: %s\r\n" 03693 "Channel2: %s\r\n" 03694 "Uniqueid1: %s\r\n" 03695 "Uniqueid2: %s\r\n" 03696 "CallerID1: %s\r\n" 03697 "CallerID2: %s\r\n", 03698 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03699 ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name); 03700 03701 return res; 03702 }
| 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 292 of file channel.c.
References ast_channel::whentohangup.
Referenced by ast_osp_lookup().
00293 { 00294 time_t whentohangup; 00295 00296 if (chan->whentohangup == 0) { 00297 if (offset == 0) 00298 return (0); 00299 else 00300 return (-1); 00301 } else { 00302 if (offset == 0) 00303 return (1); 00304 else { 00305 whentohangup = offset + time (NULL); 00306 if (chan->whentohangup < whentohangup) 00307 return (1); 00308 else if (chan->whentohangup == whentohangup) 00309 return (0); 00310 else 00311 return (-1); 00312 } 00313 } 00314 }
| int ast_channel_defer_dtmf | ( | struct ast_channel * | chan | ) |
Defers DTMF
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 693 of file channel.c.
References AST_FLAG_DEFER_DTMF, ast_set_flag, and ast_test_flag.
Referenced by __adsi_transmit_messages(), and find_cache().
00694 { 00695 int pre = 0; 00696 00697 if (chan) { 00698 pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF); 00699 ast_set_flag(chan, AST_FLAG_DEFER_DTMF); 00700 } 00701 return pre; 00702 }
| void ast_channel_free | ( | struct ast_channel * | chan | ) |
Free a channel structure.
Definition at line 886 of file channel.c.
References ast_channel::alertpipe, ast_app_group_discard(), AST_CHANNEL_NAME, ast_device_state_changed_literal(), ast_frfree(), AST_LIST_REMOVE_HEAD, ast_log(), ast_moh_cleanup(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_translator_free_path(), ast_var_delete(), channels, ast_channel::cid, free, free_cid(), last, ast_channel::lock, LOG_ERROR, LOG_WARNING, ast_channel::monitor, ast_channel::music_state, ast_channel::name, name, ast_frame::next, ast_channel::next, 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 agent_cleanup(), agent_new(), ast_do_masquerade(), ast_hangup(), ast_pbx_outgoing_cdr_failed(), local_new(), sendmail(), and sendpage().
00887 { 00888 struct ast_channel *last=NULL, *cur; 00889 int fd; 00890 struct ast_var_t *vardata; 00891 struct ast_frame *f, *fp; 00892 struct varshead *headp; 00893 char name[AST_CHANNEL_NAME]; 00894 00895 headp=&chan->varshead; 00896 00897 ast_mutex_lock(&chlock); 00898 cur = channels; 00899 while(cur) { 00900 if (cur == chan) { 00901 if (last) 00902 last->next = cur->next; 00903 else 00904 channels = cur->next; 00905 break; 00906 } 00907 last = cur; 00908 cur = cur->next; 00909 } 00910 if (!cur) { 00911 ast_mutex_unlock(&chlock); 00912 ast_log(LOG_ERROR, "Unable to find channel in list to free. Assuming it has already been done.\n"); 00913 return; 00914 } 00915 00916 /* Lock and unlock the channel just to be sure nobody 00917 has it locked still */ 00918 ast_mutex_lock(&cur->lock); 00919 ast_mutex_unlock(&cur->lock); 00920 if (chan->tech_pvt) { 00921 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name); 00922 free(chan->tech_pvt); 00923 } 00924 00925 if (chan->sched) 00926 sched_context_destroy(chan->sched); 00927 00928 ast_copy_string(name, chan->name, sizeof(name)); 00929 00930 /* Stop monitoring */ 00931 if (chan->monitor) { 00932 chan->monitor->stop( chan, 0 ); 00933 } 00934 00935 /* If there is native format music-on-hold state, free it */ 00936 if(chan->music_state) 00937 ast_moh_cleanup(chan); 00938 00939 /* Free translatosr */ 00940 if (chan->readtrans) 00941 ast_translator_free_path(chan->readtrans); 00942 if (chan->writetrans) 00943 ast_translator_free_path(chan->writetrans); 00944 if (chan->pbx) 00945 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name); 00946 free_cid(&chan->cid); 00947 ast_mutex_destroy(&chan->lock); 00948 /* Close pipes if appropriate */ 00949 if ((fd = chan->alertpipe[0]) > -1) 00950 close(fd); 00951 if ((fd = chan->alertpipe[1]) > -1) 00952 close(fd); 00953 if ((fd = chan->timingfd) > -1) 00954 close(fd); 00955 f = chan->readq; 00956 chan->readq = NULL; 00957 while(f) { 00958 fp = f; 00959 f = f->next; 00960 ast_frfree(fp); 00961 } 00962 00963 /* loop over the variables list, freeing all data and deleting list items */ 00964 /* no need to lock the list, as the channel is already locked */ 00965 00966 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) 00967 ast_var_delete(vardata); 00968 00969 /* Drop out of the group counting radar */ 00970 ast_app_group_discard(chan); 00971 00972 free(chan); 00973 ast_mutex_unlock(&chlock); 00974 00975 ast_device_state_changed_literal(name); 00976 }
| void ast_channel_inherit_variables | ( | const struct ast_channel * | parent, | |
| struct ast_channel * | child | |||
| ) |
Inherits channel variable from parent to child channel.
Scans all channel variables in the parent channel, looking for those that should be copied into the child channel. Variables whose names begin with a single '_' are copied into the child channel with the prefix removed. Variables whose names begin with '__' are copied into the child channel with their names unchanged.
Definition at line 2894 of file channel.c.
References AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_var_assign(), ast_var_full_name(), ast_var_name(), ast_var_value(), LOG_DEBUG, option_debug, and ast_channel::varshead.
Referenced by __ast_request_and_dial(), agent_call(), ast_feature_request_and_dial(), dial_exec_full(), ring_entry(), and wait_for_answer().
02895 { 02896 struct ast_var_t *current, *newvar; 02897 char *varname; 02898 02899 AST_LIST_TRAVERSE(&parent->varshead, current, entries) { 02900 int vartype = 0; 02901 02902 varname = ast_var_full_name(current); 02903 if (!varname) 02904 continue; 02905 02906 if (varname[0] == '_') { 02907 vartype = 1; 02908 if (varname[1] == '_') 02909 vartype = 2; 02910 } 02911 02912 switch (vartype) { 02913 case 1: 02914 newvar = ast_var_assign(&varname[1], ast_var_value(current)); 02915 if (newvar) { 02916 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 02917 if (option_debug) 02918 ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar)); 02919 } 02920 break; 02921 case 2: 02922 newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current)); 02923 if (newvar) { 02924 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 02925 if (option_debug) 02926 ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar)); 02927 } 02928 break; 02929 default: 02930 if (option_debug) 02931 ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current)); 02932 break; 02933 } 02934 } 02935 }
| 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 . Returns 0 on success and -1 if it could not be done |
Definition at line 2767 of file channel.c.
References AST_FORMAT_SLINEAR, ast_log(), ast_set_read_format(), ast_set_write_format(), ast_translator_best_choice(), LOG_WARNING, ast_channel::name, ast_channel::nativeformats, option_transcode_slin, ast_channel::readformat, and ast_channel::writeformat.
Referenced by ast_channel_bridge(), builtin_atxfer(), dial_exec_full(), park_exec(), try_calling(), and wait_for_answer().
02768 { 02769 int src; 02770 int dst; 02771 02772 if (chan->readformat == peer->writeformat && chan->writeformat == peer->readformat) { 02773 /* Already compatible! Moving on ... */ 02774 return 0; 02775 } 02776 02777 /* Set up translation from the chan to the peer */ 02778 src = chan->nativeformats; 02779 dst = peer->nativeformats; 02780 if (ast_translator_best_choice(&dst, &src) < 0) { 02781 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst); 02782 return -1; 02783 } 02784 02785 /* if the best path is not 'pass through', then 02786 transcoding is needed; if desired, force transcode path 02787 to use SLINEAR between channels */ 02788 if ((src != dst) && option_transcode_slin) 02789 dst = AST_FORMAT_SLINEAR; 02790 if (ast_set_read_format(chan, dst) < 0) { 02791 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst); 02792 return -1; 02793 } 02794 if (ast_set_write_format(peer, dst) < 0) { 02795 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, dst); 02796 return -1; 02797 } 02798 02799 /* Set up translation from the peer to the chan */ 02800 src = peer->nativeformats; 02801 dst = chan->nativeformats; 02802 if (ast_translator_best_choice(&dst, &src) < 0) { 02803 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst); 02804 return -1; 02805 } 02806 /* if the best path is not 'pass through', then 02807 transcoding is needed; if desired, force transcode path 02808 to use SLINEAR between channels */ 02809 if ((src != dst) && option_transcode_slin) 02810 dst = AST_FORMAT_SLINEAR; 02811 if (ast_set_read_format(peer, dst) < 0) { 02812 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst); 02813 return -1; 02814 } 02815 if (ast_set_write_format(chan, dst) < 0) { 02816 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, dst); 02817 return -1; 02818 } 02819 return 0; 02820 }
| 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 This is a very strange and freaky function used primarily for transfer. Suppose that "original" and "clone" are two channels in random situations. This function takes the guts out of "clone" and puts them into the "original" channel, then alerts the channel driver of the change, asking it to fixup any private information (like the p->owner pointer) that is affected by the change. The physical layer of the original channel is hung up. |
Definition at line 2822 of file channel.c.
References ast_channel::_bridge, ast_bridged_channel(), AST_FRAME_NULL, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::masq, ast_channel::masqr, and ast_channel::name.
Referenced by ast_async_goto(), ast_masq_park_call(), ast_pickup_call(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), check_goto_on_transfer(), iax_park(), misdn_transfer_bc(), pickup_exec(), and sip_park().
02823 { 02824 struct ast_frame null = { AST_FRAME_NULL, }; 02825 int res = -1; 02826 struct ast_channel *final_orig = original, *final_clone = clone; 02827 02828 ast_mutex_lock(&original->lock); 02829 while(ast_mutex_trylock(&clone->lock)) { 02830 ast_mutex_unlock(&original->lock); 02831 usleep(1); 02832 ast_mutex_lock(&original->lock); 02833 } 02834 02835 /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent) 02836 and if so, we don't really want to masquerade it, but its proxy */ 02837 if (original->_bridge && (original->_bridge != ast_bridged_channel(original)) && (original->_bridge->_bridge != original)) 02838 final_orig = original->_bridge; 02839 02840 if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone)) && (clone->_bridge->_bridge != clone)) 02841 final_clone = clone->_bridge; 02842 02843 if ((final_orig != original) || (final_clone != clone)) { 02844 ast_mutex_lock(&final_orig->lock); 02845 while(ast_mutex_trylock(&final_clone->lock)) { 02846 ast_mutex_unlock(&final_orig->lock); 02847 usleep(1); 02848 ast_mutex_lock(&final_orig->lock); 02849 } 02850 ast_mutex_unlock(&clone->lock); 02851 ast_mutex_unlock(&original->lock); 02852 original = final_orig; 02853 clone = final_clone; 02854 } 02855 02856 if (original == clone) { 02857 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name); 02858 ast_mutex_unlock(&clone->lock); 02859 ast_mutex_unlock(&original->lock); 02860 return -1; 02861 } 02862 02863 ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n", 02864 clone->name, original->name); 02865 if (original->masq) { 02866 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 02867 original->masq->name, original->name); 02868 } else if (clone->masqr) { 02869 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 02870 clone->name, clone->masqr->name); 02871 } else { 02872 original->masq = clone; 02873 clone->masqr = original; 02874 ast_queue_frame(original, &null); 02875 ast_queue_frame(clone, &null); 02876 ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name); 02877 res = 0; 02878 } 02879 02880 ast_mutex_unlock(&clone->lock); 02881 ast_mutex_unlock(&original->lock); 02882 02883 return res; 02884 }
| 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 317 of file channel.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), backends, ast_channel_tech::description, LOG_DEBUG, LOG_WARNING, malloc, chanlist::next, option_debug, option_verbose, chanlist::tech, ast_channel_tech::type, and VERBOSE_PREFIX_2.
Referenced by load_module(), and unload_module().
00318 { 00319 struct chanlist *chan; 00320 00321 ast_mutex_lock(&chlock); 00322 00323 chan = backends; 00324 while (chan) { 00325 if (!strcasecmp(tech->type, chan->tech->type)) { 00326 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type); 00327 ast_mutex_unlock(&chlock); 00328 return -1; 00329 } 00330 chan = chan->next; 00331 } 00332 00333 chan = malloc(sizeof(*chan)); 00334 if (!chan) { 00335 ast_log(LOG_WARNING, "Out of memory\n"); 00336 ast_mutex_unlock(&chlock); 00337 return -1; 00338 } 00339 chan->tech = tech; 00340 chan->next = backends; 00341 backends = chan; 00342 00343 if (option_debug) 00344 ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description); 00345 00346 if (option_verbose > 1) 00347 ast_verbose(VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->tech->type, 00348 chan->tech->description); 00349 00350 ast_mutex_unlock(&chlock); 00351 return 0; 00352 }
| int ast_channel_sendhtml | ( | struct ast_channel * | channel, | |
| int | subclass, | |||
| const char * | data, | |||
| int | datalen | |||
| ) |
Sends HTML on given channel
Send HTML or URL on link. Returns 0 on success or -1 on failure
Definition at line 2753 of file channel.c.
References ast_channel_tech::send_html, and ast_channel::tech.
Referenced by agent_sendhtml(), and wait_for_answer().
02754 { 02755 if (chan->tech->send_html) 02756 return chan->tech->send_html(chan, subclass, data, datalen); 02757 return -1; 02758 }
| int ast_channel_sendurl | ( | struct ast_channel * | channel, | |
| const char * | url | |||
| ) |
Sends a URL on a given link
Send URL on link. Returns 0 on success or -1 on failure
Definition at line 2760 of file channel.c.
References AST_HTML_URL, ast_channel_tech::send_html, and ast_channel::tech.
Referenced by dial_exec_full(), sendurl_exec(), and try_calling().
02761 { 02762 if (chan->tech->send_html) 02763 return chan->tech->send_html(chan, AST_HTML_URL, url, strlen(url) + 1); 02764 return -1; 02765 }
| 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 3705 of file channel.c.
References ast_log(), LOG_ERROR, ast_channel_tech::setoption, and ast_channel::tech.
Referenced by ast_bridge_call(), chanspy_exec(), conf_run(), handle_tddmode(), play_record_review(), reset_volumes(), rpt(), set_listen_volume(), set_talk_volume(), set_volume(), try_calling(), vm_forwardoptions(), and zt_hangup().
03706 { 03707 int res; 03708 03709 if (chan->tech->setoption) { 03710 res = chan->tech->setoption(chan, option, data, datalen); 03711 if (res < 0) 03712 return res; 03713 } else { 03714 errno = ENOSYS; 03715 return -1; 03716 } 03717 if (block) { 03718 /* XXX Implement blocking -- just wait for our option frame reply, discarding 03719 intermediate packets. XXX */ 03720 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 03721 return -1; 03722 } 03723 return 0; 03724 }
| 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 This function sets the absolute time out on a channel (when to hang up). |
Definition at line 277 of file channel.c.
References AST_FRAME_NULL, ast_queue_frame(), and ast_channel::whentohangup.
Referenced by action_timeout(), ast_osp_lookup(), builtin_function_timeout_write(), handle_request_invite(), and pbx_builtin_atimeout().
00278 { 00279 time_t myt; 00280 struct ast_frame fr = { AST_FRAME_NULL, }; 00281 00282 time(&myt); 00283 if (offset) 00284 chan->whentohangup = myt + offset; 00285 else 00286 chan->whentohangup = 0; 00287 ast_queue_frame(chan, &fr); 00288 return; 00289 }
| int ast_channel_spy_add | ( | struct ast_channel * | chan, | |
| struct ast_channel_spy * | spy | |||
| ) |
Adds a spy to a channel, to begin receiving copies of the channel's audio frames.
| chan | The channel to add the spy to. | |
| spy | A pointer to ast_channel_spy structure describing how the spy is to be used. |
Definition at line 978 of file channel.c.
References ast_clear_flag, ast_cond_init(), AST_FORMAT_SLINEAR, ast_getformatname(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_INSERT_TAIL, ast_log(), ast_set_flag, ast_test_flag, calloc, ast_channel_spy::chan, CHANSPY_FORMAT_AUDIO, CHANSPY_MIXAUDIO, CHANSPY_READ_VOLADJUST, CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_NONE, CHANSPY_TRIGGER_READ, CHANSPY_TRIGGER_WRITE, CHANSPY_WRITE_VOLADJUST, ast_channel_spy_queue::format, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_channel_spy::read_queue, ast_channel::spies, ast_channel_spy::trigger, ast_channel_spy::type, and ast_channel_spy::write_queue.
Referenced by start_spying(), and startmon().
00979 { 00980 /* Link the owner channel to the spy */ 00981 spy->chan = chan; 00982 00983 if (!ast_test_flag(spy, CHANSPY_FORMAT_AUDIO)) { 00984 ast_log(LOG_WARNING, "Could not add channel spy '%s' to channel '%s', only audio format spies are supported.\n", 00985 spy->type, chan->name); 00986 return -1; 00987 } 00988 00989 if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST) && (spy->read_queue.format != AST_FORMAT_SLINEAR)) { 00990 ast_log(LOG_WARNING, "Cannot provide volume adjustment on '%s' format spies\n", 00991 ast_getformatname(spy->read_queue.format)); 00992 return -1; 00993 } 00994 00995 if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST) && (spy->write_queue.format != AST_FORMAT_SLINEAR)) { 00996 ast_log(LOG_WARNING, "Cannot provide volume adjustment on '%s' format spies\n", 00997 ast_getformatname(spy->write_queue.format)); 00998 return -1; 00999 } 01000 01001 if (ast_test_flag(spy, CHANSPY_MIXAUDIO) && 01002 ((spy->read_queue.format != AST_FORMAT_SLINEAR) || 01003 (spy->write_queue.format != AST_FORMAT_SLINEAR))) { 01004 ast_log(LOG_WARNING, "Cannot provide audio mixing on '%s'-'%s' format spies\n", 01005 ast_getformatname(spy->read_queue.format), ast_getformatname(spy->write_queue.format)); 01006 return -1; 01007 } 01008 01009 if (!chan->spies) { 01010 if (!(chan->spies = calloc(1, sizeof(*chan->spies)))) { 01011 ast_log(LOG_WARNING, "Memory allocation failure\n"); 01012 return -1; 01013 } 01014 01015 AST_LIST_HEAD_INIT_NOLOCK(&chan->spies->list); 01016 AST_LIST_INSERT_HEAD(&chan->spies->list, spy, list); 01017 } else { 01018 AST_LIST_INSERT_TAIL(&chan->spies->list, spy, list); 01019 } 01020 01021 if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) { 01022 ast_cond_init(&spy->trigger, NULL); 01023 ast_set_flag(spy, CHANSPY_TRIGGER_READ); 01024 ast_clear_flag(spy, CHANSPY_TRIGGER_WRITE); 01025 } 01026 01027 ast_log(LOG_DEBUG, "Spy %s added to channel %s\n", 01028 spy->type, chan->name); 01029 01030 return 0; 01031 }
| void ast_channel_spy_free | ( | struct ast_channel_spy * | spy | ) |
Free a spy.
| spy | The spy to free |
Definition at line 1106 of file channel.c.
References ast_cond_destroy(), ast_frfree(), ast_mutex_destroy(), ast_test_flag, CHANSPY_DONE, CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_NONE, ast_channel_spy_queue::head, ast_channel_spy::lock, ast_frame::next, ast_channel_spy::read_queue, ast_channel_spy::status, ast_channel_spy::trigger, and ast_channel_spy::write_queue.
Referenced by channel_spy(), and mixmonitor_thread().
01107 { 01108 struct ast_frame *f = NULL; 01109 01110 if (spy->status == CHANSPY_DONE) 01111 return; 01112 01113 /* Switch status to done in case we get called twice */ 01114 spy->status = CHANSPY_DONE; 01115 01116 /* Drop any frames in the queue */ 01117 for (f = spy->write_queue.head; f; f = spy->write_queue.head) { 01118 spy->write_queue.head = f->next; 01119 ast_frfree(f); 01120 } 01121 for (f = spy->read_queue.head; f; f= spy->read_queue.head) { 01122 spy->read_queue.head = f->next; 01123 ast_frfree(f); 01124 } 01125 01126 /* Destroy the condition if in use */ 01127 if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) 01128 ast_cond_destroy(&spy->trigger); 01129 01130 /* Destroy our mutex since it is no longer in use */ 01131 ast_mutex_destroy(&spy->lock); 01132 01133 return; 01134 }
| struct ast_frame* ast_channel_spy_read_frame | ( | struct ast_channel_spy * | spy, | |
| unsigned int | samples | |||
| ) | [read] |
Read one (or more) frames of audio from a channel being spied upon.
| spy | The spy to operate on | |
| samples | The number of audio samples to read |
Note: This function performs no locking; you must hold the spy's lock before calling this function. You must not hold the channel's lock at the same time.
Definition at line 4014 of file channel.c.
References ast_clear_flag, ast_codec_get_len(), ast_frame_adjust_volume(), ast_frame_slinear_sum(), AST_FRAME_VOICE, ast_frdup(), ast_frfree(), ast_test_flag, CHANSPY_MIXAUDIO, CHANSPY_READ_VOLADJUST, CHANSPY_TRIGGER_FLUSH, CHANSPY_WRITE_VOLADJUST, copy_data_from_queue(), ast_channel_spy_queue::format, ast_frame::frametype, ast_channel_spy_queue::head, ast_frame::next, ast_channel_spy::read_queue, ast_channel_spy::read_vol_adjustment, result, ast_frame::samples, ast_channel_spy_queue::samples, ast_channel_spy::write_queue, and ast_channel_spy::write_vol_adjustment.
Referenced by mixmonitor_thread(), and spy_generate().
04015 { 04016 struct ast_frame *result; 04017 /* buffers are allocated to hold SLINEAR, which is the largest format */ 04018 short read_buf[samples]; 04019 short write_buf[samples]; 04020 struct ast_frame *read_frame; 04021 struct ast_frame *write_frame; 04022 int need_dup; 04023 struct ast_frame stack_read_frame = { .frametype = AST_FRAME_VOICE, 04024 .subclass = spy->read_queue.format, 04025 .data = read_buf, 04026 .samples = samples, 04027 .datalen = ast_codec_get_len(spy->read_queue.format, samples), 04028 }; 04029 struct ast_frame stack_write_frame = { .frametype = AST_FRAME_VOICE, 04030 .subclass = spy->write_queue.format, 04031 .data = write_buf, 04032 .samples = samples, 04033 .datalen = ast_codec_get_len(spy->write_queue.format, samples), 04034 }; 04035 04036 /* if a flush has been requested, dump everything in whichever queue is larger */ 04037 if (ast_test_flag(spy, CHANSPY_TRIGGER_FLUSH)) { 04038 if (spy->read_queue.samples > spy->write_queue.samples) { 04039 if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST)) { 04040 for (result = spy->read_queue.head; result; result = result->next) 04041 ast_frame_adjust_volume(result, spy->read_vol_adjustment); 04042 } 04043 result = spy->read_queue.head; 04044 spy->read_queue.head = NULL; 04045 spy->read_queue.samples = 0; 04046 ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH); 04047 return result; 04048 } else { 04049 if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST)) { 04050 for (result = spy->write_queue.head; result; result = result->next) 04051 ast_frame_adjust_volume(result, spy->write_vol_adjustment); 04052 } 04053 result = spy->write_queue.head; 04054 spy->write_queue.head = NULL; 04055 spy->write_queue.samples = 0; 04056 ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH); 04057 return result; 04058 } 04059 } 04060 04061 if ((spy->read_queue.samples < samples) || (spy->write_queue.samples < samples)) 04062 return NULL; 04063 04064 /* short-circuit if both head frames have exactly what we want */ 04065 if ((spy->read_queue.head->samples == samples) && 04066 (spy->write_queue.head->samples == samples)) { 04067 read_frame = spy->read_queue.head; 04068 spy->read_queue.head = read_frame->next; 04069 read_frame->next = NULL; 04070 04071 write_frame = spy->write_queue.head; 04072 spy->write_queue.head = write_frame->next; 04073 write_frame->next = NULL; 04074 04075 spy->read_queue.samples -= samples; 04076 spy->write_queue.samples -= samples; 04077 04078 need_dup = 0; 04079 } else { 04080 copy_data_from_queue(&spy->read_queue, read_buf, samples); 04081 copy_data_from_queue(&spy->write_queue, write_buf, samples); 04082 04083 read_frame = &stack_read_frame; 04084 write_frame = &stack_write_frame; 04085 need_dup = 1; 04086 } 04087 04088 if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST)) 04089 ast_frame_adjust_volume(read_frame, spy->read_vol_adjustment); 04090 04091 if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST)) 04092 ast_frame_adjust_volume(write_frame, spy->write_vol_adjustment); 04093 04094 if (ast_test_flag(spy, CHANSPY_MIXAUDIO)) { 04095 ast_frame_slinear_sum(read_frame, write_frame); 04096 04097 if (need_dup) 04098 result = ast_frdup(read_frame); 04099 else { 04100 result = read_frame; 04101 ast_frfree(write_frame); 04102 } 04103 } else { 04104 if (need_dup) { 04105 result = ast_frdup(read_frame); 04106 result->next = ast_frdup(write_frame); 04107 } else { 04108 result = read_frame; 04109 result->next = write_frame; 04110 } 04111 } 04112 04113 return result; 04114 }
| void ast_channel_spy_remove | ( | struct ast_channel * | chan, | |
| struct ast_channel_spy * | spy | |||
| ) |
Remove a spy from a channel.
| chan | The channel to remove the spy from | |
| spy | The spy to be removed |
Definition at line 1095 of file channel.c.
References AST_LIST_REMOVE, ast_channel::spies, spy_cleanup(), and spy_detach().
Referenced by channel_spy().
01096 { 01097 if (!chan->spies) 01098 return; 01099 01100 AST_LIST_REMOVE(&chan->spies->list, spy, list); 01101 01102 spy_detach(spy, chan); 01103 spy_cleanup(chan); 01104 }
| void ast_channel_spy_stop_by_type | ( | struct ast_channel * | chan, | |
| const char * | type | |||
| ) |
Find all spies of a particular type on a channel and stop them.
| chan | The channel to operate on | |
| type | A character string identifying the type of spies to be stopped |
Definition at line 1066 of file channel.c.
References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, CHANSPY_RUNNING, ast_channel::spies, spy_cleanup(), spy_detach(), ast_channel_spy::status, and ast_channel_spy::type.
Referenced by mixmonitor_cli().
01067 { 01068 struct ast_channel_spy *spy = NULL; 01069 01070 if (!chan->spies) 01071 return; 01072 01073 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list) { 01074 if ((spy->type == type) && (spy->status == CHANSPY_RUNNING)) { 01075 AST_LIST_REMOVE_CURRENT(&chan->spies->list, list); 01076 spy_detach(spy, chan); 01077 } 01078 } 01079 AST_LIST_TRAVERSE_SAFE_END 01080 spy_cleanup(chan); 01081 }
| void ast_channel_spy_trigger_wait | ( | struct ast_channel_spy * | spy | ) |
Efficiently wait until audio is available for a spy, or an exception occurs.
| spy | The spy to wait on |
Definition at line 1083 of file channel.c.
References ast_cond_timedwait(), ast_tvadd(), ast_channel_spy::lock, and ast_channel_spy::trigger.
Referenced by mixmonitor_thread().
01084 { 01085 struct timeval tv; 01086 struct timespec ts; 01087 01088 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(50000, 1000)); 01089 ts.tv_sec = tv.tv_sec; 01090 ts.tv_nsec = tv.tv_usec * 1000; 01091 01092 ast_cond_timedwait(&spy->trigger, &spy->lock, &ts); 01093 }
| struct ast_silence_generator* ast_channel_start_silence_generator | ( | struct ast_channel * | chan | ) | [read] |
Starts a silence generator on the given channel.
| chan | The channel to generate silence on |
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 4172 of file channel.c.
References ast_activate_generator(), AST_FORMAT_SLINEAR, ast_log(), ast_set_write_format(), calloc, free, LOG_DEBUG, LOG_ERROR, LOG_WARNING, ast_channel::name, ast_silence_generator::old_write_format, option_debug, and ast_channel::writeformat.
Referenced by ast_play_and_record_full(), and record_exec().
04173 { 04174 struct ast_silence_generator *state; 04175 04176 if (!(state = calloc(1, sizeof(*state)))) { 04177 ast_log(LOG_WARNING, "Could not allocate state structure\n"); 04178 return NULL; 04179 } 04180 04181 state->old_write_format = chan->writeformat; 04182 04183 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) { 04184 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n"); 04185 free(state); 04186 return NULL; 04187 } 04188 04189 ast_activate_generator(chan, &silence_generator, state); 04190 04191 if (option_debug) 04192 ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name); 04193 04194 return state; 04195 }
| 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 4197 of file channel.c.
References ast_deactivate_generator(), ast_log(), ast_set_write_format(), free, LOG_DEBUG, LOG_ERROR, ast_channel::name, ast_silence_generator::old_write_format, and option_debug.
Referenced by ast_play_and_record_full(), and record_exec().
04198 { 04199 if (!state) 04200 return; 04201 04202 ast_deactivate_generator(chan); 04203 04204 if (option_debug) 04205 ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name); 04206 04207 if (ast_set_write_format(chan, state->old_write_format) < 0) 04208 ast_log(LOG_ERROR, "Could not return write format to its original state\n"); 04209 04210 free(state); 04211 }
| int ast_channel_supports_html | ( | struct ast_channel * | channel | ) |
Checks for HTML support on a channel
Returns 0 if channel does not support HTML or non-zero if it does
Definition at line 2746 of file channel.c.
References ast_channel_tech::send_html, and ast_channel::tech.
Referenced by dial_exec_full(), sendurl_exec(), and try_calling().
| void ast_channel_undefer_dtmf | ( | struct ast_channel * | chan | ) |
Undeos a defer
Undo defer. ast_read will return any dtmf characters that were queued
Definition at line 705 of file channel.c.
References ast_clear_flag, and AST_FLAG_DEFER_DTMF.
Referenced by __adsi_transmit_messages(), find_cache(), and rpt_call().
00706 { 00707 if (chan) 00708 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF); 00709 }
| 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 354 of file channel.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), backends, free, last, LOG_DEBUG, chanlist::next, option_debug, option_verbose, chanlist::tech, ast_channel_tech::type, and VERBOSE_PREFIX_2.
Referenced by __unload_module(), and unload_module().
00355 { 00356 struct chanlist *chan, *last=NULL; 00357 00358 if (option_debug && tech && tech->type ) 00359 ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type); 00360 else if (option_debug) 00361 ast_log(LOG_DEBUG, "Unregistering channel, tech is NULL!!!\n"); 00362 00363 00364 ast_mutex_lock(&chlock); 00365 00366 chan = backends; 00367 while (chan) { 00368 if (chan->tech == tech) { 00369 if (last) 00370 last->next = chan->next; 00371 else 00372 backends = backends->next; 00373 free(chan); 00374 ast_mutex_unlock(&chlock); 00375 00376 if (option_verbose > 1) 00377 ast_verbose( VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type); 00378 00379 return; 00380 } 00381 last = chan; 00382 chan = chan->next; 00383 } 00384 00385 ast_mutex_unlock(&chlock); 00386 }
| struct ast_channel* ast_channel_walk_locked | ( | const struct ast_channel * | prev | ) | [read] |
Browse channels in use
| prev | where you want to start in the channel list Browse the channels currently in use Returns the next channel in the list, NULL on end. If it returns a channel, that channel *has been locked*! |
Definition at line 802 of file channel.c.
References channel_find_locked().
Referenced by action_status(), ast_pickup_call(), complete_ch_helper(), conf_exec(), handle_chanlist(), handle_debugchan(), handle_nodebugchan(), local_channel_walk(), moh_on_off(), and softhangup_exec().
00803 { 00804 return channel_find_locked(prev, NULL, 0, NULL, NULL); 00805 }
| void ast_channels_init | ( | void | ) |
Definition at line 3944 of file channel.c.
References ast_cli_register(), and cli_show_channeltypes.
Referenced by main().
03945 { 03946 ast_cli_register(&cli_show_channeltypes); 03947 }
| 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 203 of file channel.c.
References ast_channel::_softhangup, AST_SOFTHANGUP_TIMEOUT, ast_channel::tech_pvt, and ast_channel::whentohangup.
Referenced by action_redirect(), app_exec(), ast_answer(), ast_call(), ast_cdr_update(), ast_channel_bridge(), ast_check_hangup_locked(), ast_feature_request_and_dial(), ast_indicate(), ast_read(), ast_readstring(), ast_readstring_full(), ast_recvtext(), ast_rtp_bridge(), ast_sendtext(), ast_transfer(), ast_waitfordigit(), ast_waitfordigit_full(), ast_write(), builtin_atxfer(), channel_spy(), chanspy_exec(), conf_run(), handle_sendimage(), iax2_bridge(), pbx_exec(), rpt(), rpt_exec(), vpb_bridge(), wait_for_answer(), zt_sendtext(), and zt_setoption().
00204 { 00205 time_t myt; 00206 00207 /* if soft hangup flag, return true */ 00208 if (chan->_softhangup) 00209 return 1; 00210 /* if no technology private data, return true */ 00211 if (!chan->tech_pvt) 00212 return 1; 00213 /* if no hangup scheduled, just return here */ 00214 if (!chan->whentohangup) 00215 return 0; 00216 time(&myt); /* get current time */ 00217 /* return, if not yet */ 00218 if (chan->whentohangup > myt) 00219 return 0; 00220 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 00221 return 1; 00222 }
| static int ast_check_hangup_locked | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 224 of file channel.c.
References ast_check_hangup(), ast_mutex_lock(), ast_mutex_unlock(), and ast_channel::lock.
Referenced by ast_channel_bridge().
00225 { 00226 int res; 00227 ast_mutex_lock(&chan->lock); 00228 res = ast_check_hangup(chan); 00229 ast_mutex_unlock(&chan->lock); 00230 return res; 00231 }
| void ast_deactivate_generator | ( | struct ast_channel * | chan | ) |
Deactive an active generator
Definition at line 1443 of file channel.c.
References ast_clear_flag, AST_FLAG_WRITE_INT, ast_mutex_lock(), ast_mutex_unlock(), ast_settimeout(), ast_channel::generator, ast_channel::generatordata, ast_channel::lock, and ast_generator::release.
Referenced by app_exec(), ast_channel_stop_silence_generator(), ast_openstream_full(), ast_playtones_stop(), ast_quiet_chan(), ast_read(), ast_tonepair_stop(), ast_write(), cb_events(), channel_spy(), dial_exec_full(), generator_force(), local_ast_moh_stop(), milliwatt_exec(), moh_on_off(), and wait_for_answer().
01444 { 01445 ast_mutex_lock(&chan->lock); 01446 if (chan->generatordata) { 01447 if (chan->generator && chan->generator->release) 01448 chan->generator->release(chan, chan->generatordata); 01449 chan->generatordata = NULL; 01450 chan->generator = NULL; 01451 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 01452 ast_settimeout(chan, 0, NULL, NULL); 01453 } 01454 ast_mutex_unlock(&chan->lock); 01455 }
| int ast_do_masquerade | ( | struct ast_channel * | chan | ) |
Start masquerading a channel XXX This is a seriously wacked 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.
| chan | Channel to masquerade |
Definition at line 2964 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_copy_flags, AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FLAG_ZOMBIE, AST_FRAME_NULL, AST_LIST_TRAVERSE, ast_log(), AST_MAX_FDS, ast_mutex_lock(), ast_mutex_unlock(), ast_queue_frame(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_channel::blocker, ast_channel_spy::chan, ast_channel::cid, clone_variables(), EVENT_FLAG_CALL, ast_channel::fdno, ast_channel::fds, ast_channel_tech::fixup, free_translation(), ast_channel_tech::hangup, ast_channel::hangupcause, ast_channel::language, ast_channel_spy::lock, ast_channel::lock, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::musicclass, ast_channel::name, ast_channel::nativeformats, ast_frame::next, option_debug, ast_frame::prev, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::readq, ast_channel::spies, t, ast_channel::tech, ast_channel::tech_pvt, ast_channel::timingfd, ast_channel::type, ast_channel::uniqueid, and ast_channel::writeformat.
Referenced by ast_async_goto(), ast_hangup(), ast_read(), ast_waitfor_nandfds(), ast_write(), iax_park(), sip_park(), and sip_park_thread().
02965 { 02966 int x,i; 02967 int res=0; 02968 int origstate; 02969 struct ast_frame *cur, *prev; 02970 const struct ast_channel_tech *t; 02971 void *t_pvt; 02972 struct ast_callerid tmpcid; 02973 struct ast_channel *clone = original->masq; 02974 struct ast_channel_spy_list *spy_list; 02975 struct ast_channel_spy *spy = NULL; 02976 int rformat = original->readformat; 02977 int wformat = original->writeformat; 02978 char newn[100]; 02979 char orig[100]; 02980 char masqn[100]; 02981 char zombn[100]; 02982 02983 if (option_debug > 3) 02984 ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", 02985 clone->name, clone->_state, original->name, original->_state); 02986 02987 /* XXX This is a seriously wacked out operation. We're essentially putting the guts of 02988 the clone channel into the original channel. Start by killing off the original 02989 channel's backend. I'm not sure we're going to keep this function, because 02990 while the features are nice, the cost is very high in terms of pure nastiness. XXX */ 02991 02992 /* We need the clone's lock, too */ 02993 ast_mutex_lock(&clone->lock); 02994 02995 ast_log(LOG_DEBUG, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock); 02996 02997 /* Having remembered the original read/write formats, we turn off any translation on either 02998 one */ 02999 free_translation(clone); 03000 free_translation(original); 03001 03002 03003 /* Unlink the masquerade */ 03004 original->masq = NULL; 03005 clone->masqr = NULL; 03006 03007 /* Save the original name */ 03008 ast_copy_string(orig, original->name, sizeof(orig)); 03009 /* Save the new name */ 03010 ast_copy_string(newn, clone->name, sizeof(newn)); 03011 /* Create the masq name */ 03012 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn); 03013 03014 /* Copy the name from the clone channel */ 03015 ast_copy_string(original->name, newn, sizeof(original->name)); 03016 03017 /* Mangle the name of the clone channel */ 03018 ast_copy_string(clone->name, masqn, sizeof(clone->name)); 03019 03020 /* Notify any managers of the change, first the masq then the other */ 03021 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid); 03022 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid); 03023 03024 /* Swap the technlogies */ 03025 t = original->tech; 03026 original->tech = clone->tech; 03027 clone->tech = t; 03028 03029 t_pvt = original->tech_pvt; 03030 original->tech_pvt = clone->tech_pvt; 03031 clone->tech_pvt = t_pvt; 03032 03033 /* Swap the readq's */ 03034 cur = original->readq; 03035 original->readq = clone->readq; 03036 clone->readq = cur; 03037 03038 /* Swap the alertpipes */ 03039 for (i = 0; i < 2; i++) { 03040 x = original->alertpipe[i]; 03041 original->alertpipe[i] = clone->alertpipe[i]; 03042 clone->alertpipe[i] = x; 03043 } 03044 03045 /* Swap the raw formats */ 03046 x = original->rawreadformat; 03047 original->rawreadformat = clone->rawreadformat; 03048 clone->rawreadformat = x; 03049 x = original->rawwriteformat; 03050 original->rawwriteformat = clone->rawwriteformat; 03051 clone->rawwriteformat = x; 03052 03053 /* Swap the spies */ 03054 spy_list = original->spies; 03055 original->spies = clone->spies; 03056 clone->spies = spy_list; 03057 03058 /* Update channel on respective spy lists if present */ 03059 if (original->spies) { 03060 AST_LIST_TRAVERSE(&original->spies->list, spy, list) { 03061 ast_mutex_lock(&spy->lock); 03062 spy->chan = original; 03063 ast_mutex_unlock(&spy->lock); 03064 } 03065 } 03066 if (clone->spies) { 03067 AST_LIST_TRAVERSE(&clone->spies->list, spy, list) { 03068 ast_mutex_lock(&spy->lock); 03069 spy->chan = clone; 03070 ast_mutex_unlock(&spy->lock); 03071 } 03072 } 03073 03074 /* Save any pending frames on both sides. Start by counting 03075 * how many we're going to need... */ 03076 prev = NULL; 03077 cur = clone->readq; 03078 x = 0; 03079 while(cur) { 03080 x++; 03081 prev = cur; 03082 cur = cur->next; 03083 } 03084 /* If we had any, prepend them to the ones already in the queue, and 03085 * load up the alertpipe */ 03086 if (prev) { 03087 prev->next = original->readq; 03088 original->readq = clone->readq; 03089 clone->readq = NULL; 03090 if (original->alertpipe[1] > -1) { 03091 for (i = 0; i < x; i++) 03092 write(original->alertpipe[1], &x, sizeof(x)); 03093 } 03094 } 03095 clone->_softhangup = AST_SOFTHANGUP_DEV; 03096 03097 03098 /* And of course, so does our current state. Note we need not 03099 call ast_setstate since the event manager doesn't really consider 03100 these separate. We do this early so that the clone has the proper 03101 state of the original channel. */ 03102 origstate = original->_state; 03103 original->_state = clone->_state; 03104 clone->_state = origstate; 03105 03106 if (clone->tech->fixup){ 03107 res = clone->tech->fixup(original, clone); 03108 if (res) 03109 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name); 03110 } 03111 03112 /* Start by disconnecting the original's physical side */ 03113 if (clone->tech->hangup) 03114 res = clone->tech->hangup(clone); 03115 if (res) { 03116 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n"); 03117 ast_mutex_unlock(&clone->lock); 03118 return -1; 03119 } 03120 03121 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); 03122 /* Mangle the name of the clone channel */ 03123 ast_copy_string(clone->name, zombn, sizeof(clone->name)); 03124 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid); 03125 03126 /* Update the type. */ 03127 original->type = clone->type; 03128 t_pvt = original->monitor; 03129 original->monitor = clone->monitor; 03130 clone->monitor = t_pvt; 03131 03132 /* Keep the same language. */ 03133 ast_copy_string(original->language, clone->language, sizeof(original->language)); 03134 /* Copy the FD's */ 03135 for (x = 0; x < AST_MAX_FDS; x++) { 03136 original->fds[x] = clone->fds[x]; 03137 } 03138 /* Drop group from original */ 03139 ast_app_group_update(clone, original); 03140 clone_variables(original, clone); 03141 /* Presense of ADSI capable CPE follows clone */ 03142 original->adsicpe = clone->adsicpe; 03143 /* Bridge remains the same */ 03144 /* CDR fields remain the same */ 03145 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 03146 /* Application and data remain the same */ 03147 /* Clone exception becomes real one, as with fdno */ 03148 ast_copy_flags(original, clone, AST_FLAG_EXCEPTION); 03149 original->fdno = clone->fdno; 03150 /* Schedule context remains the same */ 03151 /* Stream stuff stays the same */ 03152 /* Keep the original state. The fixup code will need to work with it most likely */ 03153 03154 /* Just swap the whole structures, nevermind the allocations, they'll work themselves 03155 out. */ 03156 tmpcid = original->cid; 03157 original->cid = clone->cid; 03158 clone->cid = tmpcid; 03159 03160 /* Restore original timing file descriptor */ 03161 original->fds[AST_MAX_FDS - 2] = original->timingfd; 03162 03163 /* Our native formats are different now */ 03164 original->nativeformats = clone->nativeformats; 03165 03166 /* Context, extension, priority, app data, jump table, remain the same */ 03167 /* pvt switches. pbx stays the same, as does next */ 03168 03169 /* Set the write format */ 03170 ast_set_write_format(original, wformat); 03171 03172 /* Set the read format */ 03173 ast_set_read_format(original, rformat); 03174 03175 /* Copy the music class */ 03176 ast_copy_string(original->musicclass, clone->musicclass, sizeof(original->musicclass)); 03177 03178 ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat); 03179 03180 /* Okay. Last thing is to let the channel driver know about all this mess, so he 03181 can fix up everything as best as possible */ 03182 if (original->tech->fixup) { 03183 res = original->tech->fixup(clone, original); 03184 if (res) { 03185 ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n", 03186 original->type, original->name); 03187 ast_mutex_unlock(&clone->lock); 03188 return -1; 03189 } 03190 } else 03191 ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)! Bad things may happen.\n", 03192 original->type, original->name); 03193 03194 /* Now, at this point, the "clone" channel is totally F'd up. We mark it as 03195 a zombie so nothing tries to touch it. If it's already been marked as a 03196 zombie, then free it now (since it already is considered invalid). */ 03197 if (ast_test_flag(clone, AST_FLAG_ZOMBIE)) { 03198 ast_log(LOG_DEBUG, "Destroying channel clone '%s'\n", clone->name); 03199 ast_mutex_unlock(&clone->lock); 03200 manager_event(EVENT_FLAG_CALL, "Hangup", 03201 "Channel: %s\r\n" 03202 "Uniqueid: %s\r\n" 03203 "Cause: %d\r\n" 03204 "Cause-txt: %s\r\n", 03205 clone->name, 03206 clone->uniqueid, 03207 clone->hangupcause, 03208 ast_cause2str(clone->hangupcause) 03209 ); 03210 ast_channel_free(clone); 03211 } else { 03212 struct ast_frame null_frame = { AST_FRAME_NULL, }; 03213 ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name); 03214 ast_set_flag(clone, AST_FLAG_ZOMBIE); 03215 ast_queue_frame(clone, &null_frame); 03216 ast_mutex_unlock(&clone->lock); 03217 } 03218 03219 /* Signal any blocker */ 03220 if (ast_test_flag(original, AST_FLAG_BLOCKING)) 03221 pthread_kill(original->blocker, SIGURG); 03222 ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n", original->name, original->_state); 03223 return 0; 03224 }
| 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 3342 of file channel.c.
References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_HTML, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree(), ast_indicate(), ast_log(), ast_read(), AST_SOFTHANGUP_UNBRIDGE, ast_waitfor_n(), ast_write(), ast_bridge_config::flags, ast_frame::frametype, last, LOG_DEBUG, ast_channel::name, ast_channel::nativeformats, ast_frame::subclass, ast_channel::tech_pvt, and ast_bridge_config::timelimit.
Referenced by ast_channel_bridge().
03345 { 03346 /* Copy voice back and forth between the two channels. */ 03347 struct ast_channel *cs[3]; 03348 struct ast_frame *f; 03349 struct ast_channel *who = NULL; 03350 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 03351 int o0nativeformats; 03352 int o1nativeformats; 03353 int watch_c0_dtmf; 03354 int watch_c1_dtmf; 03355 void *pvt0, *pvt1; 03356 int to; 03357 03358 cs[0] = c0; 03359 cs[1] = c1; 03360 pvt0 = c0->tech_pvt; 03361 pvt1 = c1->tech_pvt; 03362 o0nativeformats = c0->nativeformats; 03363 o1nativeformats = c1->nativeformats; 03364 watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0; 03365 watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1; 03366 03367 for (;;) { 03368 if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) || 03369 (o0nativeformats != c0->nativeformats) || 03370 (o1nativeformats != c1->nativeformats)) { 03371 /* Check for Masquerade, codec changes, etc */ 03372 res = AST_BRIDGE_RETRY; 03373 break; 03374 } 03375 if (bridge_end.tv_sec) { 03376 to = ast_tvdiff_ms(bridge_end, ast_tvnow()); 03377 if (to <= 0) { 03378 if (config->timelimit) 03379 res = AST_BRIDGE_RETRY; 03380 else 03381 res = AST_BRIDGE_COMPLETE; 03382 break; 03383 } 03384 } else 03385 to = -1; 03386 who = ast_waitfor_n(cs, 2, &to); 03387 if (!who) { 03388 ast_log(LOG_DEBUG, "Nobody there, continuing...\n"); 03389 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) { 03390 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03391 c0->_softhangup = 0; 03392 if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03393 c1->_softhangup = 0; 03394 c0->_bridge = c1; 03395 c1->_bridge = c0; 03396 } 03397 continue; 03398 } 03399 f = ast_read(who); 03400 if (!f) { 03401 *fo = NULL; 03402 *rc = who; 03403 res = AST_BRIDGE_COMPLETE; 03404 ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name); 03405 break; 03406 } 03407 03408 if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) { 03409 if ((f->subclass == AST_CONTROL_HOLD) || (f->subclass == AST_CONTROL_UNHOLD) || 03410 (f->subclass == AST_CONTROL_VIDUPDATE)) { 03411 ast_indicate(who == c0 ? c1 : c0, f->subclass); 03412 } else { 03413 *fo = f; 03414 *rc = who; 03415 res = AST_BRIDGE_COMPLETE; 03416 ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name); 03417 break; 03418 } 03419 } 03420 if ((f->frametype == AST_FRAME_VOICE) || 03421 (f->frametype == AST_FRAME_DTMF) || 03422 (f->frametype == AST_FRAME_VIDEO) || 03423 (f->frametype == AST_FRAME_IMAGE) || 03424 (f->frametype == AST_FRAME_HTML) || 03425 (f->frametype == AST_FRAME_TEXT)) { 03426 if (f->frametype == AST_FRAME_DTMF) { 03427 if (((who == c0) && watch_c0_dtmf) || 03428 ((who == c1) && watch_c1_dtmf)) { 03429 *rc = who; 03430 *fo = f; 03431 res = AST_BRIDGE_COMPLETE; 03432 ast_log(LOG_DEBUG, "Got DTMF on channel (%s)\n", who->name); 03433 break; 03434 } else { 03435 goto tackygoto; 03436 } 03437 } else { 03438 #if 0 03439 ast_log(LOG_DEBUG, "Read from %s\n", who->name); 03440 if (who == last) 03441 ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name); 03442 last = who; 03443 #endif 03444 tackygoto: 03445 ast_write((who == c0) ? c1 : c0, f); 03446 } 03447 } 03448 ast_frfree(f); 03449 03450 /* Swap who gets priority */ 03451 cs[2] = cs[0]; 03452 cs[0] = cs[1]; 03453 cs[1] = cs[2]; 03454 } 03455 return res; 03456 }
| struct ast_channel* ast_get_channel_by_exten_locked | ( | const char * | exten, | |
| const char * | context | |||
| ) | [read] |
Definition at line 826 of file channel.c.
References channel_find_locked().
Referenced by pickup_exec().
00827 { 00828 return channel_find_locked(NULL, NULL, 0, context, exten); 00829 }
| struct ast_channel* ast_get_channel_by_name_locked | ( | const char * | chan | ) | [read] |
Get channel by name (locks channel)
Definition at line 808 of file channel.c.
References channel_find_locked().
Referenced by action_getvar(), action_hangup(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), ast_async_goto_by_name(), change_monitor_action(), get_zap_channel_locked(), handle_channelstatus(), handle_debugchan(), handle_getvariablefull(), handle_hangup(), handle_nodebugchan(), handle_showchan(), handle_softhangup(), pbx_builtin_importvar(), pickup_exec(), start_monitor_action(), and stop_monitor_action().
00809 { 00810 return channel_find_locked(NULL, name, 0, NULL, NULL); 00811 }
| struct ast_channel* ast_get_channel_by_name_prefix_locked | ( | const char * | name, | |
| const int | namelen | |||
| ) | [read] |
Get channel by name prefix (locks channel)
Definition at line 814 of file channel.c.
References channel_find_locked().
Referenced by ast_parse_device_state(), and mixmonitor_cli().
00815 { 00816 return channel_find_locked(NULL, name, namelen, NULL, NULL); 00817 }
| struct ast_channel_tech* ast_get_channel_tech | ( | const char * | name | ) | [read] |
Get a channel technology structure by name.
| name | name of technology to find |
Definition at line 388 of file channel.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), backends, LOG_WARNING, chanlist::next, chanlist::tech, and ast_channel_tech::type.
Referenced by ast_device_state().
00389 { 00390 struct chanlist *chanls; 00391 00392 if (ast_mutex_lock(&chlock)) { 00393 ast_log(LOG_WARNING, "Unable to lock channel tech list\n"); 00394 return NULL; 00395 } 00396 00397 for (chanls = backends; chanls; chanls = chanls->next) { 00398 if (strcasecmp(name, chanls->tech->type)) 00399 continue; 00400 00401 ast_mutex_unlock(&chlock); 00402 return chanls->tech; 00403 } 00404 00405 ast_mutex_unlock(&chlock); 00406 return NULL; 00407 }
| ast_group_t ast_get_group | ( | char * | s | ) |
Definition at line 3862 of file channel.c.
References ast_log(), ast_strdupa, copy(), group, LOG_ERROR, LOG_WARNING, and strsep().
Referenced by _parse(), build_device(), build_gateway(), build_peer(), build_user(), load_module(), read_agent_config(), and setup_zap().
03863 { 03864 char *copy; 03865 char *piece; 03866 char *c=NULL; 03867 int start=0, finish=0, x; 03868 ast_group_t group = 0; 03869 03870 copy = ast_strdupa(s); 03871 if (!copy) { 03872 ast_log(LOG_ERROR, "Out of memory\n"); 03873 return 0; 03874 } 03875 c = copy; 03876 03877 while((piece = strsep(&c, ","))) { 03878 if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) { 03879 /* Range */ 03880 } else if (sscanf(piece, "%30d", &start)) { 03881 /* Just one */ 03882 finish = start; 03883 } else { 03884 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece); 03885 continue; 03886 } 03887 for (x = start; x <= finish; x++) { 03888 if ((x > 63) || (x < 0)) { 03889 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x); 03890 } else 03891 group |= ((ast_group_t) 1 << x); 03892 } 03893 } 03894 return group; 03895 }
| int ast_hangup | ( | struct ast_channel * | chan | ) |
Hang up a channel.
| chan | channel to hang up |
Definition at line 1323 of file channel.c.
References ast_cause2str(), ast_cdr_detach(), ast_cdr_end(), ast_channel_free(), ast_closestream(), ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_channel::blocker, ast_channel::blockproc, ast_channel::cdr, CRASH, detach_spies(), EVENT_FLAG_CALL, free_translation(), ast_channel::generator, ast_channel::generatordata, ast_channel_tech::hangup, ast_channel::hangupcause, ast_channel::lock, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::name, option_debug, ast_generator::release, ast_channel::sched, sched_context_destroy(), ast_channel::stream, ast_channel::tech, ast_channel::uniqueid, and ast_channel::vstream.
Referenced by __ast_pbx_run(), __ast_request_and_dial(), __oh323_new(), agent_hangup(), agent_read(), alsa_new(), ast_async_goto(), ast_bridge_call_thread(), ast_feature_request_and_dial(), ast_iax2_new(), ast_modem_new(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run_app(), async_wait(), build_conf(), builtin_atxfer(), chanavail_exec(), check_goto_on_transfer(), conf_free(), dial_exec_full(), do_parking_thread(), features_hangup(), function_ilink(), handle_hd_hf(), handle_init_event(), handle_message(), handle_request_invite(), hangup_chan(), hangupcalls(), hanguptree(), iax2_request(), iax_park(), iax_park_thread(), local_hangup(), mgcp_new(), mgcp_ss(), nbs_new(), oss_new(), park_exec(), parkandannounce_exec(), phone_new(), ring_entry(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), sip_new(), sip_park(), sip_park_thread(), skinny_new(), skinny_ss(), ss_thread(), try_calling(), vpb_new(), wait_for_answer(), zt_handle_event(), and zt_new().
01324 { 01325 int res = 0; 01326 struct ast_cdr *cdr = NULL; 01327 01328 /* Don't actually hang up a channel that will masquerade as someone else, or 01329 if someone is going to masquerade as us */ 01330 ast_mutex_lock(&chan->lock); 01331 01332 detach_spies(chan); /* get rid of spies */ 01333 01334 if (chan->masq) { 01335 if (ast_do_masquerade(chan)) 01336 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01337 } 01338 01339 if (chan->masq) { 01340 ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name); 01341 ast_mutex_unlock(&chan->lock); 01342 return 0; 01343 } 01344 /* If this channel is one which will be masqueraded into something, 01345 mark it as a zombie already, so we know to free it later */ 01346 if (chan->masqr) { 01347 ast_set_flag(chan, AST_FLAG_ZOMBIE); 01348 ast_mutex_unlock(&chan->lock); 01349 return 0; 01350 } 01351 free_translation(chan); 01352 /* Close audio stream */ 01353 if (chan->stream) { 01354 ast_closestream(chan->stream); 01355 chan->stream = NULL; 01356 } 01357 /* Close video stream */ 01358 if (chan->vstream) { 01359 ast_closestream(chan->vstream); 01360 chan->vstream = NULL; 01361 } 01362 if (chan->sched) { 01363 sched_context_destroy(chan->sched); 01364 chan->sched = NULL; 01365 } 01366 01367 if (chan->generatordata) /* Clear any tone stuff remaining */ 01368 chan->generator->release(chan, chan->generatordata); 01369 chan->generatordata = NULL; 01370 chan->generator = NULL; 01371 if (chan->cdr) { /* End the CDR if it hasn't already */ 01372 ast_cdr_end(chan->cdr); 01373 cdr = chan->cdr; 01374 chan->cdr = NULL; 01375 } 01376 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 01377 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 01378 "is blocked by thread %ld in procedure %s! Expect a failure\n", 01379 (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 01380 CRASH; 01381 } 01382 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) { 01383 if (option_debug) 01384 ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name); 01385 if (chan->tech->hangup) 01386 res = chan->tech->hangup(chan); 01387 } else { 01388 if (option_debug) 01389 ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name); 01390 } 01391 01392 ast_mutex_unlock(&chan->lock); 01393 manager_event(EVENT_FLAG_CALL, "Hangup", 01394 "Channel: %s\r\n" 01395 "Uniqueid: %s\r\n" 01396 "Cause: %d\r\n" 01397 "Cause-txt: %s\r\n", 01398 chan->name, 01399 chan->uniqueid, 01400 chan->hangupcause, 01401 ast_cause2str(chan->hangupcause) 01402 ); 01403 ast_channel_free(chan); 01404 01405 /* Defer CDR processing until later */ 01406 if (cdr) 01407 ast_cdr_detach(cdr); 01408 01409 return res; 01410 }
| 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 2073 of file channel.c.
References ast_check_hangup(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_FLAG_ZOMBIE, ast_get_indication_tone(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_playtones_start(), ast_playtones_stop(), ast_test_flag, tone_zone_sound::data, ast_channel_tech::indicate, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_channel::tech, and ast_channel::zone.
Referenced by ast_bridge_call(), ast_feature_request_and_dial(), ast_generic_bridge(), ast_park_call(), ast_play_and_record_full(), ast_rtp_bridge(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), conf_run(), dial_exec_full(), disa_exec(), do_parking_thread(), features_indicate(), function_remote(), handle_recordfile(), handle_remote_data(), handle_remote_phone_dtmf(), mgcp_ss(), park_exec(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_progress(), pbx_builtin_ringing(), queue_exec(), record_exec(), rmt_telem_finish(), rmt_telem_start(), rpt(), rpt_exec(), send_waveform_to_channel(), skinny_ss(), vpb_fixup(), and wait_for_answer().
02074 { 02075 int res = -1; 02076 02077 ast_mutex_lock(&chan->lock); 02078 /* Stop if we're a zombie or need a soft hangup */ 02079 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02080 ast_mutex_unlock(&chan->lock); 02081 return -1; 02082 } 02083 if (chan->tech->indicate) 02084 res = chan->tech->indicate(chan, condition); 02085 ast_mutex_unlock(&chan->lock); 02086 if (!chan->tech->indicate || res) { 02087 /* 02088 * Device does not support (that) indication, lets fake 02089 * it by doing our own tone generation. (PM2002) 02090 */ 02091 if (condition >= 0) { 02092 const struct tone_zone_sound *ts = NULL; 02093 switch (condition) { 02094 case AST_CONTROL_RINGING: 02095 ts = ast_get_indication_tone(chan->zone, "ring"); 02096 break; 02097 case AST_CONTROL_BUSY: 02098 ts = ast_get_indication_tone(chan->zone, "busy"); 02099 break; 02100 case AST_CONTROL_CONGESTION: 02101 ts = ast_get_indication_tone(chan->zone, "congestion"); 02102 break; 02103 } 02104 if (ts && ts->data[0]) { 02105 ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition); 02106 ast_playtones_start(chan,0,ts->data, 1); 02107 res = 0; 02108 } else if (condition == AST_CONTROL_PROGRESS) { 02109 /* ast_playtones_stop(chan); */ 02110 } else if (condition == AST_CONTROL_PROCEEDING) { 02111 /* Do nothing, really */ 02112 } else if (condition == AST_CONTROL_HOLD) { 02113 /* Do nothing.... */ 02114 } else if (condition == AST_CONTROL_UNHOLD) { 02115 /* Do nothing.... */ 02116 } else if (condition == AST_CONTROL_VIDUPDATE) { 02117 /* Do nothing.... */ 02118 } else { 02119 /* not handled */ 02120 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); 02121 res = -1; 02122 } 02123 } 02124 else ast_playtones_stop(chan); 02125 } 02126 return res; 02127 }
| void ast_install_music_functions | ( | int(*)(struct ast_channel *, char *) | start_ptr, | |
| void(*)(struct ast_channel *) | stop_ptr, | |||
| void(*)(struct ast_channel *) | cleanup_ptr | |||
| ) |
Definition at line 3902 of file channel.c.
References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.
Referenced by load_module(), and reload().
03906 { 03907 ast_moh_start_ptr = start_ptr; 03908 ast_moh_stop_ptr = stop_ptr; 03909 ast_moh_cleanup_ptr = cleanup_ptr; 03910 }
| void ast_moh_cleanup | ( | struct ast_channel * | chan | ) |
Definition at line 3938 of file channel.c.
References ast_moh_cleanup_ptr.
Referenced by ast_channel_free().
03939 { 03940 if(ast_moh_cleanup_ptr) 03941 ast_moh_cleanup_ptr(chan); 03942 }
| int ast_moh_start | ( | struct ast_channel * | chan, | |
| char * | mclass | |||
| ) |
Turn on music on hold on a given channel
Definition at line 3920 of file channel.c.
References ast_moh_start_ptr, ast_verbose(), option_verbose, and VERBOSE_PREFIX_3.
Referenced by __login_exec(), agent_hangup(), ast_park_call(), builtin_atxfer(), builtin_blindtransfer(), cb_events(), conf_run(), dial_exec_full(), do_parking_thread(), handle_request(), handle_setmusic(), moh0_exec(), moh1_exec(), moh3_exec(), pbx_builtin_waitexten(), process_sdp(), queue_exec(), retrydial_exec(), say_periodic_announcement(), say_position(), socket_read(), zt_handle_event(), and zt_hangup().
03921 { 03922 if (ast_moh_start_ptr) 03923 return ast_moh_start_ptr(chan, mclass); 03924 03925 if (option_verbose > 2) 03926 ast_verbose(VERBOSE_PREFIX_3 "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : "default"); 03927 03928 return 0; 03929 }
| void ast_moh_stop | ( | struct ast_channel * | chan | ) |
Turn off music on hold on a given channel
Definition at line 3932 of file channel.c.
References ast_moh_stop_ptr.
Referenced by __zt_exception(), agent_new(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), cb_events(), conf_run(), dial_exec_full(), do_parking_thread(), handle_hd_hf(), handle_request(), handle_request_bye(), handle_request_refer(), handle_setmusic(), misdn_transfer_bc(), moh0_exec(), moh1_exec(), moh4_exec(), park_exec(), pbx_builtin_waitexten(), process_sdp(), queue_exec(), retrydial_exec(), say_periodic_announcement(), say_position(), socket_read(), ss_thread(), try_calling(), zt_handle_event(), and zt_hangup().
03933 { 03934 if(ast_moh_stop_ptr) 03935 ast_moh_stop_ptr(chan); 03936 }
| AST_MUTEX_DEFINE_STATIC | ( | chlock | ) |
| AST_MUTEX_DEFINE_STATIC | ( | uniquelock | ) |
| char* ast_print_group | ( | char * | buf, | |
| int | buflen, | |||
| ast_group_t | group | |||
| ) |
Definition at line 3950 of file channel.c.
Referenced by ast_serialize_showchan(), misdn_cfg_get_config_string(), print_group(), and read_config().
03951 { 03952 unsigned int i; 03953 int first=1; 03954 char num[3]; 03955 03956 buf[0] = '\0'; 03957 03958 if (!group) /* Return empty string if no group */ 03959 return(buf); 03960 03961 for (i=0; i<=63; i++) { /* Max group is 63 */ 03962 if (group & ((ast_group_t) 1 << i)) { 03963 if (!first) { 03964 strncat(buf, ", ", buflen); 03965 } else { 03966 first=0; 03967 } 03968 snprintf(num, sizeof(num), "%u", i); 03969 strncat(buf, num, buflen); 03970 } 03971 } 03972 return(buf); 03973 }
| int ast_prod | ( | struct ast_channel * | chan | ) |
Definition at line 2229 of file channel.c.
References ast_channel::_state, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), AST_STATE_UP, ast_write(), ast_frame::data, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_channel::rawwriteformat, ast_frame::src, and ast_frame::subclass.
Referenced by ast_activate_generator().
02230 { 02231 struct ast_frame a = { AST_FRAME_VOICE }; 02232 char nothing[128]; 02233 02234 /* Send an empty audio frame to get things moving */ 02235 if (chan->_state != AST_STATE_UP) { 02236 ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name); 02237 a.subclass = chan->rawwriteformat; 02238 a.data = nothing + AST_FRIENDLY_OFFSET; 02239 a.src = "ast_prod"; 02240 if (ast_write(chan, &a)) 02241 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 02242 } 02243 return 0; 02244 }
| int ast_queue_control | ( | struct ast_channel * | chan, | |
| int | control | |||
| ) |
Queue a control frame.
Definition at line 685 of file channel.c.
References AST_FRAME_CONTROL, ast_queue_frame(), and ast_frame::subclass.
Referenced by __oh323_update_info(), ast_pickup_call(), auto_congest(), cb_events(), handle_message(), handle_request_info(), handle_response(), handle_response_invite(), mgcp_call(), nbs_call(), phone_call(), pickup_exec(), send_cause2ast(), setup_rtp_connection(), skinny_call(), update_state(), and vpb_call().
00686 { 00687 struct ast_frame f = { AST_FRAME_CONTROL, }; 00688 f.subclass = control; 00689 return ast_queue_frame(chan, &f); 00690 }
| int ast_queue_frame | ( | struct ast_channel * | chan, | |
| struct ast_frame * | fin | |||
| ) |
Queue an outgoing frame.
Definition at line 614 of file channel.c.
References ast_channel::alertpipe, AST_CONTROL_HANGUP, AST_FLAG_BLOCKING, AST_FRAME_CONTROL, AST_FRAME_VOICE, ast_frdup(), ast_frfree(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_channel::blocker, CRASH, ast_frame::frametype, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_frame::next, ast_frame::prev, ast_channel::readq, ast_frame::subclass, and ast_channel::timingfd.
Referenced by agent_new(), alsa_call(), ast_channel_masquerade(), ast_channel_setwhentohangup(), ast_do_masquerade(), ast_dsp_process(), ast_queue_control(), ast_queue_hangup(), ast_softhangup_nolock(), cb_events(), console_answer(), console_dial(), console_flash(), console_sendtext(), dictate_exec(), do_chanreads(), do_immediate_setup(), handle_message(), handle_request_info(), handle_request_invite(), handle_response_invite(), iax2_queue_frame(), local_queue_frame(), mgcp_queue_frame(), monitor_handle_owned(), oss_call(), process_sdp(), receive_message(), send_digit(), wakeup_sub(), and zap_queue_frame().
00615 { 00616 struct ast_frame *f; 00617 struct ast_frame *prev, *cur; 00618 int blah = 1; 00619 int qlen = 0; 00620 00621 /* Build us a copy and free the original one */ 00622 f = ast_frdup(fin); 00623 if (!f) { 00624 ast_log(LOG_WARNING, "Unable to duplicate frame\n"); 00625 return -1; 00626 } 00627 ast_mutex_lock(&chan->lock); 00628 prev = NULL; 00629 cur = chan->readq; 00630 while(cur) { 00631 if ((cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) { 00632 /* Don't bother actually queueing anything after a hangup */ 00633 ast_frfree(f); 00634 ast_mutex_unlock(&chan->lock); 00635 return 0; 00636 } 00637 prev = cur; 00638 cur = cur->next; 00639 qlen++; 00640 } 00641 /* Allow up to 96 voice frames outstanding, and up to 128 total frames */ 00642 if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen > 128)) { 00643 if (fin->frametype != AST_FRAME_VOICE) { 00644 ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name); 00645 CRASH; 00646 } else { 00647 ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name); 00648 ast_frfree(f); 00649 ast_mutex_unlock(&chan->lock); 00650 return 0; 00651 } 00652 } 00653 if (prev) 00654 prev->next = f; 00655 else 00656 chan->readq = f; 00657 if (chan->alertpipe[1] > -1) { 00658 if (write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah)) 00659 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n", 00660 chan->name, f->frametype, f->subclass, qlen, strerror(errno)); 00661 #ifdef ZAPTEL_OPTIMIZATIONS 00662 } else if (chan->timingfd > -1) { 00663 ioctl(chan->timingfd, ZT_TIMERPING, &blah); 00664 #endif 00665 } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 00666 pthread_kill(chan->blocker, SIGURG); 00667 } 00668 ast_mutex_unlock(&chan->lock); 00669 return 0; 00670 }
| int ast_queue_hangup | ( | struct ast_channel * | chan | ) |
Queue a hangup frame.
Definition at line 673 of file channel.c.
References ast_channel::_softhangup, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), AST_SOFTHANGUP_DEV, and ast_channel::lock.
Referenced by __oh323_update_info(), __sip_autodestruct(), cleanup_connection(), console_hangup(), handle_message(), handle_request_bye(), handle_request_cancel(), handle_request_refer(), handle_response(), handle_response_invite(), hangup_chan(), hangup_connection(), iax2_destroy(), iax2_predestroy(), mgcp_queue_hangup(), misdn_answer(), retrans_pkt(), and zt_handle_event().
00674 { 00675 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP }; 00676 /* Yeah, let's not change a lock-critical value without locking */ 00677 if (!ast_mutex_trylock(&chan->lock)) { 00678 chan->_softhangup |= AST_SOFTHANGUP_DEV; 00679 ast_mutex_unlock(&chan->lock); 00680 } 00681 return ast_queue_frame(chan, &f); 00682 }
| struct ast_frame* ast_read | ( | struct ast_channel * | chan | ) | [read] |
Reads a frame
| chan | channel to read a frame from Read a frame. Returns a frame, or NULL on error. If it returns NULL, you best just stop reading frames and assume the channel has been disconnected. |
Definition at line 1845 of file channel.c.
References ast_channel::_softhangup, ast_channel::_state, ast_channel::alertpipe, ast_cdr_answer(), ast_cdr_end(), ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, ast_deactivate_generator(), ast_do_masquerade(), AST_FLAG_DEFER_DTMF, AST_FLAG_EXCEPTION, AST_FLAG_ZOMBIE, AST_FRAME_CNG, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frame_dump(), AST_FRAME_NULL, AST_FRAME_VOICE, ast_frfree(), ast_getformatname(), ast_log(), AST_MAX_FDS, ast_mutex_lock(), ast_mutex_unlock(), ast_seekstream(), ast_setstate(), ast_settimeout(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_translate(), ast_writestream(), ast_channel::blocker, ast_channel::cdr, ast_frame::data, ast_frame::datalen, ast_channel::dtmff, ast_channel::dtmfq, ast_channel_tech::exception, ast_channel::fdno, ast_channel::fin, ast_frame::frametype, ast_generator::generate, ast_channel::generator, generator_force(), ast_channel::generatordata, ast_channel::insmpl, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::masq, ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, ast_frame::next, ast_channel::outsmpl, queue_frame_to_spies(), ast_channel_tech::read, ast_channel_monitor::read_stream, ast_channel::readq, ast_channel::readtrans, ast_frame::samples, SEEK_FORCECUR, ast_channel::spies, SPY_READ, ast_frame::subclass, ast_channel::tech, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.
Referenced by __adsi_transmit_messages(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), agent_read(), app_exec(), ast_app_getvoice(), ast_feature_request_and_dial(), ast_generic_bridge(), ast_masq_park_call(), ast_play_and_prepend(), ast_play_and_record_full(), ast_recvtext(), ast_rtp_bridge(), ast_safe_sleep(), ast_safe_sleep_conditional(), ast_tonepair(), ast_waitfordigit(), ast_waitfordigit_full(), ast_waitstream(), ast_waitstream_exten(), ast_waitstream_fr(), ast_waitstream_full(), async_wait(), autoservice_run(), background_detect_exec(), builtin_atxfer(), channel_spy(), check_goto_on_transfer(), conf_exec(), conf_flush(), conf_run(), dictate_exec(), disa_exec(), do_parking_thread(), do_waiting(), echo_exec(), features_read(), find_cache(), handle_recordfile(), iax2_bridge(), iax_park_thread(), ices_exec(), measurenoise(), misdn_bridge(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), record_exec(), recordthread(), rpt(), rpt_exec(), run_agi(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), sms_exec(), ss_thread(), vpb_bridge(), wait_for_answer(), wait_for_hangup(), waitforring_exec(), and zt_bridge().
01846 { 01847 struct ast_frame *f = NULL; 01848 int blah; 01849 int prestate; 01850 #ifdef ZAPTEL_OPTIMIZATIONS 01851 int (*func)(void *); 01852 void *data; 01853 int res; 01854 #endif 01855 static struct ast_frame null_frame = { 01856 AST_FRAME_NULL, 01857 }; 01858 01859 ast_mutex_lock(&chan->lock); 01860 if (chan->masq) { 01861 if (ast_do_masquerade(chan)) { 01862 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01863 f = NULL; 01864 } else 01865 f = &null_frame; 01866 ast_mutex_unlock(&chan->lock); 01867 return f; 01868 } 01869 01870 /* Stop if we're a zombie or need a soft hangup */ 01871 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 01872 if (chan->generator) 01873 ast_deactivate_generator(chan); 01874 ast_mutex_unlock(&chan->lock); 01875 return NULL; 01876 } 01877 prestate = chan->_state; 01878 01879 if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && !ast_strlen_zero(chan->dtmfq)) { 01880 /* We have DTMF that has been deferred. Return it now */ 01881 chan->dtmff.frametype = AST_FRAME_DTMF; 01882 chan->dtmff.subclass = chan->dtmfq[0]; 01883 /* Drop first digit */ 01884 memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1); 01885 ast_mutex_unlock(&chan->lock); 01886 return &chan->dtmff; 01887 } 01888 01889 /* Read and ignore anything on the alertpipe, but read only 01890 one sizeof(blah) per frame that we send from it */ 01891 if (chan->alertpipe[0] > -1) { 01892 read(chan->alertpipe[0], &blah, sizeof(blah)); 01893 } 01894 #ifdef ZAPTEL_OPTIMIZATIONS 01895 if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && ast_test_flag(chan, AST_FLAG_EXCEPTION)) { 01896 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 01897 blah = -1; 01898 /* IF we can't get event, assume it's an expired as-per the old interface */ 01899 res = ioctl(chan->timingfd, ZT_GETEVENT, &blah); 01900 if (res) 01901 blah = ZT_EVENT_TIMER_EXPIRED; 01902 01903 if (blah == ZT_EVENT_TIMER_PING) { 01904 #if 0 01905 ast_log(LOG_NOTICE, "Oooh, there's a PING!\n"); 01906 #endif 01907 if (!chan->readq || !chan->readq->next) { 01908 /* Acknowledge PONG unless we need it again */ 01909 #if 0 01910 ast_log(LOG_NOTICE, "Sending a PONG!\n"); 01911 #endif 01912 if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) { 01913 ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno)); 01914 } 01915 } 01916 } else if (blah == ZT_EVENT_TIMER_EXPIRED) { 01917 ioctl(chan->timingfd, ZT_TIMERACK, &blah); 01918 func = chan->timingfunc; 01919 data = chan->timingdata; 01920 ast_mutex_unlock(&chan->lock); 01921 if (func) { 01922 #if 0 01923 ast_log(LOG_DEBUG, "Calling private function\n"); 01924 #endif 01925 func(data); 01926 } else { 01927 blah = 0; 01928 ast_mutex_lock(&chan->lock); 01929 ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah); 01930 chan->timingdata = NULL; 01931 ast_mutex_unlock(&chan->lock); 01932 } 01933 f = &null_frame; 01934 return f; 01935 } else 01936 ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name); 01937 } 01938 #endif 01939 /* Check for pending read queue */ 01940 if (chan->readq) { 01941 f = chan->readq; 01942 chan->readq = f->next; 01943 /* Interpret hangup and return NULL */ 01944 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) { 01945 ast_frfree(f); 01946 f = NULL; 01947 } 01948 } else { 01949 chan->blocker = pthread_self(); 01950 if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) { 01951 if (chan->tech->exception) 01952 f = chan->tech->exception(chan); 01953 else { 01954 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name); 01955 f = &null_frame; 01956 } 01957 /* Clear the exception flag */ 01958 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 01959 } else { 01960 if (chan->tech->read) 01961 f = chan->tech->read(chan); 01962 else 01963 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name); 01964 } 01965 } 01966 01967 01968 if (f && (f->frametype == AST_FRAME_VOICE)) { 01969 if (!(f->subclass & chan->nativeformats)) { 01970 /* This frame can't be from the current native formats -- drop it on the 01971 floor */ 01972 ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n", chan->name, ast_getformatname(f->subclass), ast_getformatname(chan->nativeformats)); 01973 ast_frfree(f); 01974 f = &null_frame; 01975 } else { 01976 if (chan->spies) 01977 queue_frame_to_spies(chan, f, SPY_READ); 01978 01979 if (chan->monitor && chan->monitor->read_stream ) { 01980 #ifndef MONITOR_CONSTANT_DELAY 01981 int jump = chan->outsmpl - chan->insmpl - 4 * f->samples; 01982 if (jump >= 0) { 01983 jump = chan->outsmpl - chan->insmpl; 01984 if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1) 01985 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01986 chan->insmpl += jump + f->samples; 01987 } else 01988 chan->insmpl+= f->samples; 01989 #else 01990 int jump = chan->outsmpl - chan->insmpl; 01991 if (jump - MONITOR_DELAY >= 0) { 01992 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1) 01993 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01994 chan->insmpl += jump; 01995 } else 01996 chan->insmpl += f->samples; 01997 #endif 01998 if (ast_writestream(chan->monitor->read_stream, f) < 0) 01999 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n"); 02000 } 02001 if (chan->readtrans) { 02002 f = ast_translate(chan->readtrans, f, 1); 02003 if (!f) 02004 f = &null_frame; 02005 } 02006 } 02007 } 02008 02009 /* Make sure we always return NULL in the future */ 02010 if (!f) { 02011 chan->_softhangup |= AST_SOFTHANGUP_DEV; 02012 if (chan->generator) 02013 ast_deactivate_generator(chan); 02014 /* End the CDR if appropriate */ 02015 if (chan->cdr) 02016 ast_cdr_end(chan->cdr); 02017 } else if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && f->frametype == AST_FRAME_DTMF) { 02018 if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) 02019 chan->dtmfq[strlen(chan->dtmfq)] = f->subclass; 02020 else 02021 ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name); 02022 ast_frfree(f); 02023 f = &null_frame; 02024 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) { 02025 if (prestate == AST_STATE_UP) { 02026 ast_log(LOG_DEBUG, "Dropping duplicate answer!\n"); 02027 ast_frfree(f); 02028 f = &null_frame; 02029 } 02030 /* Answer the CDR */ 02031 ast_setstate(chan, AST_STATE_UP); 02032 ast_cdr_answer(chan->cdr); 02033 } 02034 02035 /* Run any generator sitting on the line */ 02036 if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) { 02037 /* Mask generator data temporarily and apply. If there is a timing function, it 02038 will be calling the generator instead */ 02039 void *tmp; 02040 int res; 02041 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 02042 02043 if (chan->timingfunc) { 02044 ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n"); 02045 ast_settimeout(chan, 0, NULL, NULL); 02046 } 02047 tmp = chan->generatordata; 02048 chan->generatordata = NULL; 02049 generate = chan->generator->generate; 02050 res = generate(chan, tmp, f->datalen, f->samples); 02051 chan->generatordata = tmp; 02052 if (res) { 02053 ast_log(LOG_DEBUG, "Auto-deactivating generator\n"); 02054 ast_deactivate_generator(chan); 02055 } 02056 } else if (f && (f->frametype == AST_FRAME_CNG)) { 02057 if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) { 02058 ast_log(LOG_DEBUG, "Generator got CNG, switching to zap timed mode\n"); 02059 ast_settimeout(chan, 160, generator_force, chan); 02060 } 02061 } 02062 /* High bit prints debugging */ 02063 if (chan->fin & 0x80000000) 02064 ast_frame_dump(chan->name, f, "<<"); 02065 if ((chan->fin & 0x7fffffff) == 0x7fffffff) 02066 chan->fin &= 0x80000000; 02067 else 02068 chan->fin++; 02069 ast_mutex_unlock(&chan->lock); 02070 return f; 02071 }
| 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 2663 of file channel.c.
References ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, ast_stopstream(), ast_test_flag, ast_waitfordigit(), ast_waitstream(), and ast_channel::stream.
Referenced by __adsi_transmit_messages(), adsi_begin_download(), adsi_get_cpeinfo(), adsi_load_session(), ast_app_getdata(), dialout(), do_directory(), forward_message(), privacy_exec(), vm_authenticate(), vm_newuser(), and vm_options().
02664 { 02665 int pos=0; 02666 int to = ftimeout; 02667 int d; 02668 02669 /* XXX Merge with full version? XXX */ 02670 /* Stop if we're a zombie or need a soft hangup */ 02671 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 02672 return -1; 02673 if (!len) 02674 return -1; 02675 do { 02676 if (c->stream) { 02677 d = ast_waitstream(c, AST_DIGIT_ANY); 02678 ast_stopstream(c); 02679 usleep(1000); 02680 if (!d) 02681 d = ast_waitfordigit(c, to); 02682 } else { 02683 d = ast_waitfordigit(c, to); 02684 } 02685 if (d < 0) 02686 return -1; 02687 if (d == 0) { 02688 s[pos]='\0'; 02689 return 1; 02690 } 02691 if (!strchr(enders, d)) 02692 s[pos++] = d; 02693 if (strchr(enders, d) || (pos >= len)) { 02694 s[pos]='\0'; 02695 return 0; 02696 } 02697 to = timeout; 02698 } while(1); 02699 /* Never reached */ 02700 return 0; 02701 }
| 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 2703 of file channel.c.
References ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, ast_stopstream(), ast_test_flag, ast_waitfordigit_full(), ast_waitstream_full(), and ast_channel::stream.
Referenced by ast_app_getdata_full().
02704 { 02705 int pos=0; 02706 int to = ftimeout; 02707 int d; 02708 02709 /* Stop if we're a zombie or need a soft hangup */ 02710 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 02711 return -1; 02712 if (!len) 02713 return -1; 02714 do { 02715 if (c->stream) { 02716 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 02717 ast_stopstream(c); 02718 usleep(1000); 02719 if (!d) 02720 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 02721 } else { 02722 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 02723 } 02724 if (d < 0) 02725 return -1; 02726 if (d == 0) { 02727 s[pos]='\0'; 02728 return 1; 02729 } 02730 if (d == 1) { 02731 s[pos]='\0'; 02732 return 2; 02733 } 02734 if (!strchr(enders, d)) 02735 s[pos++] = d; 02736 if (strchr(enders, d) || (pos >= len)) { 02737 s[pos]='\0'; 02738 return 0; 02739 } 02740 to = timeout; 02741 } while(1); 02742 /* Never reached */ 02743 return 0; 02744 }
| 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 2129 of file channel.c.
References ast_recvtext(), and free.
Referenced by handle_recvchar().
02130 { 02131 int c; 02132 char *buf = ast_recvtext(chan, timeout); 02133 if (buf == NULL) 02134 return -1; /* error or timeout */ 02135 c = *(unsigned char *)buf; 02136 free(buf); 02137 return c; 02138 }
| char* ast_recvtext | ( | struct ast_channel * | chan, | |
| int | timeout | |||
| ) |
Receives a text string from a channel
| chan | channel to act upon | |
| timeout | timeout in milliseconds (0 for infinite wait) |
Definition at line 2140 of file channel.c.
References ast_check_hangup(), AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_TEXT, ast_frfree(), ast_read(), ast_waitfor(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, strndup, and ast_frame::subclass.
Referenced by ast_recvchar(), and handle_recvtext().
02141 { 02142 int res, done = 0; 02143 char *buf = NULL; 02144 02145 while (!done) { 02146 struct ast_frame *f; 02147 if (ast_check_hangup(chan)) 02148 break; 02149 res = ast_waitfor(chan, timeout); 02150 if (res <= 0) /* timeout or error */ 02151 break; 02152 timeout = res; /* update timeout */ 02153 f = ast_read(chan); 02154 if (f == NULL) 02155 break; /* no frame */ 02156 if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) 02157 done = 1; /* force a break */ 02158 else if (f->frametype == AST_FRAME_TEXT) { /* what we want */ 02159 buf = strndup((char *) f->data, f->datalen); /* dup and break */ 02160 done = 1; 02161 } 02162 ast_frfree(f); 02163 } 02164 return buf; 02165 }
| struct ast_channel* ast_request | ( | const char * | type, | |
| int | format, | |||
| void * | data, | |||
| int * | status | |||
| ) | [read] |
Requests a channel.
| type | type of channel to request | |
| format | requested channel format | |
| data | data to pass to the channel requester | |
| status | status Request a channel of a given type, with data as optional information used by the low level module |
Definition at line 2568 of file channel.c.
References ast_channel::_state, AST_CAUSE_NOSUCHDRIVER, AST_CAUSE_NOTDEFINED, AST_FLAG_NOTNEW, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_state2str(), AST_STATE_DOWN, ast_translator_best_choice(), backends, ast_channel_tech::capabilities, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, EVENT_FLAG_CALL, fmt, LOG_WARNING, manager_event(), ast_channel::name, chanlist::next, ast_channel_tech::requester, chanlist::tech, ast_channel_tech::type, and ast_channel::uniqueid.
Referenced by __ast_request_and_dial(), agent_request(), ast_feature_request_and_dial(), attempt_reconnect(), build_conf(), chanavail_exec(), dial_exec_full(), features_alloc(), function_ilink(), ring_entry(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), and wait_for_answer().
02569 { 02570 struct chanlist *chan; 02571 struct ast_channel *c; 02572 int capabilities; 02573 int fmt; 02574 int res; 02575 int foo; 02576 02577 if (!cause) 02578 cause = &foo; 02579 *cause = AST_CAUSE_NOTDEFINED; 02580 02581 if (ast_mutex_lock(&chlock)) { 02582 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 02583 return NULL; 02584 } 02585 02586 for (chan = backends; chan; chan = chan->next) { 02587 if (strcasecmp(type, chan->tech->type)) 02588 continue; 02589 02590 capabilities = chan->tech->capabilities; 02591 fmt = format; 02592 res = ast_translator_best_choice(&fmt, &capabilities); 02593 if (res < 0) { 02594 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format); 02595 ast_mutex_unlock(&chlock); 02596 return NULL; 02597 } 02598 ast_mutex_unlock(&chlock); 02599 if (!chan->tech->requester) 02600 return NULL; 02601 02602 if (!(c = chan->tech->requester(type, capabilities, data, cause))) 02603 return NULL; 02604 02605 if (c->_state == AST_STATE_DOWN) { 02606 manager_event(EVENT_FLAG_CALL, "Newchannel", 02607 "Channel: %s\r\n" 02608 "State: %s\r\n" 02609 "CallerID: %s\r\n" 02610 "CallerIDName: %s\r\n" 02611 "Uniqueid: %s\r\n", 02612 c->name, ast_state2str(c->_state), 02613 c->cid.cid_num ? c->cid.cid_num : "<unknown>", 02614 c->cid.cid_name ? c->cid.cid_name : "<unknown>", 02615 c->uniqueid); 02616 ast_set_flag(c, AST_FLAG_NOTNEW); 02617 } 02618 return c; 02619 } 02620 02621 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 02622 *cause = AST_CAUSE_NOSUCHDRIVER; 02623 ast_mutex_unlock(&chlock); 02624 02625 return NULL; 02626 }
| struct ast_channel* ast_request_and_dial | ( | const char * | type, | |
| int | format, | |||
| void * | data, | |||
| int | timeout, | |||
| int * | reason, | |||
| const char * | cidnum, | |||
| const char * | cidname | |||
| ) | [read] |
Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.
| type | type of channel to request | |
| format | 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 unsuceessful) | |
| cidnum | Caller-ID Number | |
| cidname | Caller-ID Name |
Definition at line 2563 of file channel.c.
References __ast_request_and_dial().
Referenced by ast_pbx_outgoing_exten().
02564 { 02565 return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL); 02566 }
| int ast_safe_sleep | ( | struct ast_channel * | chan, | |
| int | ms | |||
| ) |
Wait for a specied 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 854 of file channel.c.
References ast_frfree(), ast_read(), and ast_waitfor().
Referenced by __login_exec(), adsi_transmit_message_full(), alarmreceiver_exec(), ast_dtmf_stream(), dictate_exec(), flash_exec(), function_ilink(), function_remote(), handle_remote_data(), handle_remote_phone_dtmf(), milliwatt_exec(), moh0_exec(), moh1_exec(), park_call_exec(), pbx_builtin_answer(), pbx_builtin_wait(), play_tone_pair(), privacy_exec(), receive_ademco_contact_id(), rmt_telem_start(), rpt_call(), rpt_exec(), rpt_tele_thread(), send_morse(), send_tone_telemetry(), skinny_ss(), testclient_exec(), testserver_exec(), try_calling(), wait_for_hangup(), wait_interval(), and zapateller_exec().
00855 { 00856 struct ast_frame *f; 00857 while(ms > 0) { 00858 ms = ast_waitfor(chan, ms); 00859 if (ms <0) 00860 return -1; 00861 if (ms > 0) { 00862 f = ast_read(chan); 00863 if (!f) 00864 return -1; 00865 ast_frfree(f); 00866 } 00867 } 00868 return 0; 00869 }
| int ast_safe_sleep_conditional | ( | struct ast_channel * | chan, | |
| int | ms, | |||
| int(*)(void *) | cond, | |||
| void * | data | |||
| ) |
Wait for a specied 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 832 of file channel.c.
References ast_frfree(), ast_read(), and ast_waitfor().
Referenced by __login_exec().
00834 { 00835 struct ast_frame *f; 00836 00837 while(ms > 0) { 00838 if( cond && ((*cond)(data) == 0 ) ) 00839 return 0; 00840 ms = ast_waitfor(chan, ms); 00841 if (ms <0) 00842 return -1; 00843 if (ms > 0) { 00844 f = ast_read(chan); 00845 if (!f) 00846 return -1; 00847 ast_frfree(f); 00848 } 00849 } 00850 return 0; 00851 }
| int ast_senddigit | ( | struct ast_channel * | chan, | |
| char | digit | |||
| ) |
Send a DTMF digit to a channel
| chan | channel to act upon | |
| digit | the DTMF digit to send, encoded in ASCII Send a DTMF digit to a channel. Returns 0 on success, -1 on failure |
Definition at line 2224 of file channel.c.
References do_senddigit().
Referenced by dial_exec_full(), and features_digit().
02225 { 02226 return do_senddigit(chan, digit); 02227 }
| 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 Write text to a display on a channel Returns 0 on success, -1 on failure |
Definition at line 2167 of file channel.c.
References ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_test_flag, CHECK_BLOCKING, ast_channel_tech::send_text, and ast_channel::tech.
Referenced by agent_sendtext(), handle_sendtext(), and sendtext_exec().
02168 { 02169 int res = 0; 02170 /* Stop if we're a zombie or need a soft hangup */ 02171 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 02172 return -1; 02173 CHECK_BLOCKING(chan); 02174 if (chan->tech->send_text) 02175 res = chan->tech->send_text(chan, text); 02176 ast_clear_flag(chan, AST_FLAG_BLOCKING); 02177 return res; 02178 }
| void ast_set_callerid | ( | struct ast_channel * | chan, | |
| const char * | callerid, | |||
| const char * | calleridname, | |||
| const char * | ani | |||
| ) |
Definition at line 3226 of file channel.c.
References ast_cdr_setcid(), ast_describe_caller_presentation(), ast_strlen_zero(), ast_channel::cdr, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, EVENT_FLAG_CALL, free, manager_event(), ast_channel::name, strdup, and ast_channel::uniqueid.
Referenced by __ast_request_and_dial(), agent_call(), ast_feature_request_and_dial(), callerid_write(), dial_exec_full(), disa_exec(), get_callerid(), handle_setcallerid(), local_call(), lookupcidname_exec(), mgcp_ss(), monitor_handle_notowned(), privacy_exec(), read_config(), rpt_exec(), setcallerid_exec(), skinny_ss(), ss_thread(), wait_for_answer(), and zt_read().
03227 { 03228 if (callerid) { 03229 if (chan->cid.cid_num) 03230 free(chan->cid.cid_num); 03231 if (ast_strlen_zero(callerid)) 03232 chan->cid.cid_num = NULL; 03233 else 03234 chan->cid.cid_num = strdup(callerid); 03235 } 03236 if (calleridname) { 03237 if (chan->cid.cid_name) 03238 free(chan->cid.cid_name); 03239 if (ast_strlen_zero(calleridname)) 03240 chan->cid.cid_name = NULL; 03241 else 03242 chan->cid.cid_name = strdup(calleridname); 03243 } 03244 if (ani) { 03245 if (chan->cid.cid_ani) 03246 free(chan->cid.cid_ani); 03247 if (ast_strlen_zero(ani)) 03248 chan->cid.cid_ani = NULL; 03249 else 03250 chan->cid.cid_ani = strdup(ani); 03251 } 03252 if (chan->cdr) 03253 ast_cdr_setcid(chan->cdr, chan); 03254 manager_event(EVENT_FLAG_CALL, "Newcallerid", 03255 "Channel: %s\r\n" 03256 "CallerID: %s\r\n" 03257 "CallerIDName: %s\r\n" 03258 "Uniqueid: %s\r\n" 03259 "CID-CallingPres: %d (%s)\r\n", 03260 chan->name, chan->cid.cid_num ? 03261 chan->cid.cid_num : "<Unknown>", 03262 chan->cid.cid_name ? 03263 chan->cid.cid_name : "<Unknown>", 03264 chan->uniqueid, 03265 chan->cid.cid_pres, 03266 ast_describe_caller_presentation(chan->cid.cid_pres) 03267 ); 03268 }
| int ast_set_read_format | ( | struct ast_channel * | chan, | |
| int | format | |||
| ) |
Sets read format on channel chan
| chan | channel to change | |
| format | format to change to Set read format for channel to whichever component of "format" is best. Returns 0 on success, -1 on failure |
Definition at line 2437 of file channel.c.
References ast_channel::rawreadformat, ast_channel::readformat, ast_channel::readtrans, and set_format().
Referenced by __login_exec(), __oh323_update_info(), adsi_transmit_message_full(), agent_call(), alarmreceiver_exec(), ast_app_getvoice(), ast_channel_make_compatible(), ast_do_masquerade(), ast_play_and_prepend(), ast_play_and_record_full(), attempt_reconnect(), background_detect_exec(), chanspy_exec(), conf_run(), dictate_exec(), disa_exec(), do_waiting(), eagi_exec(), echo_exec(), function_ilink(), handle_recordfile(), ices_exec(), measurenoise(), mgcp_rtp_read(), milliwatt_exec(), oh323_rtp_read(), process_sdp(), record_exec(), rpt(), rpt_exec(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), sms_exec(), socket_read(), and update_features().
02438 { 02439 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat, 02440 &chan->readtrans, 0); 02441 }
| 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 3975 of file channel.c.
References ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), and ast_variable::value.
Referenced by __ast_request_and_dial(), ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().
03976 { 03977 struct ast_variable *cur; 03978 03979 for (cur = vars; cur; cur = cur->next) 03980 pbx_builtin_setvar_helper(chan, cur->name, cur->value); 03981 }
| int ast_set_write_format | ( | struct ast_channel * | chan, | |
| int | format | |||
| ) |
Sets write format on channel chan
| chan | channel to change | |
| format | new format for writing Set write format for channel to whichever compoent of "format" is best. Returns 0 on success, -1 on failure |
Definition at line 2443 of file channel.c.
References ast_channel::rawwriteformat, set_format(), ast_channel::writeformat, and ast_channel::writetrans.
Referenced by __login_exec(), __oh323_update_info(), adsi_transmit_message_full(), agent_call(), alarmreceiver_exec(), ast_channel_make_compatible(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_do_masquerade(), ast_openstream_full(), ast_stopstream(), attempt_reconnect(), chanspy_exec(), conf_run(), disa_exec(), echo_exec(), function_ilink(), linear_alloc(), linear_release(), mgcp_rtp_read(), milliwatt_exec(), moh_alloc(), moh_files_release(), moh_release(), mp3_exec(), NBScat_exec(), oh323_rtp_read(), playtones_alloc(), playtones_release(), process_sdp(), rpt(), rpt_exec(), send_waveform_to_channel(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), sms_exec(), socket_read(), tonepair_alloc(), tonepair_release(), and update_features().
02444 { 02445 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat, 02446 &chan->writetrans, 1); 02447 }
| int ast_setstate | ( | struct ast_channel * | chan, | |
| int | state | |||
| ) |
Change the state of a channel.
Definition at line 3270 of file channel.c.
References ast_channel::_state, ast_device_state_changed_literal(), AST_FLAG_NOTNEW, ast_state2str(), AST_STATE_DOWN, ast_test_flag, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, EVENT_FLAG_CALL, manager_event(), ast_channel::name, and ast_channel::uniqueid.
Referenced by __oh323_new(), __oh323_update_info(), __zt_exception(), agent_call(), agent_new(), alsa_answer(), alsa_new(), aopen_handle_escape(), ast_answer(), ast_async_goto(), ast_iax2_new(), ast_modem_new(), ast_read(), bestdata_handle_escape(), cb_events(), check_availability(), features_new(), handle_message(), handle_request_invite(), handle_response_invite(), i4l_handle_escape(), iax2_call(), local_new(), mgcp_answer(), mgcp_call(), mgcp_new(), mgcp_ss(), misdn_call(), misdn_indication(), misdn_new(), modem_answer(), modem_call(), modem_hangup(), nbs_call(), nbs_hangup(), nbs_new(), oh323_answer(), oss_answer(), oss_new(), pbx_builtin_busy(), pbx_builtin_congestion(), phone_answer(), phone_call(), phone_exception(), phone_hangup(), phone_new(), phone_write(), release_chan(), sip_answer(), sip_new(), skinny_answer(), skinny_call(), skinny_new(), skinny_ss(), ss_thread(), update_state(), vpb_answer(), vpb_call(), vpb_hangup(), vpb_new(), zt_answer(), zt_call(), zt_handle_event(), zt_indicate(), zt_new(), and zt_read().
03271 { 03272 int oldstate = chan->_state; 03273 03274 if (oldstate == state) 03275 return 0; 03276 03277 chan->_state = state; 03278 ast_device_state_changed_literal(chan->name); 03279 manager_event(EVENT_FLAG_CALL, 03280 (oldstate == AST_STATE_DOWN && !ast_test_flag(chan, AST_FLAG_NOTNEW)) ? "Newchannel" : "Newstate", 03281 "Channel: %s\r\n" 03282 "State: %s\r\n" 03283 "CallerID: %s\r\n" 03284 "CallerIDName: %s\r\n" 03285 "Uniqueid: %s\r\n", 03286 chan->name, ast_state2str(chan->_state), 03287 chan->cid.cid_num ? chan->cid.cid_num : "<unknown>", 03288 chan->cid.cid_name ? chan->cid.cid_name : "<unknown>", 03289 chan->uniqueid); 03290 03291 return 0; 03292 }
| int ast_settimeout | ( | struct ast_channel * | c, | |
| int | samples, | |||
| int(*)(void *data) | func, | |||
| void * | data | |||
| ) |
Definition at line 1768 of file channel.c.
References ast_log(), LOG_DEBUG, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.
Referenced by ast_activate_generator(), ast_closestream(), ast_deactivate_generator(), ast_read(), and ast_readaudio_callback().
01769 { 01770 int res = -1; 01771 #ifdef ZAPTEL_OPTIMIZATIONS 01772 if (c->timingfd > -1) { 01773 if (!func) { 01774 samples = 0; 01775 data = 0; 01776 } 01777 ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples); 01778 res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples); 01779 c->timingfunc = func; 01780 c->timingdata = data; 01781 } 01782 #endif 01783 return res; 01784 }
| int ast_shutting_down | ( | void | ) |
Returns non-zero if Asterisk is being shut down
Definition at line 271 of file channel.c.
References shutting_down.
00272 { 00273 return shutting_down; 00274 }
| int ast_softhangup | ( | struct ast_channel * | chan, | |
| int | cause | |||
| ) |
Softly hangup up a channel.
| chan | channel to be soft-hung-up Call the protocol layer, but don't destroy the channel structure (use this if you are trying to safely hangup a channel managed by another thread. | |
| cause | Ast hangupcause for hangup |
Definition at line 1169 of file channel.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_softhangup_nolock(), and ast_channel::lock.
Referenced by __login_exec(), __unload_module(), action_hangup(), agent_hangup(), agent_logoff(), ast_begin_shutdown(), function_ilink(), handle_hangup(), handle_link_data(), handle_softhangup(), read_agent_config(), rpt(), rpt_call(), softhangup_exec(), start_spying(), startmon(), unload_module(), and zt_handle_event().
01170 { 01171 int res; 01172 ast_mutex_lock(&chan->lock); 01173 res = ast_softhangup_nolock(chan, cause); 01174 ast_mutex_unlock(&chan->lock); 01175 return res; 01176 }
| 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 1153 of file channel.c.
References ast_channel::_softhangup, AST_FLAG_BLOCKING, AST_FRAME_NULL, ast_log(), ast_queue_frame(), ast_test_flag, ast_channel::blocker, LOG_DEBUG, ast_channel::name, and option_debug.
Referenced by ast_async_goto(), ast_softhangup(), attempt_transfer(), do_monitor(), oh323_indicate(), sip_indicate(), and skinny_indicate().
01154 { 01155 int res = 0; 01156 struct ast_frame f = { AST_FRAME_NULL }; 01157 if (option_debug) 01158 ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name); 01159 /* Inform channel driver that we need to be hung up, if it cares */ 01160 chan->_softhangup |= cause; 01161 ast_queue_frame(chan, &f); 01162 /* Interrupt any poll call or such */ 01163 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) 01164 pthread_kill(chan->blocker, SIGURG); 01165 return res; 01166 }
| char* ast_state2str | ( | int | state | ) |
Gives the string form of a given channel state
| state | state to get the name of Give a name to a state Returns the text form of the binary state given |
Definition at line 422 of file channel.c.
References AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_OFFHOOK, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, and AST_STATE_UP.
Referenced by action_status(), agent_hangup(), ast_request(), ast_serialize_showchan(), ast_setstate(), handle_chanlist(), handle_showchan(), and mgcp_new().
00423 { 00424 /* XXX Not reentrant XXX */ 00425 static char localtmp[256]; 00426 switch(state) { 00427 case AST_STATE_DOWN: 00428 return "Down"; 00429 case AST_STATE_RESERVED: 00430 return "Rsrvd"; 00431 case AST_STATE_OFFHOOK: 00432 return "OffHook"; 00433 case AST_STATE_DIALING: 00434 return "Dialing"; 00435 case AST_STATE_RING: 00436 return "Ring"; 00437 case AST_STATE_RINGING: 00438 return "Ringing"; 00439 case AST_STATE_UP: 00440 return "Up"; 00441 case AST_STATE_BUSY: 00442 return "Busy"; 00443 default: 00444 snprintf(localtmp, sizeof(localtmp), "Unknown (%d)\n", state); 00445 return localtmp; 00446 } 00447 }
| 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 3843 of file channel.c.
References ast_frfree(), ast_read(), ast_tonepair_start(), ast_waitfor(), and ast_channel::generatordata.
Referenced by zapateller_exec().
03844 { 03845 struct ast_frame *f; 03846 int res; 03847 03848 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 03849 return res; 03850 03851 /* Give us some wiggle room */ 03852 while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) { 03853 f = ast_read(chan); 03854 if (f) 03855 ast_frfree(f); 03856 else 03857 return -1; 03858 } 03859 return 0; 03860 }
| int ast_tonepair_start | ( | struct ast_channel * | chan, | |
| int | freq1, | |||
| int | freq2, | |||
| int | duration, | |||
| int | vol | |||
| ) |
Start a tone going
Definition at line 3822 of file channel.c.
References ast_activate_generator(), tonepair_def::duration, tonepair_def::freq1, tonepair_def::freq2, tonepair, and tonepair_def::vol.
Referenced by ast_tonepair(), play_dialtone(), play_tone_pair(), rpt_tele_thread(), and sendnoise().
03823 { 03824 struct tonepair_def d = { 0, }; 03825 03826 d.freq1 = freq1; 03827 d.freq2 = freq2; 03828 d.duration = duration; 03829 if (vol < 1) 03830 d.vol = 8192; 03831 else 03832 d.vol = vol; 03833 if (ast_activate_generator(chan, &tonepair, &d)) 03834 return -1; 03835 return 0; 03836 }
| void ast_tonepair_stop | ( | struct ast_channel * | chan | ) |
Stop a tone from playing
Definition at line 3838 of file channel.c.
References ast_deactivate_generator().
Referenced by sendnoise().
03839 { 03840 ast_deactivate_generator(chan); 03841 }
| 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.
| chan | current channel | |
| dest | destination extension for transfer |
Definition at line 2645 of file channel.c.
References ast_check_hangup(), AST_FLAG_ZOMBIE, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_channel::lock, ast_channel::tech, and ast_channel_tech::transfer.
Referenced by transfer_exec().
02646 { 02647 int res = -1; 02648 02649 /* Stop if we're a zombie or need a soft hangup */ 02650 ast_mutex_lock(&chan->lock); 02651 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 02652 if (chan->tech->transfer) { 02653 res = chan->tech->transfer(chan, dest); 02654 if (!res) 02655 res = 1; 02656 } else 02657 res = 0; 02658 } 02659 ast_mutex_unlock(&chan->lock); 02660 return res; 02661 }
| char* ast_transfercapability2str | ( | int | transfercapability | ) |
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 capbility |
Definition at line 450 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(), misdn_call(), zt_call(), and zt_new().
00451 { 00452 switch(transfercapability) { 00453 case AST_TRANS_CAP_SPEECH: 00454 return "SPEECH"; 00455 case AST_TRANS_CAP_DIGITAL: 00456 return "DIGITAL"; 00457 case AST_TRANS_CAP_RESTRICTED_DIGITAL: 00458 return "RESTRICTED_DIGITAL"; 00459 case AST_TRANS_CAP_3_1K_AUDIO: 00460 return "3K1AUDIO"; 00461 case AST_TRANS_CAP_DIGITAL_W_TONES: 00462 return "DIGITAL_W_TONES"; 00463 case AST_TRANS_CAP_VIDEO: 00464 return "VIDEO"; 00465 default: 00466 return "UNKNOWN"; 00467 } 00468 }
| void ast_uninstall_music_functions | ( | void | ) |
Definition at line 3912 of file channel.c.
References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.
03913 { 03914 ast_moh_start_ptr = NULL; 03915 ast_moh_stop_ptr = NULL; 03916 ast_moh_cleanup_ptr = NULL; 03917 }
| 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 1724 of file channel.c.
References ast_waitfor_n().
Referenced by __adsi_transmit_messages(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), ast_app_getvoice(), ast_dtmf_stream(), ast_play_and_prepend(), ast_play_and_record_full(), ast_recvtext(), ast_safe_sleep(), ast_safe_sleep_conditional(), ast_tonepair(), ast_waitfordigit(), ast_waitstream(), ast_waitstream_exten(), ast_waitstream_fr(), async_wait(), background_detect_exec(), channel_spy(), conf_exec(), conf_flush(), dictate_exec(), disa_exec(), do_waiting(), echo_exec(), handle_recordfile(), ices_exec(), measurenoise(), modem_call(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), record_exec(), recordthread(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), sms_exec(), ss_thread(), wait_for_hangup(), and waitforring_exec().
01725 { 01726 struct ast_channel *chan; 01727 int oldms = ms; 01728 01729 chan = ast_waitfor_n(&c, 1, &ms); 01730 if (ms < 0) { 01731 if (oldms < 0) 01732 return 0; 01733 else 01734 return -1; 01735 } 01736 return ms; 01737 }
| struct ast_channel* ast_waitfor_n | ( | struct ast_channel ** | chan, | |
| int | n, | |||
| int * | ms | |||
| ) | [read] |
Waits for input on a group of channels
Wait for input on an array of channels for a given # of milliseconds. Return channel with activity, or NULL if none has activity. time "ms" is modified in-place, if applicable
Definition at line 1719 of file channel.c.
References ast_waitfor_nandfds().
Referenced by ast_feature_request_and_dial(), ast_generic_bridge(), ast_rtp_bridge(), ast_waitfor(), autoservice_run(), iax2_bridge(), misdn_bridge(), rpt(), rpt_exec(), vpb_bridge(), wait_for_answer(), and zt_bridge().
01720 { 01721 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 01722 }
| 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 1505 of file channel.c.
References ast_fdisset(), ast_log(), pollfd::events, pollfd::fd, LOG_ERROR, poll(), POLLIN, and POLLPRI.
Referenced by ast_modem_expect(), ast_modem_read_response(), bestdata_read(), dundi_lookup_internal(), and dundi_precache_internal().
01506 { 01507 struct timeval start = { 0 , 0 }; 01508 int res; 01509 int x, y; 01510 int winner = -1; 01511 int spoint; 01512 struct pollfd *pfds; 01513 01514 pfds = alloca(sizeof(struct pollfd) * n); 01515 if (!pfds) { 01516 ast_log(LOG_ERROR, "Out of memory\n"); 01517 return -1; 01518 } 01519 if (*ms > 0) 01520 start = ast_tvnow(); 01521 y = 0; 01522 for (x=0; x < n; x++) { 01523 if (fds[x] > -1) { 01524 pfds[y].fd = fds[x]; 01525 pfds[y].events = POLLIN | POLLPRI; 01526 y++; 01527 } 01528 } 01529 res = poll(pfds, y, *ms); 01530 if (res < 0) { 01531 /* Simulate a timeout if we were interrupted */ 01532 if (errno != EINTR) 01533 *ms = -1; 01534 else 01535 *ms = 0; 01536 return -1; 01537 } 01538 spoint = 0; 01539 for (x=0; x < n; x++) { 01540 if (fds[x] > -1) { 01541 if ((res = ast_fdisset(pfds, fds[x], y, &spoint))) { 01542 winner = fds[x]; 01543 if (exception) { 01544 if (res & POLLPRI) 01545 *exception = -1; 01546 else 01547 *exception = 0; 01548 } 01549 } 01550 } 01551 } 01552 if (*ms > 0) { 01553 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 01554 if (*ms < 0) 01555 *ms = 0; 01556 } 01557 return winner; 01558 }
| struct ast_channel* ast_waitfor_nandfds | ( | struct ast_channel ** | chan, | |
| int | n, | |||
| int * | fds, | |||
| int | nfds, | |||
| int * | exception, | |||
| int * | outfd, | |||
| int * | ms | |||
| ) | [read] |
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 1561 of file channel.c.
References ast_channel::_softhangup, ast_clear_flag, ast_do_masquerade(), ast_fdisset(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, ast_log(), AST_MAX_FDS, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, AST_SOFTHANGUP_TIMEOUT, CHECK_BLOCKING, pollfd::events, pollfd::fd, ast_channel::fdno, ast_channel::fds, lock, LOG_ERROR, LOG_WARNING, ast_channel::masq, poll(), POLLIN, POLLPRI, pollfd::revents, and ast_channel::whentohangup.
Referenced by app_exec(), ast_waitfor_n(), ast_waitfordigit_full(), ast_waitstream_full(), conf_run(), find_cache(), and run_agi().
01563 { 01564 struct timeval start = { 0 , 0 }; 01565 struct pollfd *pfds; 01566 int res; 01567 long rms; 01568 int x, y, max; 01569 int spoint; 01570 time_t now = 0; 01571 long whentohangup = 0, havewhen = 0, diff; 01572 struct ast_channel *winner = NULL; 01573 01574 pfds = alloca(sizeof(struct pollfd) * (n * AST_MAX_FDS + nfds)); 01575 if (!pfds) { 01576 ast_log(LOG_ERROR, "Out of memory\n"); 01577 *outfd = -1; 01578 return NULL; 01579 } 01580 01581 if (outfd) 01582 *outfd = -99999; 01583 if (exception) 01584 *exception = 0; 01585 01586 /* Perform any pending masquerades */ 01587 for (x=0; x < n; x++) { 01588 ast_mutex_lock(&c[x]->lock); 01589 if (c[x]->whentohangup) { 01590 if (!havewhen) 01591 time(&now); 01592 diff = c[x]->whentohangup - now; 01593 if (!havewhen || (diff < whentohangup)) { 01594 havewhen++; 01595 whentohangup = diff; 01596 } 01597 } 01598 if (c[x]->masq) { 01599 if (ast_do_masquerade(c[x])) { 01600 ast_log(LOG_WARNING, "Masquerade failed\n"); 01601 *ms = -1; 01602 ast_mutex_unlock(&c[x]->lock); 01603 return NULL; 01604 } 01605 } 01606 ast_mutex_unlock(&c[x]->lock); 01607 } 01608 01609 rms = *ms; 01610 01611 if (havewhen) { 01612 if ((*ms < 0) || (whentohangup * 1000 < *ms)) { 01613 rms = whentohangup * 1000; 01614 } 01615 } 01616 max = 0; 01617 for (x=0; x < n; x++) { 01618 for (y=0; y< AST_MAX_FDS; y++) { 01619 if (c[x]->fds[y] > -1) { 01620 pfds[max].fd = c[x]->fds[y]; 01621 pfds[max].events = POLLIN | POLLPRI; 01622 pfds[max].revents = 0; 01623 max++; 01624 } 01625 } 01626 CHECK_BLOCKING(c[x]); 01627 } 01628 for (x=0; x < nfds; x++) { 01629 if (fds[x] > -1) { 01630 pfds[max].fd = fds[x]; 01631 pfds[max].events = POLLIN | POLLPRI; 01632 pfds[max].revents = 0; 01633 max++; 01634 } 01635 } 01636 if (*ms > 0) 01637 start = ast_tvnow(); 01638 01639 if (sizeof(int) == 4) { 01640 do { 01641 int kbrms = rms; 01642 if (kbrms > 600000) 01643 kbrms = 600000; 01644 res = poll(pfds, max, kbrms); 01645 if (!res) 01646 rms -= kbrms; 01647 } while (!res && (rms > 0)); 01648 } else { 01649 res = poll(pfds, max, rms); 01650 } 01651 01652 if (res < 0) { 01653 for (x=0; x < n; x++) 01654 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 01655 /* Simulate a timeout if we were interrupted */ 01656 if (errno != EINTR) 01657 *ms = -1; 01658 else { 01659 /* Just an interrupt */ 01660 #if 0 01661 *ms = 0; 01662 #endif 01663 } 01664 return NULL; 01665 } else { 01666 /* If no fds signalled, then timeout. So set ms = 0 01667 since we may not have an exact timeout. 01668 */ 01669 if (res == 0) 01670 *ms = 0; 01671 } 01672 01673 if (havewhen) 01674 time(&now); 01675 spoint = 0; 01676 for (x=0; x < n; x++) { 01677 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 01678 if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) { 01679 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 01680 if (!winner) 01681 winner = c[x]; 01682 } 01683 for (y=0; y < AST_MAX_FDS; y++) { 01684 if (c[x]->fds[y] > -1) { 01685 if ((res = ast_fdisset(pfds, c[x]->fds[y], max, &spoint))) { 01686 if (res & POLLPRI) 01687 ast_set_flag(c[x], AST_FLAG_EXCEPTION); 01688 else 01689 ast_clear_flag(c[x], AST_FLAG_EXCEPTION); 01690 c[x]->fdno = y; 01691 winner = c[x]; 01692 } 01693 } 01694 } 01695 } 01696 for (x=0; x < nfds; x++) { 01697 if (fds[x] > -1) { 01698 if ((res = ast_fdisset(pfds, fds[x], max, &spoint))) { 01699 if (outfd) 01700 *outfd = fds[x]; 01701 if (exception) { 01702 if (res & POLLPRI) 01703 *exception = -1; 01704 else 01705 *exception = 0; 01706 } 01707 winner = NULL; 01708 } 01709 } 01710 } 01711 if (*ms > 0) { 01712 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 01713 if (*ms < 0) 01714 *ms = 0; 01715 } 01716 return winner; 01717 }
| 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 Wait for a digit. Returns <0 on error, 0 on no entry, and the digit on success. |
Definition at line 1739 of file channel.c.
References ast_check_hangup(), AST_FLAG_ZOMBIE, AST_FRAME_DTMF, ast_frfree(), ast_read(), ast_test_flag, ast_waitfor(), ast_frame::frametype, result, and ast_frame::subclass.
Referenced by __ast_pbx_run(), _while_exec(), adsi_get_cpeid(), adsi_get_cpeinfo(), adsi_print(), adsi_read_encoded_dtmf(), adsi_transmit_message_full(), advanced_options(), ast_app_dtget(), ast_control_streamfile(), ast_readstring(), ast_record_review(), builtin_atxfer(), chanspy_exec(), cpeid_exec(), dialout(), directory_exec(), forward_message(), get_folder(), ivr_dispatch(), mgcp_ss(), my_getsigstr(), pbx_builtin_waitexten(), play_mailbox_owner(), play_record_review(), read_newoption(), retrydial_exec(), sendnoise(), skinny_ss(), ss_thread(), testclient_exec(), testserver_exec(), vm_execmain(), vm_forwardoptions(), vm_instructions(), vm_options(), vm_tempgreeting(), wait_a_bit(), and wait_our_turn().
01740 { 01741 /* XXX Should I be merged with waitfordigit_full XXX */ 01742 struct ast_frame *f; 01743 int result = 0; 01744 01745 /* Stop if we're a zombie or need a soft hangup */ 01746 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 01747 return -1; 01748 01749 /* Wait for a digit, no more than ms milliseconds total. */ 01750 while(ms && !result) { 01751 ms = ast_waitfor(c, ms); 01752 if (ms < 0) /* Error */ 01753 result = -1; 01754 else if (ms > 0) { 01755 /* Read something */ 01756 f = ast_read(c); 01757 if (f) { 01758 if (f->frametype == AST_FRAME_DTMF) 01759 result = f->subclass; 01760 ast_frfree(f); 01761 } else 01762 result = -1; 01763 } 01764 } 01765 return result; 01766 }
| int ast_waitfordigit_full | ( | struct ast_channel * | c, | |
| int | ms, | |||
| int | audiofd, | |||
| int | cmdfd | |||
| ) |
Definition at line 1786 of file channel.c.
References ast_check_hangup(), AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_read(), ast_test_flag, ast_waitfor_nandfds(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, and ast_frame::subclass.
Referenced by ast_readstring_full(), handle_getoption(), and handle_waitfordigit().
01787 { 01788 struct ast_frame *f; 01789 struct ast_channel *rchan; 01790 int outfd; 01791 int res; 01792 01793 /* Stop if we're a zombie or need a soft hangup */ 01794 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 01795 return -1; 01796 /* Wait for a digit, no more than ms milliseconds total. */ 01797 while(ms) { 01798 errno = 0; 01799 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01800 if ((!rchan) && (outfd < 0) && (ms)) { 01801 if (errno == 0 || errno == EINTR) 01802 continue; 01803 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01804 return -1; 01805 } else if (outfd > -1) { 01806 /* The FD we were watching has something waiting */ 01807 return 1; 01808 } else if (rchan) { 01809 f = ast_read(c); 01810 if(!f) { 01811 return -1; 01812 } 01813 01814 switch(f->frametype) { 01815 case AST_FRAME_DTMF: 01816 res = f->subclass; 01817 ast_frfree(f); 01818 return res; 01819 case AST_FRAME_CONTROL: 01820 switch(f->subclass) { 01821 case AST_CONTROL_HANGUP: 01822 ast_frfree(f); 01823 return -1; 01824 case AST_CONTROL_RINGING: 01825 case AST_CONTROL_ANSWER: 01826 /* Unimportant */ 01827 break; 01828 default: 01829 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass); 01830 break; 01831 } 01832 break; 01833 case AST_FRAME_VOICE: 01834 /* Write audio if appropriate */ 01835 if (audiofd > -1) 01836 write(audiofd, f->data, f->datalen); 01837 } 01838 /* Ignore */ 01839 ast_frfree(f); 01840 } 01841 } 01842 return 0; /* Time is up */ 01843 }
| struct ast_channel* ast_walk_channel_by_name_prefix_locked | ( | struct ast_channel * | chan, | |
| const char * | name, | |||
| const int | namelen | |||
| ) | [read] |
Get channel by name prefix (locks channel)
Definition at line 820 of file channel.c.
References channel_find_locked().
00821 { 00822 return channel_find_locked(chan, name, namelen, NULL, NULL); 00823 }
| int ast_write | ( | struct ast_channel * | chan, | |
| struct ast_frame * | frame | |||
| ) |
Write a frame to a channel
| chan | destination channel of the frame | |
| frame | frame that will be written This function writes the given frame to the indicated channel. It returns 0 on success, -1 on failure. |
Definition at line 2257 of file channel.c.
References ast_channel::_softhangup, ast_check_hangup(), ast_clear_flag, ast_deactivate_generator(), ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_WRITE_INT, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frame_dump(), AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_seekstream(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_translate(), ast_writestream(), CHECK_BLOCKING, ast_frame::data, ast_frame::datalen, do_senddigit(), ast_channel::fout, ast_frame::frametype, ast_channel::generatordata, ast_channel::insmpl, ast_channel::lock, LOG_DTMF, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::outsmpl, queue_frame_to_spies(), ast_frame::samples, SEEK_FORCECUR, ast_channel_tech::send_html, ast_channel_tech::send_text, ast_channel::spies, SPY_WRITE, ast_frame::subclass, ast_channel::tech, ast_channel_tech::write, ast_channel_monitor::write_stream, ast_channel_tech::write_video, and ast_channel::writetrans.
Referenced by adsi_careful_send(), agent_write(), ast_dtmf_stream(), ast_generic_bridge(), ast_prod(), ast_readaudio_callback(), ast_readvideo_callback(), ast_rtp_bridge(), ast_write_video(), conf_run(), dictate_exec(), echo_exec(), features_write(), function_ilink(), gen_generate(), handle_link_data(), iax2_bridge(), linear_generator(), milliwatt_generate(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), NBScat_exec(), playtones_generator(), rpt(), rpt_call(), rpt_exec(), send_link_dtmf(), send_tone_burst(), send_waveform_to_channel(), silence_generator_generate(), sms_generate(), spy_generate(), tonepair_generator(), wait_for_answer(), and zt_bridge().
02258 { 02259 int res = -1; 02260 struct ast_frame *f = NULL; 02261 /* Stop if we're a zombie or need a soft hangup */ 02262 ast_mutex_lock(&chan->lock); 02263 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02264 ast_mutex_unlock(&chan->lock); 02265 return -1; 02266 } 02267 /* Handle any pending masquerades */ 02268 if (chan->masq) { 02269 if (ast_do_masquerade(chan)) { 02270 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 02271 ast_mutex_unlock(&chan->lock); 02272 return -1; 02273 } 02274 } 02275 if (chan->masqr) { 02276 ast_mutex_unlock(&chan->lock); 02277 return 0; 02278 } 02279 if (chan->generatordata) { 02280 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) 02281 ast_deactivate_generator(chan); 02282 else { 02283 ast_mutex_unlock(&chan->lock); 02284 return 0; 02285 } 02286 } 02287 /* High bit prints debugging */ 02288 if (chan->fout & 0x80000000) 02289 ast_frame_dump(chan->name, fr, ">>"); 02290 CHECK_BLOCKING(chan); 02291 switch(fr->frametype) { 02292 case AST_FRAME_CONTROL: 02293 /* XXX Interpret control frames XXX */ 02294 ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n"); 02295 break; 02296 case AST_FRAME_DTMF: 02297 ast_clear_flag(chan, AST_FLAG_BLOCKING); 02298 ast_mutex_unlock(&chan->lock); 02299 res = do_senddigit(chan,fr->subclass); 02300 ast_mutex_lock(&chan->lock); 02301 CHECK_BLOCKING(chan); 02302 break; 02303 case AST_FRAME_TEXT: 02304 if (chan->tech->send_text) 02305 res = chan->tech->send_text(chan, (char *) fr->data); 02306 else 02307 res = 0; 02308 break; 02309 case AST_FRAME_HTML: 02310 if (chan->tech->send_html) 02311 res = chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen); 02312 else 02313 res = 0; 02314 break; 02315 case AST_FRAME_VIDEO: 02316 /* XXX Handle translation of video codecs one day XXX */ 02317 if (chan->tech->write_video) 02318 res = chan->tech->write_video(chan, fr); 02319 else 02320 res = 0; 02321 break; 02322 case AST_FRAME_NULL: 02323 case AST_FRAME_IAX: 02324 /* Ignore these */ 02325 res = 0; 02326 break; 02327 default: 02328 if (chan->tech->write) { 02329 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr; 02330 if (f) { 02331 if (f->frametype == AST_FRAME_VOICE && chan->spies) 02332 queue_frame_to_spies(chan, f, SPY_WRITE); 02333 02334 if( chan->monitor && chan->monitor->write_stream && 02335 f && ( f->frametype == AST_FRAME_VOICE ) ) { 02336 #ifndef MONITOR_CONSTANT_DELAY 02337 int jump = chan->insmpl - chan->outsmpl - 4 * f->samples; 02338 if (jump >= 0) { 02339 jump = chan->insmpl - chan->outsmpl; 02340 if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1) 02341 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 02342 chan->outsmpl += jump + f->samples; 02343 } else 02344 chan->outsmpl += f->samples; 02345 #else 02346 int jump = chan->insmpl - chan->outsmpl; 02347 if (jump - MONITOR_DELAY >= 0) { 02348 if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1) 02349 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 02350 chan->outsmpl += jump; 02351 } else 02352 chan->outsmpl += f->samples; 02353 #endif 02354 if (ast_writestream(chan->monitor->write_stream, f) < 0) 02355 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 02356 } 02357 02358 res = chan->tech->write(chan, f); 02359 } else 02360 res = 0; 02361 } 02362 } 02363 02364 /* It's possible this is a translated frame */ 02365 if (f && f->frametype == AST_FRAME_DTMF) { 02366 ast_log(LOG_DTMF, "%s : %c\n", chan->name, f->subclass); 02367 } else if (fr->frametype == AST_FRAME_DTMF) { 02368 ast_log(LOG_DTMF, "%s : %c\n", chan->name, fr->subclass); 02369 } 02370 02371 if (f && (f != fr)) 02372 ast_frfree(f); 02373 ast_clear_flag(chan, AST_FLAG_BLOCKING); 02374 /* Consider a write failure to force a soft hangup */ 02375 if (res < 0) 02376 chan->_softhangup |= AST_SOFTHANGUP_DEV; 02377 else { 02378 if ((chan->fout & 0x7fffffff) == 0x7fffffff) 02379 chan->fout &= 0x80000000; 02380 else 02381 chan->fout++; 02382 } 02383 ast_mutex_unlock(&chan->lock); 02384 return res; 02385 }
| int ast_write_video | ( | struct ast_channel * | chan, | |
| struct ast_frame * | frame | |||
| ) |
Write video frame to a channel
| chan | destination channel of the frame | |
| frame | frame that will be written This function writes the given frame to the indicated channel. It returns 1 on success, 0 if not implemented, and -1 on failure. |
Definition at line 2246 of file channel.c.
References ast_write(), ast_channel::tech, and ast_channel_tech::write_video.
02247 { 02248 int res; 02249 if (!chan->tech->write_video) 02250 return 0; 02251 res = ast_write(chan, fr); 02252 if (!res) 02253 res = 1; 02254 return res; 02255 }
| static void bridge_playfile | ( | struct ast_channel * | chan, | |
| struct ast_channel * | peer, | |||
| char * | sound, | |||
| int | remain | |||
| ) | [static] |
Definition at line 3304 of file channel.c.
References ast_autoservice_start(), ast_autoservice_stop(), AST_DIGIT_ANY, ast_say_number(), ast_streamfile(), ast_waitstream(), and ast_channel::language.
Referenced by ast_channel_bridge().
03305 { 03306 int res=0, min=0, sec=0,check=0; 03307 03308 check = ast_autoservice_start(peer); 03309 if(check) 03310 return; 03311 03312 if (remain > 0) { 03313 if (remain / 60 > 1) { 03314 min = remain / 60; 03315 sec = remain % 60; 03316 } else { 03317 sec = remain; 03318 } 03319 } 03320 03321 if (!strcmp(sound,"timeleft")) { /* Queue support */ 03322 res = ast_streamfile(chan, "vm-youhave", chan->language); 03323 res = ast_waitstream(chan, ""); 03324 if (min) { 03325 res = ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, (char *) NULL); 03326 res = ast_streamfile(chan, "queue-minutes", chan->language); 03327 res = ast_waitstream(chan, ""); 03328 } 03329 if (sec) { 03330 res = ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, (char *) NULL); 03331 res = ast_streamfile(chan, "queue-seconds", chan->language); 03332 res = ast_waitstream(chan, ""); 03333 } 03334 } else { 03335 res = ast_streamfile(chan, sound, chan->language); 03336 res = ast_waitstream(chan, ""); 03337 } 03338 03339 check = ast_autoservice_stop(peer); 03340 }
| 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, read] |
Definition at line 733 of file channel.c.
References ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), channels, ast_channel::context, ast_channel::exten, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::macrocontext, ast_channel::macroexten, ast_channel::name, and ast_channel::next.
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(), and ast_walk_channel_by_name_prefix_locked().
00736 { 00737 const char *msg = prev ? "deadlock" : "initial deadlock"; 00738 int retries; 00739 struct ast_channel *c; 00740 00741 for (retries = 0; retries < 10; retries++) { 00742 int done; 00743 00744 ast_mutex_lock(&chlock); 00745 for (c = channels; c; c = c->next) { 00746 if (prev) { /* look for next item */ 00747 if (c != prev) /* not this one */ 00748 continue; 00749 /* found, prepare to return c->next */ 00750 if ((c = c->next) == NULL) break; 00751 /* If prev was the last item on the channel list, then we just 00752 * want to return NULL, instead of trying to deref NULL in the 00753 * next section. 00754 */ 00755 } 00756 if (name) { /* want match by name */ 00757 if ((!namelen && strcasecmp(c->name, name)) || 00758 (namelen && strncasecmp(c->name, name, namelen))) 00759 continue; /* name match failed */ 00760 } else if (exten) { 00761 if (context && strcasecmp(c->context, context) && 00762 strcasecmp(c->macrocontext, context)) 00763 continue; /* context match failed */ 00764 if (strcasecmp(c->exten, exten) && 00765 strcasecmp(c->macroexten, exten)) 00766 continue; /* exten match failed */ 00767 } 00768 /* if we get here, c points to the desired record */ 00769 break; 00770 } 00771 /* exit if chan not found or mutex acquired successfully */ 00772 done = (c == NULL) || (ast_mutex_trylock(&c->lock) == 0); 00773 /* this is slightly unsafe, as we _should_ hold the lock to access c->name */ 00774 if (!done && c) { 00775 ast_log(LOG_DEBUG, "Avoiding %s for '%s'\n", msg, c->name); 00776 if (retries == 9) { 00777 /* We are about to fail due to a deadlock, so report this 00778 * while we still have the list lock. 00779 */ 00780 ast_log(LOG_WARNING, "Avoided %s for '%p', %d retries!\n", msg, c, retries); 00781 /* As we have deadlocked, we will skip this channel and see if 00782 * there is another match. 00783 * NOTE: No point doing this for a full-name match, as there 00784 * can be no more matches. 00785 */ 00786 if (!(name && !namelen)) { 00787 prev = c; 00788 retries = -1; 00789 } 00790 } 00791 } 00792 ast_mutex_unlock(&chlock); 00793 if (done) 00794 return c; 00795 usleep(1); 00796 } 00797 00798 return NULL; 00799 }
| static void clone_variables | ( | struct ast_channel * | original, | |
| struct ast_channel * | clone | |||
| ) | [static] |
Definition at line 2944 of file channel.c.
References AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_var_assign(), ast_var_t::name, ast_var_t::value, and ast_channel::varshead.
Referenced by ast_do_masquerade().
02945 { 02946 struct ast_var_t *current, *newvar; 02947 /* Append variables from clone channel into original channel */ 02948 /* XXX Is this always correct? We have to in order to keep MACROS working XXX */ 02949 if (AST_LIST_FIRST(&clone->varshead)) 02950 AST_LIST_APPEND_LIST(&original->varshead, &clone->varshead, entries); 02951 AST_LIST_HEAD_INIT_NOLOCK(&clone->varshead); 02952 02953 /* then, dup the varshead list into the clone */ 02954 02955 AST_LIST_TRAVERSE(&original->varshead, current, entries) { 02956 newvar = ast_var_assign(current->name, current->value); 02957 if (newvar) 02958 AST_LIST_INSERT_TAIL(&clone->varshead, newvar, entries); 02959 } 02960 }
| static void copy_data_from_queue | ( | struct ast_channel_spy_queue * | queue, | |
| short * | buf, | |||
| unsigned int | samples | |||
| ) | [static] |
Definition at line 3983 of file channel.c.
References ast_codec_get_len(), ast_frfree(), ast_log(), ast_frame::data, ast_frame::datalen, ast_channel_spy_queue::format, ast_channel_spy_queue::head, LOG_ERROR, ast_frame::next, ast_frame::offset, ast_channel_spy_queue::samples, and ast_frame::samples.
Referenced by ast_channel_spy_read_frame().
03984 { 03985 struct ast_frame *f; 03986 int tocopy; 03987 int bytestocopy; 03988 03989 while (samples) { 03990 f = queue->head; 03991 03992 if (!f) { 03993 ast_log(LOG_ERROR, "Ran out of frames before buffer filled!\n"); 03994 break; 03995 } 03996 03997 tocopy = (f->samples > samples) ? samples : f->samples; 03998 bytestocopy = ast_codec_get_len(queue->format, tocopy); 03999 memcpy(buf, f->data, bytestocopy); 04000 samples -= tocopy; 04001 buf += tocopy; 04002 f->samples -= tocopy; 04003 f->data += bytestocopy; 04004 f->datalen -= bytestocopy; 04005 f->offset += bytestocopy; 04006 queue->samples -= tocopy; 04007 if (!f->samples) { 04008 queue->head = f->next; 04009 ast_frfree(f); 04010 } 04011 } 04012 }
| static void detach_spies | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 1136 of file channel.c.
References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_channel::spies, spy_cleanup(), and spy_detach().
Referenced by ast_hangup().
01137 { 01138 struct ast_channel_spy *spy = NULL; 01139 01140 if (!chan->spies) 01141 return; 01142 01143 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list) { 01144 AST_LIST_REMOVE_CURRENT(&chan->spies->list, list); 01145 spy_detach(spy, chan); 01146 } 01147 AST_LIST_TRAVERSE_SAFE_END 01148 01149 spy_cleanup(chan); 01150 }
| static int do_senddigit | ( | struct ast_channel * | chan, | |
| char | digit | |||
| ) | [static] |
Definition at line 2180 of file channel.c.
References ast_log(), ast_playtones_start(), LOG_DEBUG, ast_channel::name, ast_channel_tech::send_digit, and ast_channel::tech.
Referenced by ast_senddigit(), and ast_write().
02181 { 02182 int res = -1; 02183 02184 if (chan->tech->send_digit) 02185 res = chan->tech->send_digit(chan, digit); 02186 if (!chan->tech->send_digit || res) { 02187 /* 02188 * Device does not support DTMF tones, lets fake 02189 * it by doing our own generation. (PM2002) 02190 */ 02191 static const char* dtmf_tones[] = { 02192 "!941+1336/100,!0/100", /* 0 */ 02193 "!697+1209/100,!0/100", /* 1 */ 02194 "!697+1336/100,!0/100", /* 2 */ 02195 "!697+1477/100,!0/100", /* 3 */ 02196 "!770+1209/100,!0/100", /* 4 */ 02197 "!770+1336/100,!0/100", /* 5 */ 02198 "!770+1477/100,!0/100", /* 6 */ 02199 "!852+1209/100,!0/100", /* 7 */ 02200 "!852+1336/100,!0/100", /* 8 */ 02201 "!852+1477/100,!0/100", /* 9 */ 02202 "!697+1633/100,!0/100", /* A */ 02203 "!770+1633/100,!0/100", /* B */ 02204 "!852+1633/100,!0/100", /* C */ 02205 "!941+1633/100,!0/100", /* D */ 02206 "!941+1209/100,!0/100", /* * */ 02207 "!941+1477/100,!0/100" }; /* # */ 02208 if (digit >= '0' && digit <='9') 02209 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0); 02210 else if (digit >= 'A' && digit <= 'D') 02211 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0); 02212 else if (digit == '*') 02213 ast_playtones_start(chan, 0, dtmf_tones[14], 0); 02214 else if (digit == '#') 02215 ast_playtones_start(chan, 0, dtmf_tones[15], 0); 02216 else { 02217 /* not handled */ 02218 ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name); 02219 } 02220 } 02221 return 0; 02222 }
| static void free_cid | ( | struct ast_callerid * | cid | ) | [static] |
Definition at line 871 of file channel.c.
References ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_rdnis, and free.
Referenced by ast_channel_free().
00872 { 00873 if (cid->cid_dnid) 00874 free(cid->cid_dnid); 00875 if (cid->cid_num) 00876 free(cid->cid_num); 00877 if (cid->cid_name) 00878 free(cid->cid_name); 00879 if (cid->cid_ani) 00880 free(cid->cid_ani); 00881 if (cid->cid_rdnis) 00882 free(cid->cid_rdnis); 00883 }
| static void free_translation | ( | struct ast_channel * | clone | ) | [static] |
Definition at line 1310 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().
01311 { 01312 if (clone->writetrans) 01313 ast_translator_free_path(clone->writetrans); 01314 if (clone->readtrans) 01315 ast_translator_free_path(clone->readtrans); 01316 clone->writetrans = NULL; 01317 clone->readtrans = NULL; 01318 clone->rawwriteformat = clone->nativeformats; 01319 clone->rawreadformat = clone->nativeformats; 01320 }
| static int generator_force | ( | void * | data | ) | [static] |
Definition at line 1457 of file channel.c.
References ast_deactivate_generator(), ast_log(), ast_generator::generate, ast_channel::generator, ast_channel::generatordata, and LOG_DEBUG.
Referenced by ast_activate_generator(), and ast_read().
01458 { 01459 /* Called if generator doesn't have data */ 01460 void *tmp; 01461 int res; 01462 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 01463 struct ast_channel *chan = data; 01464 tmp = chan->generatordata; 01465 chan->generatordata = NULL; 01466 generate = chan->generator->generate; 01467 res = generate(chan, tmp, 0, 160); 01468 chan->generatordata = tmp; 01469 if (res) { 01470 ast_log(LOG_DEBUG, "Auto-deactivating generator\n"); 01471 ast_deactivate_generator(chan); 01472 } 01473 return 0; 01474 }
| static void queue_frame_to_spies | ( | struct ast_channel * | chan, | |
| struct ast_frame * | f, | |||
| enum spy_direction | dir | |||
| ) | [static] |
Definition at line 1185 of file channel.c.
References ast_clear_flag, ast_cond_signal(), AST_FORMAT_SLINEAR, ast_frdup(), ast_frfree(), ast_getformatname(), AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_translate(), ast_translator_build_path(), ast_translator_free_path(), CHANSPY_RUNNING, CHANSPY_TRIGGER_FLUSH, CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_NONE, CHANSPY_TRIGGER_READ, CHANSPY_TRIGGER_WRITE, ast_channel_spy_queue::format, ast_channel_spy_queue::head, last, channel_spy_trans::last_format, ast_channel_spy::lock, LOG_DEBUG, LOG_ERROR, LOG_WARNING, ast_channel::name, ast_frame::next, option_debug, channel_spy_trans::path, ast_channel_spy::read_queue, ast_channel_spy_list::read_translator, ast_frame::samples, ast_channel_spy_queue::samples, ast_channel::spies, SPY_QUEUE_SAMPLE_LIMIT, SPY_READ, SPY_WRITE, ast_channel_spy::status, ast_frame::subclass, ast_channel_spy::trigger, ast_channel_spy::type, ast_channel_spy::write_queue, and ast_channel_spy_list::write_translator.
Referenced by ast_read(), and ast_write().
01186 { 01187 struct ast_frame *translated_frame = NULL; 01188 struct ast_channel_spy *spy; 01189 struct ast_channel_spy_queue *queue; 01190 struct channel_spy_trans *trans; 01191 struct ast_frame *last; 01192 01193 trans = (dir == SPY_READ) ? &chan->spies->read_translator : &chan->spies->write_translator; 01194 01195 AST_LIST_TRAVERSE(&chan->spies->list, spy, list) { 01196 if (spy->status != CHANSPY_RUNNING) 01197 continue; 01198 ast_mutex_lock(&spy->lock); 01199 01200 queue = (dir == SPY_READ) ? &spy->read_queue : &spy->write_queue; 01201 01202 if ((queue->format == AST_FORMAT_SLINEAR) && (f->subclass != AST_FORMAT_SLINEAR)) { 01203 if (!translated_frame) { 01204 if (trans->path && (trans->last_format != f->subclass)) { 01205 ast_translator_free_path(trans->path); 01206 trans->path = NULL; 01207 } 01208 if (!trans->path) { 01209 ast_log(LOG_DEBUG, "Building translator from %s to SLINEAR for spies on channel %s\n", 01210 ast_getformatname(f->subclass), chan->name); 01211 if ((trans->path = ast_translator_build_path(AST_FORMAT_SLINEAR, f->subclass)) == NULL) { 01212 ast_log(LOG_WARNING, "Cannot build a path from %s to %s\n", 01213 ast_getformatname(f->subclass), ast_getformatname(AST_FORMAT_SLINEAR)); 01214 ast_mutex_unlock(&spy->lock); 01215 continue; 01216 } else { 01217 trans->last_format = f->subclass; 01218 } 01219 } 01220 if (!(translated_frame = ast_translate(trans->path, f, 0))) { 01221 ast_log(LOG_ERROR, "Translation to %s failed, dropping frame for spies\n", 01222 ast_getformatname(AST_FORMAT_SLINEAR)); 01223 ast_mutex_unlock(&spy->lock); 01224 break; 01225 } 01226 } 01227 01228 for (last = queue->head; last && last->next; last = last->next); 01229 if (last) 01230 last->next = ast_frdup(translated_frame); 01231 else 01232 queue->head = ast_frdup(translated_frame); 01233 } else { 01234 if (f->subclass != queue->format) { 01235 ast_log(LOG_WARNING, "Spy '%s' on channel '%s' wants format '%s', but frame is '%s', dropping\n", 01236 spy->type, chan->name, 01237 ast_getformatname(queue->format), ast_getformatname(f->subclass)); 01238 ast_mutex_unlock(&spy->lock); 01239 continue; 01240 } 01241 01242 for (last = queue->head; last && last->next; last = last->next); 01243 if (last) 01244 last->next = ast_frdup(f); 01245 else 01246 queue->head = ast_frdup(f); 01247 } 01248 01249 queue->samples += f->samples; 01250 01251 if (queue->samples > SPY_QUEUE_SAMPLE_LIMIT) { 01252 if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) { 01253 switch (ast_test_flag(spy, CHANSPY_TRIGGER_MODE)) { 01254 case CHANSPY_TRIGGER_READ: 01255 if (dir == SPY_WRITE) { 01256 ast_set_flag(spy, CHANSPY_TRIGGER_WRITE); 01257 ast_clear_flag(spy, CHANSPY_TRIGGER_READ); 01258 if (option_debug) 01259 ast_log(LOG_DEBUG, "Switching spy '%s' on '%s' to write-trigger mode\n", 01260 spy->type, chan->name); 01261 } 01262 break; 01263 case CHANSPY_TRIGGER_WRITE: 01264 if (dir == SPY_READ) { 01265 ast_set_flag(spy, CHANSPY_TRIGGER_READ); 01266 ast_clear_flag(spy, CHANSPY_TRIGGER_WRITE); 01267 if (option_debug) 01268 ast_log(LOG_DEBUG, "Switching spy '%s' on '%s' to read-trigger mode\n", 01269 spy->type, chan->name); 01270 } 01271 break; 01272 } 01273 if (option_debug) 01274 ast_log(LOG_DEBUG, "Triggering queue flush for spy '%s' on '%s'\n", 01275 spy->type, chan->name); 01276 ast_set_flag(spy, CHANSPY_TRIGGER_FLUSH); 01277 ast_cond_signal(&spy->trigger); 01278 } else { 01279 if (option_debug) 01280 ast_log(LOG_DEBUG, "Spy '%s' on channel '%s' %s queue too long, dropping frames\n", 01281 spy->type, chan->name, (dir == SPY_READ) ? "read" : "write"); 01282 while (queue->samples > SPY_QUEUE_SAMPLE_LIMIT) { 01283 struct ast_frame *drop = queue->head; 01284 01285 queue->samples -= drop->samples; 01286 queue->head = drop->next; 01287 ast_frfree(drop); 01288 } 01289 } 01290 } else { 01291 switch (ast_test_flag(spy, CHANSPY_TRIGGER_MODE)) { 01292 case CHANSPY_TRIGGER_READ: 01293 if (dir == SPY_READ) 01294 ast_cond_signal(&spy->trigger); 01295 break; 01296 case CHANSPY_TRIGGER_WRITE: 01297 if (dir == SPY_WRITE) 01298 ast_cond_signal(&spy->trigger); 01299 break; 01300 } 01301 } 01302 01303 ast_mutex_unlock(&spy->lock); 01304 } 01305 01306 if (translated_frame) 01307 ast_frfree(translated_frame); 01308 }
| 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 2387 of file channel.c.
References ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_translator_best_choice(), ast_translator_build_path(), ast_translator_free_path(), ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, and option_debug.
Referenced by ast_set_read_format(), and ast_set_write_format().
02389 { 02390 int native; 02391 int res; 02392 02393 native = chan->nativeformats; 02394 /* Find a translation path from the native format to one of the desired formats */ 02395 if (!direction) 02396 /* reading */ 02397 res = ast_translator_best_choice(&fmt, &native); 02398 else 02399 /* writing */ 02400 res = ast_translator_best_choice(&native, &fmt); 02401 02402 if (res < 0) { 02403 ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n", 02404 ast_getformatname(native), ast_getformatname(fmt)); 02405 return -1; 02406 } 02407 02408 /* Now we have a good choice for both. */ 02409 ast_mutex_lock(&chan->lock); 02410 02411 if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) { 02412 /* the channel is already in these formats, so nothing to do */ 02413 ast_mutex_unlock(&chan->lock); 02414 return 0; 02415 } 02416 02417 *rawformat = native; 02418 /* User perspective is fmt */ 02419 *format = fmt; 02420 /* Free any read translation we have right now */ 02421 if (*trans) 02422 ast_translator_free_path(*trans); 02423 /* Build a translation path from the raw format to the desired format */ 02424 if (!direction) 02425 /* reading */ 02426 *trans = ast_translator_build_path(*format, *rawformat); 02427 else 02428 /* writing */ 02429 *trans = ast_translator_build_path(*rawformat, *format); 02430 ast_mutex_unlock(&chan->lock); 02431 if (option_debug) 02432 ast_log(LOG_DEBUG, "Set channel %s to %s format %s\n", chan->name, 02433 direction ? "write" : "read", ast_getformatname(fmt)); 02434 return 0; 02435 }
| static int show_channeltypes | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 171 of file channel.c.
References ast_cli(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), backends, ast_channel_tech::description, ast_channel_tech::devicestate, FORMAT, ast_channel_tech::indicate, LOG_WARNING, chanlist::next, RESULT_SUCCESS, chanlist::tech, ast_channel_tech::transfer, and ast_channel_tech::type.
00172 { 00173 #define FORMAT "%-10.10s %-30.30s %-12.12s %-12.12s %-12.12s\n" 00174 struct chanlist *cl = backends; 00175 ast_cli(fd, FORMAT, "Type", "Description", "Devicestate", "Indications", "Transfer"); 00176 ast_cli(fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------"); 00177 if (ast_mutex_lock(&chlock)) { 00178 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 00179 return -1; 00180 } 00181 while (cl) { 00182 ast_cli(fd, FORMAT, cl->tech->type, cl->tech->description, 00183 (cl->tech->devicestate) ? "yes" : "no", 00184 (cl->tech->indicate) ? "yes" : "no", 00185 (cl->tech->transfer) ? "yes" : "no"); 00186 cl = cl->next; 00187 } 00188 ast_mutex_unlock(&chlock); 00189 return RESULT_SUCCESS; 00190 00191 #undef FORMAT 00192 00193 }
| 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 4127 of file channel.c.
References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_write(), and ast_frame::frametype.
04128 { 04129 if (samples == 160) { 04130 short buf[160] = { 0, }; 04131 struct ast_frame frame = { 04132 .frametype = AST_FRAME_VOICE, 04133 .subclass = AST_FORMAT_SLINEAR, 04134 .data = buf, 04135 .samples = 160, 04136 .datalen = sizeof(buf), 04137 }; 04138 04139 if (ast_write(chan, &frame)) 04140 return -1; 04141 } else { 04142 short buf[samples]; 04143 int x; 04144 struct ast_frame frame = { 04145 .frametype = AST_FRAME_VOICE, 04146 .subclass = AST_FORMAT_SLINEAR, 04147 .data = buf, 04148 .samples = samples, 04149 .datalen = sizeof(buf), 04150 }; 04151 04152 for (x = 0; x < samples; x++) 04153 buf[x] = 0; 04154 04155 if (ast_write(chan, &frame)) 04156 return -1; 04157 } 04158 04159 return 0; 04160 }
| static void silence_generator_release | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
| static void spy_cleanup | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 1034 of file channel.c.
References AST_LIST_FIRST, ast_translator_free_path(), free, channel_spy_trans::path, ast_channel_spy_list::read_translator, ast_channel::spies, and ast_channel_spy_list::write_translator.
Referenced by ast_channel_spy_remove(), ast_channel_spy_stop_by_type(), and detach_spies().
01035 { 01036 if (AST_LIST_FIRST(&chan->spies->list)) 01037 return; 01038 if (chan->spies->read_translator.path) 01039 ast_translator_free_path(chan->spies->read_translator.path); 01040 if (chan->spies->write_translator.path) 01041 ast_translator_free_path(chan->spies->write_translator.path); 01042 free(chan->spies); 01043 chan->spies = NULL; 01044 return; 01045 }
| static void spy_detach | ( | struct ast_channel_spy * | spy, | |
| struct ast_channel * | chan | |||
| ) | [static] |
Definition at line 1048 of file channel.c.
References ast_cond_signal(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_channel_spy::chan, CHANSPY_DONE, CHANSPY_STOP, CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_NONE, ast_channel_spy::lock, LOG_DEBUG, ast_channel::name, ast_channel_spy::status, ast_channel_spy::trigger, and ast_channel_spy::type.
Referenced by ast_channel_spy_remove(), ast_channel_spy_stop_by_type(), and detach_spies().
01049 { 01050 /* We only need to poke them if they aren't already done */ 01051 if (spy->status != CHANSPY_DONE) { 01052 ast_mutex_lock(&spy->lock); 01053 spy->status = CHANSPY_STOP; 01054 spy->chan = NULL; 01055 if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) 01056 ast_cond_signal(&spy->trigger); 01057 ast_mutex_unlock(&spy->lock); 01058 } 01059 01060 /* Print it out while we still have a lock so the structure can't go away (if signalled above) */ 01061 ast_log(LOG_DEBUG, "Spy %s removed from channel %s\n", spy->type, chan->name); 01062 01063 return; 01064 }
| static void* tonepair_alloc | ( | struct ast_channel * | chan, | |
| void * | params | |||
| ) | [static] |
Definition at line 3755 of file channel.c.
References AST_FLAG_WRITE_INT, AST_FORMAT_SLINEAR, ast_log(), ast_set_flag, ast_set_write_format(), tonepair_def::duration, tonepair_state::duration, tonepair_def::freq1, tonepair_state::freq1, tonepair_def::freq2, tonepair_state::freq2, LOG_WARNING, malloc, ast_channel::name, tonepair_state::origwfmt, tonepair_release(), tonepair_def::vol, tonepair_state::vol, and ast_channel::writeformat.
03756 { 03757 struct tonepair_state *ts; 03758 struct tonepair_def *td = params; 03759 03760 ts = malloc(sizeof(struct tonepair_state)); 03761 if (!ts) 03762 return NULL; 03763 memset(ts, 0, sizeof(struct tonepair_state)); 03764 ts->origwfmt = chan->writeformat; 03765 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) { 03766 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name); 03767 tonepair_release(NULL, ts); 03768 ts = NULL; 03769 } else { 03770 ts->freq1 = td->freq1; 03771 ts->freq2 = td->freq2; 03772 ts->duration = td->duration; 03773 ts->vol = td->vol; 03774 } 03775 /* Let interrupts interrupt :) */ 03776 ast_set_flag(chan, AST_FLAG_WRITE_INT); 03777 return ts; 03778 }
| static int tonepair_generator | ( | struct ast_channel * | chan, | |
| void * | data, | |||
| int | len, | |||
| int | samples | |||
| ) | [static] |
Definition at line 3780 of file channel.c.
References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_write(), ast_frame::data, tonepair_state::data, ast_frame::datalen, tonepair_state::duration, tonepair_state::f, ast_frame::frametype, tonepair_state::freq1, tonepair_state::freq2, LOG_WARNING, ast_frame::offset, tonepair_state::pos, ast_frame::samples, ast_frame::subclass, and tonepair_state::vol.
03781 { 03782 struct tonepair_state *ts = data; 03783 int x; 03784 03785 /* we need to prepare a frame with 16 * timelen samples as we're 03786 * generating SLIN audio 03787 */ 03788 len = samples * 2; 03789 03790 if (len > sizeof(ts->data) / 2 - 1) { 03791 ast_log(LOG_WARNING, "Can't generate that much data!\n"); 03792 return -1; 03793 } 03794 memset(&ts->f, 0, sizeof(ts->f)); 03795 for (x = 0; x < (len / 2); x++) { 03796 ts->data[x] = ts->vol * ( 03797 sin((ts->freq1 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) + 03798 sin((ts->freq2 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) 03799 ); 03800 } 03801 ts->f.frametype = AST_FRAME_VOICE; 03802 ts->f.subclass = AST_FORMAT_SLINEAR; 03803 ts->f.datalen = len; 03804 ts->f.samples = samples; 03805 ts->f.offset = AST_FRIENDLY_OFFSET; 03806 ts->f.data = ts->data; 03807 ast_write(chan, &ts->f); 03808 ts->pos += x; 03809 if (ts->duration > 0) { 03810 if (ts->pos >= ts->duration * 8) 03811 return -1; 03812 } 03813 return 0; 03814 }
| static void tonepair_release | ( | struct ast_channel * | chan, | |
| void * | params | |||
| ) | [static] |
Definition at line 3745 of file channel.c.
References ast_set_write_format(), free, and tonepair_state::origwfmt.
Referenced by tonepair_alloc().
03746 { 03747 struct tonepair_state *ts = params; 03748 03749 if (chan) { 03750 ast_set_write_format(chan, ts->origwfmt); 03751 } 03752 free(ts); 03753 }
void(* ast_moh_cleanup_ptr)(struct ast_channel *) = NULL [static] |
Referenced by ast_install_music_functions(), ast_moh_cleanup(), and ast_uninstall_music_functions().
int(* ast_moh_start_ptr)(struct ast_channel *, char *) = NULL [static] |
Referenced by ast_install_music_functions(), ast_moh_start(), and ast_uninstall_music_functions().
void(* ast_moh_stop_ptr)(struct ast_channel *) = NULL [static] |
Referenced by ast_install_music_functions(), ast_moh_stop(), and ast_uninstall_music_functions().
Definition at line 109 of file channel.c.
Referenced by ast_channel_register(), ast_channel_unregister(), ast_get_channel_tech(), ast_request(), and show_channeltypes().
Referenced by ast_cause2str(), and dump_cause().
struct ast_channel* channels = NULL [static] |
Definition at line 114 of file channel.c.
Referenced by add_channel(), ast_active_channels(), ast_begin_shutdown(), ast_channel_alloc(), ast_channel_free(), channel_find_locked(), check_header(), check_mute(), find_channel(), getvol(), load_config(), and setvol().
struct ast_cli_entry cli_show_channeltypes [static] |
Initial value:
{ { "show", "channeltypes", NULL }, show_channeltypes, "Show available channel types", show_channeltypes_usage }
Definition at line 199 of file channel.c.
Referenced by ast_channels_init().
| unsigned long global_fin = 0 |
| unsigned long global_fout = 0 |
struct ast_channel_tech null_tech [static] |
Initial value:
{
.type = "NULL",
.description = "Null channel (should not see this)",
}
Definition at line 513 of file channel.c.
Referenced by ast_channel_alloc().
char show_channeltypes_usage[] [static] |
int shutting_down = 0 [static] |
Definition at line 95 of file channel.c.
Referenced by ast_begin_shutdown(), ast_cancel_shutdown(), ast_channel_alloc(), and ast_shutting_down().
struct ast_generator silence_generator [static] |
Initial value:
{
.alloc = silence_generator_alloc,
.release = silence_generator_release,
.generate = silence_generator_generate,
}
struct ast_generator tonepair [static] |
Initial value:
{
alloc: tonepair_alloc,
release: tonepair_release,
generate: tonepair_generator,
}
Definition at line 3816 of file channel.c.
Referenced by ast_tonepair_start().
int uniqueint = 0 [static] |
1.5.6