#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"
Include dependency graph for channel.c:
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. | |
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) |
const struct ast_channel_tech * | ast_get_channel_tech (const char *name) |
Get a channel technology structure by name. | |
ast_group_t | ast_get_group (char *s) |
int | ast_hangup (struct ast_channel *chan) |
Hang up a channel. | |
int | ast_indicate (struct ast_channel *chan, int condition) |
Indicates condition of channel. | |
void | ast_install_music_functions (int(*start_ptr)(struct ast_channel *, char *), void(*stop_ptr)(struct ast_channel *), void(*cleanup_ptr)(struct ast_channel *)) |
void | ast_moh_cleanup (struct ast_channel *chan) |
int | ast_moh_start (struct ast_channel *chan, char *mclass) |
void | ast_moh_stop (struct ast_channel *chan) |
AST_MUTEX_DEFINE_STATIC (chlock) | |
AST_MUTEX_DEFINE_STATIC (uniquelock) | |
char * | ast_print_group (char *buf, int buflen, ast_group_t group) |
int | ast_prod (struct ast_channel *chan) |
int | ast_queue_control (struct ast_channel *chan, int control) |
Queue a control frame. | |
int | ast_queue_frame (struct ast_channel *chan, struct ast_frame *fin) |
Queue an outgoing frame. | |
int | ast_queue_hangup (struct ast_channel *chan) |
Queue a hangup frame. | |
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 * | 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 |
const struct ast_cause | causes [] |
static struct ast_channel * | channels = NULL |
static struct ast_cli_entry | cli_show_channeltypes |
unsigned long | global_fin = 0 |
unsigned long | global_fout = 0 |
static const 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.
|
|
|
Definition at line 1131 of file channel.c. Referenced by queue_frame_to_spies(). |
|
Definition at line 1126 of file channel.c.
|
|
Definition at line 2365 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(). 02366 { 02367 int state = 0; 02368 int cause = 0; 02369 struct ast_channel *chan; 02370 struct ast_frame *f; 02371 int res = 0; 02372 02373 chan = ast_request(type, format, data, &cause); 02374 if (chan) { 02375 if (oh) { 02376 if (oh->vars) 02377 ast_set_variables(chan, oh->vars); 02378 if (oh->cid_num && *oh->cid_num && oh->cid_name && *oh->cid_name) 02379 ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num); 02380 if (oh->parent_channel) 02381 ast_channel_inherit_variables(oh->parent_channel, chan); 02382 if (oh->account) 02383 ast_cdr_setaccount(chan, oh->account); 02384 } 02385 ast_set_callerid(chan, cid_num, cid_name, cid_num); 02386 02387 if (!ast_call(chan, data, 0)) { 02388 res = 1; /* in case chan->_state is already AST_STATE_UP */ 02389 while (timeout && (chan->_state != AST_STATE_UP)) { 02390 res = ast_waitfor(chan, timeout); 02391 if (res < 0) { 02392 /* Something not cool, or timed out */ 02393 break; 02394 } 02395 /* If done, break out */ 02396 if (!res) 02397 break; 02398 if (timeout > -1) 02399 timeout = res; 02400 f = ast_read(chan); 02401 if (!f) { 02402 state = AST_CONTROL_HANGUP; 02403 res = 0; 02404 break; 02405 } 02406 if (f->frametype == AST_FRAME_CONTROL) { 02407 if (f->subclass == AST_CONTROL_RINGING) 02408 state = AST_CONTROL_RINGING; 02409 else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) { 02410 state = f->subclass; 02411 ast_frfree(f); 02412 break; 02413 } else if (f->subclass == AST_CONTROL_ANSWER) { 02414 state = f->subclass; 02415 ast_frfree(f); 02416 break; 02417 } else if (f->subclass == AST_CONTROL_PROGRESS) { 02418 /* Ignore */ 02419 } else if (f->subclass == -1) { 02420 /* Ignore -- just stopping indications */ 02421 } else { 02422 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass); 02423 } 02424 } 02425 ast_frfree(f); 02426 } 02427 } else 02428 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data); 02429 } else { 02430 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 02431 switch(cause) { 02432 case AST_CAUSE_BUSY: 02433 state = AST_CONTROL_BUSY; 02434 break; 02435 case AST_CAUSE_CONGESTION: 02436 state = AST_CONTROL_CONGESTION; 02437 break; 02438 } 02439 } 02440 if (chan) { 02441 /* Final fixups */ 02442 if (oh) { 02443 if (oh->context && *oh->context) 02444 ast_copy_string(chan->context, oh->context, sizeof(chan->context)); 02445 if (oh->exten && *oh->exten) 02446 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten)); 02447 if (oh->priority) 02448 chan->priority = oh->priority; 02449 } 02450 if (chan->_state == AST_STATE_UP) 02451 state = AST_CONTROL_ANSWER; 02452 } 02453 if (outstate) 02454 *outstate = state; 02455 if (chan && res <= 0) { 02456 if (!chan->cdr) { 02457 chan->cdr = ast_cdr_alloc(); 02458 if (chan->cdr) 02459 ast_cdr_init(chan->cdr, chan); 02460 } 02461 if (chan->cdr) { 02462 char tmp[256]; 02463 snprintf(tmp, 256, "%s/%s", type, (char *)data); 02464 ast_cdr_setapp(chan->cdr,"Dial",tmp); 02465 ast_cdr_update(chan); 02466 ast_cdr_start(chan->cdr); 02467 ast_cdr_end(chan->cdr); 02468 /* If the cause wasn't handled properly */ 02469 if (ast_cdr_disposition(chan->cdr,chan->hangupcause)) 02470 ast_cdr_failed(chan->cdr); 02471 } else 02472 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 02473 ast_hangup(chan); 02474 chan = NULL; 02475 } 02476 return chan; 02477 }
|
|
|
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 }
|
|
|
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 }
|
|
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_iax2_new(), builtin_atxfer(), echo_exec(), iax2_request(), 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 }
|
|
Find bridged channel.
Definition at line 3159 of file channel.c. References ast_channel::_bridge, ast_channel_tech::bridged_channel, and ast_channel::tech. Referenced by __zt_exception(), agents_show(), attempt_transfer(), 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(). 03160 { 03161 struct ast_channel *bridged; 03162 bridged = chan->_bridge; 03163 if (bridged && bridged->tech->bridged_channel) 03164 bridged = bridged->tech->bridged_channel(chan, bridged); 03165 return bridged; 03166 }
|
|
Make a call.
Definition at line 2543 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(), features_call(), function_ilink(), ring_entry(), rpt(), and wait_for_answer(). 02544 { 02545 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 02546 If the remote end does not answer within the timeout, then do NOT hang up, but 02547 return anyway. */ 02548 int res = -1; 02549 /* Stop if we're a zombie or need a soft hangup */ 02550 ast_mutex_lock(&chan->lock); 02551 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) 02552 if (chan->tech->call) 02553 res = chan->tech->call(chan, addr, timeout); 02554 ast_mutex_unlock(&chan->lock); 02555 return res; 02556 }
|
|
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 }
|
|
Definition at line 407 of file channel.c. Referenced by __transmit_response(), ast_hangup(), 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 }
|
|
Change channel name.
Definition at line 2768 of file channel.c. References EVENT_FLAG_CALL, manager_event(), ast_channel::name, and ast_channel::uniqueid. 02769 { 02770 char tmp[256]; 02771 ast_copy_string(tmp, chan->name, sizeof(tmp)); 02772 ast_copy_string(chan->name, newname, sizeof(chan->name)); 02773 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid); 02774 }
|
|
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 }
|
|
Definition at line 3320 of file channel.c. References ast_channel::_bridge, AST_BRIDGE_COMPLETE, ast_check_hangup_locked(), AST_FEATURE_PLAY_WARNING, AST_FLAG_ZOMBIE, ast_log(), ast_test_flag, ast_tvadd(), ast_tvsub(), bridge_playfile(), ast_channel::cid, ast_callerid::cid_num, config, EVENT_FLAG_CALL, LOG_WARNING, manager_event(), ast_channel::name, ast_channel::nativeformats, and ast_channel::uniqueid. Referenced by ast_bridge_call(). 03322 { 03323 struct ast_channel *who = NULL; 03324 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 03325 int nativefailed=0; 03326 int firstpass; 03327 int o0nativeformats; 03328 int o1nativeformats; 03329 long time_left_ms=0; 03330 struct timeval nexteventts = { 0, }; 03331 char caller_warning = 0; 03332 char callee_warning = 0; 03333 int to; 03334 03335 if (c0->_bridge) { 03336 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 03337 c0->name, c0->_bridge->name); 03338 return -1; 03339 } 03340 if (c1->_bridge) { 03341 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 03342 c1->name, c1->_bridge->name); 03343 return -1; 03344 } 03345 03346 /* Stop if we're a zombie or need a soft hangup */ 03347 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 03348 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 03349 return -1; 03350 03351 *fo = NULL; 03352 firstpass = config->firstpass; 03353 config->firstpass = 0; 03354 03355 if (ast_tvzero(config->start_time)) 03356 config->start_time = ast_tvnow(); 03357 time_left_ms = config->timelimit; 03358 03359 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING); 03360 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING); 03361 03362 if (config->start_sound && firstpass) { 03363 if (caller_warning) 03364 bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000); 03365 if (callee_warning) 03366 bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000); 03367 } 03368 03369 /* Keep track of bridge */ 03370 c0->_bridge = c1; 03371 c1->_bridge = c0; 03372 03373 manager_event(EVENT_FLAG_CALL, "Link", 03374 "Channel1: %s\r\n" 03375 "Channel2: %s\r\n" 03376 "Uniqueid1: %s\r\n" 03377 "Uniqueid2: %s\r\n" 03378 "CallerID1: %s\r\n" 03379 "CallerID2: %s\r\n", 03380 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03381 03382 o0nativeformats = c0->nativeformats; 03383 o1nativeformats = c1->nativeformats; 03384 03385 if (config->timelimit) { 03386 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 03387 if (caller_warning || callee_warning) 03388 nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000)); 03389 } 03390 03391 for (/* ever */;;) { 03392 to = -1; 03393 if (config->timelimit) { 03394 struct timeval now; 03395 now = ast_tvnow(); 03396 to = ast_tvdiff_ms(nexteventts, now); 03397 if (to < 0) 03398 to = 0; 03399 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time); 03400 if (time_left_ms < to) 03401 to = time_left_ms; 03402 03403 if (time_left_ms <= 0) { 03404 if (caller_warning && config->end_sound) 03405 bridge_playfile(c0, c1, config->end_sound, 0); 03406 if (callee_warning && config->end_sound) 03407 bridge_playfile(c1, c0, config->end_sound, 0); 03408 *fo = NULL; 03409 if (who) 03410 *rc = who; 03411 res = 0; 03412 break; 03413 } 03414 03415 if (!to) { 03416 if (time_left_ms >= 5000) { 03417 /* force the time left to round up if appropriate */ 03418 if (caller_warning && config->warning_sound && config->play_warning) 03419 bridge_playfile(c0, c1, config->warning_sound, 03420 (time_left_ms + 500) / 1000); 03421 if (callee_warning && config->warning_sound && config->play_warning) 03422 bridge_playfile(c1, c0, config->warning_sound, 03423 (time_left_ms + 500) / 1000); 03424 } 03425 if (config->warning_freq) { 03426 nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000)); 03427 } else 03428 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 03429 } 03430 } 03431 03432 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) { 03433 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03434 c0->_softhangup = 0; 03435 if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03436 c1->_softhangup = 0; 03437 c0->_bridge = c1; 03438 c1->_bridge = c0; 03439 ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n"); 03440 continue; 03441 } 03442 03443 /* Stop if we're a zombie or need a soft hangup */ 03444 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 03445 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) { 03446 *fo = NULL; 03447 if (who) 03448 *rc = who; 03449 res = 0; 03450 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", 03451 c0->name, c1->name, 03452 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No", 03453 ast_check_hangup(c0) ? "Yes" : "No", 03454 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No", 03455 ast_check_hangup(c1) ? "Yes" : "No"); 03456 break; 03457 } 03458 03459 if (c0->tech->bridge && 03460 (config->timelimit == 0) && 03461 (c0->tech->bridge == c1->tech->bridge) && 03462 !nativefailed && !c0->monitor && !c1->monitor && 03463 !c0->spies && !c1->spies) { 03464 /* Looks like they share a bridge method and nothing else is in the way */ 03465 if (option_verbose > 2) 03466 ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name); 03467 ast_set_flag(c0, AST_FLAG_NBRIDGE); 03468 ast_set_flag(c1, AST_FLAG_NBRIDGE); 03469 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) { 03470 manager_event(EVENT_FLAG_CALL, "Unlink", 03471 "Channel1: %s\r\n" 03472 "Channel2: %s\r\n" 03473 "Uniqueid1: %s\r\n" 03474 "Uniqueid2: %s\r\n" 03475 "CallerID1: %s\r\n" 03476 "CallerID2: %s\r\n", 03477 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03478 ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name); 03479 03480 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 03481 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 03482 03483 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03484 continue; 03485 03486 c0->_bridge = NULL; 03487 c1->_bridge = NULL; 03488 03489 return res; 03490 } else { 03491 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 03492 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 03493 } 03494 switch (res) { 03495 case AST_BRIDGE_RETRY: 03496 continue; 03497 default: 03498 ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name); 03499 /* fallthrough */ 03500 case AST_BRIDGE_FAILED_NOWARN: 03501 nativefailed++; 03502 break; 03503 } 03504 } 03505 03506 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) || 03507 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) && 03508 !(c0->generator || c1->generator)) { 03509 if (ast_channel_make_compatible(c0, c1)) { 03510 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 03511 manager_event(EVENT_FLAG_CALL, "Unlink", 03512 "Channel1: %s\r\n" 03513 "Channel2: %s\r\n" 03514 "Uniqueid1: %s\r\n" 03515 "Uniqueid2: %s\r\n" 03516 "CallerID1: %s\r\n" 03517 "CallerID2: %s\r\n", 03518 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03519 return AST_BRIDGE_FAILED; 03520 } 03521 o0nativeformats = c0->nativeformats; 03522 o1nativeformats = c1->nativeformats; 03523 } 03524 res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts); 03525 if (res != AST_BRIDGE_RETRY) 03526 break; 03527 } 03528 03529 c0->_bridge = NULL; 03530 c1->_bridge = NULL; 03531 03532 manager_event(EVENT_FLAG_CALL, "Unlink", 03533 "Channel1: %s\r\n" 03534 "Channel2: %s\r\n" 03535 "Uniqueid1: %s\r\n" 03536 "Uniqueid2: %s\r\n" 03537 "CallerID1: %s\r\n" 03538 "CallerID2: %s\r\n", 03539 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03540 ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name); 03541 03542 return res; 03543 }
|
|
Compare a offset with the settings of when to hang a channel up.
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 }
|
|
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 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 }
|
|
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 }
|
|
Inherits channel variable from parent to child channel.
Definition at line 2776 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(), option_debug, and ast_channel::varshead. Referenced by __ast_request_and_dial(), agent_call(), ast_feature_request_and_dial(), and ring_entry(). 02777 { 02778 struct ast_var_t *current, *newvar; 02779 char *varname; 02780 02781 AST_LIST_TRAVERSE(&parent->varshead, current, entries) { 02782 int vartype = 0; 02783 02784 varname = ast_var_full_name(current); 02785 if (!varname) 02786 continue; 02787 02788 if (varname[0] == '_') { 02789 vartype = 1; 02790 if (varname[1] == '_') 02791 vartype = 2; 02792 } 02793 02794 switch (vartype) { 02795 case 1: 02796 newvar = ast_var_assign(&varname[1], ast_var_value(current)); 02797 if (newvar) { 02798 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 02799 if (option_debug) 02800 ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar)); 02801 } 02802 break; 02803 case 2: 02804 newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current)); 02805 if (newvar) { 02806 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 02807 if (option_debug) 02808 ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar)); 02809 } 02810 break; 02811 default: 02812 if (option_debug) 02813 ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current)); 02814 break; 02815 } 02816 } 02817 }
|
|
Definition at line 2682 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 builtin_atxfer(), park_exec(), and wait_for_answer(). 02683 { 02684 int src; 02685 int dst; 02686 02687 /* Set up translation from the chan to the peer */ 02688 src = chan->nativeformats; 02689 dst = peer->nativeformats; 02690 if (ast_translator_best_choice(&dst, &src) < 0) { 02691 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst); 02692 return -1; 02693 } 02694 02695 /* if the best path is not 'pass through', then 02696 transcoding is needed; if desired, force transcode path 02697 to use SLINEAR between channels */ 02698 if ((src != dst) && option_transcode_slin) 02699 dst = AST_FORMAT_SLINEAR; 02700 if (ast_set_read_format(chan, dst) < 0) { 02701 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst); 02702 return -1; 02703 } 02704 if (ast_set_write_format(peer, dst) < 0) { 02705 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, dst); 02706 return -1; 02707 } 02708 02709 /* Set up translation from the peer to the chan */ 02710 src = peer->nativeformats; 02711 dst = chan->nativeformats; 02712 if (ast_translator_best_choice(&dst, &src) < 0) { 02713 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst); 02714 return -1; 02715 } 02716 /* if the best path is not 'pass through', then 02717 transcoding is needed; if desired, force transcode path 02718 to use SLINEAR between channels */ 02719 if ((src != dst) && option_transcode_slin) 02720 dst = AST_FORMAT_SLINEAR; 02721 if (ast_set_read_format(peer, dst) < 0) { 02722 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst); 02723 return -1; 02724 } 02725 if (ast_set_write_format(chan, dst) < 0) { 02726 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, dst); 02727 return -1; 02728 } 02729 return 0; 02730 }
|
|
Definition at line 2732 of file channel.c. References AST_FRAME_NULL, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), ast_channel::lock, 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(). 02733 { 02734 struct ast_frame null = { AST_FRAME_NULL, }; 02735 int res = -1; 02736 02737 if (original == clone) { 02738 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name); 02739 return -1; 02740 } 02741 ast_mutex_lock(&original->lock); 02742 while(ast_mutex_trylock(&clone->lock)) { 02743 ast_mutex_unlock(&original->lock); 02744 usleep(1); 02745 ast_mutex_lock(&original->lock); 02746 } 02747 ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n", 02748 clone->name, original->name); 02749 if (original->masq) { 02750 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 02751 original->masq->name, original->name); 02752 } else if (clone->masqr) { 02753 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 02754 clone->name, clone->masqr->name); 02755 } else { 02756 original->masq = clone; 02757 clone->masqr = original; 02758 ast_queue_frame(original, &null); 02759 ast_queue_frame(clone, &null); 02760 ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name); 02761 res = 0; 02762 } 02763 ast_mutex_unlock(&clone->lock); 02764 ast_mutex_unlock(&original->lock); 02765 return res; 02766 }
|
|
Register a channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports.
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 }
|
|
Send HTML or URL on link. Returns 0 on success or -1 on failure Definition at line 2668 of file channel.c. References ast_channel_tech::send_html, and ast_channel::tech. Referenced by agent_sendhtml(), and wait_for_answer(). 02669 { 02670 if (chan->tech->send_html) 02671 return chan->tech->send_html(chan, subclass, data, datalen); 02672 return -1; 02673 }
|
|
Send URL on link. Returns 0 on success or -1 on failure Definition at line 2675 of file channel.c. References AST_HTML_URL, ast_channel_tech::send_html, and ast_channel::tech. Referenced by sendurl_exec(). 02676 { 02677 if (chan->tech->send_html) 02678 return chan->tech->send_html(chan, AST_HTML_URL, url, strlen(url) + 1); 02679 return -1; 02680 }
|
|
Definition at line 3546 of file channel.c. References ast_log(), LOG_ERROR, ast_channel_tech::setoption, and ast_channel::tech. Referenced by ast_bridge_call(), conf_run(), handle_tddmode(), play_record_review(), reset_volumes(), rpt(), set_listen_volume(), set_talk_volume(), set_volume(), vm_forwardoptions(), and zt_hangup(). 03547 { 03548 int res; 03549 03550 if (chan->tech->setoption) { 03551 res = chan->tech->setoption(chan, option, data, datalen); 03552 if (res < 0) 03553 return res; 03554 } else { 03555 errno = ENOSYS; 03556 return -1; 03557 } 03558 if (block) { 03559 /* XXX Implement blocking -- just wait for our option frame reply, discarding 03560 intermediate packets. XXX */ 03561 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 03562 return -1; 03563 } 03564 return 0; 03565 }
|
|
Set when to hang a channel 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 }
|
|
Adds a spy to a channel, to begin receiving copies of the channel's audio frames.
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, 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_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 if (!ast_test_flag(spy, CHANSPY_FORMAT_AUDIO)) { 00968 ast_log(LOG_WARNING, "Could not add channel spy '%s' to channel '%s', only audio format spies are supported.\n", 00969 spy->type, chan->name); 00970 return -1; 00971 } 00972 00973 if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST) && (spy->read_queue.format != AST_FORMAT_SLINEAR)) { 00974 ast_log(LOG_WARNING, "Cannot provide volume adjustment on '%s' format spies\n", 00975 ast_getformatname(spy->read_queue.format)); 00976 return -1; 00977 } 00978 00979 if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST) && (spy->write_queue.format != AST_FORMAT_SLINEAR)) { 00980 ast_log(LOG_WARNING, "Cannot provide volume adjustment on '%s' format spies\n", 00981 ast_getformatname(spy->write_queue.format)); 00982 return -1; 00983 } 00984 00985 if (ast_test_flag(spy, CHANSPY_MIXAUDIO) && 00986 ((spy->read_queue.format != AST_FORMAT_SLINEAR) || 00987 (spy->write_queue.format != AST_FORMAT_SLINEAR))) { 00988 ast_log(LOG_WARNING, "Cannot provide audio mixing on '%s'-'%s' format spies\n", 00989 ast_getformatname(spy->read_queue.format), ast_getformatname(spy->write_queue.format)); 00990 return -1; 00991 } 00992 00993 if (!chan->spies) { 00994 if (!(chan->spies = calloc(1, sizeof(*chan->spies)))) { 00995 ast_log(LOG_WARNING, "Memory allocation failure\n"); 00996 return -1; 00997 } 00998 00999 AST_LIST_HEAD_INIT_NOLOCK(&chan->spies->list); 01000 AST_LIST_INSERT_HEAD(&chan->spies->list, spy, list); 01001 } else { 01002 AST_LIST_INSERT_TAIL(&chan->spies->list, spy, list); 01003 } 01004 01005 if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) { 01006 ast_cond_init(&spy->trigger, NULL); 01007 ast_set_flag(spy, CHANSPY_TRIGGER_READ); 01008 ast_clear_flag(spy, CHANSPY_TRIGGER_WRITE); 01009 } 01010 01011 ast_log(LOG_DEBUG, "Spy %s added to channel %s\n", 01012 spy->type, chan->name); 01013 01014 return 0; 01015 }
|
|
Read one (or more) frames of audio from a channel being spied upon.
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 3855 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(). 03856 { 03857 struct ast_frame *result; 03858 /* buffers are allocated to hold SLINEAR, which is the largest format */ 03859 short read_buf[samples]; 03860 short write_buf[samples]; 03861 struct ast_frame *read_frame; 03862 struct ast_frame *write_frame; 03863 int need_dup; 03864 struct ast_frame stack_read_frame = { .frametype = AST_FRAME_VOICE, 03865 .subclass = spy->read_queue.format, 03866 .data = read_buf, 03867 .samples = samples, 03868 .datalen = ast_codec_get_len(spy->read_queue.format, samples), 03869 }; 03870 struct ast_frame stack_write_frame = { .frametype = AST_FRAME_VOICE, 03871 .subclass = spy->write_queue.format, 03872 .data = write_buf, 03873 .samples = samples, 03874 .datalen = ast_codec_get_len(spy->write_queue.format, samples), 03875 }; 03876 03877 /* if a flush has been requested, dump everything in whichever queue is larger */ 03878 if (ast_test_flag(spy, CHANSPY_TRIGGER_FLUSH)) { 03879 if (spy->read_queue.samples > spy->write_queue.samples) { 03880 if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST)) { 03881 for (result = spy->read_queue.head; result; result = result->next) 03882 ast_frame_adjust_volume(result, spy->read_vol_adjustment); 03883 } 03884 result = spy->read_queue.head; 03885 spy->read_queue.head = NULL; 03886 spy->read_queue.samples = 0; 03887 ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH); 03888 return result; 03889 } else { 03890 if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST)) { 03891 for (result = spy->write_queue.head; result; result = result->next) 03892 ast_frame_adjust_volume(result, spy->write_vol_adjustment); 03893 } 03894 result = spy->write_queue.head; 03895 spy->write_queue.head = NULL; 03896 spy->write_queue.samples = 0; 03897 ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH); 03898 return result; 03899 } 03900 } 03901 03902 if ((spy->read_queue.samples < samples) || (spy->write_queue.samples < samples)) 03903 return NULL; 03904 03905 /* short-circuit if both head frames have exactly what we want */ 03906 if ((spy->read_queue.head->samples == samples) && 03907 (spy->write_queue.head->samples == samples)) { 03908 read_frame = spy->read_queue.head; 03909 spy->read_queue.head = read_frame->next; 03910 read_frame->next = NULL; 03911 03912 write_frame = spy->write_queue.head; 03913 spy->write_queue.head = write_frame->next; 03914 write_frame->next = NULL; 03915 03916 spy->read_queue.samples -= samples; 03917 spy->write_queue.samples -= samples; 03918 03919 need_dup = 0; 03920 } else { 03921 copy_data_from_queue(&spy->read_queue, read_buf, samples); 03922 copy_data_from_queue(&spy->write_queue, write_buf, samples); 03923 03924 read_frame = &stack_read_frame; 03925 write_frame = &stack_write_frame; 03926 need_dup = 1; 03927 } 03928 03929 if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST)) 03930 ast_frame_adjust_volume(read_frame, spy->read_vol_adjustment); 03931 03932 if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST)) 03933 ast_frame_adjust_volume(write_frame, spy->write_vol_adjustment); 03934 03935 if (ast_test_flag(spy, CHANSPY_MIXAUDIO)) { 03936 ast_frame_slinear_sum(read_frame, write_frame); 03937 03938 if (need_dup) 03939 result = ast_frdup(read_frame); 03940 else { 03941 result = read_frame; 03942 ast_frfree(write_frame); 03943 } 03944 } else { 03945 if (need_dup) { 03946 result = ast_frdup(read_frame); 03947 result->next = ast_frdup(write_frame); 03948 } else { 03949 result = read_frame; 03950 result->next = write_frame; 03951 } 03952 } 03953 03954 return result; 03955 }
|
|
Remove a spy from a channel.
Definition at line 1040 of file channel.c. References ast_cond_destroy(), ast_frfree(), AST_LIST_EMPTY, AST_LIST_REMOVE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_translator_free_path(), CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_NONE, free, ast_channel_spy_queue::head, list, ast_channel_spy::lock, ast_channel::name, ast_frame::next, channel_spy_trans::path, ast_channel_spy::read_queue, ast_channel_spy_list::read_translator, ast_channel::spies, ast_channel_spy::trigger, ast_channel_spy::type, ast_channel_spy::write_queue, and ast_channel_spy_list::write_translator. Referenced by detach_spies(), stop_spying(), and stopmon(). 01041 { 01042 struct ast_frame *f; 01043 01044 if (!chan->spies) 01045 return; 01046 01047 AST_LIST_REMOVE(&chan->spies->list, spy, list); 01048 01049 ast_mutex_lock(&spy->lock); 01050 01051 for (f = spy->read_queue.head; f; f = spy->read_queue.head) { 01052 spy->read_queue.head = f->next; 01053 ast_frfree(f); 01054 } 01055 for (f = spy->write_queue.head; f; f = spy->write_queue.head) { 01056 spy->write_queue.head = f->next; 01057 ast_frfree(f); 01058 } 01059 01060 if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) 01061 ast_cond_destroy(&spy->trigger); 01062 01063 ast_mutex_unlock(&spy->lock); 01064 01065 ast_log(LOG_DEBUG, "Spy %s removed from channel %s\n", 01066 spy->type, chan->name); 01067 01068 if (AST_LIST_EMPTY(&chan->spies->list)) { 01069 if (chan->spies->read_translator.path) 01070 ast_translator_free_path(chan->spies->read_translator.path); 01071 if (chan->spies->write_translator.path) 01072 ast_translator_free_path(chan->spies->write_translator.path); 01073 free(chan->spies); 01074 chan->spies = NULL; 01075 } 01076 }
|
|
Find all spies of a particular type on a channel and stop them.
Definition at line 1017 of file channel.c. References ast_cond_signal(), AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, CHANSPY_RUNNING, CHANSPY_STOP, CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_NONE, list, ast_channel_spy::lock, ast_channel::spies, ast_channel_spy::status, ast_channel_spy::trigger, and ast_channel_spy::type. Referenced by mixmonitor_cli(). 01018 { 01019 struct ast_channel_spy *spy; 01020 01021 if (!chan->spies) 01022 return; 01023 01024 AST_LIST_TRAVERSE(&chan->spies->list, spy, list) { 01025 ast_mutex_lock(&spy->lock); 01026 if ((spy->type == type) && (spy->status == CHANSPY_RUNNING)) { 01027 spy->status = CHANSPY_STOP; 01028 if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) 01029 ast_cond_signal(&spy->trigger); 01030 } 01031 ast_mutex_unlock(&spy->lock); 01032 } 01033 }
|
|
Efficiently wait until audio is available for a spy, or an exception occurs.
Definition at line 1035 of file channel.c. References ast_cond_wait(), ast_channel_spy::lock, and ast_channel_spy::trigger. Referenced by mixmonitor_thread(). 01036 { 01037 ast_cond_wait(&spy->trigger, &spy->lock); 01038 }
|
|
Starts a silence generator on the given channel.
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 4013 of file channel.c. References ast_activate_generator(), AST_FORMAT_SLINEAR, ast_log(), ast_set_write_format(), calloc, free, LOG_ERROR, LOG_WARNING, ast_channel::name, option_debug, silence_generator, and ast_channel::writeformat. Referenced by record_exec(). 04014 { 04015 struct ast_silence_generator *state; 04016 04017 if (!(state = calloc(1, sizeof(*state)))) { 04018 ast_log(LOG_WARNING, "Could not allocate state structure\n"); 04019 return NULL; 04020 } 04021 04022 state->old_write_format = chan->writeformat; 04023 04024 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) { 04025 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n"); 04026 free(state); 04027 return NULL; 04028 } 04029 04030 ast_activate_generator(chan, &silence_generator, state); 04031 04032 if (option_debug) 04033 ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name); 04034 04035 return state; 04036 }
|
|
Stops a previously-started silence generator on the given channel.
Definition at line 4038 of file channel.c. References ast_deactivate_generator(), ast_log(), ast_set_write_format(), free, LOG_ERROR, ast_channel::name, ast_silence_generator::old_write_format, and option_debug. Referenced by record_exec(). 04039 { 04040 if (!state) 04041 return; 04042 04043 ast_deactivate_generator(chan); 04044 04045 if (option_debug) 04046 ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name); 04047 04048 if (ast_set_write_format(chan, state->old_write_format) < 0) 04049 ast_log(LOG_ERROR, "Could not return write format to its original state\n"); 04050 04051 free(state); 04052 }
|
|
Returns 0 if channel does not support HTML or non-zero if it does Definition at line 2661 of file channel.c. References ast_channel_tech::send_html, and ast_channel::tech. Referenced by sendurl_exec().
|
|
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 find_cache(), and rpt_call(). 00703 { 00704 if (chan) 00705 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF); 00706 }
|
|
Unregister a channel technology.
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 }
|
|
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 }
|
|
Definition at line 3785 of file channel.c. References ast_cli_register(), and cli_show_channeltypes. 03786 { 03787 ast_cli_register(&cli_show_channeltypes); 03788 }
|
|
Check to see if a channel is needing hang 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_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(), handle_sendimage(), mixmonitor_thread(), rpt(), 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 }
|
|
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 }
|
|
Deactive an active generator Definition at line 1377 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(), generator_force(), local_ast_moh_stop(), milliwatt_exec(), moh_on_off(), and wait_for_answer(). 01378 { 01379 ast_mutex_lock(&chan->lock); 01380 if (chan->generatordata) { 01381 if (chan->generator && chan->generator->release) 01382 chan->generator->release(chan, chan->generatordata); 01383 chan->generatordata = NULL; 01384 chan->generator = NULL; 01385 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 01386 ast_settimeout(chan, 0, NULL, NULL); 01387 } 01388 ast_mutex_unlock(&chan->lock); 01389 }
|
|
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.
Definition at line 2852 of file channel.c. References ast_channel::_state, ast_channel::alertpipe, ast_log(), ast_mutex_lock(), EVENT_FLAG_CALL, free_translation(), ast_channel::lock, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::name, option_debug, ast_frame::prev, ast_channel::readformat, ast_channel::readq, 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_write(), iax_park(), sip_park(), and sip_park_thread(). 02853 { 02854 int x,i; 02855 int res=0; 02856 int origstate; 02857 struct ast_frame *cur, *prev; 02858 const struct ast_channel_tech *t; 02859 void *t_pvt; 02860 struct ast_callerid tmpcid; 02861 struct ast_channel *clone = original->masq; 02862 int rformat = original->readformat; 02863 int wformat = original->writeformat; 02864 char newn[100]; 02865 char orig[100]; 02866 char masqn[100]; 02867 char zombn[100]; 02868 02869 if (option_debug > 3) 02870 ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", 02871 clone->name, clone->_state, original->name, original->_state); 02872 02873 /* XXX This is a seriously wacked out operation. We're essentially putting the guts of 02874 the clone channel into the original channel. Start by killing off the original 02875 channel's backend. I'm not sure we're going to keep this function, because 02876 while the features are nice, the cost is very high in terms of pure nastiness. XXX */ 02877 02878 /* We need the clone's lock, too */ 02879 ast_mutex_lock(&clone->lock); 02880 02881 ast_log(LOG_DEBUG, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock); 02882 02883 /* Having remembered the original read/write formats, we turn off any translation on either 02884 one */ 02885 free_translation(clone); 02886 free_translation(original); 02887 02888 02889 /* Unlink the masquerade */ 02890 original->masq = NULL; 02891 clone->masqr = NULL; 02892 02893 /* Save the original name */ 02894 ast_copy_string(orig, original->name, sizeof(orig)); 02895 /* Save the new name */ 02896 ast_copy_string(newn, clone->name, sizeof(newn)); 02897 /* Create the masq name */ 02898 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn); 02899 02900 /* Copy the name from the clone channel */ 02901 ast_copy_string(original->name, newn, sizeof(original->name)); 02902 02903 /* Mangle the name of the clone channel */ 02904 ast_copy_string(clone->name, masqn, sizeof(clone->name)); 02905 02906 /* Notify any managers of the change, first the masq then the other */ 02907 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid); 02908 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid); 02909 02910 /* Swap the technlogies */ 02911 t = original->tech; 02912 original->tech = clone->tech; 02913 clone->tech = t; 02914 02915 t_pvt = original->tech_pvt; 02916 original->tech_pvt = clone->tech_pvt; 02917 clone->tech_pvt = t_pvt; 02918 02919 /* Swap the readq's */ 02920 cur = original->readq; 02921 original->readq = clone->readq; 02922 clone->readq = cur; 02923 02924 /* Swap the alertpipes */ 02925 for (i = 0; i < 2; i++) { 02926 x = original->alertpipe[i]; 02927 original->alertpipe[i] = clone->alertpipe[i]; 02928 clone->alertpipe[i] = x; 02929 } 02930 02931 /* Swap the raw formats */ 02932 x = original->rawreadformat; 02933 original->rawreadformat = clone->rawreadformat; 02934 clone->rawreadformat = x; 02935 x = original->rawwriteformat; 02936 original->rawwriteformat = clone->rawwriteformat; 02937 clone->rawwriteformat = x; 02938 02939 /* Save any pending frames on both sides. Start by counting 02940 * how many we're going to need... */ 02941 prev = NULL; 02942 cur = clone->readq; 02943 x = 0; 02944 while(cur) { 02945 x++; 02946 prev = cur; 02947 cur = cur->next; 02948 } 02949 /* If we had any, prepend them to the ones already in the queue, and 02950 * load up the alertpipe */ 02951 if (prev) { 02952 prev->next = original->readq; 02953 original->readq = clone->readq; 02954 clone->readq = NULL; 02955 if (original->alertpipe[1] > -1) { 02956 for (i = 0; i < x; i++) 02957 write(original->alertpipe[1], &x, sizeof(x)); 02958 } 02959 } 02960 clone->_softhangup = AST_SOFTHANGUP_DEV; 02961 02962 02963 /* And of course, so does our current state. Note we need not 02964 call ast_setstate since the event manager doesn't really consider 02965 these separate. We do this early so that the clone has the proper 02966 state of the original channel. */ 02967 origstate = original->_state; 02968 original->_state = clone->_state; 02969 clone->_state = origstate; 02970 02971 if (clone->tech->fixup){ 02972 res = clone->tech->fixup(original, clone); 02973 if (res) 02974 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name); 02975 } 02976 02977 /* Start by disconnecting the original's physical side */ 02978 if (clone->tech->hangup) 02979 res = clone->tech->hangup(clone); 02980 if (res) { 02981 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n"); 02982 ast_mutex_unlock(&clone->lock); 02983 return -1; 02984 } 02985 02986 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); 02987 /* Mangle the name of the clone channel */ 02988 ast_copy_string(clone->name, zombn, sizeof(clone->name)); 02989 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid); 02990 02991 /* Update the type. */ 02992 original->type = clone->type; 02993 t_pvt = original->monitor; 02994 original->monitor = clone->monitor; 02995 clone->monitor = t_pvt; 02996 02997 /* Keep the same language. */ 02998 ast_copy_string(original->language, clone->language, sizeof(original->language)); 02999 /* Copy the FD's */ 03000 for (x = 0; x < AST_MAX_FDS; x++) { 03001 original->fds[x] = clone->fds[x]; 03002 } 03003 clone_variables(original, clone); 03004 AST_LIST_HEAD_INIT_NOLOCK(&clone->varshead); 03005 /* Presense of ADSI capable CPE follows clone */ 03006 original->adsicpe = clone->adsicpe; 03007 /* Bridge remains the same */ 03008 /* CDR fields remain the same */ 03009 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 03010 /* Application and data remain the same */ 03011 /* Clone exception becomes real one, as with fdno */ 03012 ast_copy_flags(original, clone, AST_FLAG_EXCEPTION); 03013 original->fdno = clone->fdno; 03014 /* Schedule context remains the same */ 03015 /* Stream stuff stays the same */ 03016 /* Keep the original state. The fixup code will need to work with it most likely */ 03017 03018 /* Just swap the whole structures, nevermind the allocations, they'll work themselves 03019 out. */ 03020 tmpcid = original->cid; 03021 original->cid = clone->cid; 03022 clone->cid = tmpcid; 03023 03024 /* Restore original timing file descriptor */ 03025 original->fds[AST_MAX_FDS - 2] = original->timingfd; 03026 03027 /* Our native formats are different now */ 03028 original->nativeformats = clone->nativeformats; 03029 03030 /* Context, extension, priority, app data, jump table, remain the same */ 03031 /* pvt switches. pbx stays the same, as does next */ 03032 03033 /* Set the write format */ 03034 ast_set_write_format(original, wformat); 03035 03036 /* Set the read format */ 03037 ast_set_read_format(original, rformat); 03038 03039 /* Copy the music class */ 03040 ast_copy_string(original->musicclass, clone->musicclass, sizeof(original->musicclass)); 03041 03042 ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat); 03043 03044 /* Okay. Last thing is to let the channel driver know about all this mess, so he 03045 can fix up everything as best as possible */ 03046 if (original->tech->fixup) { 03047 res = original->tech->fixup(clone, original); 03048 if (res) { 03049 ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n", 03050 original->type, original->name); 03051 ast_mutex_unlock(&clone->lock); 03052 return -1; 03053 } 03054 } else 03055 ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)! Bad things may happen.\n", 03056 original->type, original->name); 03057 03058 /* Now, at this point, the "clone" channel is totally F'd up. We mark it as 03059 a zombie so nothing tries to touch it. If it's already been marked as a 03060 zombie, then free it now (since it already is considered invalid). */ 03061 if (ast_test_flag(clone, AST_FLAG_ZOMBIE)) { 03062 ast_log(LOG_DEBUG, "Destroying channel clone '%s'\n", clone->name); 03063 ast_mutex_unlock(&clone->lock); 03064 manager_event(EVENT_FLAG_CALL, "Hangup", 03065 "Channel: %s\r\n" 03066 "Uniqueid: %s\r\n" 03067 "Cause: %d\r\n" 03068 "Cause-txt: %s\r\n", 03069 clone->name, 03070 clone->uniqueid, 03071 clone->hangupcause, 03072 ast_cause2str(clone->hangupcause) 03073 ); 03074 ast_channel_free(clone); 03075 } else { 03076 struct ast_frame null_frame = { AST_FRAME_NULL, }; 03077 ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name); 03078 ast_set_flag(clone, AST_FLAG_ZOMBIE); 03079 ast_queue_frame(clone, &null_frame); 03080 ast_mutex_unlock(&clone->lock); 03081 } 03082 03083 /* Signal any blocker */ 03084 if (ast_test_flag(original, AST_FLAG_BLOCKING)) 03085 pthread_kill(original->blocker, SIGURG); 03086 ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n", original->name, original->_state); 03087 return 0; 03088 }
|
|
Definition at line 3206 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. 03209 { 03210 /* Copy voice back and forth between the two channels. */ 03211 struct ast_channel *cs[3]; 03212 struct ast_frame *f; 03213 struct ast_channel *who = NULL; 03214 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 03215 int o0nativeformats; 03216 int o1nativeformats; 03217 int watch_c0_dtmf; 03218 int watch_c1_dtmf; 03219 void *pvt0, *pvt1; 03220 int to; 03221 03222 cs[0] = c0; 03223 cs[1] = c1; 03224 pvt0 = c0->tech_pvt; 03225 pvt1 = c1->tech_pvt; 03226 o0nativeformats = c0->nativeformats; 03227 o1nativeformats = c1->nativeformats; 03228 watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0; 03229 watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1; 03230 03231 for (;;) { 03232 if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) || 03233 (o0nativeformats != c0->nativeformats) || 03234 (o1nativeformats != c1->nativeformats)) { 03235 /* Check for Masquerade, codec changes, etc */ 03236 res = AST_BRIDGE_RETRY; 03237 break; 03238 } 03239 if (bridge_end.tv_sec) { 03240 to = ast_tvdiff_ms(bridge_end, ast_tvnow()); 03241 if (to <= 0) { 03242 res = AST_BRIDGE_RETRY; 03243 break; 03244 } 03245 } else 03246 to = -1; 03247 who = ast_waitfor_n(cs, 2, &to); 03248 if (!who) { 03249 ast_log(LOG_DEBUG, "Nobody there, continuing...\n"); 03250 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) { 03251 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03252 c0->_softhangup = 0; 03253 if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03254 c1->_softhangup = 0; 03255 c0->_bridge = c1; 03256 c1->_bridge = c0; 03257 } 03258 continue; 03259 } 03260 f = ast_read(who); 03261 if (!f) { 03262 *fo = NULL; 03263 *rc = who; 03264 res = AST_BRIDGE_COMPLETE; 03265 ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name); 03266 break; 03267 } 03268 03269 if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) { 03270 if ((f->subclass == AST_CONTROL_HOLD) || (f->subclass == AST_CONTROL_UNHOLD) || 03271 (f->subclass == AST_CONTROL_VIDUPDATE)) { 03272 ast_indicate(who == c0 ? c1 : c0, f->subclass); 03273 } else { 03274 *fo = f; 03275 *rc = who; 03276 res = AST_BRIDGE_COMPLETE; 03277 ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name); 03278 break; 03279 } 03280 } 03281 if ((f->frametype == AST_FRAME_VOICE) || 03282 (f->frametype == AST_FRAME_DTMF) || 03283 (f->frametype == AST_FRAME_VIDEO) || 03284 (f->frametype == AST_FRAME_IMAGE) || 03285 (f->frametype == AST_FRAME_HTML) || 03286 (f->frametype == AST_FRAME_TEXT)) { 03287 if (f->frametype == AST_FRAME_DTMF) { 03288 if (((who == c0) && watch_c0_dtmf) || 03289 ((who == c1) && watch_c1_dtmf)) { 03290 *rc = who; 03291 *fo = f; 03292 res = AST_BRIDGE_COMPLETE; 03293 ast_log(LOG_DEBUG, "Got DTMF on channel (%s)\n", who->name); 03294 break; 03295 } else { 03296 goto tackygoto; 03297 } 03298 } else { 03299 #if 0 03300 ast_log(LOG_DEBUG, "Read from %s\n", who->name); 03301 if (who == last) 03302 ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name); 03303 last = who; 03304 #endif 03305 tackygoto: 03306 ast_write((who == c0) ? c1 : c0, f); 03307 } 03308 } 03309 ast_frfree(f); 03310 03311 /* Swap who gets priority */ 03312 cs[2] = cs[0]; 03313 cs[0] = cs[1]; 03314 cs[1] = cs[2]; 03315 } 03316 return res; 03317 }
|
|
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 }
|
|
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(), manager_play_dtmf(), pbx_builtin_importvar(), pickup_exec(), start_monitor_action(), and stop_monitor_action(). 00801 { 00802 return channel_find_locked(NULL, name, 0, NULL, NULL); 00803 }
|
|
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 }
|
|
Get a channel technology structure by name.
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 }
|
|
Definition at line 3703 of file channel.c. References ast_log(), ast_strdupa, copy(), group, LOG_ERROR, LOG_WARNING, and strsep(). Referenced by build_device(), build_gateway(), build_peer(), build_user(), load_module(), and read_agent_config(). 03704 { 03705 char *copy; 03706 char *piece; 03707 char *c=NULL; 03708 int start=0, finish=0, x; 03709 ast_group_t group = 0; 03710 03711 copy = ast_strdupa(s); 03712 if (!copy) { 03713 ast_log(LOG_ERROR, "Out of memory\n"); 03714 return 0; 03715 } 03716 c = copy; 03717 03718 while((piece = strsep(&c, ","))) { 03719 if (sscanf(piece, "%d-%d", &start, &finish) == 2) { 03720 /* Range */ 03721 } else if (sscanf(piece, "%d", &start)) { 03722 /* Just one */ 03723 finish = start; 03724 } else { 03725 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece); 03726 continue; 03727 } 03728 for (x = start; x <= finish; x++) { 03729 if ((x > 63) || (x < 0)) { 03730 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x); 03731 } else 03732 group |= ((ast_group_t) 1 << x); 03733 } 03734 } 03735 return group; 03736 }
|
|
Hang up a channel.
Definition at line 1269 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_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_iax2_new(), ast_modem_new(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run_app(), async_wait(), builtin_atxfer(), cb_events(), chanavail_exec(), check_goto_on_transfer(), conf_free(), do_parking_thread(), features_hangup(), function_ilink(), handle_hd_hf(), handle_init_event(), handle_request_invite(), 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(), release_chan(), ring_entry(), rpt(), rpt_call(), rpt_tele_thread(), sip_new(), sip_park(), sip_park_thread(), skinny_new(), skinny_ss(), ss_thread(), vpb_new(), wait_for_answer(), zt_handle_event(), and zt_new(). 01270 { 01271 int res = 0; 01272 01273 /* Don't actually hang up a channel that will masquerade as someone else, or 01274 if someone is going to masquerade as us */ 01275 ast_mutex_lock(&chan->lock); 01276 01277 detach_spies(chan); /* get rid of spies */ 01278 01279 if (chan->masq) { 01280 if (ast_do_masquerade(chan)) 01281 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01282 } 01283 01284 if (chan->masq) { 01285 ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name); 01286 ast_mutex_unlock(&chan->lock); 01287 return 0; 01288 } 01289 /* If this channel is one which will be masqueraded into something, 01290 mark it as a zombie already, so we know to free it later */ 01291 if (chan->masqr) { 01292 ast_set_flag(chan, AST_FLAG_ZOMBIE); 01293 ast_mutex_unlock(&chan->lock); 01294 return 0; 01295 } 01296 free_translation(chan); 01297 if (chan->stream) /* Close audio stream */ 01298 ast_closestream(chan->stream); 01299 if (chan->vstream) /* Close video stream */ 01300 ast_closestream(chan->vstream); 01301 if (chan->sched) { 01302 sched_context_destroy(chan->sched); 01303 chan->sched = NULL; 01304 } 01305 01306 if (chan->generatordata) /* Clear any tone stuff remaining */ 01307 chan->generator->release(chan, chan->generatordata); 01308 chan->generatordata = NULL; 01309 chan->generator = NULL; 01310 if (chan->cdr) { /* End the CDR if it hasn't already */ 01311 ast_cdr_end(chan->cdr); 01312 ast_cdr_detach(chan->cdr); /* Post and Free the CDR */ 01313 chan->cdr = NULL; 01314 } 01315 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 01316 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 01317 "is blocked by thread %ld in procedure %s! Expect a failure\n", 01318 (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 01319 CRASH; 01320 } 01321 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) { 01322 if (option_debug) 01323 ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name); 01324 if (chan->tech->hangup) 01325 res = chan->tech->hangup(chan); 01326 } else { 01327 if (option_debug) 01328 ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name); 01329 } 01330 01331 ast_mutex_unlock(&chan->lock); 01332 manager_event(EVENT_FLAG_CALL, "Hangup", 01333 "Channel: %s\r\n" 01334 "Uniqueid: %s\r\n" 01335 "Cause: %d\r\n" 01336 "Cause-txt: %s\r\n", 01337 chan->name, 01338 chan->uniqueid, 01339 chan->hangupcause, 01340 ast_cause2str(chan->hangupcause) 01341 ); 01342 ast_channel_free(chan); 01343 return res; 01344 }
|
|
Indicates condition of channel.
Definition at line 2002 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_WARNING, ast_channel::name, ast_channel::tech, and ast_channel::zone. Referenced by agent_indicate(), ast_bridge_call(), ast_feature_request_and_dial(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), conf_run(), do_parking_thread(), features_indicate(), handle_remote_data(), handle_remote_phone_dtmf(), mgcp_ss(), park_exec(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_progress(), pbx_builtin_ringing(), queue_exec(), record_exec(), rmt_telem_finish(), rmt_telem_start(), rpt(), send_waveform_to_channel(), skinny_ss(), vpb_fixup(), and wait_for_answer(). 02003 { 02004 int res = -1; 02005 02006 ast_mutex_lock(&chan->lock); 02007 /* Stop if we're a zombie or need a soft hangup */ 02008 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02009 ast_mutex_unlock(&chan->lock); 02010 return -1; 02011 } 02012 if (chan->tech->indicate) 02013 res = chan->tech->indicate(chan, condition); 02014 ast_mutex_unlock(&chan->lock); 02015 if (!chan->tech->indicate || res) { 02016 /* 02017 * Device does not support (that) indication, lets fake 02018 * it by doing our own tone generation. (PM2002) 02019 */ 02020 if (condition >= 0) { 02021 const struct tone_zone_sound *ts = NULL; 02022 switch (condition) { 02023 case AST_CONTROL_RINGING: 02024 ts = ast_get_indication_tone(chan->zone, "ring"); 02025 break; 02026 case AST_CONTROL_BUSY: 02027 ts = ast_get_indication_tone(chan->zone, "busy"); 02028 break; 02029 case AST_CONTROL_CONGESTION: 02030 ts = ast_get_indication_tone(chan->zone, "congestion"); 02031 break; 02032 } 02033 if (ts && ts->data[0]) { 02034 ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition); 02035 ast_playtones_start(chan,0,ts->data, 1); 02036 res = 0; 02037 } else if (condition == AST_CONTROL_PROGRESS) { 02038 /* ast_playtones_stop(chan); */ 02039 } else if (condition == AST_CONTROL_PROCEEDING) { 02040 /* Do nothing, really */ 02041 } else if (condition == AST_CONTROL_HOLD) { 02042 /* Do nothing.... */ 02043 } else if (condition == AST_CONTROL_UNHOLD) { 02044 /* Do nothing.... */ 02045 } else if (condition == AST_CONTROL_VIDUPDATE) { 02046 /* Do nothing.... */ 02047 } else { 02048 /* not handled */ 02049 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); 02050 res = -1; 02051 } 02052 } 02053 else ast_playtones_stop(chan); 02054 } 02055 return res; 02056 }
|
|
Definition at line 3743 of file channel.c. References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr. Referenced by load_module(), and reload(). 03747 { 03748 ast_moh_start_ptr = start_ptr; 03749 ast_moh_stop_ptr = stop_ptr; 03750 ast_moh_cleanup_ptr = cleanup_ptr; 03751 }
|
|
Definition at line 3779 of file channel.c. References ast_moh_cleanup_ptr. Referenced by ast_channel_free(). 03780 { 03781 if(ast_moh_cleanup_ptr) 03782 ast_moh_cleanup_ptr(chan); 03783 }
|
|
Turn on music on hold on a given channel Definition at line 3761 of file channel.c. References ast_moh_start_ptr, ast_verbose(), option_verbose, and VERBOSE_PREFIX_3. Referenced by __login_exec(), agent_hangup(), builtin_atxfer(), builtin_blindtransfer(), cb_events(), 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(). 03762 { 03763 if (ast_moh_start_ptr) 03764 return ast_moh_start_ptr(chan, mclass); 03765 03766 if (option_verbose > 2) 03767 ast_verbose(VERBOSE_PREFIX_3 "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : "default"); 03768 03769 return 0; 03770 }
|
|
Turn off music on hold on a given channel Definition at line 3773 of file channel.c. References ast_moh_stop_ptr. Referenced by __zt_exception(), agent_new(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), cb_events(), 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(), retrydial_exec(), say_periodic_announcement(), say_position(), socket_read(), ss_thread(), zt_handle_event(), and zt_hangup(). 03774 { 03775 if(ast_moh_stop_ptr) 03776 ast_moh_stop_ptr(chan); 03777 }
|
|
|
|
|
|
Definition at line 3791 of file channel.c. Referenced by ast_serialize_showchan(), misdn_new(), and print_group(). 03792 { 03793 unsigned int i; 03794 int first=1; 03795 char num[3]; 03796 03797 buf[0] = '\0'; 03798 03799 if (!group) /* Return empty string if no group */ 03800 return(buf); 03801 03802 for (i=0; i<=63; i++) { /* Max group is 63 */ 03803 if (group & ((ast_group_t) 1 << i)) { 03804 if (!first) { 03805 strncat(buf, ", ", buflen); 03806 } else { 03807 first=0; 03808 } 03809 snprintf(num, sizeof(num), "%u", i); 03810 strncat(buf, num, buflen); 03811 } 03812 } 03813 return(buf); 03814 }
|
|
Definition at line 2158 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_WARNING, ast_channel::name, ast_channel::rawwriteformat, ast_frame::src, and ast_frame::subclass. Referenced by ast_activate_generator(). 02159 { 02160 struct ast_frame a = { AST_FRAME_VOICE }; 02161 char nothing[128]; 02162 02163 /* Send an empty audio frame to get things moving */ 02164 if (chan->_state != AST_STATE_UP) { 02165 ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name); 02166 a.subclass = chan->rawwriteformat; 02167 a.data = nothing + AST_FRIENDLY_OFFSET; 02168 a.src = "ast_prod"; 02169 if (ast_write(chan, &a)) 02170 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 02171 } 02172 return 0; 02173 }
|
|
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(), cb_events(), 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 }
|
|
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(), do_chanreads(), do_immediate_setup(), handle_request_info(), handle_request_invite(), handle_response_invite(), local_queue_frame(), mgcp_queue_frame(), misdn_tx2ast_frm(), monitor_handle_owned(), oss_call(), process_sdp(), receive_message(), and send_digit(). 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 }
|
|
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_request_bye(), handle_request_cancel(), handle_request_refer(), handle_response(), hangup_connection(), iax2_destroy(), iax2_predestroy(), mgcp_queue_hangup(), misdn_answer(), release_chan(), 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 }
|
|
Definition at line 1777 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_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_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_read(), app_exec(), ast_feature_request_and_dial(), ast_masq_park_call(), 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(), do_parking_thread(), echo_exec(), features_read(), find_cache(), handle_recordfile(), iax_park_thread(), ices_exec(), measurenoise(), misdn_bridge(), record_exec(), recordthread(), rpt(), run_agi(), send_waveform_to_channel(), sendurl_exec(), ss_thread(), wait_for_answer(), wait_for_hangup(), waitforring_exec(), and zt_bridge(). 01778 { 01779 struct ast_frame *f = NULL; 01780 int blah; 01781 int prestate; 01782 #ifdef ZAPTEL_OPTIMIZATIONS 01783 int (*func)(void *); 01784 void *data; 01785 int res; 01786 #endif 01787 static struct ast_frame null_frame = { 01788 AST_FRAME_NULL, 01789 }; 01790 01791 ast_mutex_lock(&chan->lock); 01792 if (chan->masq) { 01793 if (ast_do_masquerade(chan)) { 01794 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01795 f = NULL; 01796 } else 01797 f = &null_frame; 01798 ast_mutex_unlock(&chan->lock); 01799 return f; 01800 } 01801 01802 /* Stop if we're a zombie or need a soft hangup */ 01803 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 01804 if (chan->generator) 01805 ast_deactivate_generator(chan); 01806 ast_mutex_unlock(&chan->lock); 01807 return NULL; 01808 } 01809 prestate = chan->_state; 01810 01811 if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && !ast_strlen_zero(chan->dtmfq)) { 01812 /* We have DTMF that has been deferred. Return it now */ 01813 chan->dtmff.frametype = AST_FRAME_DTMF; 01814 chan->dtmff.subclass = chan->dtmfq[0]; 01815 /* Drop first digit */ 01816 memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1); 01817 ast_mutex_unlock(&chan->lock); 01818 return &chan->dtmff; 01819 } 01820 01821 /* Read and ignore anything on the alertpipe, but read only 01822 one sizeof(blah) per frame that we send from it */ 01823 if (chan->alertpipe[0] > -1) { 01824 read(chan->alertpipe[0], &blah, sizeof(blah)); 01825 } 01826 #ifdef ZAPTEL_OPTIMIZATIONS 01827 if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && ast_test_flag(chan, AST_FLAG_EXCEPTION)) { 01828 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 01829 blah = -1; 01830 /* IF we can't get event, assume it's an expired as-per the old interface */ 01831 res = ioctl(chan->timingfd, ZT_GETEVENT, &blah); 01832 if (res) 01833 blah = ZT_EVENT_TIMER_EXPIRED; 01834 01835 if (blah == ZT_EVENT_TIMER_PING) { 01836 #if 0 01837 ast_log(LOG_NOTICE, "Oooh, there's a PING!\n"); 01838 #endif 01839 if (!chan->readq || !chan->readq->next) { 01840 /* Acknowledge PONG unless we need it again */ 01841 #if 0 01842 ast_log(LOG_NOTICE, "Sending a PONG!\n"); 01843 #endif 01844 if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) { 01845 ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno)); 01846 } 01847 } 01848 } else if (blah == ZT_EVENT_TIMER_EXPIRED) { 01849 ioctl(chan->timingfd, ZT_TIMERACK, &blah); 01850 func = chan->timingfunc; 01851 data = chan->timingdata; 01852 ast_mutex_unlock(&chan->lock); 01853 if (func) { 01854 #if 0 01855 ast_log(LOG_DEBUG, "Calling private function\n"); 01856 #endif 01857 func(data); 01858 } else { 01859 blah = 0; 01860 ast_mutex_lock(&chan->lock); 01861 ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah); 01862 chan->timingdata = NULL; 01863 ast_mutex_unlock(&chan->lock); 01864 } 01865 f = &null_frame; 01866 return f; 01867 } else 01868 ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name); 01869 } 01870 #endif 01871 /* Check for pending read queue */ 01872 if (chan->readq) { 01873 f = chan->readq; 01874 chan->readq = f->next; 01875 /* Interpret hangup and return NULL */ 01876 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) { 01877 ast_frfree(f); 01878 f = NULL; 01879 } 01880 } else { 01881 chan->blocker = pthread_self(); 01882 if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) { 01883 if (chan->tech->exception) 01884 f = chan->tech->exception(chan); 01885 else { 01886 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name); 01887 f = &null_frame; 01888 } 01889 /* Clear the exception flag */ 01890 ast_clear_flag(chan, AST_FLAG_EXCEPTION); 01891 } else { 01892 if (chan->tech->read) 01893 f = chan->tech->read(chan); 01894 else 01895 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name); 01896 } 01897 } 01898 01899 01900 if (f && (f->frametype == AST_FRAME_VOICE)) { 01901 if (!(f->subclass & chan->nativeformats)) { 01902 /* This frame can't be from the current native formats -- drop it on the 01903 floor */ 01904 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)); 01905 ast_frfree(f); 01906 f = &null_frame; 01907 } else { 01908 if (chan->spies) 01909 queue_frame_to_spies(chan, f, SPY_READ); 01910 01911 if (chan->monitor && chan->monitor->read_stream ) { 01912 #ifndef MONITOR_CONSTANT_DELAY 01913 int jump = chan->outsmpl - chan->insmpl - 4 * f->samples; 01914 if (jump >= 0) { 01915 if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1) 01916 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01917 chan->insmpl += jump + 4 * f->samples; 01918 } else 01919 chan->insmpl+= f->samples; 01920 #else 01921 int jump = chan->outsmpl - chan->insmpl; 01922 if (jump - MONITOR_DELAY >= 0) { 01923 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1) 01924 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01925 chan->insmpl += jump; 01926 } else 01927 chan->insmpl += f->samples; 01928 #endif 01929 if (ast_writestream(chan->monitor->read_stream, f) < 0) 01930 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n"); 01931 } 01932 if (chan->readtrans) { 01933 f = ast_translate(chan->readtrans, f, 1); 01934 if (!f) 01935 f = &null_frame; 01936 } 01937 } 01938 } 01939 01940 /* Make sure we always return NULL in the future */ 01941 if (!f) { 01942 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01943 if (chan->generator) 01944 ast_deactivate_generator(chan); 01945 /* End the CDR if appropriate */ 01946 if (chan->cdr) 01947 ast_cdr_end(chan->cdr); 01948 } else if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && f->frametype == AST_FRAME_DTMF) { 01949 if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) 01950 chan->dtmfq[strlen(chan->dtmfq)] = f->subclass; 01951 else 01952 ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name); 01953 f = &null_frame; 01954 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) { 01955 if (prestate == AST_STATE_UP) { 01956 ast_log(LOG_DEBUG, "Dropping duplicate answer!\n"); 01957 f = &null_frame; 01958 } 01959 /* Answer the CDR */ 01960 ast_setstate(chan, AST_STATE_UP); 01961 ast_cdr_answer(chan->cdr); 01962 } 01963 01964 /* Run any generator sitting on the line */ 01965 if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) { 01966 /* Mask generator data temporarily and apply. If there is a timing function, it 01967 will be calling the generator instead */ 01968 void *tmp; 01969 int res; 01970 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 01971 01972 if (chan->timingfunc) { 01973 ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n"); 01974 ast_settimeout(chan, 0, NULL, NULL); 01975 } 01976 tmp = chan->generatordata; 01977 chan->generatordata = NULL; 01978 generate = chan->generator->generate; 01979 res = generate(chan, tmp, f->datalen, f->samples); 01980 chan->generatordata = tmp; 01981 if (res) { 01982 ast_log(LOG_DEBUG, "Auto-deactivating generator\n"); 01983 ast_deactivate_generator(chan); 01984 } 01985 } else if (f && (f->frametype == AST_FRAME_CNG)) { 01986 if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) { 01987 ast_log(LOG_DEBUG, "Generator got CNG, switching to zap timed mode\n"); 01988 ast_settimeout(chan, 160, generator_force, chan); 01989 } 01990 } 01991 /* High bit prints debugging */ 01992 if (chan->fin & 0x80000000) 01993 ast_frame_dump(chan->name, f, "<<"); 01994 if ((chan->fin & 0x7fffffff) == 0x7fffffff) 01995 chan->fin &= 0x80000000; 01996 else 01997 chan->fin++; 01998 ast_mutex_unlock(&chan->lock); 01999 return f; 02000 }
|
|
Definition at line 2578 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_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(). 02579 { 02580 int pos=0; 02581 int to = ftimeout; 02582 int d; 02583 02584 /* XXX Merge with full version? XXX */ 02585 /* Stop if we're a zombie or need a soft hangup */ 02586 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 02587 return -1; 02588 if (!len) 02589 return -1; 02590 do { 02591 if (c->stream) { 02592 d = ast_waitstream(c, AST_DIGIT_ANY); 02593 ast_stopstream(c); 02594 usleep(1000); 02595 if (!d) 02596 d = ast_waitfordigit(c, to); 02597 } else { 02598 d = ast_waitfordigit(c, to); 02599 } 02600 if (d < 0) 02601 return -1; 02602 if (d == 0) { 02603 s[pos]='\0'; 02604 return 1; 02605 } 02606 if (!strchr(enders, d)) 02607 s[pos++] = d; 02608 if (strchr(enders, d) || (pos >= len)) { 02609 s[pos]='\0'; 02610 return 0; 02611 } 02612 to = timeout; 02613 } while(1); 02614 /* Never reached */ 02615 return 0; 02616 }
|
|
Definition at line 2618 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(). 02619 { 02620 int pos=0; 02621 int to = ftimeout; 02622 int d; 02623 02624 /* Stop if we're a zombie or need a soft hangup */ 02625 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 02626 return -1; 02627 if (!len) 02628 return -1; 02629 do { 02630 if (c->stream) { 02631 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 02632 ast_stopstream(c); 02633 usleep(1000); 02634 if (!d) 02635 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 02636 } else { 02637 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 02638 } 02639 if (d < 0) 02640 return -1; 02641 if (d == 0) { 02642 s[pos]='\0'; 02643 return 1; 02644 } 02645 if (d == 1) { 02646 s[pos]='\0'; 02647 return 2; 02648 } 02649 if (!strchr(enders, d)) 02650 s[pos++] = d; 02651 if (strchr(enders, d) || (pos >= len)) { 02652 s[pos]='\0'; 02653 return 0; 02654 } 02655 to = timeout; 02656 } while(1); 02657 /* Never reached */ 02658 return 0; 02659 }
|
|
Definition at line 2058 of file channel.c. References ast_recvtext(), and free. Referenced by handle_recvchar(). 02059 { 02060 int c; 02061 char *buf = ast_recvtext(chan, timeout); 02062 if (buf == NULL) 02063 return -1; /* error or timeout */ 02064 c = *(unsigned char *)buf; 02065 free(buf); 02066 return c; 02067 }
|
|
Definition at line 2069 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(). 02070 { 02071 int res, done = 0; 02072 char *buf = NULL; 02073 02074 while (!done) { 02075 struct ast_frame *f; 02076 if (ast_check_hangup(chan)) 02077 break; 02078 res = ast_waitfor(chan, timeout); 02079 if (res <= 0) /* timeout or error */ 02080 break; 02081 timeout = res; /* update timeout */ 02082 f = ast_read(chan); 02083 if (f == NULL) 02084 break; /* no frame */ 02085 if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) 02086 done = 1; /* force a break */ 02087 else if (f->frametype == AST_FRAME_TEXT) { /* what we want */ 02088 buf = strndup((char *) f->data, f->datalen); /* dup and break */ 02089 done = 1; 02090 } 02091 ast_frfree(f); 02092 } 02093 return buf; 02094 }
|
|
Requests a channel.
Definition at line 2484 of file channel.c. References AST_CAUSE_NOTDEFINED, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_translator_best_choice(), backends, ast_channel_tech::capabilities, fmt, LOG_WARNING, chanlist::next, chanlist::tech, and ast_channel_tech::type. Referenced by __ast_request_and_dial(), agent_request(), ast_feature_request_and_dial(), attempt_reconnect(), chanavail_exec(), features_alloc(), function_ilink(), ring_entry(), rpt(), rpt_call(), rpt_tele_thread(), and wait_for_answer(). 02485 { 02486 struct chanlist *chan; 02487 struct ast_channel *c; 02488 int capabilities; 02489 int fmt; 02490 int res; 02491 int foo; 02492 02493 if (!cause) 02494 cause = &foo; 02495 *cause = AST_CAUSE_NOTDEFINED; 02496 02497 if (ast_mutex_lock(&chlock)) { 02498 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 02499 return NULL; 02500 } 02501 02502 for (chan = backends; chan; chan = chan->next) { 02503 if (strcasecmp(type, chan->tech->type)) 02504 continue; 02505 02506 capabilities = chan->tech->capabilities; 02507 fmt = format; 02508 res = ast_translator_best_choice(&fmt, &capabilities); 02509 if (res < 0) { 02510 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format); 02511 ast_mutex_unlock(&chlock); 02512 return NULL; 02513 } 02514 ast_mutex_unlock(&chlock); 02515 if (!chan->tech->requester) 02516 return NULL; 02517 02518 if (!(c = chan->tech->requester(type, capabilities, data, cause))) 02519 return NULL; 02520 02521 if (c->_state == AST_STATE_DOWN) { 02522 manager_event(EVENT_FLAG_CALL, "Newchannel", 02523 "Channel: %s\r\n" 02524 "State: %s\r\n" 02525 "CallerID: %s\r\n" 02526 "CallerIDName: %s\r\n" 02527 "Uniqueid: %s\r\n", 02528 c->name, ast_state2str(c->_state), 02529 c->cid.cid_num ? c->cid.cid_num : "<unknown>", 02530 c->cid.cid_name ? c->cid.cid_name : "<unknown>", 02531 c->uniqueid); 02532 } 02533 return c; 02534 } 02535 02536 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 02537 *cause = AST_CAUSE_NOSUCHDRIVER; 02538 ast_mutex_unlock(&chlock); 02539 02540 return NULL; 02541 }
|
|
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.
Definition at line 2479 of file channel.c. References __ast_request_and_dial(). Referenced by ast_pbx_outgoing_exten(). 02480 { 02481 return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL); 02482 }
|
|
Wait for a specied amount of time, looking for hangups.
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(), skinny_ss(), testclient_exec(), testserver_exec(), 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 }
|
|
Wait for a specied amount of time, looking for hangups and a condition argument.
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 }
|
|
Definition at line 2153 of file channel.c. References do_senddigit(). Referenced by features_digit(), and manager_play_dtmf(). 02154 { 02155 return do_senddigit(chan, digit); 02156 }
|
|
Definition at line 2096 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(). 02097 { 02098 int res = 0; 02099 /* Stop if we're a zombie or need a soft hangup */ 02100 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 02101 return -1; 02102 CHECK_BLOCKING(chan); 02103 if (chan->tech->send_text) 02104 res = chan->tech->send_text(chan, text); 02105 ast_clear_flag(chan, AST_FLAG_BLOCKING); 02106 return res; 02107 }
|
|
Definition at line 3090 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(), ast_feature_request_and_dial(), callerid_write(), get_callerid(), handle_setcallerid(), lookupcidname_exec(), monitor_handle_notowned(), privacy_exec(), setcallerid_exec(), ss_thread(), vpb_new(), wait_for_answer(), zt_new(), and zt_read(). 03091 { 03092 if (callerid) { 03093 if (chan->cid.cid_num) 03094 free(chan->cid.cid_num); 03095 if (ast_strlen_zero(callerid)) 03096 chan->cid.cid_num = NULL; 03097 else 03098 chan->cid.cid_num = strdup(callerid); 03099 } 03100 if (calleridname) { 03101 if (chan->cid.cid_name) 03102 free(chan->cid.cid_name); 03103 if (ast_strlen_zero(calleridname)) 03104 chan->cid.cid_name = NULL; 03105 else 03106 chan->cid.cid_name = strdup(calleridname); 03107 } 03108 if (ani) { 03109 if (chan->cid.cid_ani) 03110 free(chan->cid.cid_ani); 03111 if (ast_strlen_zero(ani)) 03112 chan->cid.cid_ani = NULL; 03113 else 03114 chan->cid.cid_ani = strdup(ani); 03115 } 03116 if (chan->cdr) 03117 ast_cdr_setcid(chan->cdr, chan); 03118 manager_event(EVENT_FLAG_CALL, "Newcallerid", 03119 "Channel: %s\r\n" 03120 "CallerID: %s\r\n" 03121 "CallerIDName: %s\r\n" 03122 "Uniqueid: %s\r\n" 03123 "CID-CallingPres: %d (%s)\r\n", 03124 chan->name, chan->cid.cid_num ? 03125 chan->cid.cid_num : "<Unknown>", 03126 chan->cid.cid_name ? 03127 chan->cid.cid_name : "<Unknown>", 03128 chan->uniqueid, 03129 chan->cid.cid_pres, 03130 ast_describe_caller_presentation(chan->cid.cid_pres) 03131 ); 03132 }
|
|
Definition at line 2353 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(), attempt_reconnect(), background_detect_exec(), chanspy_exec(), conf_run(), dictate_exec(), disa_exec(), do_waiting(), eagi_exec(), echo_exec(), function_ilink(), handle_recordfile(), ices_exec(), measurenoise(), mgcp_rtp_read(), milliwatt_exec(), oh323_rtp_read(), process_sdp(), record_exec(), rpt(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_read(), and update_features(). 02354 { 02355 return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat, 02356 &chan->readtrans, 0); 02357 }
|
|
adds a list of channel variables to a channel
Definition at line 3816 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(). 03817 { 03818 struct ast_variable *cur; 03819 03820 for (cur = vars; cur; cur = cur->next) 03821 pbx_builtin_setvar_helper(chan, cur->name, cur->value); 03822 }
|
|
Definition at line 2359 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_alloc(), moh_files_release(), moh_release(), mp3_exec(), NBScat_exec(), oh323_rtp_read(), playtones_alloc(), playtones_release(), process_sdp(), rpt(), send_waveform_to_channel(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_read(), tonepair_alloc(), tonepair_release(), and update_features(). 02360 { 02361 return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat, 02362 &chan->writetrans, 1); 02363 }
|
|
Change the state of a channel.
Definition at line 3134 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(), 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(). 03135 { 03136 int oldstate = chan->_state; 03137 03138 if (oldstate == state) 03139 return 0; 03140 03141 chan->_state = state; 03142 ast_device_state_changed_literal(chan->name); 03143 manager_event(EVENT_FLAG_CALL, 03144 (oldstate == AST_STATE_DOWN) ? "Newchannel" : "Newstate", 03145 "Channel: %s\r\n" 03146 "State: %s\r\n" 03147 "CallerID: %s\r\n" 03148 "CallerIDName: %s\r\n" 03149 "Uniqueid: %s\r\n", 03150 chan->name, ast_state2str(chan->_state), 03151 chan->cid.cid_num ? chan->cid.cid_num : "<unknown>", 03152 chan->cid.cid_name ? chan->cid.cid_name : "<unknown>", 03153 chan->uniqueid); 03154 03155 return 0; 03156 }
|
|
Definition at line 1702 of file channel.c. References ast_log(), 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(). 01703 { 01704 int res = -1; 01705 #ifdef ZAPTEL_OPTIMIZATIONS 01706 if (c->timingfd > -1) { 01707 if (!func) { 01708 samples = 0; 01709 data = 0; 01710 } 01711 ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples); 01712 res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples); 01713 c->timingfunc = func; 01714 c->timingdata = data; 01715 } 01716 #endif 01717 return res; 01718 }
|
|
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 }
|
|
Softly hangup up a channel.
Definition at line 1117 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(), do_monitor(), 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(). 01118 { 01119 int res; 01120 ast_mutex_lock(&chan->lock); 01121 res = ast_softhangup_nolock(chan, cause); 01122 ast_mutex_unlock(&chan->lock); 01123 return res; 01124 }
|
|
Softly hangup up a channel (no channel lock).
Definition at line 1101 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, ast_channel::name, and option_debug. Referenced by ast_async_goto(), ast_softhangup(), attempt_transfer(), oh323_indicate(), sip_indicate(), and skinny_indicate(). 01102 { 01103 int res = 0; 01104 struct ast_frame f = { AST_FRAME_NULL }; 01105 if (option_debug) 01106 ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name); 01107 /* Inform channel driver that we need to be hung up, if it cares */ 01108 chan->_softhangup |= cause; 01109 ast_queue_frame(chan, &f); 01110 /* Interrupt any poll call or such */ 01111 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) 01112 pthread_kill(chan->blocker, SIGURG); 01113 return res; 01114 }
|
|
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_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 }
|
|
Play a tone pair for a given amount of time Definition at line 3684 of file channel.c. References ast_frfree(), ast_read(), ast_tonepair_start(), ast_waitfor(), and ast_channel::generatordata. Referenced by zapateller_exec(). 03685 { 03686 struct ast_frame *f; 03687 int res; 03688 03689 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 03690 return res; 03691 03692 /* Give us some wiggle room */ 03693 while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) { 03694 f = ast_read(chan); 03695 if (f) 03696 ast_frfree(f); 03697 else 03698 return -1; 03699 } 03700 return 0; 03701 }
|
|
Start a tone going Definition at line 3663 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(), and sendnoise(). 03664 { 03665 struct tonepair_def d = { 0, }; 03666 03667 d.freq1 = freq1; 03668 d.freq2 = freq2; 03669 d.duration = duration; 03670 if (vol < 1) 03671 d.vol = 8192; 03672 else 03673 d.vol = vol; 03674 if (ast_activate_generator(chan, &tonepair, &d)) 03675 return -1; 03676 return 0; 03677 }
|
|
Stop a tone from playing Definition at line 3679 of file channel.c. References ast_deactivate_generator(). Referenced by sendnoise(). 03680 { 03681 ast_deactivate_generator(chan); 03682 }
|
|
Transfer a channel (if supported). Returns -1 on error, 0 if not supported and 1 if supported and requested.
Definition at line 2560 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(). 02561 { 02562 int res = -1; 02563 02564 /* Stop if we're a zombie or need a soft hangup */ 02565 ast_mutex_lock(&chan->lock); 02566 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 02567 if (chan->tech->transfer) { 02568 res = chan->tech->transfer(chan, dest); 02569 if (!res) 02570 res = 1; 02571 } else 02572 res = 0; 02573 } 02574 ast_mutex_unlock(&chan->lock); 02575 return res; 02576 }
|
|
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 }
|
|
Definition at line 3753 of file channel.c. References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr. 03754 { 03755 ast_moh_start_ptr = NULL; 03756 ast_moh_stop_ptr = NULL; 03757 ast_moh_cleanup_ptr = NULL; 03758 }
|
|
Wait for input on a channel.
Definition at line 1658 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_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(), do_waiting(), echo_exec(), handle_recordfile(), ices_exec(), measurenoise(), modem_call(), record_exec(), recordthread(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), ss_thread(), wait_for_hangup(), and waitforring_exec(). 01659 { 01660 struct ast_channel *chan; 01661 int oldms = ms; 01662 01663 chan = ast_waitfor_n(&c, 1, &ms); 01664 if (ms < 0) { 01665 if (oldms < 0) 01666 return 0; 01667 else 01668 return -1; 01669 } 01670 return ms; 01671 }
|
|
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 1653 of file channel.c. References ast_waitfor_nandfds(). Referenced by ast_feature_request_and_dial(), ast_waitfor(), autoservice_run(), misdn_bridge(), rpt(), wait_for_answer(), and zt_bridge(). 01654 { 01655 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 01656 }
|
|
This version works on fd's only. Be careful with it. Definition at line 1439 of file channel.c. References ast_log(), pollfd::events, pollfd::fd, LOG_ERROR, POLLIN, and POLLPRI. Referenced by ast_modem_expect(), ast_modem_read_response(), bestdata_read(), dundi_lookup_internal(), and dundi_precache_internal(). 01440 { 01441 struct timeval start = { 0 , 0 }; 01442 int res; 01443 int x, y; 01444 int winner = -1; 01445 int spoint; 01446 struct pollfd *pfds; 01447 01448 pfds = alloca(sizeof(struct pollfd) * n); 01449 if (!pfds) { 01450 ast_log(LOG_ERROR, "Out of memory\n"); 01451 return -1; 01452 } 01453 if (*ms > 0) 01454 start = ast_tvnow(); 01455 y = 0; 01456 for (x=0; x < n; x++) { 01457 if (fds[x] > -1) { 01458 pfds[y].fd = fds[x]; 01459 pfds[y].events = POLLIN | POLLPRI; 01460 y++; 01461 } 01462 } 01463 res = poll(pfds, y, *ms); 01464 if (res < 0) { 01465 /* Simulate a timeout if we were interrupted */ 01466 if (errno != EINTR) 01467 *ms = -1; 01468 else 01469 *ms = 0; 01470 return -1; 01471 } 01472 spoint = 0; 01473 for (x=0; x < n; x++) { 01474 if (fds[x] > -1) { 01475 if ((res = ast_fdisset(pfds, fds[x], y, &spoint))) { 01476 winner = fds[x]; 01477 if (exception) { 01478 if (res & POLLPRI) 01479 *exception = -1; 01480 else 01481 *exception = 0; 01482 } 01483 } 01484 } 01485 } 01486 if (*ms > 0) { 01487 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 01488 if (*ms < 0) 01489 *ms = 0; 01490 } 01491 return winner; 01492 }
|
|
Waits for activity on a group of channels.
Definition at line 1495 of file channel.c. References ast_log(), AST_MAX_FDS, ast_mutex_lock(), lock, LOG_ERROR, and ast_channel::whentohangup. Referenced by app_exec(), ast_waitfor_n(), ast_waitfordigit_full(), ast_waitstream_full(), conf_run(), find_cache(), and run_agi(). 01497 { 01498 struct timeval start = { 0 , 0 }; 01499 struct pollfd *pfds; 01500 int res; 01501 long rms; 01502 int x, y, max; 01503 int spoint; 01504 time_t now = 0; 01505 long whentohangup = 0, havewhen = 0, diff; 01506 struct ast_channel *winner = NULL; 01507 01508 pfds = alloca(sizeof(struct pollfd) * (n * AST_MAX_FDS + nfds)); 01509 if (!pfds) { 01510 ast_log(LOG_ERROR, "Out of memory\n"); 01511 *outfd = -1; 01512 return NULL; 01513 } 01514 01515 if (outfd) 01516 *outfd = -99999; 01517 if (exception) 01518 *exception = 0; 01519 01520 /* Perform any pending masquerades */ 01521 for (x=0; x < n; x++) { 01522 ast_mutex_lock(&c[x]->lock); 01523 if (c[x]->whentohangup) { 01524 if (!havewhen) 01525 time(&now); 01526 diff = c[x]->whentohangup - now; 01527 if (!havewhen || (diff < whentohangup)) { 01528 havewhen++; 01529 whentohangup = diff; 01530 } 01531 } 01532 if (c[x]->masq) { 01533 if (ast_do_masquerade(c[x])) { 01534 ast_log(LOG_WARNING, "Masquerade failed\n"); 01535 *ms = -1; 01536 ast_mutex_unlock(&c[x]->lock); 01537 return NULL; 01538 } 01539 } 01540 ast_mutex_unlock(&c[x]->lock); 01541 } 01542 01543 rms = *ms; 01544 01545 if (havewhen) { 01546 if ((*ms < 0) || (whentohangup * 1000 < *ms)) { 01547 rms = whentohangup * 1000; 01548 } 01549 } 01550 max = 0; 01551 for (x=0; x < n; x++) { 01552 for (y=0; y< AST_MAX_FDS; y++) { 01553 if (c[x]->fds[y] > -1) { 01554 pfds[max].fd = c[x]->fds[y]; 01555 pfds[max].events = POLLIN | POLLPRI; 01556 pfds[max].revents = 0; 01557 max++; 01558 } 01559 } 01560 CHECK_BLOCKING(c[x]); 01561 } 01562 for (x=0; x < nfds; x++) { 01563 if (fds[x] > -1) { 01564 pfds[max].fd = fds[x]; 01565 pfds[max].events = POLLIN | POLLPRI; 01566 pfds[max].revents = 0; 01567 max++; 01568 } 01569 } 01570 if (*ms > 0) 01571 start = ast_tvnow(); 01572 01573 if (sizeof(int) == 4) { 01574 do { 01575 int kbrms = rms; 01576 if (kbrms > 600000) 01577 kbrms = 600000; 01578 res = poll(pfds, max, kbrms); 01579 if (!res) 01580 rms -= kbrms; 01581 } while (!res && (rms > 0)); 01582 } else { 01583 res = poll(pfds, max, rms); 01584 } 01585 01586 if (res < 0) { 01587 for (x=0; x < n; x++) 01588 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 01589 /* Simulate a timeout if we were interrupted */ 01590 if (errno != EINTR) 01591 *ms = -1; 01592 else { 01593 /* Just an interrupt */ 01594 #if 0 01595 *ms = 0; 01596 #endif 01597 } 01598 return NULL; 01599 } else { 01600 /* If no fds signalled, then timeout. So set ms = 0 01601 since we may not have an exact timeout. 01602 */ 01603 if (res == 0) 01604 *ms = 0; 01605 } 01606 01607 if (havewhen) 01608 time(&now); 01609 spoint = 0; 01610 for (x=0; x < n; x++) { 01611 ast_clear_flag(c[x], AST_FLAG_BLOCKING); 01612 if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) { 01613 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 01614 if (!winner) 01615 winner = c[x]; 01616 } 01617 for (y=0; y < AST_MAX_FDS; y++) { 01618 if (c[x]->fds[y] > -1) { 01619 if ((res = ast_fdisset(pfds, c[x]->fds[y], max, &spoint))) { 01620 if (res & POLLPRI) 01621 ast_set_flag(c[x], AST_FLAG_EXCEPTION); 01622 else 01623 ast_clear_flag(c[x], AST_FLAG_EXCEPTION); 01624 c[x]->fdno = y; 01625 winner = c[x]; 01626 } 01627 } 01628 } 01629 } 01630 for (x=0; x < nfds; x++) { 01631 if (fds[x] > -1) { 01632 if ((res = ast_fdisset(pfds, fds[x], max, &spoint))) { 01633 if (outfd) 01634 *outfd = fds[x]; 01635 if (exception) { 01636 if (res & POLLPRI) 01637 *exception = -1; 01638 else 01639 *exception = 0; 01640 } 01641 winner = NULL; 01642 } 01643 } 01644 } 01645 if (*ms > 0) { 01646 *ms -= ast_tvdiff_ms(ast_tvnow(), start); 01647 if (*ms < 0) 01648 *ms = 0; 01649 } 01650 return winner; 01651 }
|
|
Definition at line 1673 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(), 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(), and wait_a_bit(). 01674 { 01675 /* XXX Should I be merged with waitfordigit_full XXX */ 01676 struct ast_frame *f; 01677 int result = 0; 01678 01679 /* Stop if we're a zombie or need a soft hangup */ 01680 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 01681 return -1; 01682 01683 /* Wait for a digit, no more than ms milliseconds total. */ 01684 while(ms && !result) { 01685 ms = ast_waitfor(c, ms); 01686 if (ms < 0) /* Error */ 01687 result = -1; 01688 else if (ms > 0) { 01689 /* Read something */ 01690 f = ast_read(c); 01691 if (f) { 01692 if (f->frametype == AST_FRAME_DTMF) 01693 result = f->subclass; 01694 ast_frfree(f); 01695 } else 01696 result = -1; 01697 } 01698 } 01699 return result; 01700 }
|
|
Definition at line 1720 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(). 01721 { 01722 struct ast_frame *f; 01723 struct ast_channel *rchan; 01724 int outfd; 01725 int res; 01726 01727 /* Stop if we're a zombie or need a soft hangup */ 01728 if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 01729 return -1; 01730 /* Wait for a digit, no more than ms milliseconds total. */ 01731 while(ms) { 01732 errno = 0; 01733 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01734 if ((!rchan) && (outfd < 0) && (ms)) { 01735 if (errno == 0 || errno == EINTR) 01736 continue; 01737 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01738 return -1; 01739 } else if (outfd > -1) { 01740 /* The FD we were watching has something waiting */ 01741 return 1; 01742 } else if (rchan) { 01743 f = ast_read(c); 01744 if(!f) { 01745 return -1; 01746 } 01747 01748 switch(f->frametype) { 01749 case AST_FRAME_DTMF: 01750 res = f->subclass; 01751 ast_frfree(f); 01752 return res; 01753 case AST_FRAME_CONTROL: 01754 switch(f->subclass) { 01755 case AST_CONTROL_HANGUP: 01756 ast_frfree(f); 01757 return -1; 01758 case AST_CONTROL_RINGING: 01759 case AST_CONTROL_ANSWER: 01760 /* Unimportant */ 01761 break; 01762 default: 01763 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass); 01764 } 01765 case AST_FRAME_VOICE: 01766 /* Write audio if appropriate */ 01767 if (audiofd > -1) 01768 write(audiofd, f->data, f->datalen); 01769 } 01770 /* Ignore */ 01771 ast_frfree(f); 01772 } 01773 } 01774 return 0; /* Time is up */ 01775 }
|
|
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 }
|
|
Definition at line 2186 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(), echo_exec(), features_write(), function_ilink(), gen_generate(), handle_link_data(), linear_generator(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), NBScat_exec(), rpt(), rpt_call(), send_link_dtmf(), send_waveform_to_channel(), silence_generator_generate(), spy_generate(), wait_for_answer(), and zt_bridge(). 02187 { 02188 int res = -1; 02189 struct ast_frame *f = NULL; 02190 /* Stop if we're a zombie or need a soft hangup */ 02191 ast_mutex_lock(&chan->lock); 02192 if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { 02193 ast_mutex_unlock(&chan->lock); 02194 return -1; 02195 } 02196 /* Handle any pending masquerades */ 02197 if (chan->masq) { 02198 if (ast_do_masquerade(chan)) { 02199 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 02200 ast_mutex_unlock(&chan->lock); 02201 return -1; 02202 } 02203 } 02204 if (chan->masqr) { 02205 ast_mutex_unlock(&chan->lock); 02206 return 0; 02207 } 02208 if (chan->generatordata) { 02209 if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) 02210 ast_deactivate_generator(chan); 02211 else { 02212 ast_mutex_unlock(&chan->lock); 02213 return 0; 02214 } 02215 } 02216 /* High bit prints debugging */ 02217 if (chan->fout & 0x80000000) 02218 ast_frame_dump(chan->name, fr, ">>"); 02219 CHECK_BLOCKING(chan); 02220 switch(fr->frametype) { 02221 case AST_FRAME_CONTROL: 02222 /* XXX Interpret control frames XXX */ 02223 ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n"); 02224 break; 02225 case AST_FRAME_DTMF: 02226 ast_clear_flag(chan, AST_FLAG_BLOCKING); 02227 ast_mutex_unlock(&chan->lock); 02228 res = do_senddigit(chan,fr->subclass); 02229 ast_mutex_lock(&chan->lock); 02230 CHECK_BLOCKING(chan); 02231 break; 02232 case AST_FRAME_TEXT: 02233 if (chan->tech->send_text) 02234 res = chan->tech->send_text(chan, (char *) fr->data); 02235 else 02236 res = 0; 02237 break; 02238 case AST_FRAME_HTML: 02239 if (chan->tech->send_html) 02240 res = chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen); 02241 else 02242 res = 0; 02243 break; 02244 case AST_FRAME_VIDEO: 02245 /* XXX Handle translation of video codecs one day XXX */ 02246 if (chan->tech->write_video) 02247 res = chan->tech->write_video(chan, fr); 02248 else 02249 res = 0; 02250 break; 02251 default: 02252 if (chan->tech->write) { 02253 f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr; 02254 if (f) { 02255 if (f->frametype == AST_FRAME_VOICE && chan->spies) 02256 queue_frame_to_spies(chan, f, SPY_WRITE); 02257 02258 if( chan->monitor && chan->monitor->write_stream && 02259 f && ( f->frametype == AST_FRAME_VOICE ) ) { 02260 #ifndef MONITOR_CONSTANT_DELAY 02261 int jump = chan->insmpl - chan->outsmpl - 4 * f->samples; 02262 if (jump >= 0) { 02263 if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1) 02264 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 02265 chan->outsmpl += jump + 4 * f->samples; 02266 } else 02267 chan->outsmpl += f->samples; 02268 #else 02269 int jump = chan->insmpl - chan->outsmpl; 02270 if (jump - MONITOR_DELAY >= 0) { 02271 if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1) 02272 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 02273 chan->outsmpl += jump; 02274 } else 02275 chan->outsmpl += f->samples; 02276 #endif 02277 if (ast_writestream(chan->monitor->write_stream, f) < 0) 02278 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 02279 } 02280 02281 res = chan->tech->write(chan, f); 02282 } else 02283 res = 0; 02284 } 02285 } 02286 02287 /* It's possible this is a translated frame */ 02288 if (f && f->frametype == AST_FRAME_DTMF) { 02289 ast_log(LOG_DTMF, "%s : %c\n", chan->name, f->subclass); 02290 } else if (fr->frametype == AST_FRAME_DTMF) { 02291 ast_log(LOG_DTMF, "%s : %c\n", chan->name, fr->subclass); 02292 } 02293 02294 if (f && (f != fr)) 02295 ast_frfree(f); 02296 ast_clear_flag(chan, AST_FLAG_BLOCKING); 02297 /* Consider a write failure to force a soft hangup */ 02298 if (res < 0) 02299 chan->_softhangup |= AST_SOFTHANGUP_DEV; 02300 else { 02301 if ((chan->fout & 0x7fffffff) == 0x7fffffff) 02302 chan->fout &= 0x80000000; 02303 else 02304 chan->fout++; 02305 } 02306 ast_mutex_unlock(&chan->lock); 02307 return res; 02308 }
|
|
Definition at line 2175 of file channel.c. References ast_write(), ast_channel::tech, and ast_channel_tech::write_video. 02176 { 02177 int res; 02178 if (!chan->tech->write_video) 02179 return 0; 02180 res = ast_write(chan, fr); 02181 if (!res) 02182 res = 1; 02183 return res; 02184 }
|
|
Definition at line 3168 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(). 03169 { 03170 int res=0, min=0, sec=0,check=0; 03171 03172 check = ast_autoservice_start(peer); 03173 if(check) 03174 return; 03175 03176 if (remain > 0) { 03177 if (remain / 60 > 1) { 03178 min = remain / 60; 03179 sec = remain % 60; 03180 } else { 03181 sec = remain; 03182 } 03183 } 03184 03185 if (!strcmp(sound,"timeleft")) { /* Queue support */ 03186 res = ast_streamfile(chan, "vm-youhave", chan->language); 03187 res = ast_waitstream(chan, ""); 03188 if (min) { 03189 res = ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, (char *) NULL); 03190 res = ast_streamfile(chan, "queue-minutes", chan->language); 03191 res = ast_waitstream(chan, ""); 03192 } 03193 if (sec) { 03194 res = ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, (char *) NULL); 03195 res = ast_streamfile(chan, "queue-seconds", chan->language); 03196 res = ast_waitstream(chan, ""); 03197 } 03198 } else { 03199 res = ast_streamfile(chan, sound, chan->language); 03200 res = ast_waitstream(chan, ""); 03201 } 03202 03203 check = ast_autoservice_stop(peer); 03204 }
|
|
Definition at line 730 of file channel.c. References ast_mutex_lock(), channels, 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 }
|
|
Definition at line 2826 of file channel.c. References AST_LIST_FIRST, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_var_delete(), ast_var_name(), GROUP_CATEGORY_PREFIX, and ast_channel::varshead. 02827 { 02828 struct ast_var_t *varptr; 02829 02830 /* we need to remove all app_groupcount related variables from the original 02831 channel before merging in the clone's variables; any groups assigned to the 02832 original channel should be released, only those assigned to the clone 02833 should remain 02834 */ 02835 02836 AST_LIST_TRAVERSE_SAFE_BEGIN(&original->varshead, varptr, entries) { 02837 if (!strncmp(ast_var_name(varptr), GROUP_CATEGORY_PREFIX, strlen(GROUP_CATEGORY_PREFIX))) { 02838 AST_LIST_REMOVE(&original->varshead, varptr, entries); 02839 ast_var_delete(varptr); 02840 } 02841 } 02842 AST_LIST_TRAVERSE_SAFE_END; 02843 02844 /* Append variables from clone channel into original channel */ 02845 /* XXX Is this always correct? We have to in order to keep MACROS working XXX */ 02846 if (AST_LIST_FIRST(&clone->varshead)) 02847 AST_LIST_INSERT_TAIL(&original->varshead, AST_LIST_FIRST(&clone->varshead), entries); 02848 }
|
|
Definition at line 3824 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(). 03825 { 03826 struct ast_frame *f; 03827 int tocopy; 03828 int bytestocopy; 03829 03830 while (samples) { 03831 f = queue->head; 03832 03833 if (!f) { 03834 ast_log(LOG_ERROR, "Ran out of frames before buffer filled!\n"); 03835 break; 03836 } 03837 03838 tocopy = (f->samples > samples) ? samples : f->samples; 03839 bytestocopy = ast_codec_get_len(queue->format, tocopy); 03840 memcpy(buf, f->data, bytestocopy); 03841 samples -= tocopy; 03842 buf += tocopy; 03843 f->samples -= tocopy; 03844 f->data += bytestocopy; 03845 f->datalen -= bytestocopy; 03846 f->offset += bytestocopy; 03847 queue->samples -= tocopy; 03848 if (!f->samples) { 03849 queue->head = f->next; 03850 ast_frfree(f); 03851 } 03852 } 03853 }
|
|
Definition at line 1078 of file channel.c. References ast_channel_spy_remove(), ast_cond_signal(), AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, CHANSPY_DONE, CHANSPY_RUNNING, CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_NONE, list, ast_channel_spy::lock, ast_channel::spies, ast_channel_spy::status, and ast_channel_spy::trigger. Referenced by ast_hangup(). 01079 { 01080 struct ast_channel_spy *spy; 01081 01082 if (!chan->spies) 01083 return; 01084 01085 /* Marking the spies as done is sufficient. Chanspy or spy users will get the picture. */ 01086 AST_LIST_TRAVERSE(&chan->spies->list, spy, list) { 01087 ast_mutex_lock(&spy->lock); 01088 if (spy->status == CHANSPY_RUNNING) 01089 spy->status = CHANSPY_DONE; 01090 if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) 01091 ast_cond_signal(&spy->trigger); 01092 ast_mutex_unlock(&spy->lock); 01093 } 01094 01095 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list) 01096 ast_channel_spy_remove(chan, spy); 01097 AST_LIST_TRAVERSE_SAFE_END; 01098 }
|
|
Definition at line 2109 of file channel.c. References ast_log(), ast_playtones_start(), ast_channel::name, ast_channel_tech::send_digit, and ast_channel::tech. Referenced by ast_senddigit(), and ast_write(). 02110 { 02111 int res = -1; 02112 02113 if (chan->tech->send_digit) 02114 res = chan->tech->send_digit(chan, digit); 02115 if (!chan->tech->send_digit || res) { 02116 /* 02117 * Device does not support DTMF tones, lets fake 02118 * it by doing our own generation. (PM2002) 02119 */ 02120 static const char* dtmf_tones[] = { 02121 "!941+1336/100,!0/100", /* 0 */ 02122 "!697+1209/100,!0/100", /* 1 */ 02123 "!697+1336/100,!0/100", /* 2 */ 02124 "!697+1477/100,!0/100", /* 3 */ 02125 "!770+1209/100,!0/100", /* 4 */ 02126 "!770+1336/100,!0/100", /* 5 */ 02127 "!770+1477/100,!0/100", /* 6 */ 02128 "!852+1209/100,!0/100", /* 7 */ 02129 "!852+1336/100,!0/100", /* 8 */ 02130 "!852+1477/100,!0/100", /* 9 */ 02131 "!697+1633/100,!0/100", /* A */ 02132 "!770+1633/100,!0/100", /* B */ 02133 "!852+1633/100,!0/100", /* C */ 02134 "!941+1633/100,!0/100", /* D */ 02135 "!941+1209/100,!0/100", /* * */ 02136 "!941+1477/100,!0/100" }; /* # */ 02137 if (digit >= '0' && digit <='9') 02138 ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0); 02139 else if (digit >= 'A' && digit <= 'D') 02140 ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0); 02141 else if (digit == '*') 02142 ast_playtones_start(chan, 0, dtmf_tones[14], 0); 02143 else if (digit == '#') 02144 ast_playtones_start(chan, 0, dtmf_tones[15], 0); 02145 else { 02146 /* not handled */ 02147 ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name); 02148 } 02149 } 02150 return 0; 02151 }
|
|
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 }
|
|
Definition at line 1256 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(). 01257 { 01258 if (clone->writetrans) 01259 ast_translator_free_path(clone->writetrans); 01260 if (clone->readtrans) 01261 ast_translator_free_path(clone->readtrans); 01262 clone->writetrans = NULL; 01263 clone->readtrans = NULL; 01264 clone->rawwriteformat = clone->nativeformats; 01265 clone->rawreadformat = clone->nativeformats; 01266 }
|
|
Definition at line 1391 of file channel.c. References ast_deactivate_generator(), ast_log(), ast_generator::generate, ast_channel::generator, and ast_channel::generatordata. Referenced by ast_activate_generator(), and ast_read(). 01392 { 01393 /* Called if generator doesn't have data */ 01394 void *tmp; 01395 int res; 01396 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 01397 struct ast_channel *chan = data; 01398 tmp = chan->generatordata; 01399 chan->generatordata = NULL; 01400 generate = chan->generator->generate; 01401 res = generate(chan, tmp, 0, 160); 01402 chan->generatordata = tmp; 01403 if (res) { 01404 ast_log(LOG_DEBUG, "Auto-deactivating generator\n"); 01405 ast_deactivate_generator(chan); 01406 } 01407 return 0; 01408 }
|
|
Definition at line 1133 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_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(). 01134 { 01135 struct ast_frame *translated_frame = NULL; 01136 struct ast_channel_spy *spy; 01137 struct ast_channel_spy_queue *queue; 01138 struct channel_spy_trans *trans; 01139 struct ast_frame *last; 01140 01141 trans = (dir == SPY_READ) ? &chan->spies->read_translator : &chan->spies->write_translator; 01142 01143 AST_LIST_TRAVERSE(&chan->spies->list, spy, list) { 01144 ast_mutex_lock(&spy->lock); 01145 01146 queue = (dir == SPY_READ) ? &spy->read_queue : &spy->write_queue; 01147 01148 if ((queue->format == AST_FORMAT_SLINEAR) && (f->subclass != AST_FORMAT_SLINEAR)) { 01149 if (!translated_frame) { 01150 if (trans->path && (trans->last_format != f->subclass)) { 01151 ast_translator_free_path(trans->path); 01152 trans->path = NULL; 01153 } 01154 if (!trans->path) { 01155 ast_log(LOG_DEBUG, "Building translator from %s to SLINEAR for spies on channel %s\n", 01156 ast_getformatname(f->subclass), chan->name); 01157 if ((trans->path = ast_translator_build_path(AST_FORMAT_SLINEAR, f->subclass)) == NULL) { 01158 ast_log(LOG_WARNING, "Cannot build a path from %s to %s\n", 01159 ast_getformatname(f->subclass), ast_getformatname(AST_FORMAT_SLINEAR)); 01160 ast_mutex_unlock(&spy->lock); 01161 continue; 01162 } else { 01163 trans->last_format = f->subclass; 01164 } 01165 } 01166 if (!(translated_frame = ast_translate(trans->path, f, 0))) { 01167 ast_log(LOG_ERROR, "Translation to %s failed, dropping frame for spies\n", 01168 ast_getformatname(AST_FORMAT_SLINEAR)); 01169 ast_mutex_unlock(&spy->lock); 01170 break; 01171 } 01172 } 01173 01174 for (last = queue->head; last && last->next; last = last->next); 01175 if (last) 01176 last->next = ast_frdup(translated_frame); 01177 else 01178 queue->head = ast_frdup(translated_frame); 01179 } else { 01180 if (f->subclass != queue->format) { 01181 ast_log(LOG_WARNING, "Spy '%s' on channel '%s' wants format '%s', but frame is '%s', dropping\n", 01182 spy->type, chan->name, 01183 ast_getformatname(queue->format), ast_getformatname(f->subclass)); 01184 ast_mutex_unlock(&spy->lock); 01185 continue; 01186 } 01187 01188 for (last = queue->head; last && last->next; last = last->next); 01189 if (last) 01190 last->next = ast_frdup(f); 01191 else 01192 queue->head = ast_frdup(f); 01193 } 01194 01195 queue->samples += f->samples; 01196 01197 if (queue->samples > SPY_QUEUE_SAMPLE_LIMIT) { 01198 if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) { 01199 switch (ast_test_flag(spy, CHANSPY_TRIGGER_MODE)) { 01200 case CHANSPY_TRIGGER_READ: 01201 if (dir == SPY_WRITE) { 01202 ast_set_flag(spy, CHANSPY_TRIGGER_WRITE); 01203 ast_clear_flag(spy, CHANSPY_TRIGGER_READ); 01204 if (option_debug) 01205 ast_log(LOG_DEBUG, "Switching spy '%s' on '%s' to write-trigger mode\n", 01206 spy->type, chan->name); 01207 } 01208 break; 01209 case CHANSPY_TRIGGER_WRITE: 01210 if (dir == SPY_READ) { 01211 ast_set_flag(spy, CHANSPY_TRIGGER_READ); 01212 ast_clear_flag(spy, CHANSPY_TRIGGER_WRITE); 01213 if (option_debug) 01214 ast_log(LOG_DEBUG, "Switching spy '%s' on '%s' to read-trigger mode\n", 01215 spy->type, chan->name); 01216 } 01217 break; 01218 } 01219 if (option_debug) 01220 ast_log(LOG_DEBUG, "Triggering queue flush for spy '%s' on '%s'\n", 01221 spy->type, chan->name); 01222 ast_set_flag(spy, CHANSPY_TRIGGER_FLUSH); 01223 ast_cond_signal(&spy->trigger); 01224 } else { 01225 if (option_debug) 01226 ast_log(LOG_DEBUG, "Spy '%s' on channel '%s' %s queue too long, dropping frames\n", 01227 spy->type, chan->name, (dir == SPY_READ) ? "read" : "write"); 01228 while (queue->samples > SPY_QUEUE_SAMPLE_LIMIT) { 01229 struct ast_frame *drop = queue->head; 01230 01231 queue->samples -= drop->samples; 01232 queue->head = drop->next; 01233 ast_frfree(drop); 01234 } 01235 } 01236 } else { 01237 switch (ast_test_flag(spy, CHANSPY_TRIGGER_MODE)) { 01238 case CHANSPY_TRIGGER_READ: 01239 if (dir == SPY_READ) 01240 ast_cond_signal(&spy->trigger); 01241 break; 01242 case CHANSPY_TRIGGER_WRITE: 01243 if (dir == SPY_WRITE) 01244 ast_cond_signal(&spy->trigger); 01245 break; 01246 } 01247 } 01248 01249 ast_mutex_unlock(&spy->lock); 01250 } 01251 01252 if (translated_frame) 01253 ast_frfree(translated_frame); 01254 }
|
|
Definition at line 2310 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_WARNING, ast_channel::name, ast_channel::nativeformats, and option_debug. Referenced by ast_set_read_format(), and ast_set_write_format(). 02312 { 02313 int native; 02314 int res; 02315 02316 native = chan->nativeformats; 02317 /* Find a translation path from the native format to one of the desired formats */ 02318 if (!direction) 02319 /* reading */ 02320 res = ast_translator_best_choice(&fmt, &native); 02321 else 02322 /* writing */ 02323 res = ast_translator_best_choice(&native, &fmt); 02324 02325 if (res < 0) { 02326 ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n", 02327 ast_getformatname(native), ast_getformatname(fmt)); 02328 return -1; 02329 } 02330 02331 /* Now we have a good choice for both. */ 02332 ast_mutex_lock(&chan->lock); 02333 *rawformat = native; 02334 /* User perspective is fmt */ 02335 *format = fmt; 02336 /* Free any read translation we have right now */ 02337 if (*trans) 02338 ast_translator_free_path(*trans); 02339 /* Build a translation path from the raw format to the desired format */ 02340 if (!direction) 02341 /* reading */ 02342 *trans = ast_translator_build_path(*format, *rawformat); 02343 else 02344 /* writing */ 02345 *trans = ast_translator_build_path(*rawformat, *format); 02346 ast_mutex_unlock(&chan->lock); 02347 if (option_debug) 02348 ast_log(LOG_DEBUG, "Set channel %s to %s format %s\n", chan->name, 02349 direction ? "write" : "read", ast_getformatname(fmt)); 02350 return 0; 02351 }
|
|
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 }
|
|
Definition at line 3957 of file channel.c.
|
|
Definition at line 3968 of file channel.c. References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_write(), and ast_frame::frametype. 03969 { 03970 if (samples == 160) { 03971 short buf[160] = { 0, }; 03972 struct ast_frame frame = { 03973 .frametype = AST_FRAME_VOICE, 03974 .subclass = AST_FORMAT_SLINEAR, 03975 .data = buf, 03976 .samples = 160, 03977 .datalen = sizeof(buf), 03978 }; 03979 03980 if (ast_write(chan, &frame)) 03981 return -1; 03982 } else { 03983 short buf[samples]; 03984 int x; 03985 struct ast_frame frame = { 03986 .frametype = AST_FRAME_VOICE, 03987 .subclass = AST_FORMAT_SLINEAR, 03988 .data = buf, 03989 .samples = samples, 03990 .datalen = sizeof(buf), 03991 }; 03992 03993 for (x = 0; x < samples; x++) 03994 buf[x] = 0; 03995 03996 if (ast_write(chan, &frame)) 03997 return -1; 03998 } 03999 04000 return 0; 04001 }
|
|
Definition at line 3963 of file channel.c.
|
|
Definition at line 3596 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. 03597 { 03598 struct tonepair_state *ts; 03599 struct tonepair_def *td = params; 03600 03601 ts = malloc(sizeof(struct tonepair_state)); 03602 if (!ts) 03603 return NULL; 03604 memset(ts, 0, sizeof(struct tonepair_state)); 03605 ts->origwfmt = chan->writeformat; 03606 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) { 03607 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name); 03608 tonepair_release(NULL, ts); 03609 ts = NULL; 03610 } else { 03611 ts->freq1 = td->freq1; 03612 ts->freq2 = td->freq2; 03613 ts->duration = td->duration; 03614 ts->vol = td->vol; 03615 } 03616 /* Let interrupts interrupt :) */ 03617 ast_set_flag(chan, AST_FLAG_WRITE_INT); 03618 return ts; 03619 }
|
|
Definition at line 3621 of file channel.c. References ast_log(), tonepair_state::data, tonepair_state::f, tonepair_state::freq1, tonepair_state::freq2, LOG_WARNING, tonepair_state::pos, and tonepair_state::vol. 03622 { 03623 struct tonepair_state *ts = data; 03624 int x; 03625 03626 /* we need to prepare a frame with 16 * timelen samples as we're 03627 * generating SLIN audio 03628 */ 03629 len = samples * 2; 03630 03631 if (len > sizeof(ts->data) / 2 - 1) { 03632 ast_log(LOG_WARNING, "Can't generate that much data!\n"); 03633 return -1; 03634 } 03635 memset(&ts->f, 0, sizeof(ts->f)); 03636 for (x = 0; x < (len / 2); x++) { 03637 ts->data[x] = ts->vol * ( 03638 sin((ts->freq1 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) + 03639 sin((ts->freq2 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) 03640 ); 03641 } 03642 ts->f.frametype = AST_FRAME_VOICE; 03643 ts->f.subclass = AST_FORMAT_SLINEAR; 03644 ts->f.datalen = len; 03645 ts->f.samples = samples; 03646 ts->f.offset = AST_FRIENDLY_OFFSET; 03647 ts->f.data = ts->data; 03648 ast_write(chan, &ts->f); 03649 ts->pos += x; 03650 if (ts->duration > 0) { 03651 if (ts->pos >= ts->duration * 8) 03652 return -1; 03653 } 03654 return 0; 03655 }
|
|
Definition at line 3586 of file channel.c. References ast_set_write_format(), free, and tonepair_state::origwfmt. Referenced by tonepair_alloc(). 03587 { 03588 struct tonepair_state *ts = params; 03589 03590 if (chan) { 03591 ast_set_write_format(chan, ts->origwfmt); 03592 } 03593 free(ts); 03594 }
|
|
Definition at line 3740 of file channel.c. Referenced by ast_install_music_functions(), ast_moh_cleanup(), and ast_uninstall_music_functions(). |
|
Definition at line 3738 of file channel.c. Referenced by ast_install_music_functions(), ast_moh_start(), and ast_uninstall_music_functions(). |
|
Definition at line 3739 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(). |
|
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(). |
|
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(). |
|
Definition at line 100 of file channel.c. Referenced by handle_debugchan(), and handle_nodebugchan(). |
|
Definition at line 100 of file channel.c. Referenced by handle_debugchan(), and handle_nodebugchan(). |
|
Initial value: { .type = "NULL", .description = "Null channel (should not see this)", } |
|
Initial value: "Usage: show channeltypes\n" " Shows available channel types registered in your Asterisk server.\n" |
|
Definition at line 95 of file channel.c. Referenced by ast_begin_shutdown(), ast_cancel_shutdown(), ast_channel_alloc(), and ast_shutting_down(). |
|
Initial value: { .alloc = silence_generator_alloc, .release = silence_generator_release, .generate = silence_generator_generate, } Definition at line 4003 of file channel.c. Referenced by ast_channel_start_silence_generator(). |
|
Initial value: { alloc: tonepair_alloc, release: tonepair_release, generate: tonepair_generator, } Definition at line 3657 of file channel.c. Referenced by ast_tonepair_start(). |
|
|