Sat Mar 24 23:27:26 2007

Asterisk developer's documentation


channel.c File Reference

Channel Management. More...

#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_channelast_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_channelast_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_frameast_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_generatorast_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_channelast_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_channelast_get_channel_by_exten_locked (const char *exten, const char *context)
ast_channelast_get_channel_by_name_locked (const char *name)
ast_channelast_get_channel_by_name_prefix_locked (const char *name, const int namelen)
const struct ast_channel_techast_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_frameast_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_channelast_request (const char *type, int format, void *data, int *cause)
 Requests a channel.
ast_channelast_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_channelast_waitfor_n (struct ast_channel **c, int n, int *ms)
int ast_waitfor_n_fd (int *fds, int n, int *ms, int *exception)
ast_channelast_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_channelast_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_channelchannel_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 chanlistbackends = NULL
const struct ast_cause causes []
static struct ast_channelchannels = 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


Detailed Description

Channel Management.

Definition in file channel.c.


Define Documentation

#define FORMAT   "%-10.10s %-30.30s %-12.12s %-12.12s %-12.12s\n"
 

#define SPY_QUEUE_SAMPLE_LIMIT   4000
 

Definition at line 1131 of file channel.c.

Referenced by queue_frame_to_spies().


Enumeration Type Documentation

enum spy_direction
 

Enumerator:
SPY_READ 
SPY_WRITE 

Definition at line 1126 of file channel.c.

01126                    {
01127    SPY_READ,
01128    SPY_WRITE,
01129 };


Function Documentation

struct ast_channel* __ast_request_and_dial const char *  type,
int  format,
void *  data,
int  timeout,
int *  outstate,
const char *  cid_num,
const char *  cid_name,
struct outgoing_helper oh
 

Definition at line 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 }

int ast_activate_generator struct ast_channel chan,
struct ast_generator gen,
void *  params
 

Activate a given generator

Definition at line 1410 of file channel.c.

References ast_generator::alloc, ast_mutex_lock(), ast_mutex_unlock(), ast_prod(), ast_settimeout(), gen, ast_channel::generator, generator_force(), ast_channel::generatordata, ast_channel::lock, and ast_generator::release.

Referenced by app_exec(), ast_channel_start_silence_generator(), ast_linear_stream(), ast_playtones_start(), ast_tonepair_start(), channel_spy(), local_ast_moh_start(), and milliwatt_exec().

01411 {
01412    int res = 0;
01413 
01414    ast_mutex_lock(&chan->lock);
01415 
01416    if (chan->generatordata) {
01417       if (chan->generator && chan->generator->release)
01418          chan->generator->release(chan, chan->generatordata);
01419       chan->generatordata = NULL;
01420    }
01421 
01422    ast_prod(chan);
01423    if (gen->alloc) {
01424       if (!(chan->generatordata = gen->alloc(chan, params)))
01425          res = -1;
01426    }
01427    
01428    if (!res) {
01429       ast_settimeout(chan, 160, generator_force, chan);
01430       chan->generator = gen;
01431    }
01432 
01433    ast_mutex_unlock(&chan->lock);
01434 
01435    return res;
01436 }

int ast_active_channels void   ) 
 

Returns number of active/allocated channels

Definition at line 250 of file channel.c.

References ast_mutex_lock(), ast_mutex_unlock(), channels, and ast_channel::next.

Referenced by quit_handler().

00251 {
00252    struct ast_channel *c;
00253    int cnt = 0;
00254    ast_mutex_lock(&chlock);
00255    c = channels;
00256    while(c) {
00257       cnt++;
00258       c = c->next;
00259    }
00260    ast_mutex_unlock(&chlock);
00261    return cnt;
00262 }

int ast_answer struct ast_channel chan  ) 
 

Answer a ringing call.

Parameters:
chan channel to answer This function answers a channel and handles all necessary call setup functions.
Returns:
Returns 0 on success, -1 on failure

Definition at line 1346 of file channel.c.

References ast_channel::_state, ast_channel_tech::answer, ast_cdr_answer(), ast_check_hangup(), AST_FLAG_ZOMBIE, ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_test_flag, ast_channel::cdr, ast_channel::lock, and ast_channel::tech.

Referenced by __login_exec(), agi_exec_full(), alarmreceiver_exec(), app_exec(), ast_bridge_call(), ast_control_streamfile(), ast_pickup_call(), auth_exec(), background_detect_exec(), chanspy_exec(), conf_exec(), count_exec(), datetime_exec(), dictate_exec(), directory_exec(), disa_exec(), features_answer(), handle_answer(), ices_exec(), milliwatt_exec(), park_call_exec(), park_exec(), pbx_builtin_answer(), pbx_builtin_background(), pickup_exec(), playback_exec(), privacy_exec(), read_exec(), record_exec(), sayunixtime_exec(), send_waveform_to_channel(), skel_exec(), testclient_exec(), testserver_exec(), vm_exec(), vm_execmain(), waitforsilence_exec(), zapateller_exec(), and zapras_exec().

01347 {
01348    int res = 0;
01349    ast_mutex_lock(&chan->lock);
01350    /* Stop if we're a zombie or need a soft hangup */
01351    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
01352       ast_mutex_unlock(&chan->lock);
01353       return -1;
01354    }
01355    switch(chan->_state) {
01356    case AST_STATE_RINGING:
01357    case AST_STATE_RING:
01358       if (chan->tech->answer)
01359          res = chan->tech->answer(chan);
01360       ast_setstate(chan, AST_STATE_UP);
01361       if (chan->cdr)
01362          ast_cdr_answer(chan->cdr);
01363       ast_mutex_unlock(&chan->lock);
01364       return res;
01365       break;
01366    case AST_STATE_UP:
01367       if (chan->cdr)
01368          ast_cdr_answer(chan->cdr);
01369       break;
01370    }
01371    ast_mutex_unlock(&chan->lock);
01372    return 0;
01373 }

void ast_begin_shutdown int  hangup  ) 
 

Initiate system shutdown -- prevents new channels from being allocated. If "hangup" is non-zero, all existing channels will receive soft hangups

Definition at line 234 of file channel.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_softhangup(), AST_SOFTHANGUP_SHUTDOWN, channels, and shutting_down.

Referenced by quit_handler().

00235 {
00236    struct ast_channel *c;
00237    shutting_down = 1;
00238    if (hangup) {
00239       ast_mutex_lock(&chlock);
00240       c = channels;
00241       while(c) {
00242          ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
00243          c = c->next;
00244       }
00245       ast_mutex_unlock(&chlock);
00246    }
00247 }

int ast_best_codec int  fmts  ) 
 

Pick the best codec

Definition at line 468 of file channel.c.

References AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_G723_1, AST_FORMAT_G726, AST_FORMAT_G729A, AST_FORMAT_GSM, AST_FORMAT_ILBC, AST_FORMAT_LPC10, AST_FORMAT_SLINEAR, AST_FORMAT_SPEEX, AST_FORMAT_ULAW, ast_log(), LOG_WARNING, and prefs.

Referenced by __login_exec(), __oh323_new(), agent_call(), ast_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 }

struct ast_channel* ast_bridged_channel struct ast_channel chan  ) 
 

Find bridged channel.

Parameters:
chan Current 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 }

int ast_call struct ast_channel chan,
char *  addr,
int  timeout
 

Make a call.

Parameters:
chan which channel to make the call on
addr destination of the call
timeout time to wait on for connect Place a call, take no longer than timeout ms.
Returns:
Returns -1 on failure, 0 on not enough time (does not automatically stop ringing), and the number of seconds the connect took otherwise.

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 }

void ast_cancel_shutdown void   ) 
 

Cancels an existing shutdown and returns to normal operation

Definition at line 265 of file channel.c.

References shutting_down.

Referenced by handle_abort_halt().

00266 {
00267    shutting_down = 0;
00268 }

const char* ast_cause2str int  state  ) 
 

Parameters:
state cause to get the description of Give a name to a cause code Returns the text form of the binary cause code given

Definition at line 407 of file channel.c.

References causes, and desc.

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 }

void ast_change_name struct ast_channel chan,
char *  newname
 

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 }

struct ast_channel* ast_channel_alloc int  needalertpipe  ) 
 

Create a channel structure.

Returns:
Returns NULL on failure to allocate.
Note:
New channels are by default set to the "default" context and extension "s"

Definition at line 516 of file channel.c.

References ast_log(), AST_MAX_FDS, ast_channel::fds, ast_channel::flags, free, LOG_WARNING, malloc, ast_channel::sched, sched_context_create(), shutting_down, and ast_channel::timingfd.

Referenced by __oh323_new(), agent_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_masq_park_call(), ast_modem_new(), ast_pbx_outgoing_cdr_failed(), ast_pbx_outgoing_exten(), builtin_atxfer(), check_goto_on_transfer(), features_new(), iax_park(), local_new(), mgcp_new(), misdn_new(), nbs_new(), oss_new(), phone_new(), sendmail(), sendpage(), sip_new(), sip_park(), skinny_new(), vpb_new(), and zt_new().

00517 {
00518    struct ast_channel *tmp;
00519    int x;
00520    int flags;
00521    struct varshead *headp;        
00522            
00523 
00524    /* If shutting down, don't allocate any new channels */
00525    if (shutting_down) {
00526       ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n");
00527       return NULL;
00528    }
00529 
00530    tmp = malloc(sizeof(struct ast_channel));
00531    if (!tmp) {
00532       ast_log(LOG_WARNING, "Channel allocation failed: Out of memory\n");
00533       return NULL;
00534    }
00535 
00536    memset(tmp, 0, sizeof(struct ast_channel));
00537    tmp->sched = sched_context_create();
00538    if (!tmp->sched) {
00539       ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n");
00540       free(tmp);
00541       return NULL;
00542    }
00543    
00544    for (x=0; x<AST_MAX_FDS - 1; x++)
00545       tmp->fds[x] = -1;
00546 
00547 #ifdef ZAPTEL_OPTIMIZATIONS
00548    tmp->timingfd = open("/dev/zap/timer", O_RDWR);
00549    if (tmp->timingfd > -1) {
00550       /* Check if timing interface supports new
00551          ping/pong scheme */
00552       flags = 1;
00553       if (!ioctl(tmp->timingfd, ZT_TIMERPONG, &flags))
00554          needqueue = 0;
00555    }
00556 #else
00557    tmp->timingfd = -1;              
00558 #endif               
00559 
00560    if (needqueue) {
00561       if (pipe(tmp->alertpipe)) {
00562          ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n");
00563          free(tmp);
00564          return NULL;
00565       } else {
00566          flags = fcntl(tmp->alertpipe[0], F_GETFL);
00567          fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
00568          flags = fcntl(tmp->alertpipe[1], F_GETFL);
00569          fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
00570       }
00571    } else 
00572       /* Make sure we've got it done right if they don't */
00573       tmp->alertpipe[0] = tmp->alertpipe[1] = -1;
00574 
00575    /* Always watch the alertpipe */
00576    tmp->fds[AST_MAX_FDS-1] = tmp->alertpipe[0];
00577    /* And timing pipe */
00578    tmp->fds[AST_MAX_FDS-2] = tmp->timingfd;
00579    strcpy(tmp->name, "**Unknown**");
00580    /* Initial state */
00581    tmp->_state = AST_STATE_DOWN;
00582    tmp->streamid = -1;
00583    tmp->appl = NULL;
00584    tmp->data = NULL;
00585    tmp->fin = global_fin;
00586    tmp->fout = global_fout;
00587    ast_mutex_lock(&uniquelock);
00588    snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long) time(NULL), uniqueint++);
00589    ast_mutex_unlock(&uniquelock);
00590    headp = &tmp->varshead;
00591    ast_mutex_init(&tmp->lock);
00592    AST_LIST_HEAD_INIT_NOLOCK(headp);
00593    strcpy(tmp->context, "default");
00594    ast_copy_string(tmp->language, defaultlanguage, sizeof(tmp->language));
00595    strcpy(tmp->exten, "s");
00596    tmp->priority = 1;
00597    tmp->amaflags = ast_default_amaflags;
00598    ast_copy_string(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode));
00599 
00600    tmp->tech = &null_tech;
00601 
00602    ast_mutex_lock(&chlock);
00603    tmp->next = channels;
00604    channels = tmp;
00605 
00606    ast_mutex_unlock(&chlock);
00607    return tmp;
00608 }

enum ast_bridge_result ast_channel_bridge struct ast_channel c0,
struct ast_channel c1,
struct ast_bridge_config config,
struct ast_frame **  fo,
struct ast_channel **  rc
 

Parameters:
c0 first channel to bridge
c1 second channel to bridge
config config for the channels
fo destination frame(?)
rc destination channel(?) Bridge two channels (c0 and c1) together. If an important frame occurs, we return that frame in rf (remember, it could be NULL) and which channel (0 or 1) in rc

Definition at line 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 }

int ast_channel_cmpwhentohangup struct ast_channel chan,
time_t  offset
 

Compare a offset with the settings of when to hang a channel up.

Parameters:
chan channel on which to check for hang up
offset offset in seconds from current time
Returns:
1, 0, or -1 This function compares a offset from current time with the absolute time out on a channel (when to hang up). If the absolute time out on a channel is earlier than current time plus the offset, it returns 1, if the two time values are equal, it return 0, otherwise, it retturn -1.

Definition at line 292 of file channel.c.

References ast_channel::whentohangup.

Referenced by ast_osp_lookup().

00293 {
00294    time_t whentohangup;
00295 
00296    if (chan->whentohangup == 0) {
00297       if (offset == 0)
00298          return (0);
00299       else
00300          return (-1);
00301    } else { 
00302       if (offset == 0)
00303          return (1);
00304       else {
00305          whentohangup = offset + time (NULL);
00306          if (chan->whentohangup < whentohangup)
00307             return (1);
00308          else if (chan->whentohangup == whentohangup)
00309             return (0);
00310          else
00311             return (-1);
00312       }
00313    }
00314 }

int ast_channel_defer_dtmf struct ast_channel chan  ) 
 

Defer DTMF so that you only read things like hangups and audio. Returns non-zero if channel was already DTMF-deferred or 0 if channel is just now being DTMF-deferred

Definition at line 690 of file channel.c.

References AST_FLAG_DEFER_DTMF, ast_set_flag, and ast_test_flag.

Referenced by find_cache().

00691 {
00692    int pre = 0;
00693 
00694    if (chan) {
00695       pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
00696       ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
00697    }
00698    return pre;
00699 }

void ast_channel_free struct ast_channel chan  ) 
 

Free a channel structure.

Definition at line 878 of file channel.c.

References ast_channel::alertpipe, AST_CHANNEL_NAME, ast_device_state_changed_literal(), ast_frfree(), AST_LIST_REMOVE_HEAD, ast_log(), ast_moh_cleanup(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_translator_free_path(), ast_var_delete(), channels, ast_channel::cid, free, free_cid(), last, ast_channel::lock, LOG_WARNING, ast_channel::monitor, ast_channel::music_state, name, ast_channel::name, ast_channel::next, msglist::next, ast_frame::next, ast_channel::pbx, ast_channel::readq, ast_channel::readtrans, ast_channel::sched, sched_context_destroy(), ast_channel_monitor::stop, ast_channel::tech_pvt, ast_channel::timingfd, ast_channel::varshead, and ast_channel::writetrans.

Referenced by agent_cleanup(), agent_new(), ast_hangup(), ast_pbx_outgoing_cdr_failed(), local_new(), sendmail(), and sendpage().

00879 {
00880    struct ast_channel *last=NULL, *cur;
00881    int fd;
00882    struct ast_var_t *vardata;
00883    struct ast_frame *f, *fp;
00884    struct varshead *headp;
00885    char name[AST_CHANNEL_NAME];
00886    
00887    headp=&chan->varshead;
00888    
00889    ast_mutex_lock(&chlock);
00890    cur = channels;
00891    while(cur) {
00892       if (cur == chan) {
00893          if (last)
00894             last->next = cur->next;
00895          else
00896             channels = cur->next;
00897          break;
00898       }
00899       last = cur;
00900       cur = cur->next;
00901    }
00902    if (!cur)
00903       ast_log(LOG_WARNING, "Unable to find channel in list\n");
00904    else {
00905       /* Lock and unlock the channel just to be sure nobody
00906          has it locked still */
00907       ast_mutex_lock(&cur->lock);
00908       ast_mutex_unlock(&cur->lock);
00909    }
00910    if (chan->tech_pvt) {
00911       ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
00912       free(chan->tech_pvt);
00913    }
00914 
00915    if (chan->sched)
00916       sched_context_destroy(chan->sched);
00917 
00918    ast_copy_string(name, chan->name, sizeof(name));
00919 
00920    /* Stop monitoring */
00921    if (chan->monitor) {
00922       chan->monitor->stop( chan, 0 );
00923    }
00924 
00925    /* If there is native format music-on-hold state, free it */
00926    if(chan->music_state)
00927       ast_moh_cleanup(chan);
00928 
00929    /* Free translatosr */
00930    if (chan->readtrans)
00931       ast_translator_free_path(chan->readtrans);
00932    if (chan->writetrans)
00933       ast_translator_free_path(chan->writetrans);
00934    if (chan->pbx) 
00935       ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
00936    free_cid(&chan->cid);
00937    ast_mutex_destroy(&chan->lock);
00938    /* Close pipes if appropriate */
00939    if ((fd = chan->alertpipe[0]) > -1)
00940       close(fd);
00941    if ((fd = chan->alertpipe[1]) > -1)
00942       close(fd);
00943    if ((fd = chan->timingfd) > -1)
00944       close(fd);
00945    f = chan->readq;
00946    chan->readq = NULL;
00947    while(f) {
00948       fp = f;
00949       f = f->next;
00950       ast_frfree(fp);
00951    }
00952    
00953    /* loop over the variables list, freeing all data and deleting list items */
00954    /* no need to lock the list, as the channel is already locked */
00955    
00956    while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
00957       ast_var_delete(vardata);
00958 
00959    free(chan);
00960    ast_mutex_unlock(&chlock);
00961 
00962    ast_device_state_changed_literal(name);
00963 }

void ast_channel_inherit_variables const struct ast_channel parent,
struct ast_channel child
 

Inherits channel variable from parent to child channel.

Parameters:
parent Parent channel
child Child channel
Scans all channel variables in the parent channel, looking for those that should be copied into the child channel. Variables whose names begin with a single '_' are copied into the child channel with the prefix removed. Variables whose names begin with '__' are copied into the child channel with their names unchanged.

Definition at line 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 }

int ast_channel_make_compatible struct ast_channel c0,
struct ast_channel c1
 

Parameters:
c0 first channel to make compatible
c1 other channel to make compatible Set two channels to compatible formats -- call before ast_channel_bridge in general . Returns 0 on success and -1 if it could not be done

Definition at line 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 }

int ast_channel_masquerade struct ast_channel original,
struct ast_channel clone
 

Parameters:
original channel to make a copy of
clone copy of the original channel This is a very strange and freaky function used primarily for transfer. Suppose that "original" and "clone" are two channels in random situations. This function takes the guts out of "clone" and puts them into the "original" channel, then alerts the channel driver of the change, asking it to fixup any private information (like the p->owner pointer) that is affected by the change. The physical layer of the original channel is hung up.

Definition at line 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 }

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.

Parameters:
tech Structure defining channel technology or "type"
Returns:
Returns 0 on success, -1 on failure.

Definition at line 317 of file channel.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), backends, LOG_DEBUG, LOG_WARNING, malloc, chanlist::next, option_debug, option_verbose, chanlist::tech, ast_channel_tech::type, and VERBOSE_PREFIX_2.

Referenced by load_module(), and unload_module().

00318 {
00319    struct chanlist *chan;
00320 
00321    ast_mutex_lock(&chlock);
00322 
00323    chan = backends;
00324    while (chan) {
00325       if (!strcasecmp(tech->type, chan->tech->type)) {
00326          ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
00327          ast_mutex_unlock(&chlock);
00328          return -1;
00329       }
00330       chan = chan->next;
00331    }
00332 
00333    chan = malloc(sizeof(*chan));
00334    if (!chan) {
00335       ast_log(LOG_WARNING, "Out of memory\n");
00336       ast_mutex_unlock(&chlock);
00337       return -1;
00338    }
00339    chan->tech = tech;
00340    chan->next = backends;
00341    backends = chan;
00342 
00343    if (option_debug)
00344       ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
00345 
00346    if (option_verbose > 1)
00347       ast_verbose(VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->tech->type,
00348              chan->tech->description);
00349 
00350    ast_mutex_unlock(&chlock);
00351    return 0;
00352 }

int ast_channel_sendhtml struct ast_channel channel,
int  subclass,
const char *  data,
int  datalen
 

Send HTML or URL on link. Returns 0 on success or -1 on failure

Definition at line 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 }

int ast_channel_sendurl struct ast_channel channel,
const char *  url
 

Send URL on link. Returns 0 on success or -1 on failure

Definition at line 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 }

int ast_channel_setoption struct ast_channel channel,
int  option,
void *  data,
int  datalen,
int  block
 

Parameters:
channel channel to set options on
option option to change
data data specific to option
datalen length of the data
block blocking or not Set an option on a channel (see frame.h), optionally blocking awaiting the reply Returns 0 on success and -1 on failure

Definition at line 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 }

void ast_channel_setwhentohangup struct ast_channel chan,
time_t  offset
 

Set when to hang a channel up.

Parameters:
chan channel on which to check for hang up
offset offset in seconds from current time of when to hang up This function sets the absolute time out on a channel (when to hang up).

Definition at line 277 of file channel.c.

References AST_FRAME_NULL, ast_queue_frame(), and ast_channel::whentohangup.

Referenced by action_timeout(), ast_osp_lookup(), builtin_function_timeout_write(), handle_request_invite(), and pbx_builtin_atimeout().

00278 {
00279    time_t   myt;
00280    struct ast_frame fr = { AST_FRAME_NULL, };
00281 
00282    time(&myt);
00283    if (offset)
00284       chan->whentohangup = myt + offset;
00285    else
00286       chan->whentohangup = 0;
00287    ast_queue_frame(chan, &fr);
00288    return;
00289 }

int ast_channel_spy_add struct ast_channel chan,
struct ast_channel_spy spy
 

Adds a spy to a channel, to begin receiving copies of the channel's audio frames.

Parameters:
chan The channel to add the spy to.
spy A pointer to ast_channel_spy structure describing how the spy is to be used.
Returns:
0 for success, non-zero for failure
Note: This function performs no locking; you must hold the channel's lock before calling this function.

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 }

struct ast_frame* ast_channel_spy_read_frame struct ast_channel_spy spy,
unsigned int  samples
 

Read one (or more) frames of audio from a channel being spied upon.

Parameters:
spy The spy to operate on
samples The number of audio samples to read
Returns:
NULL for failure, one ast_frame pointer, or a chain of ast_frame pointers
This function can return multiple frames if the spy structure needs to be 'flushed' due to mismatched queue lengths, or if the spy structure is configured to return unmixed audio (in which case each call to this function will return a frame of audio from each side of channel).

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 }

void ast_channel_spy_remove struct ast_channel chan,
struct ast_channel_spy spy
 

Remove a spy from a channel.

Parameters:
chan The channel to remove the spy from
spy The spy to be removed
Returns:
nothing
Note: This function performs no locking; you must hold the channel's lock before calling this function.

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 }

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.

Parameters:
chan The channel to operate on
type A character string identifying the type of spies to be stopped
Returns:
nothing
Note: This function performs no locking; you must hold the channel's lock before calling this function.

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 }

void ast_channel_spy_trigger_wait struct ast_channel_spy spy  ) 
 

Efficiently wait until audio is available for a spy, or an exception occurs.

Parameters:
spy The spy to wait on
Returns:
nothing
Note: The locking rules for this function are non-obvious... first, you must not hold the channel's lock when calling this function. Second, you must hold the spy's lock before making the function call; while the function runs the lock will be released, and when the trigger event occurs, the lock will be re-obtained. This means that when control returns to your code, you will again hold the spy's lock.

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 }

struct ast_silence_generator* ast_channel_start_silence_generator struct ast_channel chan  ) 
 

Starts a silence generator on the given channel.

Parameters:
chan The channel to generate silence on
Returns:
An ast_silence_generator pointer, or NULL if an error occurs
This function will cause SLINEAR silence to be generated on the supplied channel until it is disabled; if the channel cannot be put into SLINEAR mode then the function will fail.

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 }

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.

Parameters:
chan The channel to operate on
state The ast_silence_generator pointer return by a previous call to ast_channel_start_silence_generator.
Returns:
nothing
This function will stop the operating silence generator and return the channel to its previous write format.

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 }

int ast_channel_supports_html struct ast_channel channel  ) 
 

Returns 0 if channel does not support HTML or non-zero if it does

Definition at line 2661 of file channel.c.

References ast_channel_tech::send_html, and ast_channel::tech.

Referenced by sendurl_exec().

02662 {
02663    if (chan->tech->send_html)
02664       return 1;
02665    return 0;
02666 }

void ast_channel_undefer_dtmf struct ast_channel chan  ) 
 

Undo defer. ast_read will return any dtmf characters that were queued

Definition at line 702 of file channel.c.

References ast_clear_flag, and AST_FLAG_DEFER_DTMF.

Referenced by find_cache(), and rpt_call().

00703 {
00704    if (chan)
00705       ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
00706 }

void ast_channel_unregister const struct ast_channel_tech tech  ) 
 

Unregister a channel technology.

Parameters:
tech Structure defining channel technology or "type" that was previously registered
Returns:
No return value.

Definition at line 354 of file channel.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), backends, free, last, LOG_DEBUG, chanlist::next, option_debug, option_verbose, chanlist::tech, ast_channel_tech::type, and VERBOSE_PREFIX_2.

Referenced by __unload_module(), and unload_module().

00355 {
00356    struct chanlist *chan, *last=NULL;
00357 
00358    if (option_debug)
00359       ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type);
00360 
00361    ast_mutex_lock(&chlock);
00362 
00363    chan = backends;
00364    while (chan) {
00365       if (chan->tech == tech) {
00366          if (last)
00367             last->next = chan->next;
00368          else
00369             backends = backends->next;
00370          free(chan);
00371          ast_mutex_unlock(&chlock);
00372 
00373          if (option_verbose > 1)
00374             ast_verbose( VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type);
00375 
00376          return;
00377       }
00378       last = chan;
00379       chan = chan->next;
00380    }
00381 
00382    ast_mutex_unlock(&chlock);
00383 }

struct ast_channel* ast_channel_walk_locked const struct ast_channel prev  ) 
 

Parameters:
prev where you want to start in the channel list Browse the channels currently in use Returns the next channel in the list, NULL on end. If it returns a channel, that channel *has been locked*!

Definition at line 794 of file channel.c.

References channel_find_locked().

Referenced by action_status(), ast_app_group_get_count(), ast_app_group_match_get_count(), ast_pickup_call(), complete_ch_helper(), conf_exec(), group_show_channels(), handle_chanlist(), handle_debugchan(), handle_nodebugchan(), local_channel_walk(), moh_on_off(), and softhangup_exec().

00795 {
00796    return channel_find_locked(prev, NULL, 0, NULL, NULL);
00797 }

void ast_channels_init void   ) 
 

Definition at line 3785 of file channel.c.

References ast_cli_register(), and cli_show_channeltypes.

03786 {
03787    ast_cli_register(&cli_show_channeltypes);
03788 }

int ast_check_hangup struct ast_channel chan  ) 
 

Check to see if a channel is needing hang up.

Parameters:
chan channel on which to check for hang up This function determines if the channel is being requested to be hung up.
Returns:
Returns 0 if not, or 1 if hang up is requested (including time-out).

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 }

static int ast_check_hangup_locked struct ast_channel chan  )  [static]
 

Definition at line 224 of file channel.c.

References ast_check_hangup(), ast_mutex_lock(), ast_mutex_unlock(), and ast_channel::lock.

Referenced by ast_channel_bridge().

00225 {
00226    int res;
00227    ast_mutex_lock(&chan->lock);
00228    res = ast_check_hangup(chan);
00229    ast_mutex_unlock(&chan->lock);
00230    return res;
00231 }

void ast_deactivate_generator struct ast_channel chan  ) 
 

Deactive an active generator

Definition at line 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 }

int ast_do_masquerade struct ast_channel chan  ) 
 

Start masquerading a channel XXX This is a seriously wacked out operation. We're essentially putting the guts of the clone channel into the original channel. Start by killing off the original channel's backend. I'm not sure we're going to keep this function, because while the features are nice, the cost is very high in terms of pure nastiness. XXX.

Parameters:
chan Channel to masquerade

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 }

static enum ast_bridge_result ast_generic_bridge struct ast_channel c0,
struct ast_channel c1,
struct ast_bridge_config config,
struct ast_frame **  fo,
struct ast_channel **  rc,
struct timeval  bridge_end
[static]
 

Definition at line 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 }

struct ast_channel* ast_get_channel_by_exten_locked const char *  exten,
const char *  context
 

Definition at line 818 of file channel.c.

References channel_find_locked().

Referenced by pickup_exec().

00819 {
00820    return channel_find_locked(NULL, NULL, 0, context, exten);
00821 }

struct ast_channel* ast_get_channel_by_name_locked const char *  chan  ) 
 

Get channel by name (locks channel)

Definition at line 800 of file channel.c.

References channel_find_locked().

Referenced by action_getvar(), action_hangup(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), ast_async_goto_by_name(), change_monitor_action(), get_zap_channel_locked(), handle_channelstatus(), handle_debugchan(), handle_getvariablefull(), handle_hangup(), handle_nodebugchan(), handle_showchan(), handle_softhangup(), 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 }

struct ast_channel* ast_get_channel_by_name_prefix_locked const char *  name,
const int  namelen
 

Get channel by name prefix (locks channel)

Definition at line 806 of file channel.c.

References channel_find_locked().

Referenced by ast_parse_device_state(), and mixmonitor_cli().

00807 {
00808    return channel_find_locked(NULL, name, namelen, NULL, NULL);
00809 }

const struct ast_channel_tech* ast_get_channel_tech const char *  name  ) 
 

Get a channel technology structure by name.

Parameters:
name name of technology to find
Returns:
a pointer to the structure, or NULL if no matching technology found

Definition at line 385 of file channel.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), backends, LOG_WARNING, chanlist::next, chanlist::tech, and ast_channel_tech::type.

Referenced by ast_device_state().

00386 {
00387    struct chanlist *chanls;
00388 
00389    if (ast_mutex_lock(&chlock)) {
00390       ast_log(LOG_WARNING, "Unable to lock channel tech list\n");
00391       return NULL;
00392    }
00393 
00394    for (chanls = backends; chanls; chanls = chanls->next) {
00395       if (strcasecmp(name, chanls->tech->type))
00396          continue;
00397 
00398       ast_mutex_unlock(&chlock);
00399       return chanls->tech;
00400    }
00401 
00402    ast_mutex_unlock(&chlock);
00403    return NULL;
00404 }

ast_group_t ast_get_group char *  s  ) 
 

Definition at line 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 }

int ast_hangup struct ast_channel chan  ) 
 

Hang up a channel.

Note:
This function performs a hard hangup on a channel. Unlike the soft-hangup, this function performs all stream stopping, etc, on the channel that needs to end. chan is no longer valid after this call.
Parameters:
chan channel to hang up
Returns:
Returns 0 on success, -1 on failure.

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 }

int ast_indicate struct ast_channel chan,
int  condition
 

Indicates condition of channel.

Note:
Indicate a condition such as AST_CONTROL_BUSY, AST_CONTROL_RINGING, or AST_CONTROL_CONGESTION on a channel
Parameters:
chan channel to change the indication
condition which condition to indicate on the channel
Returns:
Returns 0 on success, -1 on failure

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 }

void ast_install_music_functions int(*)(struct ast_channel *, char *)  start_ptr,
void(*)(struct ast_channel *)  stop_ptr,
void(*)(struct ast_channel *)  cleanup_ptr
 

Definition at line 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 }

void ast_moh_cleanup struct ast_channel chan  ) 
 

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 }

int ast_moh_start struct ast_channel chan,
char *  mclass
 

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 }

void ast_moh_stop struct ast_channel chan  ) 
 

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 }

AST_MUTEX_DEFINE_STATIC chlock   ) 
 

AST_MUTEX_DEFINE_STATIC uniquelock   ) 
 

char* ast_print_group char *  buf,
int  buflen,
ast_group_t  group
 

Definition at line 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 }

int ast_prod struct ast_channel chan  ) 
 

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 }

int ast_queue_control struct ast_channel chan,
int  control
 

Queue a control frame.

Definition at line 682 of file channel.c.

References AST_FRAME_CONTROL, ast_queue_frame(), and ast_frame::subclass.

Referenced by __oh323_update_info(), ast_pickup_call(), auto_congest(), 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 }

int ast_queue_frame struct ast_channel chan,
struct ast_frame fin
 

Queue an outgoing frame.

Definition at line 611 of file channel.c.

References ast_channel::alertpipe, AST_CONTROL_HANGUP, AST_FLAG_BLOCKING, AST_FRAME_CONTROL, AST_FRAME_VOICE, ast_frdup(), ast_frfree(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_channel::blocker, CRASH, ast_frame::frametype, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_frame::next, ast_frame::prev, ast_channel::readq, ast_frame::subclass, and ast_channel::timingfd.

Referenced by agent_new(), alsa_call(), ast_channel_masquerade(), ast_channel_setwhentohangup(), ast_dsp_process(), ast_queue_control(), ast_queue_hangup(), ast_softhangup_nolock(), cb_events(), console_answer(), console_dial(), console_flash(), console_sendtext(), 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 }

int ast_queue_hangup struct ast_channel chan  ) 
 

Queue a hangup frame.

Definition at line 670 of file channel.c.

References ast_channel::_softhangup, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), AST_SOFTHANGUP_DEV, and ast_channel::lock.

Referenced by __oh323_update_info(), __sip_autodestruct(), cleanup_connection(), console_hangup(), handle_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 }

struct ast_frame* ast_read struct ast_channel chan  ) 
 

Parameters:
chan channel to read a frame from Read a frame. Returns a frame, or NULL on error. If it returns NULL, you best just stop reading frames and assume the channel has been disconnected.

Definition at line 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 }

int ast_readstring struct ast_channel c,
char *  s,
int  len,
int  timeout,
int  rtimeout,
char *  enders
 

Parameters:
c channel to read from
s string to read in to. Must be at least the size of your length
len how many digits to read (maximum)
timeout how long to timeout between digits
rtimeout timeout to wait on the first digit
enders digits to end the string Read in a digit string "s", max length "len", maximum timeout between digits "timeout" (-1 for none), terminated by anything in "enders". Give them rtimeout for the first digit. Returns 0 on normal return, or 1 on a timeout. In the case of a timeout, any digits that were read before the timeout will still be available in s. RETURNS 2 in full version when ctrlfd is available, NOT 1

Definition at line 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 }

int ast_readstring_full struct ast_channel c,
char *  s,
int  len,
int  timeout,
int  ftimeout,
char *  enders,
int  audiofd,
int  ctrlfd
 

Definition at line 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 }

int ast_recvchar struct ast_channel chan,
int  timeout
 

Parameters:
chan channel to act upon
timeout timeout in milliseconds (0 for infinite wait) Read a char of text from a channel Returns 0 on success, -1 on failure

Definition at line 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 }

char* ast_recvtext struct ast_channel chan,
int  timeout
 

Parameters:
chan channel to act upon
timeout timeout in milliseconds (0 for infinite wait)
Returns:
the received text, or NULL to signify failure. Read a string of text from a channel

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 }

struct ast_channel* ast_request const char *  type,
int  format,
void *  data,
int *  status
 

Requests a channel.

Parameters:
type type of channel to request
format requested channel format
data data to pass to the channel requester
status status Request a channel of a given type, with data as optional information used by the low level module
Returns:
Returns an ast_channel on success, NULL on failure.

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 }

struct ast_channel* ast_request_and_dial const char *  type,
int  format,
void *  data,
int  timeout,
int *  reason,
const char *  cidnum,
const char *  cidname
 

Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.

Parameters:
type type of channel to request
format requested channel format
data data to pass to the channel requester
timeout maximum amount of time to wait for an answer
reason why unsuccessful (if unsuceessful)
cidnum Caller-ID Number
cidname Caller-ID Name
Returns:
Returns an ast_channel on success or no answer, NULL on failure. Check the value of chan->_state to know if the call was answered or not.

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 }

int ast_safe_sleep struct ast_channel chan,
int  ms
 

Wait for a specied amount of time, looking for hangups.

Parameters:
chan channel to wait for
ms length of time in milliseconds to sleep Waits for a specified amount of time, servicing the channel as required.
Returns:
returns -1 on hangup, otherwise 0.

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 }

int ast_safe_sleep_conditional struct ast_channel chan,
int  ms,
int(*)(void *)  cond,
void *  data
 

Wait for a specied amount of time, looking for hangups and a condition argument.

Parameters:
chan channel to wait for
ms length of time in milliseconds to sleep
cond a function pointer for testing continue condition
data argument to be passed to the condition test function
Returns:
returns -1 on hangup, otherwise 0. Waits for a specified amount of time, servicing the channel as required. If cond returns 0, this function returns.

Definition at line 824 of file channel.c.

References ast_frfree(), ast_read(), and ast_waitfor().

Referenced by __login_exec().

00826 {
00827    struct ast_frame *f;
00828 
00829    while(ms > 0) {
00830       if( cond && ((*cond)(data) == 0 ) )
00831          return 0;
00832       ms = ast_waitfor(chan, ms);
00833       if (ms <0)
00834          return -1;
00835       if (ms > 0) {
00836          f = ast_read(chan);
00837          if (!f)
00838             return -1;
00839          ast_frfree(f);
00840       }
00841    }
00842    return 0;
00843 }

int ast_senddigit struct ast_channel chan,
char  digit
 

Parameters:
chan channel to act upon
digit the DTMF digit to send, encoded in ASCII Send a DTMF digit to a channel. Returns 0 on success, -1 on failure

Definition at line 2153 of file channel.c.

References do_senddigit().

Referenced by features_digit(), and manager_play_dtmf().

02154 {
02155    return do_senddigit(chan, digit);
02156 }

int ast_sendtext struct ast_channel chan,
const char *  text
 

Parameters:
chan channel to act upon
text string of text to send on the channel Write text to a display on a channel Returns 0 on success, -1 on failure

Definition at line 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 }

void ast_set_callerid struct ast_channel chan,
const char *  callerid,
const char *  calleridname,
const char *  ani
 

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 }

int ast_set_read_format struct ast_channel chan,
int  format
 

Parameters:
chan channel to change
format format to change to Set read format for channel to whichever component of "format" is best. Returns 0 on success, -1 on failure

Definition at line 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 }

void ast_set_variables struct ast_channel chan,
struct ast_variable vars
 

adds a list of channel variables to a channel

Parameters:
chan the channel
vars a linked list of variables
Variable names can be for a regular channel variable or a dialplan function that has the ability to be written to.

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 }

int ast_set_write_format struct ast_channel chan,
int  format
 

Parameters:
chan channel to change
format new format for writing Set write format for channel to whichever compoent of "format" is best. Returns 0 on success, -1 on failure

Definition at line 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 }

int ast_setstate struct ast_channel chan,
int  state
 

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 }

int ast_settimeout struct ast_channel c,
int  samples,
int(*)(void *data)  func,
void *  data
 

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 }

int ast_shutting_down void   ) 
 

Returns non-zero if Asterisk is being shut down

Definition at line 271 of file channel.c.

References shutting_down.

00272 {
00273    return shutting_down;
00274 }

int ast_softhangup struct ast_channel chan,
int  cause
 

Softly hangup up a channel.

Parameters:
chan channel to be soft-hung-up Call the protocol layer, but don't destroy the channel structure (use this if you are trying to safely hangup a channel managed by another thread.
cause Ast hangupcause for hangup
Returns:
Returns 0 regardless

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 }

int ast_softhangup_nolock struct ast_channel chan,
int  cause
 

Softly hangup up a channel (no channel lock).

Parameters:
chan channel to be soft-hung-up
cause Ast hangupcause for hangup (see cause.h)

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 }

char* ast_state2str int  state  ) 
 

Parameters:
state state to get the name of Give a name to a state Returns the text form of the binary state given

Definition at line 419 of file channel.c.

References AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_OFFHOOK, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, and AST_STATE_UP.

Referenced by action_status(), agent_hangup(), ast_serialize_showchan(), ast_setstate(), handle_chanlist(), handle_showchan(), and mgcp_new().

00420 {
00421    /* XXX Not reentrant XXX */
00422    static char localtmp[256];
00423    switch(state) {
00424    case AST_STATE_DOWN:
00425       return "Down";
00426    case AST_STATE_RESERVED:
00427       return "Rsrvd";
00428    case AST_STATE_OFFHOOK:
00429       return "OffHook";
00430    case AST_STATE_DIALING:
00431       return "Dialing";
00432    case AST_STATE_RING:
00433       return "Ring";
00434    case AST_STATE_RINGING:
00435       return "Ringing";
00436    case AST_STATE_UP:
00437       return "Up";
00438    case AST_STATE_BUSY:
00439       return "Busy";
00440    default:
00441       snprintf(localtmp, sizeof(localtmp), "Unknown (%d)\n", state);
00442       return localtmp;
00443    }
00444 }

int ast_tonepair struct ast_channel chan,
int  freq1,
int  freq2,
int  duration,
int  vol
 

Play a tone pair for a given amount of time

Definition at line 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 }

int ast_tonepair_start struct ast_channel chan,
int  freq1,
int  freq2,
int  duration,
int  vol
 

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 }

void ast_tonepair_stop struct ast_channel chan  ) 
 

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 }

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.

Parameters:
chan current channel
dest destination extension for transfer

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 }

char* ast_transfercapability2str int  transfercapability  ) 
 

Parameters:
transfercapability transfercapabilty to get the name of Give a name to a transfercapbility See above Returns the text form of the binary transfer capbility

Definition at line 447 of file channel.c.

References AST_TRANS_CAP_3_1K_AUDIO, AST_TRANS_CAP_DIGITAL, AST_TRANS_CAP_DIGITAL_W_TONES, AST_TRANS_CAP_RESTRICTED_DIGITAL, AST_TRANS_CAP_SPEECH, and AST_TRANS_CAP_VIDEO.

Referenced by cb_events(), misdn_call(), zt_call(), and zt_new().

00448 {
00449    switch(transfercapability) {
00450    case AST_TRANS_CAP_SPEECH:
00451       return "SPEECH";
00452    case AST_TRANS_CAP_DIGITAL:
00453       return "DIGITAL";
00454    case AST_TRANS_CAP_RESTRICTED_DIGITAL:
00455       return "RESTRICTED_DIGITAL";
00456    case AST_TRANS_CAP_3_1K_AUDIO:
00457       return "3K1AUDIO";
00458    case AST_TRANS_CAP_DIGITAL_W_TONES:
00459       return "DIGITAL_W_TONES";
00460    case AST_TRANS_CAP_VIDEO:
00461       return "VIDEO";
00462    default:
00463       return "UNKNOWN";
00464    }
00465 }

void ast_uninstall_music_functions void   ) 
 

Definition at line 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 }

int ast_waitfor struct ast_channel chan,
int  ms
 

Wait for input on a channel.

Parameters:
chan channel to wait on
ms length of time to wait on the channel Wait for input on a channel for a given # of milliseconds (<0 for indefinite).
Returns:
Returns < 0 on failure, 0 if nothing ever arrived, and the # of ms remaining otherwise

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 }

struct ast_channel* ast_waitfor_n struct ast_channel **  chan,
int  n,
int *  ms
 

Wait for input on an array of channels for a given # of milliseconds. Return channel with activity, or NULL if none has activity. time "ms" is modified in-place, if applicable

Definition at line 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 }

int ast_waitfor_n_fd int *  fds,
int  n,
int *  ms,
int *  exception
 

This version works on fd's only. Be careful with it.

Definition at line 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 }

struct ast_channel* ast_waitfor_nandfds struct ast_channel **  chan,
int  n,
int *  fds,
int  nfds,
int *  exception,
int *  outfd,
int *  ms
 

Waits for activity on a group of channels.

Parameters:
chan an array of pointers to channels
n number of channels that are to be waited upon
fds an array of fds to wait upon
nfds the number of fds to wait upon
exception exception flag
outfd fd that had activity on it
ms how long the wait was Big momma function here. Wait for activity on any of the n channels, or any of the nfds file descriptors.
Returns:
Returns the channel with activity, or NULL on error or if an FD came first. If the FD came first, it will be returned in outfd, otherwise, outfd will be -1

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 }

int ast_waitfordigit struct ast_channel c,
int  ms
 

Parameters:
c channel to wait for a digit on
ms how many milliseconds to wait Wait for a digit. Returns <0 on error, 0 on no entry, and the digit on success.

Definition at line 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 }

int ast_waitfordigit_full struct ast_channel c,
int  ms,
int  audiofd,
int  cmdfd
 

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 }

struct ast_channel* ast_walk_channel_by_name_prefix_locked struct ast_channel chan,
const char *  name,
const int  namelen
 

Get channel by name prefix (locks channel)

Definition at line 812 of file channel.c.

References channel_find_locked().

00813 {
00814    return channel_find_locked(chan, name, namelen, NULL, NULL);
00815 }

int ast_write struct ast_channel chan,
struct ast_frame frame
 

Parameters:
chan destination channel of the frame
frame frame that will be written This function writes the given frame to the indicated channel. It returns 0 on success, -1 on failure.

Definition at line 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 }

int ast_write_video struct ast_channel chan,
struct ast_frame frame
 

Parameters:
chan destination channel of the frame
frame frame that will be written This function writes the given frame to the indicated channel. It returns 1 on success, 0 if not implemented, and -1 on failure.

Definition at line 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 }

static void bridge_playfile struct ast_channel chan,
struct ast_channel peer,
char *  sound,
int  remain
[static]
 

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 }

static struct ast_channel* channel_find_locked const struct ast_channel prev,
const char *  name,
const int  namelen,
const char *  context,
const char *  exten
[static]
 

Definition at line 730 of file channel.c.

References ast_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 }

static void clone_variables struct ast_channel original,
struct ast_channel clone
[static]
 

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 }

static void copy_data_from_queue struct ast_channel_spy_queue queue,
short *  buf,
unsigned int  samples
[static]
 

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 }

static void detach_spies struct ast_channel chan  )  [static]
 

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 }

static int do_senddigit struct ast_channel chan,
char  digit
[static]
 

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 }

static void free_cid struct ast_callerid cid  )  [static]
 

Definition at line 863 of file channel.c.

References ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_rdnis, and free.

Referenced by ast_channel_free().

00864 {
00865    if (cid->cid_dnid)
00866       free(cid->cid_dnid);
00867    if (cid->cid_num)
00868       free(cid->cid_num);  
00869    if (cid->cid_name)
00870       free(cid->cid_name); 
00871    if (cid->cid_ani)
00872       free(cid->cid_ani);
00873    if (cid->cid_rdnis)
00874       free(cid->cid_rdnis);
00875 }

static void free_translation struct ast_channel clone  )  [static]
 

Definition at line 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 }

static int generator_force void *  data  )  [static]
 

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 }

static void queue_frame_to_spies struct ast_channel chan,
struct ast_frame f,
enum spy_direction  dir
[static]
 

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 }

static int set_format struct ast_channel chan,
int  fmt,
int *  rawformat,
int *  format,
struct ast_trans_pvt **  trans,
const int  direction
[static]
 

Definition at line 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 }

static int show_channeltypes int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 171 of file channel.c.

References ast_cli(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), backends, ast_channel_tech::description, ast_channel_tech::devicestate, FORMAT, ast_channel_tech::indicate, LOG_WARNING, chanlist::next, RESULT_SUCCESS, chanlist::tech, ast_channel_tech::transfer, and ast_channel_tech::type.

00172 {
00173 #define FORMAT  "%-10.10s  %-30.30s %-12.12s %-12.12s %-12.12s\n"
00174    struct chanlist *cl = backends;
00175    ast_cli(fd, FORMAT, "Type", "Description",       "Devicestate", "Indications", "Transfer");
00176    ast_cli(fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------");
00177    if (ast_mutex_lock(&chlock)) {
00178       ast_log(LOG_WARNING, "Unable to lock channel list\n");
00179       return -1;
00180    }
00181    while (cl) {
00182       ast_cli(fd, FORMAT, cl->tech->type, cl->tech->description, 
00183          (cl->tech->devicestate) ? "yes" : "no", 
00184          (cl->tech->indicate) ? "yes" : "no",
00185          (cl->tech->transfer) ? "yes" : "no");
00186       cl = cl->next;
00187    }
00188    ast_mutex_unlock(&chlock);
00189    return RESULT_SUCCESS;
00190 
00191 #undef FORMAT
00192 
00193 }

static void* silence_generator_alloc struct ast_channel chan,
void *  data
[static]
 

Definition at line 3957 of file channel.c.

03958 {
03959    /* just store the data pointer in the channel structure */
03960    return data;
03961 }

static int silence_generator_generate struct ast_channel chan,
void *  data,
int  len,
int  samples
[static]
 

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 }

static void silence_generator_release struct ast_channel chan,
void *  data
[static]
 

Definition at line 3963 of file channel.c.

03964 {
03965    /* nothing to do */
03966 }

static void* tonepair_alloc struct ast_channel chan,
void *  params
[static]
 

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 }

static int tonepair_generator struct ast_channel chan,
void *  data,
int  len,
int  samples
[static]
 

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 }

static void tonepair_release struct ast_channel chan,
void *  params
[static]
 

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 }


Variable Documentation

void(* ast_moh_cleanup_ptr)(struct ast_channel *) = NULL [static]
 

Definition at line 3740 of file channel.c.

Referenced by ast_install_music_functions(), ast_moh_cleanup(), and ast_uninstall_music_functions().

int(* ast_moh_start_ptr)(struct ast_channel *, char *) = NULL [static]
 

Definition at line 3738 of file channel.c.

Referenced by ast_install_music_functions(), ast_moh_start(), and ast_uninstall_music_functions().

void(* ast_moh_stop_ptr)(struct ast_channel *) = NULL [static]
 

Definition at line 3739 of file channel.c.

Referenced by ast_install_music_functions(), ast_moh_stop(), and ast_uninstall_music_functions().

struct chanlist* backends = NULL [static]
 

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().

const struct ast_cause causes[]
 

Referenced by ast_cause2str(), and dump_cause().

struct ast_channel* channels = NULL [static]
 

Definition at line 114 of file channel.c.

Referenced by add_channel(), ast_active_channels(), ast_begin_shutdown(), ast_channel_free(), channel_find_locked(), check_header(), check_mute(), find_channel(), getvol(), load_config(), and setvol().

struct ast_cli_entry cli_show_channeltypes [static]
 

Initial value:

 
   { { "show", "channeltypes", NULL }, show_channeltypes, "Show available channel types", show_channeltypes_usage }

Definition at line 199 of file channel.c.

Referenced by ast_channels_init().

unsigned long global_fin = 0
 

Definition at line 100 of file channel.c.

Referenced by handle_debugchan(), and handle_nodebugchan().

unsigned long global_fout = 0
 

Definition at line 100 of file channel.c.

Referenced by handle_debugchan(), and handle_nodebugchan().

const struct ast_channel_tech null_tech [static]
 

Initial value:

 {
   .type = "NULL",
   .description = "Null channel (should not see this)",
}

Definition at line 510 of file channel.c.

char show_channeltypes_usage[] [static]
 

Initial value:

 
"Usage: show channeltypes\n"
"       Shows available channel types registered in your Asterisk server.\n"

Definition at line 195 of file channel.c.

int shutting_down = 0 [static]
 

Definition at line 95 of file channel.c.

Referenced by ast_begin_shutdown(), ast_cancel_shutdown(), ast_channel_alloc(), and ast_shutting_down().

struct ast_generator silence_generator [static]
 

Initial value:

Definition at line 4003 of file channel.c.

Referenced by ast_channel_start_silence_generator().

struct ast_generator tonepair [static]
 

Initial value:

 {
   alloc: tonepair_alloc,
   release: tonepair_release,
   generate: tonepair_generator,
}

Definition at line 3657 of file channel.c.

Referenced by ast_tonepair_start().

int uniqueint = 0 [static]
 

Definition at line 98 of file channel.c.


Generated on Sat Mar 24 23:27:27 2007 for Asterisk - the Open Source PBX by  doxygen 1.4.6