#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 | |
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) |
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. | |
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. | |
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. | |
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. | |
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) |
ast_channel * | ast_get_channel_by_exten_locked (const char *exten, const char *context) |
ast_channel * | ast_get_channel_by_name_locked (const char *name) |
ast_channel * | ast_get_channel_by_name_prefix_locked (const char *name, const int namelen) |
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. | |
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) |
ast_channel * | ast_request (const char *type, int format, void *data, int *cause) |
Requests a channel. | |
ast_channel * | ast_request_and_dial (const char *type, int format, void *data, int timeout, int *outstate, const char *cidnum, const char *cidname) |
Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it. | |
int | ast_safe_sleep (struct ast_channel *chan, int ms) |
Wait for a 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. | |
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) |
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) |
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 |
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 | |||
) |
Definition at line 2426 of file channel.c.
References ast_channel::_state, 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_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, ast_channel::context, ast_channel::exten, ast_frame::frametype, ast_channel::hangupcause, LOG_NOTICE, LOG_WARNING, ast_channel::priority, and ast_frame::subclass.
Referenced by ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_request_and_dial(), and parkandannounce_exec().
02427 { 02428 int state = 0; 02429 int cause = 0; 02430 struct ast_channel *chan; 02431 struct ast_frame *f; 02432 int res = 0; 02433 02434 chan = ast_request(type, format, data, &cause); 02435 if (chan) { 02436 if (oh) { 02437 if (oh->vars) 02438 ast_set_variables(chan, oh->vars); 02439 if (oh->cid_num && *oh->cid_num && oh->cid_name && *oh->cid_name) 02440 ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num); 02441 if (oh->parent_channel) 02442 ast_channel_inherit_variables(oh->parent_channel, chan); 02443 if (oh->account) 02444 ast_cdr_setaccount(chan, oh->account); 02445 } 02446 ast_set_callerid(chan, cid_num, cid_name, cid_num); 02447 02448 if (!ast_call(chan, data, 0)) { 02449 res = 1; /* in case chan->_state is already AST_STATE_UP */ 02450 while (timeout && (chan->_state != AST_STATE_UP)) { 02451 res = ast_waitfor(chan, timeout); 02452 if (res < 0) { 02453 /* Something not cool, or timed out */ 02454 break; 02455 } 02456 /* If done, break out */ 02457 if (!res) 02458 break; 02459 if (timeout > -1) 02460 timeout = res; 02461 f = ast_read(chan); 02462 if (!f) { 02463 state = AST_CONTROL_HANGUP; 02464 res = 0; 02465 break; 02466 } 02467 if (f->frametype == AST_FRAME_CONTROL) { 02468 if (f->subclass == AST_CONTROL_RINGING) 02469 state = AST_CONTROL_RINGING; 02470 else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) { 02471 state = f->subclass; 02472 ast_frfree(f); 02473 break; 02474 } else if (f->subclass == AST_CONTROL_ANSWER) { 02475 state = f->subclass; 02476 ast_frfree(f); 02477 break; 02478 } else if (f->subclass == AST_CONTROL_PROGRESS) { 02479 /* Ignore */ 02480 } else if (f->subclass == -1) { 02481 /* Ignore -- just stopping indications */ 02482 } else { 02483 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass); 02484 } 02485 } 02486 ast_frfree(f); 02487 } 02488 } else 02489 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data); 02490 } else { 02491 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 02492 switch(cause) { 02493 case AST_CAUSE_BUSY: 02494 state = AST_CONTROL_BUSY; 02495 break; 02496 case AST_CAUSE_CONGESTION: 02497 state = AST_CONTROL_CONGESTION; 02498 break; 02499 } 02500 } 02501 if (chan) { 02502 /* Final fixups */ 02503 if (oh) { 02504 if (oh->context && *oh->context) 02505 ast_copy_string(chan->context, oh->context, sizeof(chan->context)); 02506 if (oh->exten && *oh->exten) 02507 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten)); 02508 if (oh->priority) 02509 chan->priority = oh->priority; 02510 } 02511 if (chan->_state == AST_STATE_UP) 02512 state = AST_CONTROL_ANSWER; 02513 } 02514 if (outstate) 02515 *outstate = state; 02516 if (chan && res <= 0) { 02517 if (!chan->cdr) { 02518 chan->cdr = ast_cdr_alloc(); 02519 if (chan->cdr) 02520 ast_cdr_init(chan->cdr, chan); 02521 } 02522 if (chan->cdr) { 02523 char tmp[256]; 02524 snprintf(tmp, 256, "%s/%s", type, (char *)data); 02525 ast_cdr_setapp(chan->cdr,"Dial",tmp); 02526 ast_cdr_update(chan); 02527 ast_cdr_start(chan->cdr); 02528 ast_cdr_end(chan->cdr); 02529 /* If the cause wasn't handled properly */ 02530 if (ast_cdr_disposition(chan->cdr,chan->hangupcause)) 02531 ast_cdr_failed(chan->cdr); 02532 } else 02533 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 02534 ast_hangup(chan); 02535 chan = NULL; 02536 } 02537 return chan; 02538 }
int ast_activate_generator | ( | struct ast_channel * | chan, | |
struct ast_generator * | gen, | |||
void * | params | |||
) |
Activate a given generator
Definition at line 1460 of file channel.c.
References ast_generator::alloc, ast_mutex_lock(), ast_mutex_unlock(), ast_prod(), ast_settimeout(), gen, 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(), and milliwatt_exec().
01461 { 01462 int res = 0; 01463 01464 ast_mutex_lock(&chan->lock); 01465 01466 if (chan->generatordata) { 01467 if (chan->generator && chan->generator->release) 01468 chan->generator->release(chan, chan->generatordata); 01469 chan->generatordata = NULL; 01470 } 01471 01472 ast_prod(chan); 01473 if (gen->alloc) { 01474 if (!(chan->generatordata = gen->alloc(chan, params))) 01475 res = -1; 01476 } 01477 01478 if (!res) { 01479 ast_settimeout(chan, 160, generator_force, chan); 01480 chan->generator = gen; 01481 } 01482 01483 ast_mutex_unlock(&chan->lock); 01484 01485 return res; 01486 }
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 1396 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(), 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(), rpt_exec(), rxfax_exec(), sayunixtime_exec(), send_waveform_to_channel(), skel_exec(), testclient_exec(), testserver_exec(), txfax_exec(), vm_exec(), vm_execmain(), waitforsilence_exec(), zapateller_exec(), and zapras_exec().
01397 { 01398 int res = 0; 01399 ast_mutex_lock(&chan->lock); 01400 /* Stop if we're a zombie or need a soft hangup */ 01401 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 01402 ast_mutex_unlock(&chan->lock); 01403 return -1; 01404 } 01405 switch(chan->_state) { 01406 case AST_STATE_RINGING: 01407 case AST_STATE_RING: 01408 if (chan->tech->answer) 01409 res = chan->tech->answer(chan); 01410 ast_setstate(chan, AST_STATE_UP); 01411 if (chan->cdr) 01412 ast_cdr_answer(chan->cdr); 01413 ast_mutex_unlock(&chan->lock); 01414 return res; 01415 break; 01416 case AST_STATE_UP: 01417 if (chan->cdr) 01418 ast_cdr_answer(chan->cdr); 01419 break; 01420 } 01421 ast_mutex_unlock(&chan->lock); 01422 return 0; 01423 }
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, 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 468 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().
00469 { 00470 /* This just our opinion, expressed in code. We are asked to choose 00471 the best codec to use, given no information */ 00472 int x; 00473 static int prefs[] = 00474 { 00475 /* Okay, ulaw is used by all telephony equipment, so start with it */ 00476 AST_FORMAT_ULAW, 00477 /* Unless of course, you're a silly European, so then prefer ALAW */ 00478 AST_FORMAT_ALAW, 00479 /* Okay, well, signed linear is easy to translate into other stuff */ 00480 AST_FORMAT_SLINEAR, 00481 /* G.726 is standard ADPCM */ 00482 AST_FORMAT_G726, 00483 /* ADPCM has great sound quality and is still pretty easy to translate */ 00484 AST_FORMAT_ADPCM, 00485 /* Okay, we're down to vocoders now, so pick GSM because it's small and easier to 00486 translate and sounds pretty good */ 00487 AST_FORMAT_GSM, 00488 /* iLBC is not too bad */ 00489 AST_FORMAT_ILBC, 00490 /* Speex is free, but computationally more expensive than GSM */ 00491 AST_FORMAT_SPEEX, 00492 /* Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough 00493 to use it */ 00494 AST_FORMAT_LPC10, 00495 /* G.729a is faster than 723 and slightly less expensive */ 00496 AST_FORMAT_G729A, 00497 /* Down to G.723.1 which is proprietary but at least designed for voice */ 00498 AST_FORMAT_G723_1, 00499 }; 00500 00501 00502 /* Find the first prefered codec in the format given */ 00503 for (x=0; x < (sizeof(prefs) / sizeof(prefs[0]) ); x++) 00504 if (fmts & prefs[x]) 00505 return prefs[x]; 00506 ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts); 00507 return 0; 00508 }
struct ast_channel* ast_bridged_channel | ( | struct ast_channel * | chan | ) |
Find bridged channel.
chan | Current channel |
Definition at line 3271 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(), 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(), skinny_ss(), socket_read(), ss_thread(), start_spying(), startmon(), zt_handle_event(), and zt_hangup().
03272 { 03273 struct ast_channel *bridged; 03274 bridged = chan->_bridge; 03275 if (bridged && bridged->tech->bridged_channel) 03276 bridged = bridged->tech->bridged_channel(chan, bridged); 03277 return bridged; 03278 }
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 2604 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().
02605 { 02606 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 02607 If the remote end does not answer within the timeout, then do NOT hang up, but 02608 return anyway. */ 02609 int res = -1; 02610 /* Stop if we're a zombie or need a soft hangup */ 02611 ast_mutex_lock(&chan->lock); 02612 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) 02613 if (chan->tech->call) 02614 res = chan->tech->call(chan, addr, timeout); 02615 ast_mutex_unlock(&chan->lock); 02616 return res; 02617 }
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 | ) |
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 407 of file channel.c.
Referenced by __transmit_response(), ast_hangup(), dial_exec_full(), and transmit_request_with_auth().
00408 { 00409 int x; 00410 00411 for (x=0; x < sizeof(causes) / sizeof(causes[0]); x++) 00412 if (causes[x].cause == cause) 00413 return causes[x].desc; 00414 00415 return "Unknown"; 00416 }
void ast_change_name | ( | struct ast_channel * | chan, | |
char * | newname | |||
) |
Change channel name.
Definition at line 2857 of file channel.c.
References EVENT_FLAG_CALL, manager_event(), ast_channel::name, and ast_channel::uniqueid.
02858 { 02859 char tmp[256]; 02860 ast_copy_string(tmp, chan->name, sizeof(tmp)); 02861 ast_copy_string(chan->name, newname, sizeof(chan->name)); 02862 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid); 02863 }
struct ast_channel* ast_channel_alloc | ( | int | needalertpipe | ) |
Create a channel structure.
Definition at line 516 of file channel.c.
References ast_log(), AST_MAX_FDS, ast_channel::fds, ast_channel::flags, free, LOG_WARNING, malloc, ast_channel::sched, sched_context_create(), shutting_down, and ast_channel::timingfd.
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().
00517 { 00518 struct ast_channel *tmp; 00519 int x; 00520 int flags; 00521 struct varshead *headp; 00522 00523 00524 /* If shutting down, don't allocate any new channels */ 00525 if (shutting_down) { 00526 ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n"); 00527 return NULL; 00528 } 00529 00530 tmp = malloc(sizeof(struct ast_channel)); 00531 if (!tmp) { 00532 ast_log(LOG_WARNING, "Channel allocation failed: Out of memory\n"); 00533 return NULL; 00534 } 00535 00536 memset(tmp, 0, sizeof(struct ast_channel)); 00537 tmp->sched = sched_context_create(); 00538 if (!tmp->sched) { 00539 ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n"); 00540 free(tmp); 00541 return NULL; 00542 } 00543 00544 for (x=0; x<AST_MAX_FDS - 1; x++) 00545 tmp->fds[x] = -1; 00546 00547 #ifdef ZAPTEL_OPTIMIZATIONS 00548 tmp->timingfd = open("/dev/zap/timer", O_RDWR); 00549 if (tmp->timingfd > -1) { 00550 /* Check if timing interface supports new 00551 ping/pong scheme */ 00552 flags = 1; 00553 if (!ioctl(tmp->timingfd, ZT_TIMERPONG, &flags)) 00554 needqueue = 0; 00555 } 00556 #else 00557 tmp->timingfd = -1; 00558 #endif 00559 00560 if (needqueue) { 00561 if (pipe(tmp->alertpipe)) { 00562 ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n"); 00563 free(tmp); 00564 return NULL; 00565 } else { 00566 flags = fcntl(tmp->alertpipe[0], F_GETFL); 00567 fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK); 00568 flags = fcntl(tmp->alertpipe[1], F_GETFL); 00569 fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK); 00570 } 00571 } else 00572 /* Make sure we've got it done right if they don't */ 00573 tmp->alertpipe[0] = tmp->alertpipe[1] = -1; 00574 00575 /* Always watch the alertpipe */ 00576 tmp->fds[AST_MAX_FDS-1] = tmp->alertpipe[0]; 00577 /* And timing pipe */ 00578 tmp->fds[AST_MAX_FDS-2] = tmp->timingfd; 00579 strcpy(tmp->name, "**Unknown**"); 00580 /* Initial state */ 00581 tmp->_state = AST_STATE_DOWN; 00582 tmp->streamid = -1; 00583 tmp->appl = NULL; 00584 tmp->data = NULL; 00585 tmp->fin = global_fin; 00586 tmp->fout = global_fout; 00587 ast_mutex_lock(&uniquelock); 00588 snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long) time(NULL), uniqueint++); 00589 ast_mutex_unlock(&uniquelock); 00590 headp = &tmp->varshead; 00591 ast_mutex_init(&tmp->lock); 00592 AST_LIST_HEAD_INIT_NOLOCK(headp); 00593 strcpy(tmp->context, "default"); 00594 ast_copy_string(tmp->language, defaultlanguage, sizeof(tmp->language)); 00595 strcpy(tmp->exten, "s"); 00596 tmp->priority = 1; 00597 tmp->amaflags = ast_default_amaflags; 00598 ast_copy_string(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode)); 00599 00600 tmp->tech = &null_tech; 00601 00602 ast_mutex_lock(&chlock); 00603 tmp->next = channels; 00604 channels = tmp; 00605 00606 ast_mutex_unlock(&chlock); 00607 return tmp; 00608 }
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 | |||
) |
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 3432 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_test_flag, ast_tvadd(), ast_tvsub(), ast_verbose(), ast_channel_tech::bridge, bridge_playfile(), ast_channel::cid, ast_callerid::cid_num, config, EVENT_FLAG_CALL, ast_channel::generator, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, option_verbose, ast_channel::readformat, ast_channel::spies, ast_channel::tech, ast_channel::uniqueid, VERBOSE_PREFIX_3, and ast_channel::writeformat.
Referenced by ast_bridge_call().
03434 { 03435 struct ast_channel *who = NULL; 03436 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 03437 int nativefailed=0; 03438 int firstpass; 03439 int o0nativeformats; 03440 int o1nativeformats; 03441 long time_left_ms=0; 03442 struct timeval nexteventts = { 0, }; 03443 char caller_warning = 0; 03444 char callee_warning = 0; 03445 03446 if (c0->_bridge) { 03447 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 03448 c0->name, c0->_bridge->name); 03449 return -1; 03450 } 03451 if (c1->_bridge) { 03452 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 03453 c1->name, c1->_bridge->name); 03454 return -1; 03455 } 03456 03457 /* Stop if we're a zombie or need a soft hangup */ 03458 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 03459 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 03460 return -1; 03461 03462 *fo = NULL; 03463 firstpass = config->firstpass; 03464 config->firstpass = 0; 03465 03466 if (ast_tvzero(config->start_time)) 03467 config->start_time = ast_tvnow(); 03468 time_left_ms = config->timelimit; 03469 03470 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING); 03471 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING); 03472 03473 if (config->start_sound && firstpass) { 03474 if (caller_warning) 03475 bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000); 03476 if (callee_warning) 03477 bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000); 03478 } 03479 03480 /* Keep track of bridge */ 03481 c0->_bridge = c1; 03482 c1->_bridge = c0; 03483 03484 manager_event(EVENT_FLAG_CALL, "Link", 03485 "Channel1: %s\r\n" 03486 "Channel2: %s\r\n" 03487 "Uniqueid1: %s\r\n" 03488 "Uniqueid2: %s\r\n" 03489 "CallerID1: %s\r\n" 03490 "CallerID2: %s\r\n", 03491 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03492 03493 o0nativeformats = c0->nativeformats; 03494 o1nativeformats = c1->nativeformats; 03495 03496 if (config->feature_timer) { 03497 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000)); 03498 } else if (config->timelimit) { 03499 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 03500 if (caller_warning || callee_warning) 03501 nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000)); 03502 } 03503 03504 for (/* ever */;;) { 03505 struct timeval now = { 0, }; 03506 int to; 03507 03508 to = -1; 03509 03510 if (!ast_tvzero(nexteventts)) { 03511 now = ast_tvnow(); 03512 to = ast_tvdiff_ms(nexteventts, now); 03513 if (to < 0) 03514 to = 0; 03515 } 03516 03517 if (config->timelimit) { 03518 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time); 03519 if (time_left_ms < to) 03520 to = time_left_ms; 03521 03522 if (time_left_ms <= 0) { 03523 if (caller_warning && config->end_sound) 03524 bridge_playfile(c0, c1, config->end_sound, 0); 03525 if (callee_warning && config->end_sound) 03526 bridge_playfile(c1, c0, config->end_sound, 0); 03527 *fo = NULL; 03528 if (who) 03529 *rc = who; 03530 res = 0; 03531 break; 03532 } 03533 03534 if (!to) { 03535 if (time_left_ms >= 5000) { 03536 /* force the time left to round up if appropriate */ 03537 if (caller_warning && config->warning_sound && config->play_warning) 03538 bridge_playfile(c0, c1, config->warning_sound, 03539 (time_left_ms + 500) / 1000); 03540 if (callee_warning && config->warning_sound && config->play_warning) 03541 bridge_playfile(c1, c0, config->warning_sound, 03542 (time_left_ms + 500) / 1000); 03543 } 03544 if (config->warning_freq) { 03545 nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000)); 03546 } else 03547 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 03548 } 03549 } 03550 03551 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) { 03552 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03553 c0->_softhangup = 0; 03554 if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03555 c1->_softhangup = 0; 03556 c0->_bridge = c1; 03557 c1->_bridge = c0; 03558 ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n"); 03559 continue; 03560 } 03561 03562 /* Stop if we're a zombie or need a soft hangup */ 03563 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 03564 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) { 03565 *fo = NULL; 03566 if (who) 03567 *rc = who; 03568 res = 0; 03569 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", 03570 c0->name, c1->name, 03571 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No", 03572 ast_check_hangup(c0) ? "Yes" : "No", 03573 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No", 03574 ast_check_hangup(c1) ? "Yes" : "No"); 03575 break; 03576 } 03577 03578 if (c0->tech->bridge && 03579 (config->timelimit == 0) && 03580 (c0->tech->bridge == c1->tech->bridge) && 03581 !nativefailed && !c0->monitor && !c1->monitor && 03582 !c0->spies && !c1->spies && !ast_test_flag(&(config->features_callee),AST_FEATURE_REDIRECT) && 03583 !ast_test_flag(&(config->features_caller),AST_FEATURE_REDIRECT) ) { 03584 /* Looks like they share a bridge method and nothing else is in the way */ 03585 if (option_verbose > 2) 03586 ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name); 03587 ast_set_flag(c0, AST_FLAG_NBRIDGE); 03588 ast_set_flag(c1, AST_FLAG_NBRIDGE); 03589 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) { 03590 manager_event(EVENT_FLAG_CALL, "Unlink", 03591 "Channel1: %s\r\n" 03592 "Channel2: %s\r\n" 03593 "Uniqueid1: %s\r\n" 03594 "Uniqueid2: %s\r\n" 03595 "CallerID1: %s\r\n" 03596 "CallerID2: %s\r\n", 03597 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03598 ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name); 03599 03600 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 03601 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 03602 03603 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03604 continue; 03605 03606 c0->_bridge = NULL; 03607 c1->_bridge = NULL; 03608 03609 return res; 03610 } else { 03611 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 03612 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 03613 } 03614 switch (res) { 03615 case AST_BRIDGE_RETRY: 03616 continue; 03617 default: 03618 ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name); 03619 /* fallthrough */ 03620 case AST_BRIDGE_FAILED_NOWARN: 03621 nativefailed++; 03622 break; 03623 } 03624 } 03625 03626 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) || 03627 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) && 03628 !(c0->generator || c1->generator)) { 03629 if (ast_channel_make_compatible(c0, c1)) { 03630 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 03631 manager_event(EVENT_FLAG_CALL, "Unlink", 03632 "Channel1: %s\r\n" 03633 "Channel2: %s\r\n" 03634 "Uniqueid1: %s\r\n" 03635 "Uniqueid2: %s\r\n" 03636 "CallerID1: %s\r\n" 03637 "CallerID2: %s\r\n", 03638 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03639 return AST_BRIDGE_FAILED; 03640 } 03641 o0nativeformats = c0->nativeformats; 03642 o1nativeformats = c1->nativeformats; 03643 } 03644 res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts); 03645 if (res != AST_BRIDGE_RETRY) 03646 break; 03647 } 03648 03649 c0->_bridge = NULL; 03650 c1->_bridge = NULL; 03651 03652 manager_event(EVENT_FLAG_CALL, "Unlink", 03653 "Channel1: %s\r\n" 03654 "Channel2: %s\r\n" 03655 "Uniqueid1: %s\r\n" 03656 "Uniqueid2: %s\r\n" 03657 "CallerID1: %s\r\n" 03658 "CallerID2: %s\r\n", 03659 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03660 ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name); 03661 03662 return res; 03663 }
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 | ) |
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 690 of file channel.c.
References AST_FLAG_DEFER_DTMF, ast_set_flag, and ast_test_flag.
Referenced by __adsi_transmit_messages(), and find_cache().
00691 { 00692 int pre = 0; 00693 00694 if (chan) { 00695 pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF); 00696 ast_set_flag(chan, AST_FLAG_DEFER_DTMF); 00697 } 00698 return pre; 00699 }
void ast_channel_free | ( | struct ast_channel * | chan | ) |
Free a channel structure.
Definition at line 878 of file channel.c.
References ast_channel::alertpipe, 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_WARNING, ast_channel::monitor, ast_channel::music_state, name, ast_channel::name, ast_channel::next, msglist::next, ast_frame::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_hangup(), ast_pbx_outgoing_cdr_failed(), local_new(), sendmail(), and sendpage().
00879 { 00880 struct ast_channel *last=NULL, *cur; 00881 int fd; 00882 struct ast_var_t *vardata; 00883 struct ast_frame *f, *fp; 00884 struct varshead *headp; 00885 char name[AST_CHANNEL_NAME]; 00886 00887 headp=&chan->varshead; 00888 00889 ast_mutex_lock(&chlock); 00890 cur = channels; 00891 while(cur) { 00892 if (cur == chan) { 00893 if (last) 00894 last->next = cur->next; 00895 else 00896 channels = cur->next; 00897 break; 00898 } 00899 last = cur; 00900 cur = cur->next; 00901 } 00902 if (!cur) 00903 ast_log(LOG_WARNING, "Unable to find channel in list\n"); 00904 else { 00905 /* Lock and unlock the channel just to be sure nobody 00906 has it locked still */ 00907 ast_mutex_lock(&cur->lock); 00908 ast_mutex_unlock(&cur->lock); 00909 } 00910 if (chan->tech_pvt) { 00911 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name); 00912 free(chan->tech_pvt); 00913 } 00914 00915 if (chan->sched) 00916 sched_context_destroy(chan->sched); 00917 00918 ast_copy_string(name, chan->name, sizeof(name)); 00919 00920 /* Stop monitoring */ 00921 if (chan->monitor) { 00922 chan->monitor->stop( chan, 0 ); 00923 } 00924 00925 /* If there is native format music-on-hold state, free it */ 00926 if(chan->music_state) 00927 ast_moh_cleanup(chan); 00928 00929 /* Free translatosr */ 00930 if (chan->readtrans) 00931 ast_translator_free_path(chan->readtrans); 00932 if (chan->writetrans) 00933 ast_translator_free_path(chan->writetrans); 00934 if (chan->pbx) 00935 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name); 00936 free_cid(&chan->cid); 00937 ast_mutex_destroy(&chan->lock); 00938 /* Close pipes if appropriate */ 00939 if ((fd = chan->alertpipe[0]) > -1) 00940 close(fd); 00941 if ((fd = chan->alertpipe[1]) > -1) 00942 close(fd); 00943 if ((fd = chan->timingfd) > -1) 00944 close(fd); 00945 f = chan->readq; 00946 chan->readq = NULL; 00947 while(f) { 00948 fp = f; 00949 f = f->next; 00950 ast_frfree(fp); 00951 } 00952 00953 /* loop over the variables list, freeing all data and deleting list items */ 00954 /* no need to lock the list, as the channel is already locked */ 00955 00956 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) 00957 ast_var_delete(vardata); 00958 00959 free(chan); 00960 ast_mutex_unlock(&chlock); 00961 00962 ast_device_state_changed_literal(name); 00963 }
void ast_channel_inherit_variables | ( | const struct ast_channel * | parent, | |
struct ast_channel * | child | |||
) |
Inherits channel variable from parent to child channel.
parent | Parent channel | |
child | Child channel |
Definition at line 2865 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().
02866 { 02867 struct ast_var_t *current, *newvar; 02868 char *varname; 02869 02870 AST_LIST_TRAVERSE(&parent->varshead, current, entries) { 02871 int vartype = 0; 02872 02873 varname = ast_var_full_name(current); 02874 if (!varname) 02875 continue; 02876 02877 if (varname[0] == '_') { 02878 vartype = 1; 02879 if (varname[1] == '_') 02880 vartype = 2; 02881 } 02882 02883 switch (vartype) { 02884 case 1: 02885 newvar = ast_var_assign(&varname[1], ast_var_value(current)); 02886 if (newvar) { 02887 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 02888 if (option_debug) 02889 ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar)); 02890 } 02891 break; 02892 case 2: 02893 newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current)); 02894 if (newvar) { 02895 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 02896 if (option_debug) 02897 ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar)); 02898 } 02899 break; 02900 default: 02901 if (option_debug) 02902 ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current)); 02903 break; 02904 } 02905 } 02906 }
int ast_channel_make_compatible | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1 | |||
) |
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 2743 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, and option_transcode_slin.
Referenced by ast_channel_bridge(), builtin_atxfer(), dial_exec_full(), park_exec(), try_calling(), and wait_for_answer().
02744 { 02745 int src; 02746 int dst; 02747 02748 /* Set up translation from the chan to the peer */ 02749 src = chan->nativeformats; 02750 dst = peer->nativeformats; 02751 if (ast_translator_best_choice(&dst, &src) < 0) { 02752 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst); 02753 return -1; 02754 } 02755 02756 /* if the best path is not 'pass through', then 02757 transcoding is needed; if desired, force transcode path 02758 to use SLINEAR between channels */ 02759 if ((src != dst) && option_transcode_slin) 02760 dst = AST_FORMAT_SLINEAR; 02761 if (ast_set_read_format(chan, dst) < 0) { 02762 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst); 02763 return -1; 02764 } 02765 if (ast_set_write_format(peer, dst) < 0) { 02766 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, dst); 02767 return -1; 02768 } 02769 02770 /* Set up translation from the peer to the chan */ 02771 src = peer->nativeformats; 02772 dst = chan->nativeformats; 02773 if (ast_translator_best_choice(&dst, &src) < 0) { 02774 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst); 02775 return -1; 02776 } 02777 /* if the best path is not 'pass through', then 02778 transcoding is needed; if desired, force transcode path 02779 to use SLINEAR between channels */ 02780 if ((src != dst) && option_transcode_slin) 02781 dst = AST_FORMAT_SLINEAR; 02782 if (ast_set_read_format(peer, dst) < 0) { 02783 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst); 02784 return -1; 02785 } 02786 if (ast_set_write_format(chan, dst) < 0) { 02787 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, dst); 02788 return -1; 02789 } 02790 return 0; 02791 }
int ast_channel_masquerade | ( | struct ast_channel * | original, | |
struct ast_channel * | clone | |||
) |
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 2793 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().
02794 { 02795 struct ast_frame null = { AST_FRAME_NULL, }; 02796 int res = -1; 02797 struct ast_channel *final_orig = original, *final_clone = clone; 02798 02799 ast_mutex_lock(&original->lock); 02800 while(ast_mutex_trylock(&clone->lock)) { 02801 ast_mutex_unlock(&original->lock); 02802 usleep(1); 02803 ast_mutex_lock(&original->lock); 02804 } 02805 02806 /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent) 02807 and if so, we don't really want to masquerade it, but its proxy */ 02808 if (original->_bridge && (original->_bridge != ast_bridged_channel(original))) 02809 final_orig = original->_bridge; 02810 02811 if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone))) 02812 final_clone = clone->_bridge; 02813 02814 if ((final_orig != original) || (final_clone != clone)) { 02815 ast_mutex_lock(&final_orig->lock); 02816 while(ast_mutex_trylock(&final_clone->lock)) { 02817 ast_mutex_unlock(&final_orig->lock); 02818 usleep(1); 02819 ast_mutex_lock(&final_orig->lock); 02820 } 02821 ast_mutex_unlock(&clone->lock); 02822 ast_mutex_unlock(&original->lock); 02823 original = final_orig; 02824 clone = final_clone; 02825 } 02826 02827 if (original == clone) { 02828 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name); 02829 ast_mutex_unlock(&clone->lock); 02830 ast_mutex_unlock(&original->lock); 02831 return -1; 02832 } 02833 02834 ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n", 02835 clone->name, original->name); 02836 if (original->masq) { 02837 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 02838 original->masq->name, original->name); 02839 } else if (clone->masqr) { 02840 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 02841 clone->name, clone->masqr->name); 02842 } else { 02843 original->masq = clone; 02844 clone->masqr = original; 02845 ast_queue_frame(original, &null); 02846 ast_queue_frame(clone, &null); 02847 ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name); 02848 res = 0; 02849 } 02850 02851 ast_mutex_unlock(&clone->lock); 02852 ast_mutex_unlock(&original->lock); 02853 02854 return res; 02855 }
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, 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 | |||
) |
Send HTML or URL on link. Returns 0 on success or -1 on failure
Definition at line 2729 of file channel.c.
References ast_channel_tech::send_html, and ast_channel::tech.
Referenced by agent_sendhtml(), and wait_for_answer().
02730 { 02731 if (chan->tech->send_html) 02732 return chan->tech->send_html(chan, subclass, data, datalen); 02733 return -1; 02734 }
int ast_channel_sendurl | ( | struct ast_channel * | channel, | |
const char * | url | |||
) |
Send URL on link. Returns 0 on success or -1 on failure
Definition at line 2736 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().
02737 { 02738 if (chan->tech->send_html) 02739 return chan->tech->send_html(chan, AST_HTML_URL, url, strlen(url) + 1); 02740 return -1; 02741 }
int ast_channel_setoption | ( | struct ast_channel * | channel, | |
int | option, | |||
void * | data, | |||
int | datalen, | |||
int | block | |||
) |
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 3666 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().
03667 { 03668 int res; 03669 03670 if (chan->tech->setoption) { 03671 res = chan->tech->setoption(chan, option, data, datalen); 03672 if (res < 0) 03673 return res; 03674 } else { 03675 errno = ENOSYS; 03676 return -1; 03677 } 03678 if (block) { 03679 /* XXX Implement blocking -- just wait for our option frame reply, discarding 03680 intermediate packets. XXX */ 03681 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 03682 return -1; 03683 } 03684 return 0; 03685 }
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 965 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, list, 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().
00966 { 00967 /* Link the owner channel to the spy */ 00968 spy->chan = chan; 00969 00970 if (!ast_test_flag(spy, CHANSPY_FORMAT_AUDIO)) { 00971 ast_log(LOG_WARNING, "Could not add channel spy '%s' to channel '%s', only audio format spies are supported.\n", 00972 spy->type, chan->name); 00973 return -1; 00974 } 00975 00976 if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST) && (spy->read_queue.format != AST_FORMAT_SLINEAR)) { 00977 ast_log(LOG_WARNING, "Cannot provide volume adjustment on '%s' format spies\n", 00978 ast_getformatname(spy->read_queue.format)); 00979 return -1; 00980 } 00981 00982 if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST) && (spy->write_queue.format != AST_FORMAT_SLINEAR)) { 00983 ast_log(LOG_WARNING, "Cannot provide volume adjustment on '%s' format spies\n", 00984 ast_getformatname(spy->write_queue.format)); 00985 return -1; 00986 } 00987 00988 if (ast_test_flag(spy, CHANSPY_MIXAUDIO) && 00989 ((spy->read_queue.format != AST_FORMAT_SLINEAR) || 00990 (spy->write_queue.format != AST_FORMAT_SLINEAR))) { 00991 ast_log(LOG_WARNING, "Cannot provide audio mixing on '%s'-'%s' format spies\n", 00992 ast_getformatname(spy->read_queue.format), ast_getformatname(spy->write_queue.format)); 00993 return -1; 00994 } 00995 00996 if (!chan->spies) { 00997 if (!(chan->spies = calloc(1, sizeof(*chan->spies)))) { 00998 ast_log(LOG_WARNING, "Memory allocation failure\n"); 00999 return -1; 01000 } 01001 01002 AST_LIST_HEAD_INIT_NOLOCK(&chan->spies->list); 01003 AST_LIST_INSERT_HEAD(&chan->spies->list, spy, list); 01004 } else { 01005 AST_LIST_INSERT_TAIL(&chan->spies->list, spy, list); 01006 } 01007 01008 if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) { 01009 ast_cond_init(&spy->trigger, NULL); 01010 ast_set_flag(spy, CHANSPY_TRIGGER_READ); 01011 ast_clear_flag(spy, CHANSPY_TRIGGER_WRITE); 01012 } 01013 01014 ast_log(LOG_DEBUG, "Spy %s added to channel %s\n", 01015 spy->type, chan->name); 01016 01017 return 0; 01018 }
void ast_channel_spy_free | ( | struct ast_channel_spy * | spy | ) |
Free a spy.
spy | The spy to free |
Definition at line 1098 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().
01099 { 01100 struct ast_frame *f = NULL; 01101 01102 if (spy->status == CHANSPY_DONE) 01103 return; 01104 01105 /* Switch status to done in case we get called twice */ 01106 spy->status = CHANSPY_DONE; 01107 01108 /* Drop any frames in the queue */ 01109 for (f = spy->write_queue.head; f; f = spy->write_queue.head) { 01110 spy->write_queue.head = f->next; 01111 ast_frfree(f); 01112 } 01113 for (f = spy->read_queue.head; f; f= spy->read_queue.head) { 01114 spy->read_queue.head = f->next; 01115 ast_frfree(f); 01116 } 01117 01118 /* Destroy the condition if in use */ 01119 if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) 01120 ast_cond_destroy(&spy->trigger); 01121 01122 /* Destroy our mutex since it is no longer in use */ 01123 ast_mutex_destroy(&spy->lock); 01124 01125 return; 01126 }
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.
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 3975 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_channel_spy_queue::samples, ast_frame::samples, ast_channel_spy::write_queue, and ast_channel_spy::write_vol_adjustment.
Referenced by mixmonitor_thread(), and spy_generate().
03976 { 03977 struct ast_frame *result; 03978 /* buffers are allocated to hold SLINEAR, which is the largest format */ 03979 short read_buf[samples]; 03980 short write_buf[samples]; 03981 struct ast_frame *read_frame; 03982 struct ast_frame *write_frame; 03983 int need_dup; 03984 struct ast_frame stack_read_frame = { .frametype = AST_FRAME_VOICE, 03985 .subclass = spy->read_queue.format, 03986 .data = read_buf, 03987 .samples = samples, 03988 .datalen = ast_codec_get_len(spy->read_queue.format, samples), 03989 }; 03990 struct ast_frame stack_write_frame = { .frametype = AST_FRAME_VOICE, 03991 .subclass = spy->write_queue.format, 03992 .data = write_buf, 03993 .samples = samples, 03994 .datalen = ast_codec_get_len(spy->write_queue.format, samples), 03995 }; 03996 03997 /* if a flush has been requested, dump everything in whichever queue is larger */ 03998 if (ast_test_flag(spy, CHANSPY_TRIGGER_FLUSH)) { 03999 if (spy->read_queue.samples > spy->write_queue.samples) { 04000 if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST)) { 04001 for (result = spy->read_queue.head; result; result = result->next) 04002 ast_frame_adjust_volume(result, spy->read_vol_adjustment); 04003 } 04004 result = spy->read_queue.head; 04005 spy->read_queue.head = NULL; 04006 spy->read_queue.samples = 0; 04007 ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH); 04008 return result; 04009 } else { 04010 if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST)) { 04011 for (result = spy->write_queue.head; result; result = result->next) 04012 ast_frame_adjust_volume(result, spy->write_vol_adjustment); 04013 } 04014 result = spy->write_queue.head; 04015 spy->write_queue.head = NULL; 04016 spy->write_queue.samples = 0; 04017 ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH); 04018 return result; 04019 } 04020 } 04021 04022 if ((spy->read_queue.samples < samples) || (spy->write_queue.samples < samples)) 04023 return NULL; 04024 04025 /* short-circuit if both head frames have exactly what we want */ 04026 if ((spy->read_queue.head->samples == samples) && 04027 (spy->write_queue.head->samples == samples)) { 04028 read_frame = spy->read_queue.head; 04029 spy->read_queue.head = read_frame->next; 04030 read_frame->next = NULL; 04031 04032 write_frame = spy->write_queue.head; 04033 spy->write_queue.head = write_frame->next; 04034 write_frame->next = NULL; 04035 04036 spy->read_queue.samples -= samples; 04037 spy->write_queue.samples -= samples; 04038 04039 need_dup = 0; 04040 } else { 04041 copy_data_from_queue(&spy->read_queue, read_buf, samples); 04042 copy_data_from_queue(&spy->write_queue, write_buf, samples); 04043 04044 read_frame = &stack_read_frame; 04045 write_frame = &stack_write_frame; 04046 need_dup = 1; 04047 } 04048 04049 if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST)) 04050 ast_frame_adjust_volume(read_frame, spy->read_vol_adjustment); 04051 04052 if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST)) 04053 ast_frame_adjust_volume(write_frame, spy->write_vol_adjustment); 04054 04055 if (ast_test_flag(spy, CHANSPY_MIXAUDIO)) { 04056 ast_frame_slinear_sum(read_frame, write_frame); 04057 04058 if (need_dup) 04059 result = ast_frdup(read_frame); 04060 else { 04061 result = read_frame; 04062 ast_frfree(write_frame); 04063 } 04064 } else { 04065 if (need_dup) { 04066 result = ast_frdup(read_frame); 04067 result->next = ast_frdup(write_frame); 04068 } else { 04069 result = read_frame; 04070 result->next = write_frame; 04071 } 04072 } 04073 04074 return result; 04075 }
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 1087 of file channel.c.
References AST_LIST_REMOVE, list, ast_channel::spies, spy_cleanup(), and spy_detach().
Referenced by channel_spy().
01088 { 01089 if (!chan->spies) 01090 return; 01091 01092 AST_LIST_REMOVE(&chan->spies->list, spy, list); 01093 01094 spy_detach(spy, chan); 01095 spy_cleanup(chan); 01096 }
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 1055 of file channel.c.
References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock(), ast_mutex_unlock(), ast_channel_spy::chan, CHANSPY_RUNNING, list, ast_channel_spy::lock, ast_channel::spies, spy_cleanup(), spy_detach(), ast_channel_spy::status, and ast_channel_spy::type.
Referenced by mixmonitor_cli().
01056 { 01057 struct ast_channel_spy *spy = NULL; 01058 01059 if (!chan->spies) 01060 return; 01061 01062 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list) { 01063 ast_mutex_lock(&spy->lock); 01064 if ((spy->type == type) && (spy->status == CHANSPY_RUNNING)) { 01065 ast_mutex_unlock(&spy->lock); 01066 AST_LIST_REMOVE_CURRENT(&chan->spies->list, list); 01067 spy_detach(spy, chan); 01068 } else 01069 ast_mutex_unlock(&spy->lock); 01070 } 01071 AST_LIST_TRAVERSE_SAFE_END 01072 spy_cleanup(chan); 01073 }
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 1075 of file channel.c.
References ast_cond_timedwait(), ast_tvadd(), ast_channel_spy::lock, and ast_channel_spy::trigger.
Referenced by mixmonitor_thread().
01076 { 01077 struct timeval tv; 01078 struct timespec ts; 01079 01080 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(50000, 1000)); 01081 ts.tv_sec = tv.tv_sec; 01082 ts.tv_nsec = tv.tv_usec * 1000; 01083 01084 ast_cond_timedwait(&spy->trigger, &spy->lock, &ts); 01085 }
struct ast_silence_generator* ast_channel_start_silence_generator | ( | struct ast_channel * | chan | ) |
Starts a silence generator on the given channel.
chan | The channel to generate silence on |
The pointer returned by this function must be preserved and passed to ast_channel_stop_silence_generator when you wish to stop the silence generation.
Definition at line 4133 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, option_debug, silence_generator, and ast_channel::writeformat.
Referenced by ast_play_and_record_full().
04134 { 04135 struct ast_silence_generator *state; 04136 04137 if (!(state = calloc(1, sizeof(*state)))) { 04138 ast_log(LOG_WARNING, "Could not allocate state structure\n"); 04139 return NULL; 04140 } 04141 04142 state->old_write_format = chan->writeformat; 04143 04144 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) { 04145 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n"); 04146 free(state); 04147 return NULL; 04148 } 04149 04150 ast_activate_generator(chan, &silence_generator, state); 04151 04152 if (option_debug) 04153 ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name); 04154 04155 return state; 04156 }
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 4158 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().
04159 { 04160 if (!state) 04161 return; 04162 04163 ast_deactivate_generator(chan); 04164 04165 if (option_debug) 04166 ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name); 04167 04168 if (ast_set_write_format(chan, state->old_write_format) < 0) 04169 ast_log(LOG_ERROR, "Could not return write format to its original state\n"); 04170 04171 free(state); 04172 }
int ast_channel_supports_html | ( | struct ast_channel * | channel | ) |
Returns 0 if channel does not support HTML or non-zero if it does
Definition at line 2722 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 | ) |
Undo defer. ast_read will return any dtmf characters that were queued
Definition at line 702 of file channel.c.
References ast_clear_flag, and AST_FLAG_DEFER_DTMF.
Referenced by __adsi_transmit_messages(), find_cache(), and rpt_call().
00703 { 00704 if (chan) 00705 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF); 00706 }
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) 00359 ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type); 00360 00361 ast_mutex_lock(&chlock); 00362 00363 chan = backends; 00364 while (chan) { 00365 if (chan->tech == tech) { 00366 if (last) 00367 last->next = chan->next; 00368 else 00369 backends = backends->next; 00370 free(chan); 00371 ast_mutex_unlock(&chlock); 00372 00373 if (option_verbose > 1) 00374 ast_verbose( VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type); 00375 00376 return; 00377 } 00378 last = chan; 00379 chan = chan->next; 00380 } 00381 00382 ast_mutex_unlock(&chlock); 00383 }
struct ast_channel* ast_channel_walk_locked | ( | const struct ast_channel * | prev | ) |
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 794 of file channel.c.
References channel_find_locked().
Referenced by action_status(), ast_app_group_get_count(), ast_app_group_match_get_count(), ast_pickup_call(), complete_ch_helper(), conf_exec(), group_show_channels(), handle_chanlist(), handle_debugchan(), handle_nodebugchan(), local_channel_walk(), moh_on_off(), and softhangup_exec().
00795 { 00796 return channel_find_locked(prev, NULL, 0, NULL, NULL); 00797 }
void ast_channels_init | ( | void | ) |
Definition at line 3905 of file channel.c.
References ast_cli_register(), and cli_show_channeltypes.
Referenced by main().
03906 { 03907 ast_cli_register(&cli_show_channeltypes); 03908 }
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 app_exec(), ast_answer(), ast_call(), ast_channel_bridge(), ast_check_hangup_locked(), ast_feature_request_and_dial(), ast_indicate(), ast_read(), ast_readstring(), ast_readstring_full(), ast_recvtext(), ast_sendtext(), ast_transfer(), ast_waitfordigit(), ast_waitfordigit_full(), ast_write(), builtin_atxfer(), channel_spy(), chanspy_exec(), handle_sendimage(), rpt(), rpt_exec(), vpb_bridge(), 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 1427 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(), channel_spy(), dial_exec_full(), generator_force(), local_ast_moh_stop(), milliwatt_exec(), moh_on_off(), and wait_for_answer().
01428 { 01429 ast_mutex_lock(&chan->lock); 01430 if (chan->generatordata) { 01431 if (chan->generator && chan->generator->release) 01432 chan->generator->release(chan, chan->generatordata); 01433 chan->generatordata = NULL; 01434 chan->generator = NULL; 01435 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 01436 ast_settimeout(chan, 0, NULL, NULL); 01437 } 01438 ast_mutex_unlock(&chan->lock); 01439 }
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 2941 of file channel.c.
References ast_channel::_state, ast_channel::alertpipe, AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_channel_spy::chan, EVENT_FLAG_CALL, free_translation(), list, ast_channel::lock, ast_channel_spy::lock, LOG_DEBUG, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::name, 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::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().
02942 { 02943 int x,i; 02944 int res=0; 02945 int origstate; 02946 struct ast_frame *cur, *prev; 02947 const struct ast_channel_tech *t; 02948 void *t_pvt; 02949 struct ast_callerid tmpcid; 02950 struct ast_channel *clone = original->masq; 02951 struct ast_channel_spy_list *spy_list; 02952 struct ast_channel_spy *spy = NULL; 02953 int rformat = original->readformat; 02954 int wformat = original->writeformat; 02955 char newn[100]; 02956 char orig[100]; 02957 char masqn[100]; 02958 char zombn[100]; 02959 02960 if (option_debug > 3) 02961 ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", 02962 clone->name, clone->_state, original->name, original->_state); 02963 02964 /* XXX This is a seriously wacked out operation. We're essentially putting the guts of 02965 the clone channel into the original channel. Start by killing off the original 02966 channel's backend. I'm not sure we're going to keep this function, because 02967 while the features are nice, the cost is very high in terms of pure nastiness. XXX */ 02968 02969 /* We need the clone's lock, too */ 02970 ast_mutex_lock(&clone->lock); 02971 02972 ast_log(LOG_DEBUG, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock); 02973 02974 /* Having remembered the original read/write formats, we turn off any translation on either 02975 one */ 02976 free_translation(clone); 02977 free_translation(original); 02978 02979 02980 /* Unlink the masquerade */ 02981 original->masq = NULL; 02982 clone->masqr = NULL; 02983 02984 /* Save the original name */ 02985 ast_copy_string(orig, original->name, sizeof(orig)); 02986 /* Save the new name */ 02987 ast_copy_string(newn, clone->name, sizeof(newn)); 02988 /* Create the masq name */ 02989 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn); 02990 02991 /* Copy the name from the clone channel */ 02992 ast_copy_string(original->name, newn, sizeof(original->name)); 02993 02994 /* Mangle the name of the clone channel */ 02995 ast_copy_string(clone->name, masqn, sizeof(clone->name)); 02996 02997 /* Notify any managers of the change, first the masq then the other */ 02998 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid); 02999 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid); 03000 03001 /* Swap the technlogies */ 03002 t = original->tech; 03003 original->tech = clone->tech; 03004 clone->tech = t; 03005 03006 t_pvt = original->tech_pvt; 03007 original->tech_pvt = clone->tech_pvt; 03008 clone->tech_pvt = t_pvt; 03009 03010 /* Swap the readq's */ 03011 cur = original->readq; 03012 original->readq = clone->readq; 03013 clone->readq = cur; 03014 03015 /* Swap the alertpipes */ 03016 for (i = 0; i < 2; i++) { 03017 x = original->alertpipe[i]; 03018 original->alertpipe[i] = clone->alertpipe[i]; 03019 clone->alertpipe[i] = x; 03020 } 03021 03022 /* Swap the raw formats */ 03023 x = original->rawreadformat; 03024 original->rawreadformat = clone->rawreadformat; 03025 clone->rawreadformat = x; 03026 x = original->rawwriteformat; 03027 original->rawwriteformat = clone->rawwriteformat; 03028 clone->rawwriteformat = x; 03029 03030 /* Swap the spies */ 03031 spy_list = original->spies; 03032 original->spies = clone->spies; 03033 clone->spies = spy_list; 03034 03035 /* Update channel on respective spy lists if present */ 03036 if (original->spies) { 03037 AST_LIST_TRAVERSE(&original->spies->list, spy, list) { 03038 ast_mutex_lock(&spy->lock); 03039 spy->chan = original; 03040 ast_mutex_unlock(&spy->lock); 03041 } 03042 } 03043 if (clone->spies) { 03044 AST_LIST_TRAVERSE(&clone->spies->list, spy, list) { 03045 ast_mutex_lock(&spy->lock); 03046 spy->chan = clone; 03047 ast_mutex_unlock(&spy->lock); 03048 } 03049 } 03050 03051 /* Save any pending frames on both sides. Start by counting 03052 * how many we're going to need... */ 03053 prev = NULL; 03054 cur = clone->readq; 03055 x = 0; 03056 while(cur) { 03057 x++; 03058 prev = cur; 03059 cur = cur->next; 03060 } 03061 /* If we had any, prepend them to the ones already in the queue, and 03062 * load up the alertpipe */ 03063 if (prev) { 03064 prev->next = original->readq; 03065 original->readq = clone->readq; 03066 clone->readq = NULL; 03067 if (original->alertpipe[1] > -1) { 03068 for (i = 0; i < x; i++) 03069 write(original->alertpipe[1], &x, sizeof(x)); 03070 } 03071 } 03072 clone->_softhangup = AST_SOFTHANGUP_DEV; 03073 03074 03075 /* And of course, so does our current state. Note we need not 03076 call ast_setstate since the event manager doesn't really consider 03077 these separate. We do this early so that the clone has the proper 03078 state of the original channel. */ 03079 origstate = original->_state; 03080 original->_state = clone->_state; 03081 clone->_state = origstate; 03082 03083 if (clone->tech->fixup){ 03084 res = clone->tech->fixup(original, clone); 03085 if (res) 03086 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name); 03087 } 03088 03089 /* Start by disconnecting the original's physical side */ 03090 if (clone->tech->hangup) 03091 res = clone->tech->hangup(clone); 03092 if (res) { 03093 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n"); 03094 ast_mutex_unlock(&clone->lock); 03095 return -1; 03096 } 03097 03098 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); 03099 /* Mangle the name of the clone channel */ 03100 ast_copy_string(clone->name, zombn, sizeof(clone->name)); 03101 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid); 03102 03103 /* Update the type. */ 03104 original->type = clone->type; 03105 t_pvt = original->monitor; 03106 original->monitor = clone->monitor; 03107 clone->monitor = t_pvt; 03108 03109 /* Keep the same language. */ 03110 ast_copy_string(original->language, clone->language, sizeof(original->language)); 03111 /* Copy the FD's */ 03112 for (x = 0; x < AST_MAX_FDS; x++) { 03113 original->fds[x] = clone->fds[x]; 03114 } 03115 clone_variables(original, clone); 03116 AST_LIST_HEAD_INIT_NOLOCK(&clone->varshead); 03117 /* Presense of ADSI capable CPE follows clone */ 03118 original->adsicpe = clone->adsicpe; 03119 /* Bridge remains the same */ 03120 /* CDR fields remain the same */ 03121 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 03122 /* Application and data remain the same */ 03123 /* Clone exception becomes real one, as with fdno */ 03124 ast_copy_flags(original, clone, AST_FLAG_EXCEPTION); 03125 original->fdno = clone->fdno; 03126 /* Schedule context remains the same */ 03127 /* Stream stuff stays the same */ 03128 /* Keep the original state. The fixup code will need to work with it most likely */ 03129 03130 /* Just swap the whole structures, nevermind the allocations, they'll work themselves 03131 out. */ 03132 tmpcid = original->cid; 03133 original->cid = clone->cid; 03134 clone->cid = tmpcid; 03135 03136 /* Restore original timing file descriptor */ 03137 original->fds[AST_MAX_FDS - 2] = original->timingfd; 03138 03139 /* Our native formats are different now */ 03140 original->nativeformats = clone->nativeformats; 03141 03142 /* Context, extension, priority, app data, jump table, remain the same */ 03143 /* pvt switches. pbx stays the same, as does next */ 03144 03145 /* Set the write format */ 03146 ast_set_write_format(original, wformat); 03147 03148 /* Set the read format */ 03149 ast_set_read_format(original, rformat); 03150 03151 /* Copy the music class */ 03152 ast_copy_string(original->musicclass, clone->musicclass, sizeof(original->musicclass)); 03153 03154 ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat); 03155 03156 /* Okay. Last thing is to let the channel driver know about all this mess, so he 03157 can fix up everything as best as possible */ 03158 if (original->tech->fixup) { 03159 res = original->tech->fixup(clone, original); 03160 if (res) { 03161 ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n", 03162 original->type, original->name); 03163 ast_mutex_unlock(&clone->lock); 03164 return -1; 03165 } 03166 } else 03167 ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)! Bad things may happen.\n", 03168 original->type, original->name); 03169 03170 /* Now, at this point, the "clone" channel is totally F'd up. We mark it as 03171 a zombie so nothing tries to touch it. If it's already been marked as a 03172 zombie, then free it now (since it already is considered invalid). */ 03173 if (ast_test_flag(clone, AST_FLAG_ZOMBIE)) { 03174 ast_log(LOG_DEBUG, "Destroying channel clone '%s'\n", clone->name); 03175 ast_mutex_unlock(&clone->lock); 03176 manager_event(EVENT_FLAG_CALL, "Hangup", 03177 "Channel: %s\r\n" 03178 "Uniqueid: %s\r\n" 03179 "Cause: %d\r\n" 03180 "Cause-txt: %s\r\n", 03181 clone->name, 03182 clone->uniqueid, 03183 clone->hangupcause, 03184 ast_cause2str(clone->hangupcause) 03185 ); 03186 ast_channel_free(clone); 03187 } else { 03188 struct ast_frame null_frame = { AST_FRAME_NULL, }; 03189 ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name); 03190 ast_set_flag(clone, AST_FLAG_ZOMBIE); 03191 ast_queue_frame(clone, &null_frame); 03192 ast_mutex_unlock(&clone->lock); 03193 } 03194 03195 /* Signal any blocker */ 03196 if (ast_test_flag(original, AST_FLAG_BLOCKING)) 03197 pthread_kill(original->blocker, SIGURG); 03198 ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n", original->name, original->_state); 03199 return 0; 03200 }
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 3318 of file channel.c.
References AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_RETRY, config, ast_channel::nativeformats, and ast_channel::tech_pvt.
Referenced by ast_channel_bridge().
03321 { 03322 /* Copy voice back and forth between the two channels. */ 03323 struct ast_channel *cs[3]; 03324 struct ast_frame *f; 03325 struct ast_channel *who = NULL; 03326 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 03327 int o0nativeformats; 03328 int o1nativeformats; 03329 int watch_c0_dtmf; 03330 int watch_c1_dtmf; 03331 void *pvt0, *pvt1; 03332 int to; 03333 03334 cs[0] = c0; 03335 cs[1] = c1; 03336 pvt0 = c0->tech_pvt; 03337 pvt1 = c1->tech_pvt; 03338 o0nativeformats = c0->nativeformats; 03339 o1nativeformats = c1->nativeformats; 03340 watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0; 03341 watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1; 03342 03343 for (;;) { 03344 if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) || 03345 (o0nativeformats != c0->nativeformats) || 03346 (o1nativeformats != c1->nativeformats)) { 03347 /* Check for Masquerade, codec changes, etc */ 03348 res = AST_BRIDGE_RETRY; 03349 break; 03350 } 03351 if (bridge_end.tv_sec) { 03352 to = ast_tvdiff_ms(bridge_end, ast_tvnow()); 03353 if (to <= 0) { 03354 res = AST_BRIDGE_RETRY; 03355 break; 03356 } 03357 } else 03358 to = -1; 03359 who = ast_waitfor_n(cs, 2, &to); 03360 if (!who) { 03361 ast_log(LOG_DEBUG, "Nobody there, continuing...\n"); 03362 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) { 03363 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03364 c0->_softhangup = 0; 03365 if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03366 c1->_softhangup = 0; 03367 c0->_bridge = c1; 03368 c1->_bridge = c0; 03369 } 03370 continue; 03371 } 03372 f = ast_read(who); 03373 if (!f) { 03374 *fo = NULL; 03375 *rc = who; 03376 res = AST_BRIDGE_COMPLETE; 03377 ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name); 03378 break; 03379 } 03380 03381 if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) { 03382 if ((f->subclass == AST_CONTROL_HOLD) || (f->subclass == AST_CONTROL_UNHOLD) || 03383 (f->subclass == AST_CONTROL_VIDUPDATE)) { 03384 ast_indicate(who == c0 ? c1 : c0, f->subclass); 03385 } else { 03386 *fo = f; 03387 *rc = who; 03388 res = AST_BRIDGE_COMPLETE; 03389 ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name); 03390 break; 03391 } 03392 } 03393 if ((f->frametype == AST_FRAME_VOICE) || 03394 (f->frametype == AST_FRAME_DTMF) || 03395 (f->frametype == AST_FRAME_VIDEO) || 03396 (f->frametype == AST_FRAME_IMAGE) || 03397 (f->frametype == AST_FRAME_HTML) || 03398 (f->frametype == AST_FRAME_TEXT)) { 03399 if (f->frametype == AST_FRAME_DTMF) { 03400 if (((who == c0) && watch_c0_dtmf) || 03401 ((who == c1) && watch_c1_dtmf)) { 03402 *rc = who; 03403 *fo = f; 03404 res = AST_BRIDGE_COMPLETE; 03405 ast_log(LOG_DEBUG, "Got DTMF on channel (%s)\n", who->name); 03406 break; 03407 } else { 03408 goto tackygoto; 03409 } 03410 } else { 03411 #if 0 03412 ast_log(LOG_DEBUG, "Read from %s\n", who->name); 03413 if (who == last) 03414 ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name); 03415 last = who; 03416 #endif 03417 tackygoto: 03418 ast_write((who == c0) ? c1 : c0, f); 03419 } 03420 } 03421 ast_frfree(f); 03422 03423 /* Swap who gets priority */ 03424 cs[2] = cs[0]; 03425 cs[0] = cs[1]; 03426 cs[1] = cs[2]; 03427 } 03428 return res; 03429 }
struct ast_channel* ast_get_channel_by_exten_locked | ( | const char * | exten, | |
const char * | context | |||
) |
Definition at line 818 of file channel.c.
References channel_find_locked().
Referenced by pickup_exec().
00819 { 00820 return channel_find_locked(NULL, NULL, 0, context, exten); 00821 }
struct ast_channel* ast_get_channel_by_name_locked | ( | const char * | chan | ) |
Get channel by name (locks channel)
Definition at line 800 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().
00801 { 00802 return channel_find_locked(NULL, name, 0, NULL, NULL); 00803 }
struct ast_channel* ast_get_channel_by_name_prefix_locked | ( | const char * | name, | |
const int | namelen | |||
) |
Get channel by name prefix (locks channel)
Definition at line 806 of file channel.c.
References channel_find_locked().
Referenced by ast_parse_device_state(), and mixmonitor_cli().
00807 { 00808 return channel_find_locked(NULL, name, namelen, NULL, NULL); 00809 }
struct ast_channel_tech* ast_get_channel_tech | ( | const char * | name | ) |
Get a channel technology structure by name.
name | name of technology to find |
Definition at line 385 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().
00386 { 00387 struct chanlist *chanls; 00388 00389 if (ast_mutex_lock(&chlock)) { 00390 ast_log(LOG_WARNING, "Unable to lock channel tech list\n"); 00391 return NULL; 00392 } 00393 00394 for (chanls = backends; chanls; chanls = chanls->next) { 00395 if (strcasecmp(name, chanls->tech->type)) 00396 continue; 00397 00398 ast_mutex_unlock(&chlock); 00399 return chanls->tech; 00400 } 00401 00402 ast_mutex_unlock(&chlock); 00403 return NULL; 00404 }
ast_group_t ast_get_group | ( | char * | s | ) |
Definition at line 3823 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().
03824 { 03825 char *copy; 03826 char *piece; 03827 char *c=NULL; 03828 int start=0, finish=0, x; 03829 ast_group_t group = 0; 03830 03831 copy = ast_strdupa(s); 03832 if (!copy) { 03833 ast_log(LOG_ERROR, "Out of memory\n"); 03834 return 0; 03835 } 03836 c = copy; 03837 03838 while((piece = strsep(&c, ","))) { 03839 if (sscanf(piece, "%d-%d", &start, &finish) == 2) { 03840 /* Range */ 03841 } else if (sscanf(piece, "%d", &start)) { 03842 /* Just one */ 03843 finish = start; 03844 } else { 03845 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece); 03846 continue; 03847 } 03848 for (x = start; x <= finish; x++) { 03849 if ((x > 63) || (x < 0)) { 03850 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x); 03851 } else 03852 group |= ((ast_group_t) 1 << x); 03853 } 03854 } 03855 return group; 03856 }
int ast_hangup | ( | struct ast_channel * | chan | ) |
Hang up a channel.
chan | channel to hang up |
Definition at line 1313 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_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().
01314 { 01315 int res = 0; 01316 01317 /* Don't actually hang up a channel that will masquerade as someone else, or 01318 if someone is going to masquerade as us */ 01319 ast_mutex_lock(&chan->lock); 01320 01321 detach_spies(chan); /* get rid of spies */ 01322 01323 if (chan->masq) { 01324 if (ast_do_masquerade(chan)) 01325 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01326 } 01327 01328 if (chan->masq) { 01329 ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name); 01330 ast_mutex_unlock(&chan->lock); 01331 return 0; 01332 } 01333 /* If this channel is one which will be masqueraded into something, 01334 mark it as a zombie already, so we know to free it later */ 01335 if (chan->masqr) { 01336 ast_set_flag(chan, AST_FLAG_ZOMBIE); 01337 ast_mutex_unlock(&chan->lock); 01338 return 0; 01339 } 01340 free_translation(chan); 01341 /* Close audio stream */ 01342 if (chan->stream) { 01343 ast_closestream(chan->stream); 01344 chan->stream = NULL; 01345 } 01346 /* Close video stream */ 01347 if (chan->vstream) { 01348 ast_closestream(chan->vstream); 01349 chan->vstream = NULL; 01350 } 01351 if (chan->sched) { 01352 sched_context_destroy(chan->sched); 01353 chan->sched = NULL; 01354 } 01355 01356 if (chan->generatordata) /* Clear any tone stuff remaining */ 01357 chan->generator->release(chan, chan->generatordata); 01358 chan->generatordata = NULL; 01359 chan->generator = NULL; 01360 if (chan->cdr) { /* End the CDR if it hasn't already */ 01361 ast_cdr_end(chan->cdr); 01362 ast_cdr_detach(chan->cdr); /* Post and Free the CDR */ 01363 chan->cdr = NULL; 01364 } 01365 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 01366 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 01367 "is blocked by thread %ld in procedure %s! Expect a failure\n", 01368 (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 01369 CRASH; 01370 } 01371 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) { 01372 if (option_debug) 01373 ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name); 01374 if (chan->tech->hangup) 01375 res = chan->tech->hangup(chan); 01376 } else { 01377 if (option_debug) 01378 ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name); 01379 } 01380 01381 ast_mutex_unlock(&chan->lock); 01382 manager_event(EVENT_FLAG_CALL, "Hangup", 01383 "Channel: %s\r\n" 01384 "Uniqueid: %s\r\n" 01385 "Cause: %d\r\n" 01386 "Cause-txt: %s\r\n", 01387 chan->name, 01388 chan->uniqueid, 01389 chan->hangupcause, 01390 ast_cause2str(chan->hangupcause) 01391 ); 01392 ast_channel_free(chan); 01393 return res; 01394 }
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 2056 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 agent_indicate(), ast_bridge_call(), ast_feature_request_and_dial(), ast_park_call(), ast_play_and_record_full(), 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(), rmt_telem_finish(), rmt_telem_start(), rpt(), rpt_exec(), send_waveform_to_channel(), skinny_ss(), vpb_fixup(), and wait_for_answer().
02057 { 02058 int res = -1; 02059 02060 ast_mutex_lock(&chan->lock); 02061 /* Stop if we're a zombie or need a soft hangup */ 02062 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02063 ast_mutex_unlock(&chan->lock); 02064 return -1; 02065 } 02066 if (chan->tech->indicate) 02067 res = chan->tech->indicate(chan, condition); 02068 ast_mutex_unlock(&chan->lock); 02069 if (!chan->tech->indicate || res) { 02070 /* 02071 * Device does not support (that) indication, lets fake 02072 * it by doing our own tone generation. (PM2002) 02073 */ 02074 if (condition >= 0) { 02075 const struct tone_zone_sound *ts = NULL; 02076 switch (condition) { 02077 case AST_CONTROL_RINGING: 02078 ts = ast_get_indication_tone(chan->zone, "ring"); 02079 break; 02080 case AST_CONTROL_BUSY: 02081 ts = ast_get_indication_tone(chan->zone, "busy"); 02082 break; 02083 case AST_CONTROL_CONGESTION: 02084 ts = ast_get_indication_tone(chan->zone, "congestion"); 02085 break; 02086 } 02087 if (ts && ts->data[0]) { 02088 ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition); 02089 ast_playtones_start(chan,0,ts->data, 1); 02090 res = 0; 02091 } else if (condition == AST_CONTROL_PROGRESS) { 02092 /* ast_playtones_stop(chan); */ 02093 } else if (condition == AST_CONTROL_PROCEEDING) { 02094 /* Do nothing, really */ 02095 } else if (condition == AST_CONTROL_HOLD) { 02096 /* Do nothing.... */ 02097 } else if (condition == AST_CONTROL_UNHOLD) { 02098 /* Do nothing.... */ 02099 } else if (condition == AST_CONTROL_VIDUPDATE) { 02100 /* Do nothing.... */ 02101 } else { 02102 /* not handled */ 02103 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); 02104 res = -1; 02105 } 02106 } 02107 else ast_playtones_stop(chan); 02108 } 02109 return res; 02110 }
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 3863 of file channel.c.
References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.
Referenced by load_module(), and reload().
03867 { 03868 ast_moh_start_ptr = start_ptr; 03869 ast_moh_stop_ptr = stop_ptr; 03870 ast_moh_cleanup_ptr = cleanup_ptr; 03871 }
void ast_moh_cleanup | ( | struct ast_channel * | chan | ) |
Definition at line 3899 of file channel.c.
References ast_moh_cleanup_ptr.
Referenced by ast_channel_free().
03900 { 03901 if(ast_moh_cleanup_ptr) 03902 ast_moh_cleanup_ptr(chan); 03903 }
int ast_moh_start | ( | struct ast_channel * | chan, | |
char * | mclass | |||
) |
Turn on music on hold on a given channel
Definition at line 3881 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(), 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().
03882 { 03883 if (ast_moh_start_ptr) 03884 return ast_moh_start_ptr(chan, mclass); 03885 03886 if (option_verbose > 2) 03887 ast_verbose(VERBOSE_PREFIX_3 "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : "default"); 03888 03889 return 0; 03890 }
void ast_moh_stop | ( | struct ast_channel * | chan | ) |
Turn off music on hold on a given channel
Definition at line 3893 of file channel.c.
References ast_moh_stop_ptr.
Referenced by __zt_exception(), agent_new(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), 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().
03894 { 03895 if(ast_moh_stop_ptr) 03896 ast_moh_stop_ptr(chan); 03897 }
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 3911 of file channel.c.
Referenced by ast_serialize_showchan(), misdn_cfg_get_config_string(), print_group(), and read_config().
03912 { 03913 unsigned int i; 03914 int first=1; 03915 char num[3]; 03916 03917 buf[0] = '\0'; 03918 03919 if (!group) /* Return empty string if no group */ 03920 return(buf); 03921 03922 for (i=0; i<=63; i++) { /* Max group is 63 */ 03923 if (group & ((ast_group_t) 1 << i)) { 03924 if (!first) { 03925 strncat(buf, ", ", buflen); 03926 } else { 03927 first=0; 03928 } 03929 snprintf(num, sizeof(num), "%u", i); 03930 strncat(buf, num, buflen); 03931 } 03932 } 03933 return(buf); 03934 }
int ast_prod | ( | struct ast_channel * | chan | ) |
Definition at line 2212 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().
02213 { 02214 struct ast_frame a = { AST_FRAME_VOICE }; 02215 char nothing[128]; 02216 02217 /* Send an empty audio frame to get things moving */ 02218 if (chan->_state != AST_STATE_UP) { 02219 ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name); 02220 a.subclass = chan->rawwriteformat; 02221 a.data = nothing + AST_FRIENDLY_OFFSET; 02222 a.src = "ast_prod"; 02223 if (ast_write(chan, &a)) 02224 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 02225 } 02226 return 0; 02227 }
int ast_queue_control | ( | struct ast_channel * | chan, | |
int | control | |||
) |
Queue a control frame.
Definition at line 682 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(), 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(), and update_state().
00683 { 00684 struct ast_frame f = { AST_FRAME_CONTROL, }; 00685 f.subclass = control; 00686 return ast_queue_frame(chan, &f); 00687 }
int ast_queue_frame | ( | struct ast_channel * | chan, | |
struct ast_frame * | fin | |||
) |
Queue an outgoing frame.
Definition at line 611 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_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().
00612 { 00613 struct ast_frame *f; 00614 struct ast_frame *prev, *cur; 00615 int blah = 1; 00616 int qlen = 0; 00617 00618 /* Build us a copy and free the original one */ 00619 f = ast_frdup(fin); 00620 if (!f) { 00621 ast_log(LOG_WARNING, "Unable to duplicate frame\n"); 00622 return -1; 00623 } 00624 ast_mutex_lock(&chan->lock); 00625 prev = NULL; 00626 cur = chan->readq; 00627 while(cur) { 00628 if ((cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) { 00629 /* Don't bother actually queueing anything after a hangup */ 00630 ast_frfree(f); 00631 ast_mutex_unlock(&chan->lock); 00632 return 0; 00633 } 00634 prev = cur; 00635 cur = cur->next; 00636 qlen++; 00637 } 00638 /* Allow up to 96 voice frames outstanding, and up to 128 total frames */ 00639 if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen > 128)) { 00640 if (fin->frametype != AST_FRAME_VOICE) { 00641 ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name); 00642 CRASH; 00643 } else { 00644 ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name); 00645 ast_frfree(f); 00646 ast_mutex_unlock(&chan->lock); 00647 return 0; 00648 } 00649 } 00650 if (prev) 00651 prev->next = f; 00652 else 00653 chan->readq = f; 00654 if (chan->alertpipe[1] > -1) { 00655 if (write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah)) 00656 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n", 00657 chan->name, f->frametype, f->subclass, qlen, strerror(errno)); 00658 #ifdef ZAPTEL_OPTIMIZATIONS 00659 } else if (chan->timingfd > -1) { 00660 ioctl(chan->timingfd, ZT_TIMERPING, &blah); 00661 #endif 00662 } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 00663 pthread_kill(chan->blocker, SIGURG); 00664 } 00665 ast_mutex_unlock(&chan->lock); 00666 return 0; 00667 }
int ast_queue_hangup | ( | struct ast_channel * | chan | ) |
Queue a hangup frame.
Definition at line 670 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(), hangup_chan(), hangup_connection(), iax2_destroy(), iax2_predestroy(), mgcp_queue_hangup(), misdn_answer(), retrans_pkt(), and zt_handle_event().
00671 { 00672 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP }; 00673 /* Yeah, let's not change a lock-critical value without locking */ 00674 if (!ast_mutex_trylock(&chan->lock)) { 00675 chan->_softhangup |= AST_SOFTHANGUP_DEV; 00676 ast_mutex_unlock(&chan->lock); 00677 } 00678 return ast_queue_frame(chan, &f); 00679 }
struct ast_frame* ast_read | ( | struct ast_channel * | chan | ) |
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 1829 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::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_masq_park_call(), ast_play_and_prepend(), ast_play_and_record_full(), ast_recvtext(), 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(), iax_park_thread(), ices_exec(), measurenoise(), misdn_bridge(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), recordthread(), rpt(), run_agi(), rxfax_exec(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), ss_thread(), txfax_exec(), vpb_bridge(), wait_for_answer(), wait_for_hangup(), waitforring_exec(), and zt_bridge().
01830 { 01831 struct ast_frame *f = NULL; 01832 int blah; 01833 int prestate; 01834 #ifdef ZAPTEL_OPTIMIZATIONS 01835 int (*func)(void *); 01836 void *data; 01837 int res; 01838 #endif 01839 static struct ast_frame null_frame = { 01840 AST_FRAME_NULL, 01841 }; 01842 01843 ast_mutex_lock(&chan->lock); 01844 if (chan->masq) { 01845 if (ast_do_masquerade(chan)) { 01846 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01847 f = NULL; 01848 } else 01849 f = &null_frame; 01850 ast_mutex_unlock(&chan->lock); 01851 return f; 01852 } 01853 01854 /* Stop if we're a zombie or need a soft hangup */ 01855 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 01856 if (chan->generator) 01857 ast_deactivate_generator(chan); 01858 ast_mutex_unlock(&chan->lock); 01859 return NULL; 01860 } 01861 prestate = chan->_state; 01862 01863 if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && !ast_strlen_zero(chan->dtmfq)) { 01864 /* We have DTMF that has been deferred. Return it now */ 01865 chan->dtmff.frametype = AST_FRAME_DTMF; 01866 chan->dtmff.subclass = chan->dtmfq[0]; 01867 /* Drop first digit */ 01868 memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1); 01869 ast_mutex_unlock(&chan->lock); 01870 return &chan->dtmff; 01871 } 01872 01873 /* Read and ignore anything on the alertpipe, but read only 01874 one sizeof(blah) per frame that we send from it */ 01875 if (chan->alertpipe[0] > -1) { 01876 read(chan->alertpipe[0], &blah, sizeof(blah)); 01877 } 01878 #ifdef ZAPTEL_OPTIMIZATIONS 01879 if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && ast_test_flag(chan, AST_FLAG_EXCEPTION)) { 01880 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 01881 blah = -1; 01882 /* IF we can't get event, assume it's an expired as-per the old interface */ 01883 res = ioctl(chan->timingfd, ZT_GETEVENT, &blah); 01884 if (res) 01885 blah = ZT_EVENT_TIMER_EXPIRED; 01886 01887 if (blah == ZT_EVENT_TIMER_PING) { 01888 #if 0 01889 ast_log(LOG_NOTICE, "Oooh, there's a PING!\n"); 01890 #endif 01891 if (!chan->readq || !chan->readq->next) { 01892 /* Acknowledge PONG unless we need it again */ 01893 #if 0 01894 ast_log(LOG_NOTICE, "Sending a PONG!\n"); 01895 #endif 01896 if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) { 01897 ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno)); 01898 } 01899 } 01900 } else if (blah == ZT_EVENT_TIMER_EXPIRED) { 01901 ioctl(chan->timingfd, ZT_TIMERACK, &blah); 01902 func = chan->timingfunc; 01903 data = chan->timingdata; 01904 ast_mutex_unlock(&chan->lock); 01905 if (func) { 01906 #if 0 01907 ast_log(LOG_DEBUG, "Calling private function\n"); 01908 #endif 01909 func(data); 01910 } else { 01911 blah = 0; 01912 ast_mutex_lock(&chan->lock); 01913 ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah); 01914 chan->timingdata = NULL; 01915 ast_mutex_unlock(&chan->lock); 01916 } 01917 f = &null_frame; 01918 return f; 01919 } else 01920 ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name); 01921 } 01922 #endif 01923 /* Check for pending read queue */ 01924 if (chan->readq) { 01925 f = chan->readq; 01926 chan->readq = f->next; 01927 /* Interpret hangup and return NULL */ 01928 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) { 01929 ast_frfree(f); 01930 f = NULL; 01931 } 01932 } else { 01933 chan->blocker = pthread_self(); 01934 if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) { 01935 if (chan->tech->exception) 01936 f = chan->tech->exception(chan); 01937 else { 01938 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name); 01939 f = &null_frame; 01940 } 01941 /* Clear the exception flag */ 01942 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 01943 } else { 01944 if (chan->tech->read) 01945 f = chan->tech->read(chan); 01946 else 01947 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name); 01948 } 01949 } 01950 01951 01952 if (f && (f->frametype == AST_FRAME_VOICE)) { 01953 if (!(f->subclass & chan->nativeformats)) { 01954 /* This frame can't be from the current native formats -- drop it on the 01955 floor */ 01956 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)); 01957 ast_frfree(f); 01958 f = &null_frame; 01959 } else { 01960 if (chan->spies) 01961 queue_frame_to_spies(chan, f, SPY_READ); 01962 01963 if (chan->monitor && chan->monitor->read_stream ) { 01964 #ifndef MONITOR_CONSTANT_DELAY 01965 int jump = chan->outsmpl - chan->insmpl - 4 * f->samples; 01966 if (jump >= 0) { 01967 if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1) 01968 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01969 chan->insmpl += jump + 4 * f->samples; 01970 } else 01971 chan->insmpl+= f->samples; 01972 #else 01973 int jump = chan->outsmpl - chan->insmpl; 01974 if (jump - MONITOR_DELAY >= 0) { 01975 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1) 01976 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01977 chan->insmpl += jump; 01978 } else 01979 chan->insmpl += f->samples; 01980 #endif 01981 if (ast_writestream(chan->monitor->read_stream, f) < 0) 01982 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n"); 01983 } 01984 if (chan->readtrans) { 01985 f = ast_translate(chan->readtrans, f, 1); 01986 if (!f) 01987 f = &null_frame; 01988 } 01989 } 01990 } 01991 01992 /* Make sure we always return NULL in the future */ 01993 if (!f) { 01994 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01995 if (chan->generator) 01996 ast_deactivate_generator(chan); 01997 /* End the CDR if appropriate */ 01998 if (chan->cdr) 01999 ast_cdr_end(chan->cdr); 02000 } else if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && f->frametype == AST_FRAME_DTMF) { 02001 if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) 02002 chan->dtmfq[strlen(chan->dtmfq)] = f->subclass; 02003 else 02004 ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name); 02005 ast_frfree(f); 02006 f = &null_frame; 02007 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) { 02008 if (prestate == AST_STATE_UP) { 02009 ast_log(LOG_DEBUG, "Dropping duplicate answer!\n"); 02010 ast_frfree(f); 02011 f = &null_frame; 02012 } 02013 /* Answer the CDR */ 02014 ast_setstate(chan, AST_STATE_UP); 02015 ast_cdr_answer(chan->cdr); 02016 } 02017 02018 /* Run any generator sitting on the line */ 02019 if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) { 02020 /* Mask generator data temporarily and apply. If there is a timing function, it 02021 will be calling the generator instead */ 02022 void *tmp; 02023 int res; 02024 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 02025 02026 if (chan->timingfunc) { 02027 ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n"); 02028 ast_settimeout(chan, 0, NULL, NULL); 02029 } 02030 tmp = chan->generatordata; 02031 chan->generatordata = NULL; 02032 generate = chan->generator->generate; 02033 res = generate(chan, tmp, f->datalen, f->samples); 02034 chan->generatordata = tmp; 02035 if (res) { 02036 ast_log(LOG_DEBUG, "Auto-deactivating generator\n"); 02037 ast_deactivate_generator(chan); 02038 } 02039 } else if (f && (f->frametype == AST_FRAME_CNG)) { 02040 if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) { 02041 ast_log(LOG_DEBUG, "Generator got CNG, switching to zap timed mode\n"); 02042 ast_settimeout(chan, 160, generator_force, chan); 02043 } 02044 } 02045 /* High bit prints debugging */ 02046 if (chan->fin & 0x80000000) 02047 ast_frame_dump(chan->name, f, "<<"); 02048 if ((chan->fin & 0x7fffffff) == 0x7fffffff) 02049 chan->fin &= 0x80000000; 02050 else 02051 chan->fin++; 02052 ast_mutex_unlock(&chan->lock); 02053 return f; 02054 }
int ast_readstring | ( | struct ast_channel * | c, | |
char * | s, | |||
int | len, | |||
int | timeout, | |||
int | rtimeout, | |||
char * | enders | |||
) |
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 2639 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().
02640 { 02641 int pos=0; 02642 int to = ftimeout; 02643 int d; 02644 02645 /* XXX Merge with full version? XXX */ 02646 /* Stop if we're a zombie or need a soft hangup */ 02647 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 02648 return -1; 02649 if (!len) 02650 return -1; 02651 do { 02652 if (c->stream) { 02653 d = ast_waitstream(c, AST_DIGIT_ANY); 02654 ast_stopstream(c); 02655 usleep(1000); 02656 if (!d) 02657 d = ast_waitfordigit(c, to); 02658 } else { 02659 d = ast_waitfordigit(c, to); 02660 } 02661 if (d < 0) 02662 return -1; 02663 if (d == 0) { 02664 s[pos]='\0'; 02665 return 1; 02666 } 02667 if (!strchr(enders, d)) 02668 s[pos++] = d; 02669 if (strchr(enders, d) || (pos >= len)) { 02670 s[pos]='\0'; 02671 return 0; 02672 } 02673 to = timeout; 02674 } while(1); 02675 /* Never reached */ 02676 return 0; 02677 }
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 2679 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().
02680 { 02681 int pos=0; 02682 int to = ftimeout; 02683 int d; 02684 02685 /* Stop if we're a zombie or need a soft hangup */ 02686 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 02687 return -1; 02688 if (!len) 02689 return -1; 02690 do { 02691 if (c->stream) { 02692 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 02693 ast_stopstream(c); 02694 usleep(1000); 02695 if (!d) 02696 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 02697 } else { 02698 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 02699 } 02700 if (d < 0) 02701 return -1; 02702 if (d == 0) { 02703 s[pos]='\0'; 02704 return 1; 02705 } 02706 if (d == 1) { 02707 s[pos]='\0'; 02708 return 2; 02709 } 02710 if (!strchr(enders, d)) 02711 s[pos++] = d; 02712 if (strchr(enders, d) || (pos >= len)) { 02713 s[pos]='\0'; 02714 return 0; 02715 } 02716 to = timeout; 02717 } while(1); 02718 /* Never reached */ 02719 return 0; 02720 }
int ast_recvchar | ( | struct ast_channel * | chan, | |
int | timeout | |||
) |
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 2112 of file channel.c.
References ast_recvtext(), and free.
Referenced by handle_recvchar().
02113 { 02114 int c; 02115 char *buf = ast_recvtext(chan, timeout); 02116 if (buf == NULL) 02117 return -1; /* error or timeout */ 02118 c = *(unsigned char *)buf; 02119 free(buf); 02120 return c; 02121 }
char* ast_recvtext | ( | struct ast_channel * | chan, | |
int | timeout | |||
) |
chan | channel to act upon | |
timeout | timeout in milliseconds (0 for infinite wait) |
Definition at line 2123 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().
02124 { 02125 int res, done = 0; 02126 char *buf = NULL; 02127 02128 while (!done) { 02129 struct ast_frame *f; 02130 if (ast_check_hangup(chan)) 02131 break; 02132 res = ast_waitfor(chan, timeout); 02133 if (res <= 0) /* timeout or error */ 02134 break; 02135 timeout = res; /* update timeout */ 02136 f = ast_read(chan); 02137 if (f == NULL) 02138 break; /* no frame */ 02139 if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) 02140 done = 1; /* force a break */ 02141 else if (f->frametype == AST_FRAME_TEXT) { /* what we want */ 02142 buf = strndup((char *) f->data, f->datalen); /* dup and break */ 02143 done = 1; 02144 } 02145 ast_frfree(f); 02146 } 02147 return buf; 02148 }
struct ast_channel* ast_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | status | |||
) |
Requests a channel.
type | type of channel to request | |
format | requested channel format | |
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 2545 of file channel.c.
References ast_channel::_state, AST_CAUSE_NOSUCHDRIVER, AST_CAUSE_NOTDEFINED, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), 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().
02546 { 02547 struct chanlist *chan; 02548 struct ast_channel *c; 02549 int capabilities; 02550 int fmt; 02551 int res; 02552 int foo; 02553 02554 if (!cause) 02555 cause = &foo; 02556 *cause = AST_CAUSE_NOTDEFINED; 02557 02558 if (ast_mutex_lock(&chlock)) { 02559 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 02560 return NULL; 02561 } 02562 02563 for (chan = backends; chan; chan = chan->next) { 02564 if (strcasecmp(type, chan->tech->type)) 02565 continue; 02566 02567 capabilities = chan->tech->capabilities; 02568 fmt = format; 02569 res = ast_translator_best_choice(&fmt, &capabilities); 02570 if (res < 0) { 02571 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format); 02572 ast_mutex_unlock(&chlock); 02573 return NULL; 02574 } 02575 ast_mutex_unlock(&chlock); 02576 if (!chan->tech->requester) 02577 return NULL; 02578 02579 if (!(c = chan->tech->requester(type, capabilities, data, cause))) 02580 return NULL; 02581 02582 if (c->_state == AST_STATE_DOWN) { 02583 manager_event(EVENT_FLAG_CALL, "Newchannel", 02584 "Channel: %s\r\n" 02585 "State: %s\r\n" 02586 "CallerID: %s\r\n" 02587 "CallerIDName: %s\r\n" 02588 "Uniqueid: %s\r\n", 02589 c->name, ast_state2str(c->_state), 02590 c->cid.cid_num ? c->cid.cid_num : "<unknown>", 02591 c->cid.cid_name ? c->cid.cid_name : "<unknown>", 02592 c->uniqueid); 02593 } 02594 return c; 02595 } 02596 02597 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 02598 *cause = AST_CAUSE_NOSUCHDRIVER; 02599 ast_mutex_unlock(&chlock); 02600 02601 return NULL; 02602 }
struct ast_channel* ast_request_and_dial | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int | timeout, | |||
int * | reason, | |||
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.
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 2540 of file channel.c.
References __ast_request_and_dial().
Referenced by ast_pbx_outgoing_exten().
02541 { 02542 return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL); 02543 }
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 846 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().
00847 { 00848 struct ast_frame *f; 00849 while(ms > 0) { 00850 ms = ast_waitfor(chan, ms); 00851 if (ms <0) 00852 return -1; 00853 if (ms > 0) { 00854 f = ast_read(chan); 00855 if (!f) 00856 return -1; 00857 ast_frfree(f); 00858 } 00859 } 00860 return 0; 00861 }
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 824 of file channel.c.
References ast_frfree(), ast_read(), and ast_waitfor().
Referenced by __login_exec().
00826 { 00827 struct ast_frame *f; 00828 00829 while(ms > 0) { 00830 if( cond && ((*cond)(data) == 0 ) ) 00831 return 0; 00832 ms = ast_waitfor(chan, ms); 00833 if (ms <0) 00834 return -1; 00835 if (ms > 0) { 00836 f = ast_read(chan); 00837 if (!f) 00838 return -1; 00839 ast_frfree(f); 00840 } 00841 } 00842 return 0; 00843 }
int ast_senddigit | ( | struct ast_channel * | chan, | |
char | digit | |||
) |
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 2207 of file channel.c.
References do_senddigit().
Referenced by dial_exec_full(), and features_digit().
02208 { 02209 return do_senddigit(chan, digit); 02210 }
int ast_sendtext | ( | struct ast_channel * | chan, | |
const char * | text | |||
) |
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 2150 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().
02151 { 02152 int res = 0; 02153 /* Stop if we're a zombie or need a soft hangup */ 02154 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 02155 return -1; 02156 CHECK_BLOCKING(chan); 02157 if (chan->tech->send_text) 02158 res = chan->tech->send_text(chan, text); 02159 ast_clear_flag(chan, AST_FLAG_BLOCKING); 02160 return res; 02161 }
void ast_set_callerid | ( | struct ast_channel * | chan, | |
const char * | callerid, | |||
const char * | calleridname, | |||
const char * | ani | |||
) |
Definition at line 3202 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().
03203 { 03204 if (callerid) { 03205 if (chan->cid.cid_num) 03206 free(chan->cid.cid_num); 03207 if (ast_strlen_zero(callerid)) 03208 chan->cid.cid_num = NULL; 03209 else 03210 chan->cid.cid_num = strdup(callerid); 03211 } 03212 if (calleridname) { 03213 if (chan->cid.cid_name) 03214 free(chan->cid.cid_name); 03215 if (ast_strlen_zero(calleridname)) 03216 chan->cid.cid_name = NULL; 03217 else 03218 chan->cid.cid_name = strdup(calleridname); 03219 } 03220 if (ani) { 03221 if (chan->cid.cid_ani) 03222 free(chan->cid.cid_ani); 03223 if (ast_strlen_zero(ani)) 03224 chan->cid.cid_ani = NULL; 03225 else 03226 chan->cid.cid_ani = strdup(ani); 03227 } 03228 if (chan->cdr) 03229 ast_cdr_setcid(chan->cdr, chan); 03230 manager_event(EVENT_FLAG_CALL, "Newcallerid", 03231 "Channel: %s\r\n" 03232 "CallerID: %s\r\n" 03233 "CallerIDName: %s\r\n" 03234 "Uniqueid: %s\r\n" 03235 "CID-CallingPres: %d (%s)\r\n", 03236 chan->name, chan->cid.cid_num ? 03237 chan->cid.cid_num : "<Unknown>", 03238 chan->cid.cid_name ? 03239 chan->cid.cid_name : "<Unknown>", 03240 chan->uniqueid, 03241 chan->cid.cid_pres, 03242 ast_describe_caller_presentation(chan->cid.cid_pres) 03243 ); 03244 }
int ast_set_read_format | ( | struct ast_channel * | chan, | |
int | format | |||
) |
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 2414 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_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(), rpt(), rpt_exec(), rxfax_exec(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_read(), txfax_exec(), and update_features().
02415 { 02416 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat, 02417 &chan->readtrans, 0); 02418 }
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 3936 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().
03937 { 03938 struct ast_variable *cur; 03939 03940 for (cur = vars; cur; cur = cur->next) 03941 pbx_builtin_setvar_helper(chan, cur->name, cur->value); 03942 }
int ast_set_write_format | ( | struct ast_channel * | chan, | |
int | format | |||
) |
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 2420 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_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(), rxfax_exec(), send_waveform_to_channel(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_read(), tonepair_alloc(), tonepair_release(), txfax_exec(), and update_features().
02421 { 02422 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat, 02423 &chan->writetrans, 1); 02424 }
int ast_setstate | ( | struct ast_channel * | chan, | |
int | state | |||
) |
Change the state of a channel.
Definition at line 3246 of file channel.c.
References ast_channel::_state, ast_device_state_changed_literal(), ast_state2str(), AST_STATE_DOWN, 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_hangup(), vpb_new(), zt_answer(), zt_call(), zt_handle_event(), zt_indicate(), zt_new(), and zt_read().
03247 { 03248 int oldstate = chan->_state; 03249 03250 if (oldstate == state) 03251 return 0; 03252 03253 chan->_state = state; 03254 ast_device_state_changed_literal(chan->name); 03255 manager_event(EVENT_FLAG_CALL, 03256 (oldstate == AST_STATE_DOWN) ? "Newchannel" : "Newstate", 03257 "Channel: %s\r\n" 03258 "State: %s\r\n" 03259 "CallerID: %s\r\n" 03260 "CallerIDName: %s\r\n" 03261 "Uniqueid: %s\r\n", 03262 chan->name, ast_state2str(chan->_state), 03263 chan->cid.cid_num ? chan->cid.cid_num : "<unknown>", 03264 chan->cid.cid_name ? chan->cid.cid_name : "<unknown>", 03265 chan->uniqueid); 03266 03267 return 0; 03268 }
int ast_settimeout | ( | struct ast_channel * | c, | |
int | samples, | |||
int(*)(void *data) | func, | |||
void * | data | |||
) |
Definition at line 1752 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().
01753 { 01754 int res = -1; 01755 #ifdef ZAPTEL_OPTIMIZATIONS 01756 if (c->timingfd > -1) { 01757 if (!func) { 01758 samples = 0; 01759 data = 0; 01760 } 01761 ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples); 01762 res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples); 01763 c->timingfunc = func; 01764 c->timingdata = data; 01765 } 01766 #endif 01767 return res; 01768 }
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 1161 of file channel.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_softhangup_nolock(), and ast_channel::lock.
Referenced by __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().
01162 { 01163 int res; 01164 ast_mutex_lock(&chan->lock); 01165 res = ast_softhangup_nolock(chan, cause); 01166 ast_mutex_unlock(&chan->lock); 01167 return res; 01168 }
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 1145 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().
01146 { 01147 int res = 0; 01148 struct ast_frame f = { AST_FRAME_NULL }; 01149 if (option_debug) 01150 ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name); 01151 /* Inform channel driver that we need to be hung up, if it cares */ 01152 chan->_softhangup |= cause; 01153 ast_queue_frame(chan, &f); 01154 /* Interrupt any poll call or such */ 01155 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) 01156 pthread_kill(chan->blocker, SIGURG); 01157 return res; 01158 }
char* ast_state2str | ( | int | 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 419 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().
00420 { 00421 /* XXX Not reentrant XXX */ 00422 static char localtmp[256]; 00423 switch(state) { 00424 case AST_STATE_DOWN: 00425 return "Down"; 00426 case AST_STATE_RESERVED: 00427 return "Rsrvd"; 00428 case AST_STATE_OFFHOOK: 00429 return "OffHook"; 00430 case AST_STATE_DIALING: 00431 return "Dialing"; 00432 case AST_STATE_RING: 00433 return "Ring"; 00434 case AST_STATE_RINGING: 00435 return "Ringing"; 00436 case AST_STATE_UP: 00437 return "Up"; 00438 case AST_STATE_BUSY: 00439 return "Busy"; 00440 default: 00441 snprintf(localtmp, sizeof(localtmp), "Unknown (%d)\n", state); 00442 return localtmp; 00443 } 00444 }
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 3804 of file channel.c.
References ast_frfree(), ast_read(), ast_tonepair_start(), ast_waitfor(), and ast_channel::generatordata.
Referenced by zapateller_exec().
03805 { 03806 struct ast_frame *f; 03807 int res; 03808 03809 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 03810 return res; 03811 03812 /* Give us some wiggle room */ 03813 while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) { 03814 f = ast_read(chan); 03815 if (f) 03816 ast_frfree(f); 03817 else 03818 return -1; 03819 } 03820 return 0; 03821 }
int ast_tonepair_start | ( | struct ast_channel * | chan, | |
int | freq1, | |||
int | freq2, | |||
int | duration, | |||
int | vol | |||
) |
Start a tone going
Definition at line 3783 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().
03784 { 03785 struct tonepair_def d = { 0, }; 03786 03787 d.freq1 = freq1; 03788 d.freq2 = freq2; 03789 d.duration = duration; 03790 if (vol < 1) 03791 d.vol = 8192; 03792 else 03793 d.vol = vol; 03794 if (ast_activate_generator(chan, &tonepair, &d)) 03795 return -1; 03796 return 0; 03797 }
void ast_tonepair_stop | ( | struct ast_channel * | chan | ) |
Stop a tone from playing
Definition at line 3799 of file channel.c.
References ast_deactivate_generator().
Referenced by sendnoise().
03800 { 03801 ast_deactivate_generator(chan); 03802 }
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 2621 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().
02622 { 02623 int res = -1; 02624 02625 /* Stop if we're a zombie or need a soft hangup */ 02626 ast_mutex_lock(&chan->lock); 02627 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 02628 if (chan->tech->transfer) { 02629 res = chan->tech->transfer(chan, dest); 02630 if (!res) 02631 res = 1; 02632 } else 02633 res = 0; 02634 } 02635 ast_mutex_unlock(&chan->lock); 02636 return res; 02637 }
char* ast_transfercapability2str | ( | int | transfercapability | ) |
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 447 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().
00448 { 00449 switch(transfercapability) { 00450 case AST_TRANS_CAP_SPEECH: 00451 return "SPEECH"; 00452 case AST_TRANS_CAP_DIGITAL: 00453 return "DIGITAL"; 00454 case AST_TRANS_CAP_RESTRICTED_DIGITAL: 00455 return "RESTRICTED_DIGITAL"; 00456 case AST_TRANS_CAP_3_1K_AUDIO: 00457 return "3K1AUDIO"; 00458 case AST_TRANS_CAP_DIGITAL_W_TONES: 00459 return "DIGITAL_W_TONES"; 00460 case AST_TRANS_CAP_VIDEO: 00461 return "VIDEO"; 00462 default: 00463 return "UNKNOWN"; 00464 } 00465 }
void ast_uninstall_music_functions | ( | void | ) |
Definition at line 3873 of file channel.c.
References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.
03874 { 03875 ast_moh_start_ptr = NULL; 03876 ast_moh_stop_ptr = NULL; 03877 ast_moh_cleanup_ptr = NULL; 03878 }
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 1708 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(), recordthread(), rxfax_exec(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), ss_thread(), txfax_exec(), wait_for_hangup(), and waitforring_exec().
01709 { 01710 struct ast_channel *chan; 01711 int oldms = ms; 01712 01713 chan = ast_waitfor_n(&c, 1, &ms); 01714 if (ms < 0) { 01715 if (oldms < 0) 01716 return 0; 01717 else 01718 return -1; 01719 } 01720 return ms; 01721 }
struct ast_channel* ast_waitfor_n | ( | struct ast_channel ** | chan, | |
int | n, | |||
int * | ms | |||
) |
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 1703 of file channel.c.
References ast_waitfor_nandfds().
Referenced by ast_feature_request_and_dial(), ast_waitfor(), autoservice_run(), misdn_bridge(), rpt(), rpt_exec(), vpb_bridge(), wait_for_answer(), and zt_bridge().
01704 { 01705 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 01706 }
int ast_waitfor_n_fd | ( | int * | fds, | |
int | n, | |||
int * | ms, | |||
int * | exception | |||
) |
This version works on fd's only. Be careful with it.
Definition at line 1489 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().
01490 { 01491 struct timeval start = { 0 , 0 }; 01492 int res; 01493 int x, y; 01494 int winner = -1; 01495 int spoint; 01496 struct pollfd *pfds; 01497 01498 pfds = alloca(sizeof(struct pollfd) * n); 01499 if (!pfds) { 01500 ast_log(LOG_ERROR, "Out of memory\n"); 01501 return -1; 01502 } 01503 if (*ms > 0) 01504 start = ast_tvnow(); 01505 y = 0; 01506 for (x=0; x < n; x++) { 01507 if (fds[x] > -1) { 01508 pfds[y].fd = fds[x]; 01509 pfds[y].events = POLLIN | POLLPRI; 01510 y++; 01511 } 01512 } 01513 res = poll(pfds, y, *ms); 01514 if (res < 0) { 01515 /* Simulate a timeout if we were interrupted */ 01516 if (errno != EINTR) 01517 *ms = -1; 01518 else 01519 *ms = 0; 01520 return -1; 01521 } 01522 spoint = 0; 01523 for (x=0; x < n; x++) { 01524 if (fds[x] > -1) { 01525 if ((res = ast_fdisset(pfds, fds[x], y, &spoint))) { 01526 winner = fds[x]; 01527 if (exception) { 01528 if (res & POLLPRI) 01529 *exception = -1; 01530 else 01531 *exception = 0; 01532 } 01533 } 01534 } 01535 } 01536 if (*ms > 0) { 01537 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 01538 if (*ms < 0) 01539 *ms = 0; 01540 } 01541 return winner; 01542 }
struct ast_channel* ast_waitfor_nandfds | ( | struct ast_channel ** | chan, | |
int | n, | |||
int * | fds, | |||
int | nfds, | |||
int * | exception, | |||
int * | outfd, | |||
int * | ms | |||
) |
Waits for activity on a group of channels.
chan | an array of pointers to channels | |
n | number of channels that are to be waited upon | |
fds | an array of fds to wait upon | |
nfds | the number of fds to wait upon | |
exception | exception flag | |
outfd | fd that had activity on it | |
ms | how long the wait was Big momma function here. Wait for activity on any of the n channels, or any of the nfds file descriptors. |
Definition at line 1545 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, ast_channel::fdno, 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().
01547 { 01548 struct timeval start = { 0 , 0 }; 01549 struct pollfd *pfds; 01550 int res; 01551 long rms; 01552 int x, y, max; 01553 int spoint; 01554 time_t now = 0; 01555 long whentohangup = 0, havewhen = 0, diff; 01556 struct ast_channel *winner = NULL; 01557 01558 pfds = alloca(sizeof(struct pollfd) * (n * AST_MAX_FDS + nfds)); 01559 if (!pfds) { 01560 ast_log(LOG_ERROR, "Out of memory\n"); 01561 *outfd = -1; 01562 return NULL; 01563 } 01564 01565 if (outfd) 01566 *outfd = -99999; 01567 if (exception) 01568 *exception = 0; 01569 01570 /* Perform any pending masquerades */ 01571 for (x=0; x < n; x++) { 01572 ast_mutex_lock(&c[x]->lock); 01573 if (c[x]->whentohangup) { 01574 if (!havewhen) 01575 time(&now); 01576 diff = c[x]->whentohangup - now; 01577 if (!havewhen || (diff < whentohangup)) { 01578 havewhen++; 01579 whentohangup = diff; 01580 } 01581 } 01582 if (c[x]->masq) { 01583 if (ast_do_masquerade(c[x])) { 01584 ast_log(LOG_WARNING, "Masquerade failed\n"); 01585 *ms = -1; 01586 ast_mutex_unlock(&c[x]->lock); 01587 return NULL; 01588 } 01589 } 01590 ast_mutex_unlock(&c[x]->lock); 01591 } 01592 01593 rms = *ms; 01594 01595 if (havewhen) { 01596 if ((*ms < 0) || (whentohangup * 1000 < *ms)) { 01597 rms = whentohangup * 1000; 01598 } 01599 } 01600 max = 0; 01601 for (x=0; x < n; x++) { 01602 for (y=0; y< AST_MAX_FDS; y++) { 01603 if (c[x]->fds[y] > -1) { 01604 pfds[max].fd = c[x]->fds[y]; 01605 pfds[max].events = POLLIN | POLLPRI; 01606 pfds[max].revents = 0; 01607 max++; 01608 } 01609 } 01610 CHECK_BLOCKING(c[x]); 01611 } 01612 for (x=0; x < nfds; x++) { 01613 if (fds[x] > -1) { 01614 pfds[max].fd = fds[x]; 01615 pfds[max].events = POLLIN | POLLPRI; 01616 pfds[max].revents = 0; 01617 max++; 01618 } 01619 } 01620 if (*ms > 0) 01621 start = ast_tvnow(); 01622 01623 if (sizeof(int) == 4) { 01624 do { 01625 int kbrms = rms; 01626 if (kbrms > 600000) 01627 kbrms = 600000; 01628 res = poll(pfds, max, kbrms); 01629 if (!res) 01630 rms -= kbrms; 01631 } while (!res && (rms > 0)); 01632 } else { 01633 res = poll(pfds, max, rms); 01634 } 01635 01636 if (res < 0) { 01637 for (x=0; x < n; x++) 01638 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 01639 /* Simulate a timeout if we were interrupted */ 01640 if (errno != EINTR) 01641 *ms = -1; 01642 else { 01643 /* Just an interrupt */ 01644 #if 0 01645 *ms = 0; 01646 #endif 01647 } 01648 return NULL; 01649 } else { 01650 /* If no fds signalled, then timeout. So set ms = 0 01651 since we may not have an exact timeout. 01652 */ 01653 if (res == 0) 01654 *ms = 0; 01655 } 01656 01657 if (havewhen) 01658 time(&now); 01659 spoint = 0; 01660 for (x=0; x < n; x++) { 01661 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 01662 if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) { 01663 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 01664 if (!winner) 01665 winner = c[x]; 01666 } 01667 for (y=0; y < AST_MAX_FDS; y++) { 01668 if (c[x]->fds[y] > -1) { 01669 if ((res = ast_fdisset(pfds, c[x]->fds[y], max, &spoint))) { 01670 if (res & POLLPRI) 01671 ast_set_flag(c[x], AST_FLAG_EXCEPTION); 01672 else 01673 ast_clear_flag(c[x], AST_FLAG_EXCEPTION); 01674 c[x]->fdno = y; 01675 winner = c[x]; 01676 } 01677 } 01678 } 01679 } 01680 for (x=0; x < nfds; x++) { 01681 if (fds[x] > -1) { 01682 if ((res = ast_fdisset(pfds, fds[x], max, &spoint))) { 01683 if (outfd) 01684 *outfd = fds[x]; 01685 if (exception) { 01686 if (res & POLLPRI) 01687 *exception = -1; 01688 else 01689 *exception = 0; 01690 } 01691 winner = NULL; 01692 } 01693 } 01694 } 01695 if (*ms > 0) { 01696 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 01697 if (*ms < 0) 01698 *ms = 0; 01699 } 01700 return winner; 01701 }
int ast_waitfordigit | ( | struct ast_channel * | c, | |
int | ms | |||
) |
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 1723 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 _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().
01724 { 01725 /* XXX Should I be merged with waitfordigit_full XXX */ 01726 struct ast_frame *f; 01727 int result = 0; 01728 01729 /* Stop if we're a zombie or need a soft hangup */ 01730 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 01731 return -1; 01732 01733 /* Wait for a digit, no more than ms milliseconds total. */ 01734 while(ms && !result) { 01735 ms = ast_waitfor(c, ms); 01736 if (ms < 0) /* Error */ 01737 result = -1; 01738 else if (ms > 0) { 01739 /* Read something */ 01740 f = ast_read(c); 01741 if (f) { 01742 if (f->frametype == AST_FRAME_DTMF) 01743 result = f->subclass; 01744 ast_frfree(f); 01745 } else 01746 result = -1; 01747 } 01748 } 01749 return result; 01750 }
int ast_waitfordigit_full | ( | struct ast_channel * | c, | |
int | ms, | |||
int | audiofd, | |||
int | cmdfd | |||
) |
Definition at line 1770 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().
01771 { 01772 struct ast_frame *f; 01773 struct ast_channel *rchan; 01774 int outfd; 01775 int res; 01776 01777 /* Stop if we're a zombie or need a soft hangup */ 01778 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 01779 return -1; 01780 /* Wait for a digit, no more than ms milliseconds total. */ 01781 while(ms) { 01782 errno = 0; 01783 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01784 if ((!rchan) && (outfd < 0) && (ms)) { 01785 if (errno == 0 || errno == EINTR) 01786 continue; 01787 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01788 return -1; 01789 } else if (outfd > -1) { 01790 /* The FD we were watching has something waiting */ 01791 return 1; 01792 } else if (rchan) { 01793 f = ast_read(c); 01794 if(!f) { 01795 return -1; 01796 } 01797 01798 switch(f->frametype) { 01799 case AST_FRAME_DTMF: 01800 res = f->subclass; 01801 ast_frfree(f); 01802 return res; 01803 case AST_FRAME_CONTROL: 01804 switch(f->subclass) { 01805 case AST_CONTROL_HANGUP: 01806 ast_frfree(f); 01807 return -1; 01808 case AST_CONTROL_RINGING: 01809 case AST_CONTROL_ANSWER: 01810 /* Unimportant */ 01811 break; 01812 default: 01813 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass); 01814 break; 01815 } 01816 break; 01817 case AST_FRAME_VOICE: 01818 /* Write audio if appropriate */ 01819 if (audiofd > -1) 01820 write(audiofd, f->data, f->datalen); 01821 } 01822 /* Ignore */ 01823 ast_frfree(f); 01824 } 01825 } 01826 return 0; /* Time is up */ 01827 }
struct ast_channel* ast_walk_channel_by_name_prefix_locked | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const int | namelen | |||
) |
Get channel by name prefix (locks channel)
Definition at line 812 of file channel.c.
References channel_find_locked().
00813 { 00814 return channel_find_locked(chan, name, namelen, NULL, NULL); 00815 }
int ast_write | ( | struct ast_channel * | chan, | |
struct ast_frame * | frame | |||
) |
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 2240 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_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_prod(), ast_readaudio_callback(), ast_readvideo_callback(), ast_write_video(), conf_run(), dictate_exec(), echo_exec(), features_write(), function_ilink(), gen_generate(), handle_link_data(), linear_generator(), milliwatt_generate(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), NBScat_exec(), rpt(), rpt_call(), rxfax_exec(), send_link_dtmf(), send_tone_burst(), send_waveform_to_channel(), silence_generator_generate(), spy_generate(), tonepair_generator(), txfax_exec(), wait_for_answer(), and zt_bridge().
02241 { 02242 int res = -1; 02243 struct ast_frame *f = NULL; 02244 /* Stop if we're a zombie or need a soft hangup */ 02245 ast_mutex_lock(&chan->lock); 02246 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02247 ast_mutex_unlock(&chan->lock); 02248 return -1; 02249 } 02250 /* Handle any pending masquerades */ 02251 if (chan->masq) { 02252 if (ast_do_masquerade(chan)) { 02253 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 02254 ast_mutex_unlock(&chan->lock); 02255 return -1; 02256 } 02257 } 02258 if (chan->masqr) { 02259 ast_mutex_unlock(&chan->lock); 02260 return 0; 02261 } 02262 if (chan->generatordata) { 02263 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) 02264 ast_deactivate_generator(chan); 02265 else { 02266 ast_mutex_unlock(&chan->lock); 02267 return 0; 02268 } 02269 } 02270 /* High bit prints debugging */ 02271 if (chan->fout & 0x80000000) 02272 ast_frame_dump(chan->name, fr, ">>"); 02273 CHECK_BLOCKING(chan); 02274 switch(fr->frametype) { 02275 case AST_FRAME_CONTROL: 02276 /* XXX Interpret control frames XXX */ 02277 ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n"); 02278 break; 02279 case AST_FRAME_DTMF: 02280 ast_clear_flag(chan, AST_FLAG_BLOCKING); 02281 ast_mutex_unlock(&chan->lock); 02282 res = do_senddigit(chan,fr->subclass); 02283 ast_mutex_lock(&chan->lock); 02284 CHECK_BLOCKING(chan); 02285 break; 02286 case AST_FRAME_TEXT: 02287 if (chan->tech->send_text) 02288 res = chan->tech->send_text(chan, (char *) fr->data); 02289 else 02290 res = 0; 02291 break; 02292 case AST_FRAME_HTML: 02293 if (chan->tech->send_html) 02294 res = chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen); 02295 else 02296 res = 0; 02297 break; 02298 case AST_FRAME_VIDEO: 02299 /* XXX Handle translation of video codecs one day XXX */ 02300 if (chan->tech->write_video) 02301 res = chan->tech->write_video(chan, fr); 02302 else 02303 res = 0; 02304 break; 02305 default: 02306 if (chan->tech->write) { 02307 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr; 02308 if (f) { 02309 if (f->frametype == AST_FRAME_VOICE && chan->spies) 02310 queue_frame_to_spies(chan, f, SPY_WRITE); 02311 02312 if( chan->monitor && chan->monitor->write_stream && 02313 f && ( f->frametype == AST_FRAME_VOICE ) ) { 02314 #ifndef MONITOR_CONSTANT_DELAY 02315 int jump = chan->insmpl - chan->outsmpl - 4 * f->samples; 02316 if (jump >= 0) { 02317 if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1) 02318 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 02319 chan->outsmpl += jump + 4 * f->samples; 02320 } else 02321 chan->outsmpl += f->samples; 02322 #else 02323 int jump = chan->insmpl - chan->outsmpl; 02324 if (jump - MONITOR_DELAY >= 0) { 02325 if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1) 02326 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 02327 chan->outsmpl += jump; 02328 } else 02329 chan->outsmpl += f->samples; 02330 #endif 02331 if (ast_writestream(chan->monitor->write_stream, f) < 0) 02332 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 02333 } 02334 02335 res = chan->tech->write(chan, f); 02336 } else 02337 res = 0; 02338 } 02339 } 02340 02341 /* It's possible this is a translated frame */ 02342 if (f && f->frametype == AST_FRAME_DTMF) { 02343 ast_log(LOG_DTMF, "%s : %c\n", chan->name, f->subclass); 02344 } else if (fr->frametype == AST_FRAME_DTMF) { 02345 ast_log(LOG_DTMF, "%s : %c\n", chan->name, fr->subclass); 02346 } 02347 02348 if (f && (f != fr)) 02349 ast_frfree(f); 02350 ast_clear_flag(chan, AST_FLAG_BLOCKING); 02351 /* Consider a write failure to force a soft hangup */ 02352 if (res < 0) 02353 chan->_softhangup |= AST_SOFTHANGUP_DEV; 02354 else { 02355 if ((chan->fout & 0x7fffffff) == 0x7fffffff) 02356 chan->fout &= 0x80000000; 02357 else 02358 chan->fout++; 02359 } 02360 ast_mutex_unlock(&chan->lock); 02361 return res; 02362 }
int ast_write_video | ( | struct ast_channel * | chan, | |
struct ast_frame * | frame | |||
) |
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 2229 of file channel.c.
References ast_write(), ast_channel::tech, and ast_channel_tech::write_video.
02230 { 02231 int res; 02232 if (!chan->tech->write_video) 02233 return 0; 02234 res = ast_write(chan, fr); 02235 if (!res) 02236 res = 1; 02237 return res; 02238 }
static void bridge_playfile | ( | struct ast_channel * | chan, | |
struct ast_channel * | peer, | |||
char * | sound, | |||
int | remain | |||
) | [static] |
Definition at line 3280 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().
03281 { 03282 int res=0, min=0, sec=0,check=0; 03283 03284 check = ast_autoservice_start(peer); 03285 if(check) 03286 return; 03287 03288 if (remain > 0) { 03289 if (remain / 60 > 1) { 03290 min = remain / 60; 03291 sec = remain % 60; 03292 } else { 03293 sec = remain; 03294 } 03295 } 03296 03297 if (!strcmp(sound,"timeleft")) { /* Queue support */ 03298 res = ast_streamfile(chan, "vm-youhave", chan->language); 03299 res = ast_waitstream(chan, ""); 03300 if (min) { 03301 res = ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, (char *) NULL); 03302 res = ast_streamfile(chan, "queue-minutes", chan->language); 03303 res = ast_waitstream(chan, ""); 03304 } 03305 if (sec) { 03306 res = ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, (char *) NULL); 03307 res = ast_streamfile(chan, "queue-seconds", chan->language); 03308 res = ast_waitstream(chan, ""); 03309 } 03310 } else { 03311 res = ast_streamfile(chan, sound, chan->language); 03312 res = ast_waitstream(chan, ""); 03313 } 03314 03315 check = ast_autoservice_stop(peer); 03316 }
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] |
Definition at line 730 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().
00733 { 00734 const char *msg = prev ? "deadlock" : "initial deadlock"; 00735 int retries, done; 00736 struct ast_channel *c; 00737 00738 for (retries = 0; retries < 10; retries++) { 00739 ast_mutex_lock(&chlock); 00740 for (c = channels; c; c = c->next) { 00741 if (!prev) { 00742 /* want head of list */ 00743 if (!name && !exten) 00744 break; 00745 if (name) { 00746 /* want match by full name */ 00747 if (!namelen) { 00748 if (!strcasecmp(c->name, name)) 00749 break; 00750 else 00751 continue; 00752 } 00753 /* want match by name prefix */ 00754 if (!strncasecmp(c->name, name, namelen)) 00755 break; 00756 } else if (exten) { 00757 /* want match by context and exten */ 00758 if (context && (strcasecmp(c->context, context) && 00759 strcasecmp(c->macrocontext, context))) 00760 continue; 00761 /* match by exten */ 00762 if (strcasecmp(c->exten, exten) && 00763 strcasecmp(c->macroexten, exten)) 00764 continue; 00765 else 00766 break; 00767 } 00768 } else if (c == prev) { /* found, return c->next */ 00769 c = c->next; 00770 break; 00771 } 00772 } 00773 /* exit if chan not found or mutex acquired successfully */ 00774 done = (c == NULL) || (ast_mutex_trylock(&c->lock) == 0); 00775 /* this is slightly unsafe, as we _should_ hold the lock to access c->name */ 00776 if (!done && c) 00777 ast_log(LOG_DEBUG, "Avoiding %s for '%s'\n", msg, c->name); 00778 ast_mutex_unlock(&chlock); 00779 if (done) 00780 return c; 00781 usleep(1); 00782 } 00783 /* 00784 * c is surely not null, but we don't have the lock so cannot 00785 * access c->name 00786 */ 00787 ast_log(LOG_WARNING, "Avoided %s for '%p', %d retries!\n", 00788 msg, c, retries); 00789 00790 return NULL; 00791 }
static void clone_variables | ( | struct ast_channel * | original, | |
struct ast_channel * | clone | |||
) | [static] |
Definition at line 2915 of file channel.c.
References AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_var_delete(), ast_var_name(), GROUP_CATEGORY_PREFIX, and ast_channel::varshead.
02916 { 02917 struct ast_var_t *varptr; 02918 02919 /* we need to remove all app_groupcount related variables from the original 02920 channel before merging in the clone's variables; any groups assigned to the 02921 original channel should be released, only those assigned to the clone 02922 should remain 02923 */ 02924 02925 AST_LIST_TRAVERSE_SAFE_BEGIN(&original->varshead, varptr, entries) { 02926 if (!strncmp(ast_var_name(varptr), GROUP_CATEGORY_PREFIX, strlen(GROUP_CATEGORY_PREFIX))) { 02927 AST_LIST_REMOVE_CURRENT(&original->varshead, entries); 02928 ast_var_delete(varptr); 02929 } 02930 } 02931 AST_LIST_TRAVERSE_SAFE_END; 02932 02933 /* Append variables from clone channel into original channel */ 02934 /* XXX Is this always correct? We have to in order to keep MACROS working XXX */ 02935 if (AST_LIST_FIRST(&clone->varshead)) 02936 AST_LIST_APPEND_LIST(&original->varshead, &clone->varshead, entries); 02937 }
static void copy_data_from_queue | ( | struct ast_channel_spy_queue * | queue, | |
short * | buf, | |||
unsigned int | samples | |||
) | [static] |
Definition at line 3944 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().
03945 { 03946 struct ast_frame *f; 03947 int tocopy; 03948 int bytestocopy; 03949 03950 while (samples) { 03951 f = queue->head; 03952 03953 if (!f) { 03954 ast_log(LOG_ERROR, "Ran out of frames before buffer filled!\n"); 03955 break; 03956 } 03957 03958 tocopy = (f->samples > samples) ? samples : f->samples; 03959 bytestocopy = ast_codec_get_len(queue->format, tocopy); 03960 memcpy(buf, f->data, bytestocopy); 03961 samples -= tocopy; 03962 buf += tocopy; 03963 f->samples -= tocopy; 03964 f->data += bytestocopy; 03965 f->datalen -= bytestocopy; 03966 f->offset += bytestocopy; 03967 queue->samples -= tocopy; 03968 if (!f->samples) { 03969 queue->head = f->next; 03970 ast_frfree(f); 03971 } 03972 } 03973 }
static void detach_spies | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 1128 of file channel.c.
References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_channel_spy::chan, list, ast_channel::spies, spy_cleanup(), and spy_detach().
Referenced by ast_hangup().
01129 { 01130 struct ast_channel_spy *spy = NULL; 01131 01132 if (!chan->spies) 01133 return; 01134 01135 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list) { 01136 AST_LIST_REMOVE_CURRENT(&chan->spies->list, list); 01137 spy_detach(spy, chan); 01138 } 01139 AST_LIST_TRAVERSE_SAFE_END 01140 01141 spy_cleanup(chan); 01142 }
static int do_senddigit | ( | struct ast_channel * | chan, | |
char | digit | |||
) | [static] |
Definition at line 2163 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().
02164 { 02165 int res = -1; 02166 02167 if (chan->tech->send_digit) 02168 res = chan->tech->send_digit(chan, digit); 02169 if (!chan->tech->send_digit || res) { 02170 /* 02171 * Device does not support DTMF tones, lets fake 02172 * it by doing our own generation. (PM2002) 02173 */ 02174 static const char* dtmf_tones[] = { 02175 "!941+1336/100,!0/100", /* 0 */ 02176 "!697+1209/100,!0/100", /* 1 */ 02177 "!697+1336/100,!0/100", /* 2 */ 02178 "!697+1477/100,!0/100", /* 3 */ 02179 "!770+1209/100,!0/100", /* 4 */ 02180 "!770+1336/100,!0/100", /* 5 */ 02181 "!770+1477/100,!0/100", /* 6 */ 02182 "!852+1209/100,!0/100", /* 7 */ 02183 "!852+1336/100,!0/100", /* 8 */ 02184 "!852+1477/100,!0/100", /* 9 */ 02185 "!697+1633/100,!0/100", /* A */ 02186 "!770+1633/100,!0/100", /* B */ 02187 "!852+1633/100,!0/100", /* C */ 02188 "!941+1633/100,!0/100", /* D */ 02189 "!941+1209/100,!0/100", /* * */ 02190 "!941+1477/100,!0/100" }; /* # */ 02191 if (digit >= '0' && digit <='9') 02192 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0); 02193 else if (digit >= 'A' && digit <= 'D') 02194 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0); 02195 else if (digit == '*') 02196 ast_playtones_start(chan, 0, dtmf_tones[14], 0); 02197 else if (digit == '#') 02198 ast_playtones_start(chan, 0, dtmf_tones[15], 0); 02199 else { 02200 /* not handled */ 02201 ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name); 02202 } 02203 } 02204 return 0; 02205 }
static void free_cid | ( | struct ast_callerid * | cid | ) | [static] |
Definition at line 863 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().
00864 { 00865 if (cid->cid_dnid) 00866 free(cid->cid_dnid); 00867 if (cid->cid_num) 00868 free(cid->cid_num); 00869 if (cid->cid_name) 00870 free(cid->cid_name); 00871 if (cid->cid_ani) 00872 free(cid->cid_ani); 00873 if (cid->cid_rdnis) 00874 free(cid->cid_rdnis); 00875 }
static void free_translation | ( | struct ast_channel * | clone | ) | [static] |
Definition at line 1300 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().
01301 { 01302 if (clone->writetrans) 01303 ast_translator_free_path(clone->writetrans); 01304 if (clone->readtrans) 01305 ast_translator_free_path(clone->readtrans); 01306 clone->writetrans = NULL; 01307 clone->readtrans = NULL; 01308 clone->rawwriteformat = clone->nativeformats; 01309 clone->rawreadformat = clone->nativeformats; 01310 }
static int generator_force | ( | void * | data | ) | [static] |
Definition at line 1441 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().
01442 { 01443 /* Called if generator doesn't have data */ 01444 void *tmp; 01445 int res; 01446 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 01447 struct ast_channel *chan = data; 01448 tmp = chan->generatordata; 01449 chan->generatordata = NULL; 01450 generate = chan->generator->generate; 01451 res = generate(chan, tmp, 0, 160); 01452 chan->generatordata = tmp; 01453 if (res) { 01454 ast_log(LOG_DEBUG, "Auto-deactivating generator\n"); 01455 ast_deactivate_generator(chan); 01456 } 01457 return 0; 01458 }
static void queue_frame_to_spies | ( | struct ast_channel * | chan, | |
struct ast_frame * | f, | |||
enum spy_direction | dir | |||
) | [static] |
Definition at line 1177 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_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, list, ast_channel_spy::lock, LOG_DEBUG, LOG_ERROR, LOG_WARNING, ast_channel::name, ast_frame::next, msglist::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_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().
01178 { 01179 struct ast_frame *translated_frame = NULL; 01180 struct ast_channel_spy *spy; 01181 struct ast_channel_spy_queue *queue; 01182 struct channel_spy_trans *trans; 01183 struct ast_frame *last; 01184 01185 trans = (dir == SPY_READ) ? &chan->spies->read_translator : &chan->spies->write_translator; 01186 01187 AST_LIST_TRAVERSE(&chan->spies->list, spy, list) { 01188 ast_mutex_lock(&spy->lock); 01189 01190 queue = (dir == SPY_READ) ? &spy->read_queue : &spy->write_queue; 01191 01192 if ((queue->format == AST_FORMAT_SLINEAR) && (f->subclass != AST_FORMAT_SLINEAR)) { 01193 if (!translated_frame) { 01194 if (trans->path && (trans->last_format != f->subclass)) { 01195 ast_translator_free_path(trans->path); 01196 trans->path = NULL; 01197 } 01198 if (!trans->path) { 01199 ast_log(LOG_DEBUG, "Building translator from %s to SLINEAR for spies on channel %s\n", 01200 ast_getformatname(f->subclass), chan->name); 01201 if ((trans->path = ast_translator_build_path(AST_FORMAT_SLINEAR, f->subclass)) == NULL) { 01202 ast_log(LOG_WARNING, "Cannot build a path from %s to %s\n", 01203 ast_getformatname(f->subclass), ast_getformatname(AST_FORMAT_SLINEAR)); 01204 ast_mutex_unlock(&spy->lock); 01205 continue; 01206 } else { 01207 trans->last_format = f->subclass; 01208 } 01209 } 01210 if (!(translated_frame = ast_translate(trans->path, f, 0))) { 01211 ast_log(LOG_ERROR, "Translation to %s failed, dropping frame for spies\n", 01212 ast_getformatname(AST_FORMAT_SLINEAR)); 01213 ast_mutex_unlock(&spy->lock); 01214 break; 01215 } 01216 } 01217 01218 for (last = queue->head; last && last->next; last = last->next); 01219 if (last) 01220 last->next = ast_frdup(translated_frame); 01221 else 01222 queue->head = ast_frdup(translated_frame); 01223 } else { 01224 if (f->subclass != queue->format) { 01225 ast_log(LOG_WARNING, "Spy '%s' on channel '%s' wants format '%s', but frame is '%s', dropping\n", 01226 spy->type, chan->name, 01227 ast_getformatname(queue->format), ast_getformatname(f->subclass)); 01228 ast_mutex_unlock(&spy->lock); 01229 continue; 01230 } 01231 01232 for (last = queue->head; last && last->next; last = last->next); 01233 if (last) 01234 last->next = ast_frdup(f); 01235 else 01236 queue->head = ast_frdup(f); 01237 } 01238 01239 queue->samples += f->samples; 01240 01241 if (queue->samples > SPY_QUEUE_SAMPLE_LIMIT) { 01242 if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) { 01243 switch (ast_test_flag(spy, CHANSPY_TRIGGER_MODE)) { 01244 case CHANSPY_TRIGGER_READ: 01245 if (dir == SPY_WRITE) { 01246 ast_set_flag(spy, CHANSPY_TRIGGER_WRITE); 01247 ast_clear_flag(spy, CHANSPY_TRIGGER_READ); 01248 if (option_debug) 01249 ast_log(LOG_DEBUG, "Switching spy '%s' on '%s' to write-trigger mode\n", 01250 spy->type, chan->name); 01251 } 01252 break; 01253 case CHANSPY_TRIGGER_WRITE: 01254 if (dir == SPY_READ) { 01255 ast_set_flag(spy, CHANSPY_TRIGGER_READ); 01256 ast_clear_flag(spy, CHANSPY_TRIGGER_WRITE); 01257 if (option_debug) 01258 ast_log(LOG_DEBUG, "Switching spy '%s' on '%s' to read-trigger mode\n", 01259 spy->type, chan->name); 01260 } 01261 break; 01262 } 01263 if (option_debug) 01264 ast_log(LOG_DEBUG, "Triggering queue flush for spy '%s' on '%s'\n", 01265 spy->type, chan->name); 01266 ast_set_flag(spy, CHANSPY_TRIGGER_FLUSH); 01267 ast_cond_signal(&spy->trigger); 01268 } else { 01269 if (option_debug) 01270 ast_log(LOG_DEBUG, "Spy '%s' on channel '%s' %s queue too long, dropping frames\n", 01271 spy->type, chan->name, (dir == SPY_READ) ? "read" : "write"); 01272 while (queue->samples > SPY_QUEUE_SAMPLE_LIMIT) { 01273 struct ast_frame *drop = queue->head; 01274 01275 queue->samples -= drop->samples; 01276 queue->head = drop->next; 01277 ast_frfree(drop); 01278 } 01279 } 01280 } else { 01281 switch (ast_test_flag(spy, CHANSPY_TRIGGER_MODE)) { 01282 case CHANSPY_TRIGGER_READ: 01283 if (dir == SPY_READ) 01284 ast_cond_signal(&spy->trigger); 01285 break; 01286 case CHANSPY_TRIGGER_WRITE: 01287 if (dir == SPY_WRITE) 01288 ast_cond_signal(&spy->trigger); 01289 break; 01290 } 01291 } 01292 01293 ast_mutex_unlock(&spy->lock); 01294 } 01295 01296 if (translated_frame) 01297 ast_frfree(translated_frame); 01298 }
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 2364 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().
02366 { 02367 int native; 02368 int res; 02369 02370 native = chan->nativeformats; 02371 /* Find a translation path from the native format to one of the desired formats */ 02372 if (!direction) 02373 /* reading */ 02374 res = ast_translator_best_choice(&fmt, &native); 02375 else 02376 /* writing */ 02377 res = ast_translator_best_choice(&native, &fmt); 02378 02379 if (res < 0) { 02380 ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n", 02381 ast_getformatname(native), ast_getformatname(fmt)); 02382 return -1; 02383 } 02384 02385 /* Now we have a good choice for both. */ 02386 ast_mutex_lock(&chan->lock); 02387 02388 if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) { 02389 /* the channel is already in these formats, so nothing to do */ 02390 ast_mutex_unlock(&chan->lock); 02391 return 0; 02392 } 02393 02394 *rawformat = native; 02395 /* User perspective is fmt */ 02396 *format = fmt; 02397 /* Free any read translation we have right now */ 02398 if (*trans) 02399 ast_translator_free_path(*trans); 02400 /* Build a translation path from the raw format to the desired format */ 02401 if (!direction) 02402 /* reading */ 02403 *trans = ast_translator_build_path(*format, *rawformat); 02404 else 02405 /* writing */ 02406 *trans = ast_translator_build_path(*rawformat, *format); 02407 ast_mutex_unlock(&chan->lock); 02408 if (option_debug) 02409 ast_log(LOG_DEBUG, "Set channel %s to %s format %s\n", chan->name, 02410 direction ? "write" : "read", ast_getformatname(fmt)); 02411 return 0; 02412 }
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 4088 of file channel.c.
References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_write(), and ast_frame::frametype.
04089 { 04090 if (samples == 160) { 04091 short buf[160] = { 0, }; 04092 struct ast_frame frame = { 04093 .frametype = AST_FRAME_VOICE, 04094 .subclass = AST_FORMAT_SLINEAR, 04095 .data = buf, 04096 .samples = 160, 04097 .datalen = sizeof(buf), 04098 }; 04099 04100 if (ast_write(chan, &frame)) 04101 return -1; 04102 } else { 04103 short buf[samples]; 04104 int x; 04105 struct ast_frame frame = { 04106 .frametype = AST_FRAME_VOICE, 04107 .subclass = AST_FORMAT_SLINEAR, 04108 .data = buf, 04109 .samples = samples, 04110 .datalen = sizeof(buf), 04111 }; 04112 04113 for (x = 0; x < samples; x++) 04114 buf[x] = 0; 04115 04116 if (ast_write(chan, &frame)) 04117 return -1; 04118 } 04119 04120 return 0; 04121 }
static void silence_generator_release | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
static void spy_cleanup | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 1021 of file channel.c.
References AST_LIST_EMPTY, 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().
01022 { 01023 if (AST_LIST_EMPTY(&chan->spies->list)) 01024 return; 01025 if (chan->spies->read_translator.path) 01026 ast_translator_free_path(chan->spies->read_translator.path); 01027 if (chan->spies->write_translator.path) 01028 ast_translator_free_path(chan->spies->write_translator.path); 01029 free(chan->spies); 01030 chan->spies = NULL; 01031 return; 01032 }
static void spy_detach | ( | struct ast_channel_spy * | spy, | |
struct ast_channel * | chan | |||
) | [static] |
Definition at line 1035 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().
01036 { 01037 ast_mutex_lock(&spy->lock); 01038 01039 /* We only need to poke them if they aren't already done */ 01040 if (spy->status != CHANSPY_DONE) { 01041 spy->status = CHANSPY_STOP; 01042 spy->chan = NULL; 01043 if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) 01044 ast_cond_signal(&spy->trigger); 01045 } 01046 01047 /* Print it out while we still have a lock so the structure can't go away (if signalled above) */ 01048 ast_log(LOG_DEBUG, "Spy %s removed from channel %s\n", spy->type, chan->name); 01049 01050 ast_mutex_unlock(&spy->lock); 01051 01052 return; 01053 }
static void* tonepair_alloc | ( | struct ast_channel * | chan, | |
void * | params | |||
) | [static] |
Definition at line 3716 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.
03717 { 03718 struct tonepair_state *ts; 03719 struct tonepair_def *td = params; 03720 03721 ts = malloc(sizeof(struct tonepair_state)); 03722 if (!ts) 03723 return NULL; 03724 memset(ts, 0, sizeof(struct tonepair_state)); 03725 ts->origwfmt = chan->writeformat; 03726 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) { 03727 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name); 03728 tonepair_release(NULL, ts); 03729 ts = NULL; 03730 } else { 03731 ts->freq1 = td->freq1; 03732 ts->freq2 = td->freq2; 03733 ts->duration = td->duration; 03734 ts->vol = td->vol; 03735 } 03736 /* Let interrupts interrupt :) */ 03737 ast_set_flag(chan, AST_FLAG_WRITE_INT); 03738 return ts; 03739 }
static int tonepair_generator | ( | struct ast_channel * | chan, | |
void * | data, | |||
int | len, | |||
int | samples | |||
) | [static] |
Definition at line 3741 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.
03742 { 03743 struct tonepair_state *ts = data; 03744 int x; 03745 03746 /* we need to prepare a frame with 16 * timelen samples as we're 03747 * generating SLIN audio 03748 */ 03749 len = samples * 2; 03750 03751 if (len > sizeof(ts->data) / 2 - 1) { 03752 ast_log(LOG_WARNING, "Can't generate that much data!\n"); 03753 return -1; 03754 } 03755 memset(&ts->f, 0, sizeof(ts->f)); 03756 for (x = 0; x < (len / 2); x++) { 03757 ts->data[x] = ts->vol * ( 03758 sin((ts->freq1 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) + 03759 sin((ts->freq2 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) 03760 ); 03761 } 03762 ts->f.frametype = AST_FRAME_VOICE; 03763 ts->f.subclass = AST_FORMAT_SLINEAR; 03764 ts->f.datalen = len; 03765 ts->f.samples = samples; 03766 ts->f.offset = AST_FRIENDLY_OFFSET; 03767 ts->f.data = ts->data; 03768 ast_write(chan, &ts->f); 03769 ts->pos += x; 03770 if (ts->duration > 0) { 03771 if (ts->pos >= ts->duration * 8) 03772 return -1; 03773 } 03774 return 0; 03775 }
static void tonepair_release | ( | struct ast_channel * | chan, | |
void * | params | |||
) | [static] |
Definition at line 3706 of file channel.c.
References ast_set_write_format(), free, and tonepair_state::origwfmt.
Referenced by tonepair_alloc().
03707 { 03708 struct tonepair_state *ts = params; 03709 03710 if (chan) { 03711 ast_set_write_format(chan, ts->origwfmt); 03712 } 03713 free(ts); 03714 }
void(*) ast_moh_cleanup_ptr(struct ast_channel *) = NULL [static] |
Definition at line 3860 of file channel.c.
Referenced by ast_install_music_functions(), ast_moh_cleanup(), and ast_uninstall_music_functions().
int(*) ast_moh_start_ptr(struct ast_channel *, char *) = NULL [static] |
Definition at line 3858 of file channel.c.
Referenced by ast_install_music_functions(), ast_moh_start(), and ast_uninstall_music_functions().
void(*) ast_moh_stop_ptr(struct ast_channel *) = NULL [static] |
Definition at line 3859 of file channel.c.
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_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] |
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, }
Definition at line 4123 of file channel.c.
Referenced by ast_channel_start_silence_generator().
struct ast_generator tonepair [static] |
Initial value:
{ alloc: tonepair_alloc, release: tonepair_release, generate: tonepair_generator, }
Definition at line 3777 of file channel.c.
Referenced by ast_tonepair_start().