Sat Sep 16 05:47:59 2006

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"

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.
void ast_channel_spy_free (struct ast_channel_spy *spy)
 Free a spy.
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)
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 spy_cleanup (struct ast_channel *chan)
static void spy_detach (struct ast_channel_spy *spy, struct ast_channel *chan)
static void * tonepair_alloc (struct ast_channel *chan, void *params)
static int tonepair_generator (struct ast_channel *chan, void *data, int len, int samples)
static void tonepair_release (struct ast_channel *chan, void *params)

Variables

static void(*) ast_moh_cleanup_ptr (struct ast_channel *) = NULL
static int(*) ast_moh_start_ptr (struct ast_channel *, char *) = NULL
static void(*) ast_moh_stop_ptr (struct ast_channel *) = NULL
static struct chanlistbackends = NULL
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 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 1175 of file channel.c.

Referenced by queue_frame_to_spies().


Enumeration Type Documentation

enum spy_direction

Enumerator:
SPY_READ 
SPY_WRITE 

Definition at line 1170 of file channel.c.

01170                    {
01171    SPY_READ,
01172    SPY_WRITE,
01173 };


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 2426 of file channel.c.

References ast_channel::_state, ast_call(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_setapp(), ast_cdr_start(), ast_cdr_update(), ast_channel_inherit_variables(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_FRAME_CONTROL, ast_frfree(), ast_hangup(), ast_log(), ast_read(), ast_request(), ast_set_callerid(), ast_set_variables(), AST_STATE_UP, ast_waitfor(), ast_channel::cdr, ast_channel::context, ast_channel::exten, ast_frame::frametype, ast_channel::hangupcause, LOG_NOTICE, LOG_WARNING, ast_channel::priority, and ast_frame::subclass.

Referenced by ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_request_and_dial(), and parkandannounce_exec().

02427 {
02428    int state = 0;
02429    int cause = 0;
02430    struct ast_channel *chan;
02431    struct ast_frame *f;
02432    int res = 0;
02433    
02434    chan = ast_request(type, format, data, &cause);
02435    if (chan) {
02436       if (oh) {
02437          if (oh->vars)  
02438             ast_set_variables(chan, oh->vars);
02439          if (oh->cid_num && *oh->cid_num && oh->cid_name && *oh->cid_name)
02440             ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
02441          if (oh->parent_channel)
02442             ast_channel_inherit_variables(oh->parent_channel, chan);
02443          if (oh->account)
02444             ast_cdr_setaccount(chan, oh->account); 
02445       }
02446       ast_set_callerid(chan, cid_num, cid_name, cid_num);
02447 
02448       if (!ast_call(chan, data, 0)) {
02449          res = 1; /* in case chan->_state is already AST_STATE_UP */
02450          while (timeout && (chan->_state != AST_STATE_UP)) {
02451             res = ast_waitfor(chan, timeout);
02452             if (res < 0) {
02453                /* Something not cool, or timed out */
02454                break;
02455             }
02456             /* If done, break out */
02457             if (!res)
02458                break;
02459             if (timeout > -1)
02460                timeout = res;
02461             f = ast_read(chan);
02462             if (!f) {
02463                state = AST_CONTROL_HANGUP;
02464                res = 0;
02465                break;
02466             }
02467             if (f->frametype == AST_FRAME_CONTROL) {
02468                if (f->subclass == AST_CONTROL_RINGING)
02469                   state = AST_CONTROL_RINGING;
02470                else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
02471                   state = f->subclass;
02472                   ast_frfree(f);
02473                   break;
02474                } else if (f->subclass == AST_CONTROL_ANSWER) {
02475                   state = f->subclass;
02476                   ast_frfree(f);
02477                   break;
02478                } else if (f->subclass == AST_CONTROL_PROGRESS) {
02479                   /* Ignore */
02480                } else if (f->subclass == -1) {
02481                   /* Ignore -- just stopping indications */
02482                } else {
02483                   ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
02484                }
02485             }
02486             ast_frfree(f);
02487          }
02488       } else
02489          ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
02490    } else {
02491       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
02492       switch(cause) {
02493       case AST_CAUSE_BUSY:
02494          state = AST_CONTROL_BUSY;
02495          break;
02496       case AST_CAUSE_CONGESTION:
02497          state = AST_CONTROL_CONGESTION;
02498          break;
02499       }
02500    }
02501    if (chan) {
02502       /* Final fixups */
02503       if (oh) {
02504          if (oh->context && *oh->context)
02505             ast_copy_string(chan->context, oh->context, sizeof(chan->context));
02506          if (oh->exten && *oh->exten)
02507             ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
02508          if (oh->priority) 
02509             chan->priority = oh->priority;
02510       }
02511       if (chan->_state == AST_STATE_UP) 
02512          state = AST_CONTROL_ANSWER;
02513    }
02514    if (outstate)
02515       *outstate = state;
02516    if (chan && res <= 0) {
02517       if (!chan->cdr) {
02518          chan->cdr = ast_cdr_alloc();
02519          if (chan->cdr)
02520             ast_cdr_init(chan->cdr, chan);
02521       }
02522       if (chan->cdr) {
02523          char tmp[256];
02524          snprintf(tmp, 256, "%s/%s", type, (char *)data);
02525          ast_cdr_setapp(chan->cdr,"Dial",tmp);
02526          ast_cdr_update(chan);
02527          ast_cdr_start(chan->cdr);
02528          ast_cdr_end(chan->cdr);
02529          /* If the cause wasn't handled properly */
02530          if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
02531             ast_cdr_failed(chan->cdr);
02532       } else 
02533          ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
02534       ast_hangup(chan);
02535       chan = NULL;
02536    }
02537    return chan;
02538 }

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

Activate a given generator

Definition at line 1460 of file channel.c.

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

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

01461 {
01462    int res = 0;
01463 
01464    ast_mutex_lock(&chan->lock);
01465 
01466    if (chan->generatordata) {
01467       if (chan->generator && chan->generator->release)
01468          chan->generator->release(chan, chan->generatordata);
01469       chan->generatordata = NULL;
01470    }
01471 
01472    ast_prod(chan);
01473    if (gen->alloc) {
01474       if (!(chan->generatordata = gen->alloc(chan, params)))
01475          res = -1;
01476    }
01477    
01478    if (!res) {
01479       ast_settimeout(chan, 160, generator_force, chan);
01480       chan->generator = gen;
01481    }
01482 
01483    ast_mutex_unlock(&chan->lock);
01484 
01485    return res;
01486 }

int ast_active_channels ( void   ) 

Returns number of active/allocated channels

Definition at line 250 of file channel.c.

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

Referenced by quit_handler().

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

int ast_answer ( struct ast_channel chan  ) 

Answer a ringing call.

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 1396 of file channel.c.

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

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

01397 {
01398    int res = 0;
01399    ast_mutex_lock(&chan->lock);
01400    /* Stop if we're a zombie or need a soft hangup */
01401    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
01402       ast_mutex_unlock(&chan->lock);
01403       return -1;
01404    }
01405    switch(chan->_state) {
01406    case AST_STATE_RINGING:
01407    case AST_STATE_RING:
01408       if (chan->tech->answer)
01409          res = chan->tech->answer(chan);
01410       ast_setstate(chan, AST_STATE_UP);
01411       if (chan->cdr)
01412          ast_cdr_answer(chan->cdr);
01413       ast_mutex_unlock(&chan->lock);
01414       return res;
01415       break;
01416    case AST_STATE_UP:
01417       if (chan->cdr)
01418          ast_cdr_answer(chan->cdr);
01419       break;
01420    }
01421    ast_mutex_unlock(&chan->lock);
01422    return 0;
01423 }

void ast_begin_shutdown ( int  hangup  ) 

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

Definition at line 234 of file channel.c.

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

Referenced by quit_handler().

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

int ast_best_codec ( int  fmts  ) 

Pick the best codec

Definition at line 468 of file channel.c.

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

Referenced by __login_exec(), __oh323_new(), agent_call(), ast_codec_choose(), ast_iax2_new(), builtin_atxfer(), echo_exec(), iax2_request(), local_new(), mgcp_new(), sip_new(), skinny_new(), and socket_read().

00469 {
00470    /* This just our opinion, expressed in code.  We are asked to choose
00471       the best codec to use, given no information */
00472    int x;
00473    static int prefs[] = 
00474    {
00475       /* Okay, ulaw is used by all telephony equipment, so start with it */
00476       AST_FORMAT_ULAW,
00477       /* Unless of course, you're a silly European, so then prefer ALAW */
00478       AST_FORMAT_ALAW,
00479       /* Okay, well, signed linear is easy to translate into other stuff */
00480       AST_FORMAT_SLINEAR,
00481       /* G.726 is standard ADPCM */
00482       AST_FORMAT_G726,
00483       /* ADPCM has great sound quality and is still pretty easy to translate */
00484       AST_FORMAT_ADPCM,
00485       /* Okay, we're down to vocoders now, so pick GSM because it's small and easier to
00486          translate and sounds pretty good */
00487       AST_FORMAT_GSM,
00488       /* iLBC is not too bad */
00489       AST_FORMAT_ILBC,
00490       /* Speex is free, but computationally more expensive than GSM */
00491       AST_FORMAT_SPEEX,
00492       /* Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough
00493          to use it */
00494       AST_FORMAT_LPC10,
00495       /* G.729a is faster than 723 and slightly less expensive */
00496       AST_FORMAT_G729A,
00497       /* Down to G.723.1 which is proprietary but at least designed for voice */
00498       AST_FORMAT_G723_1,
00499    };
00500    
00501    
00502    /* Find the first prefered codec in the format given */
00503    for (x=0; x < (sizeof(prefs) / sizeof(prefs[0]) ); x++)
00504       if (fmts & prefs[x])
00505          return prefs[x];
00506    ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts);
00507    return 0;
00508 }

struct ast_channel* ast_bridged_channel ( struct ast_channel chan  ) 

Find bridged channel.

Parameters:
chan Current channel

Definition at line 3271 of file channel.c.

References ast_channel::_bridge, ast_channel_tech::bridged_channel, and ast_channel::tech.

Referenced by __zt_exception(), agents_show(), ast_channel_masquerade(), attempt_transfer(), chanspy_exec(), console_transfer(), get_refer_info(), handle_chanlist(), handle_hd_hf(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_refer(), handle_showchan(), mgcp_hangup(), mgcp_ss(), mixmonitor_thread(), process_sdp(), skinny_ss(), socket_read(), ss_thread(), start_spying(), startmon(), zt_handle_event(), and zt_hangup().

03272 {
03273    struct ast_channel *bridged;
03274    bridged = chan->_bridge;
03275    if (bridged && bridged->tech->bridged_channel) 
03276       bridged = bridged->tech->bridged_channel(chan, bridged);
03277    return bridged;
03278 }

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

Make a call.

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 2604 of file channel.c.

References ast_check_hangup(), AST_FLAG_ZOMBIE, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_channel_tech::call, ast_channel::lock, and ast_channel::tech.

Referenced by __ast_request_and_dial(), agent_call(), ast_feature_request_and_dial(), attempt_reconnect(), dial_exec_full(), features_call(), function_ilink(), ring_entry(), rpt(), rpt_exec(), and wait_for_answer().

02605 {
02606    /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 
02607       If the remote end does not answer within the timeout, then do NOT hang up, but 
02608       return anyway.  */
02609    int res = -1;
02610    /* Stop if we're a zombie or need a soft hangup */
02611    ast_mutex_lock(&chan->lock);
02612    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) 
02613       if (chan->tech->call)
02614          res = chan->tech->call(chan, addr, timeout);
02615    ast_mutex_unlock(&chan->lock);
02616    return res;
02617 }

void ast_cancel_shutdown ( void   ) 

Cancels an existing shutdown and returns to normal operation

Definition at line 265 of file channel.c.

References shutting_down.

Referenced by handle_abort_halt().

00266 {
00267    shutting_down = 0;
00268 }

const char* ast_cause2str ( int  state  ) 

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(), dial_exec_full(), and transmit_request_with_auth().

00408 {
00409    int x;
00410 
00411    for (x=0; x < sizeof(causes) / sizeof(causes[0]); x++) 
00412       if (causes[x].cause == cause)
00413          return causes[x].desc;
00414 
00415    return "Unknown";
00416 }

void ast_change_name ( struct ast_channel chan,
char *  newname 
)

Change channel name.

Definition at line 2857 of file channel.c.

References EVENT_FLAG_CALL, manager_event(), ast_channel::name, and ast_channel::uniqueid.

02858 {
02859    char tmp[256];
02860    ast_copy_string(tmp, chan->name, sizeof(tmp));
02861    ast_copy_string(chan->name, newname, sizeof(chan->name));
02862    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid);
02863 }

struct ast_channel* ast_channel_alloc ( int  needalertpipe  ) 

Create a channel structure.

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 3432 of file channel.c.

References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_RETRY, ast_channel_make_compatible(), ast_check_hangup(), ast_check_hangup_locked(), ast_clear_flag, AST_FEATURE_PLAY_WARNING, AST_FEATURE_REDIRECT, AST_FLAG_NBRIDGE, AST_FLAG_ZOMBIE, ast_generic_bridge(), ast_log(), ast_set_flag, AST_SOFTHANGUP_UNBRIDGE, ast_test_flag, ast_tvadd(), ast_tvsub(), ast_verbose(), ast_channel_tech::bridge, bridge_playfile(), ast_channel::cid, ast_callerid::cid_num, config, EVENT_FLAG_CALL, ast_channel::generator, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, option_verbose, ast_channel::readformat, ast_channel::spies, ast_channel::tech, ast_channel::uniqueid, VERBOSE_PREFIX_3, and ast_channel::writeformat.

Referenced by ast_bridge_call().

03434 {
03435    struct ast_channel *who = NULL;
03436    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
03437    int nativefailed=0;
03438    int firstpass;
03439    int o0nativeformats;
03440    int o1nativeformats;
03441    long time_left_ms=0;
03442    struct timeval nexteventts = { 0, };
03443    char caller_warning = 0;
03444    char callee_warning = 0;
03445 
03446    if (c0->_bridge) {
03447       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
03448          c0->name, c0->_bridge->name);
03449       return -1;
03450    }
03451    if (c1->_bridge) {
03452       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
03453          c1->name, c1->_bridge->name);
03454       return -1;
03455    }
03456    
03457    /* Stop if we're a zombie or need a soft hangup */
03458    if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
03459        ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 
03460       return -1;
03461 
03462    *fo = NULL;
03463    firstpass = config->firstpass;
03464    config->firstpass = 0;
03465 
03466    if (ast_tvzero(config->start_time))
03467       config->start_time = ast_tvnow();
03468    time_left_ms = config->timelimit;
03469 
03470    caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
03471    callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
03472 
03473    if (config->start_sound && firstpass) {
03474       if (caller_warning)
03475          bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000);
03476       if (callee_warning)
03477          bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000);
03478    }
03479 
03480    /* Keep track of bridge */
03481    c0->_bridge = c1;
03482    c1->_bridge = c0;
03483    
03484    manager_event(EVENT_FLAG_CALL, "Link", 
03485             "Channel1: %s\r\n"
03486             "Channel2: %s\r\n"
03487             "Uniqueid1: %s\r\n"
03488             "Uniqueid2: %s\r\n"
03489             "CallerID1: %s\r\n"
03490             "CallerID2: %s\r\n",
03491             c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
03492                                                                         
03493    o0nativeformats = c0->nativeformats;
03494    o1nativeformats = c1->nativeformats;
03495 
03496    if (config->feature_timer) {
03497       nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000));
03498    } else if (config->timelimit) {
03499       nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
03500       if (caller_warning || callee_warning)
03501          nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000));
03502    }
03503 
03504    for (/* ever */;;) {
03505       struct timeval now = { 0, };
03506       int to;
03507 
03508       to = -1;
03509 
03510       if (!ast_tvzero(nexteventts)) {
03511          now = ast_tvnow();
03512          to = ast_tvdiff_ms(nexteventts, now);
03513          if (to < 0)
03514             to = 0;
03515       }
03516 
03517       if (config->timelimit) {
03518          time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
03519          if (time_left_ms < to)
03520             to = time_left_ms;
03521 
03522          if (time_left_ms <= 0) {
03523             if (caller_warning && config->end_sound)
03524                bridge_playfile(c0, c1, config->end_sound, 0);
03525             if (callee_warning && config->end_sound)
03526                bridge_playfile(c1, c0, config->end_sound, 0);
03527             *fo = NULL;
03528             if (who) 
03529                *rc = who;
03530             res = 0;
03531             break;
03532          }
03533          
03534          if (!to) {
03535             if (time_left_ms >= 5000) {
03536                /* force the time left to round up if appropriate */
03537                if (caller_warning && config->warning_sound && config->play_warning)
03538                   bridge_playfile(c0, c1, config->warning_sound,
03539                         (time_left_ms + 500) / 1000);
03540                if (callee_warning && config->warning_sound && config->play_warning)
03541                   bridge_playfile(c1, c0, config->warning_sound,
03542                         (time_left_ms + 500) / 1000);
03543             }
03544             if (config->warning_freq) {
03545                nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000));
03546             } else
03547                nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
03548          }
03549       }
03550 
03551       if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
03552          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03553             c0->_softhangup = 0;
03554          if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03555             c1->_softhangup = 0;
03556          c0->_bridge = c1;
03557          c1->_bridge = c0;
03558          ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n");
03559          continue;
03560       }
03561       
03562       /* Stop if we're a zombie or need a soft hangup */
03563       if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
03564           ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
03565          *fo = NULL;
03566          if (who)
03567             *rc = who;
03568          res = 0;
03569          ast_log(LOG_DEBUG, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",
03570             c0->name, c1->name,
03571             ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
03572             ast_check_hangup(c0) ? "Yes" : "No",
03573             ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
03574             ast_check_hangup(c1) ? "Yes" : "No");
03575          break;
03576       }
03577 
03578       if (c0->tech->bridge &&
03579           (config->timelimit == 0) &&
03580           (c0->tech->bridge == c1->tech->bridge) &&
03581           !nativefailed && !c0->monitor && !c1->monitor &&
03582           !c0->spies && !c1->spies && !ast_test_flag(&(config->features_callee),AST_FEATURE_REDIRECT) &&
03583           !ast_test_flag(&(config->features_caller),AST_FEATURE_REDIRECT) ) {
03584          /* Looks like they share a bridge method and nothing else is in the way */
03585          if (option_verbose > 2) 
03586             ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name);
03587          ast_set_flag(c0, AST_FLAG_NBRIDGE);
03588          ast_set_flag(c1, AST_FLAG_NBRIDGE);
03589          if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) {
03590             manager_event(EVENT_FLAG_CALL, "Unlink", 
03591                      "Channel1: %s\r\n"
03592                      "Channel2: %s\r\n"
03593                      "Uniqueid1: %s\r\n"
03594                      "Uniqueid2: %s\r\n"
03595                      "CallerID1: %s\r\n"
03596                      "CallerID2: %s\r\n",
03597                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
03598             ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
03599 
03600             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
03601             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
03602 
03603             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03604                continue;
03605 
03606             c0->_bridge = NULL;
03607             c1->_bridge = NULL;
03608 
03609             return res;
03610          } else {
03611             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
03612             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
03613          }
03614          switch (res) {
03615          case AST_BRIDGE_RETRY:
03616             continue;
03617          default:
03618             ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name);
03619             /* fallthrough */
03620          case AST_BRIDGE_FAILED_NOWARN:
03621             nativefailed++;
03622             break;
03623          }
03624       }
03625    
03626       if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
03627           (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
03628           !(c0->generator || c1->generator)) {
03629          if (ast_channel_make_compatible(c0, c1)) {
03630             ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
03631                                 manager_event(EVENT_FLAG_CALL, "Unlink",
03632                      "Channel1: %s\r\n"
03633                      "Channel2: %s\r\n"
03634                      "Uniqueid1: %s\r\n"
03635                      "Uniqueid2: %s\r\n"
03636                      "CallerID1: %s\r\n"
03637                      "CallerID2: %s\r\n",
03638                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
03639             return AST_BRIDGE_FAILED;
03640          }
03641          o0nativeformats = c0->nativeformats;
03642          o1nativeformats = c1->nativeformats;
03643       }
03644       res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts);
03645       if (res != AST_BRIDGE_RETRY)
03646          break;
03647    }
03648 
03649    c0->_bridge = NULL;
03650    c1->_bridge = NULL;
03651 
03652    manager_event(EVENT_FLAG_CALL, "Unlink",
03653             "Channel1: %s\r\n"
03654             "Channel2: %s\r\n"
03655             "Uniqueid1: %s\r\n"
03656             "Uniqueid2: %s\r\n"
03657             "CallerID1: %s\r\n"
03658             "CallerID2: %s\r\n",
03659             c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
03660    ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
03661 
03662    return res;
03663 }

int ast_channel_cmpwhentohangup ( struct ast_channel chan,
time_t  offset 
)

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

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 __adsi_transmit_messages(), and find_cache().

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

void ast_channel_free ( struct ast_channel chan  ) 

Free a channel structure.

Definition at line 878 of file channel.c.

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

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

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

void ast_channel_inherit_variables ( const struct ast_channel parent,
struct ast_channel child 
)

Inherits channel variable from parent to child channel.

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 2865 of file channel.c.

References AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_var_assign(), ast_var_full_name(), ast_var_name(), ast_var_value(), LOG_DEBUG, option_debug, and ast_channel::varshead.

Referenced by __ast_request_and_dial(), agent_call(), ast_feature_request_and_dial(), dial_exec_full(), ring_entry(), and wait_for_answer().

02866 {
02867    struct ast_var_t *current, *newvar;
02868    char *varname;
02869 
02870    AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
02871       int vartype = 0;
02872 
02873       varname = ast_var_full_name(current);
02874       if (!varname)
02875          continue;
02876 
02877       if (varname[0] == '_') {
02878          vartype = 1;
02879          if (varname[1] == '_')
02880             vartype = 2;
02881       }
02882 
02883       switch (vartype) {
02884       case 1:
02885          newvar = ast_var_assign(&varname[1], ast_var_value(current));
02886          if (newvar) {
02887             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
02888             if (option_debug)
02889                ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
02890          }
02891          break;
02892       case 2:
02893          newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current));
02894          if (newvar) {
02895             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
02896             if (option_debug)
02897                ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
02898          }
02899          break;
02900       default:
02901          if (option_debug)
02902             ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current));
02903          break;
02904       }
02905    }
02906 }

int ast_channel_make_compatible ( struct ast_channel c0,
struct ast_channel c1 
)

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 2743 of file channel.c.

References AST_FORMAT_SLINEAR, ast_log(), ast_set_read_format(), ast_set_write_format(), ast_translator_best_choice(), LOG_WARNING, ast_channel::name, ast_channel::nativeformats, and option_transcode_slin.

Referenced by ast_channel_bridge(), builtin_atxfer(), dial_exec_full(), park_exec(), try_calling(), and wait_for_answer().

02744 {
02745    int src;
02746    int dst;
02747 
02748    /* Set up translation from the chan to the peer */
02749    src = chan->nativeformats;
02750    dst = peer->nativeformats;
02751    if (ast_translator_best_choice(&dst, &src) < 0) {
02752       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst);
02753       return -1;
02754    }
02755 
02756    /* if the best path is not 'pass through', then
02757       transcoding is needed; if desired, force transcode path
02758       to use SLINEAR between channels */
02759    if ((src != dst) && option_transcode_slin)
02760       dst = AST_FORMAT_SLINEAR;
02761    if (ast_set_read_format(chan, dst) < 0) {
02762       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst);
02763       return -1;
02764    }
02765    if (ast_set_write_format(peer, dst) < 0) {
02766       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, dst);
02767       return -1;
02768    }
02769 
02770    /* Set up translation from the peer to the chan */
02771    src = peer->nativeformats;
02772    dst = chan->nativeformats;
02773    if (ast_translator_best_choice(&dst, &src) < 0) {
02774       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst);
02775       return -1;
02776    }
02777    /* if the best path is not 'pass through', then
02778       transcoding is needed; if desired, force transcode path
02779       to use SLINEAR between channels */
02780    if ((src != dst) && option_transcode_slin)
02781       dst = AST_FORMAT_SLINEAR;
02782    if (ast_set_read_format(peer, dst) < 0) {
02783       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst);
02784       return -1;
02785    }
02786    if (ast_set_write_format(chan, dst) < 0) {
02787       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, dst);
02788       return -1;
02789    }
02790    return 0;
02791 }

int ast_channel_masquerade ( struct ast_channel original,
struct ast_channel clone 
)

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 2793 of file channel.c.

References ast_channel::_bridge, ast_bridged_channel(), AST_FRAME_NULL, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::masq, ast_channel::masqr, and ast_channel::name.

Referenced by ast_async_goto(), ast_masq_park_call(), ast_pickup_call(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), check_goto_on_transfer(), iax_park(), misdn_transfer_bc(), pickup_exec(), and sip_park().

02794 {
02795    struct ast_frame null = { AST_FRAME_NULL, };
02796    int res = -1;
02797    struct ast_channel *final_orig = original, *final_clone = clone;
02798 
02799    ast_mutex_lock(&original->lock);
02800    while(ast_mutex_trylock(&clone->lock)) {
02801       ast_mutex_unlock(&original->lock);
02802       usleep(1);
02803       ast_mutex_lock(&original->lock);
02804    }
02805 
02806    /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent)
02807       and if so, we don't really want to masquerade it, but its proxy */
02808    if (original->_bridge && (original->_bridge != ast_bridged_channel(original)))
02809       final_orig = original->_bridge;
02810 
02811    if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone)))
02812       final_clone = clone->_bridge;
02813 
02814    if ((final_orig != original) || (final_clone != clone)) {
02815       ast_mutex_lock(&final_orig->lock);
02816       while(ast_mutex_trylock(&final_clone->lock)) {
02817          ast_mutex_unlock(&final_orig->lock);
02818          usleep(1);
02819          ast_mutex_lock(&final_orig->lock);
02820       }
02821       ast_mutex_unlock(&clone->lock);
02822       ast_mutex_unlock(&original->lock);
02823       original = final_orig;
02824       clone = final_clone;
02825    }
02826 
02827    if (original == clone) {
02828       ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
02829       ast_mutex_unlock(&clone->lock);
02830       ast_mutex_unlock(&original->lock);
02831       return -1;
02832    }
02833 
02834    ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n",
02835       clone->name, original->name);
02836    if (original->masq) {
02837       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
02838          original->masq->name, original->name);
02839    } else if (clone->masqr) {
02840       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
02841          clone->name, clone->masqr->name);
02842    } else {
02843       original->masq = clone;
02844       clone->masqr = original;
02845       ast_queue_frame(original, &null);
02846       ast_queue_frame(clone, &null);
02847       ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name);
02848       res = 0;
02849    }
02850 
02851    ast_mutex_unlock(&clone->lock);
02852    ast_mutex_unlock(&original->lock);
02853 
02854    return res;
02855 }

int ast_channel_register ( const struct ast_channel_tech tech  ) 

Register a channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports.

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 2729 of file channel.c.

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

Referenced by agent_sendhtml(), and wait_for_answer().

02730 {
02731    if (chan->tech->send_html)
02732       return chan->tech->send_html(chan, subclass, data, datalen);
02733    return -1;
02734 }

int ast_channel_sendurl ( struct ast_channel channel,
const char *  url 
)

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

Definition at line 2736 of file channel.c.

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

Referenced by dial_exec_full(), sendurl_exec(), and try_calling().

02737 {
02738    if (chan->tech->send_html)
02739       return chan->tech->send_html(chan, AST_HTML_URL, url, strlen(url) + 1);
02740    return -1;
02741 }

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

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 3666 of file channel.c.

References ast_log(), LOG_ERROR, ast_channel_tech::setoption, and ast_channel::tech.

Referenced by ast_bridge_call(), chanspy_exec(), conf_run(), handle_tddmode(), play_record_review(), reset_volumes(), rpt(), set_listen_volume(), set_talk_volume(), set_volume(), try_calling(), vm_forwardoptions(), and zt_hangup().

03667 {
03668    int res;
03669 
03670    if (chan->tech->setoption) {
03671       res = chan->tech->setoption(chan, option, data, datalen);
03672       if (res < 0)
03673          return res;
03674    } else {
03675       errno = ENOSYS;
03676       return -1;
03677    }
03678    if (block) {
03679       /* XXX Implement blocking -- just wait for our option frame reply, discarding
03680          intermediate packets. XXX */
03681       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
03682       return -1;
03683    }
03684    return 0;
03685 }

void ast_channel_setwhentohangup ( struct ast_channel chan,
time_t  offset 
)

Set when to hang a channel up.

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, ast_channel_spy::chan, CHANSPY_FORMAT_AUDIO, CHANSPY_MIXAUDIO, CHANSPY_READ_VOLADJUST, CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_NONE, CHANSPY_TRIGGER_READ, CHANSPY_TRIGGER_WRITE, CHANSPY_WRITE_VOLADJUST, ast_channel_spy_queue::format, list, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_channel_spy::read_queue, ast_channel::spies, ast_channel_spy::trigger, ast_channel_spy::type, and ast_channel_spy::write_queue.

Referenced by start_spying(), and startmon().

00966 {
00967    /* Link the owner channel to the spy */
00968    spy->chan = chan;
00969 
00970    if (!ast_test_flag(spy, CHANSPY_FORMAT_AUDIO)) {
00971       ast_log(LOG_WARNING, "Could not add channel spy '%s' to channel '%s', only audio format spies are supported.\n",
00972          spy->type, chan->name);
00973       return -1;
00974    }
00975 
00976    if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST) && (spy->read_queue.format != AST_FORMAT_SLINEAR)) {
00977       ast_log(LOG_WARNING, "Cannot provide volume adjustment on '%s' format spies\n",
00978          ast_getformatname(spy->read_queue.format));
00979       return -1;
00980    }
00981 
00982    if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST) && (spy->write_queue.format != AST_FORMAT_SLINEAR)) {
00983       ast_log(LOG_WARNING, "Cannot provide volume adjustment on '%s' format spies\n",
00984          ast_getformatname(spy->write_queue.format));
00985       return -1;
00986    }
00987 
00988    if (ast_test_flag(spy, CHANSPY_MIXAUDIO) &&
00989        ((spy->read_queue.format != AST_FORMAT_SLINEAR) ||
00990         (spy->write_queue.format != AST_FORMAT_SLINEAR))) {
00991       ast_log(LOG_WARNING, "Cannot provide audio mixing on '%s'-'%s' format spies\n",
00992          ast_getformatname(spy->read_queue.format), ast_getformatname(spy->write_queue.format));
00993       return -1;
00994    }
00995 
00996    if (!chan->spies) {
00997       if (!(chan->spies = calloc(1, sizeof(*chan->spies)))) {
00998          ast_log(LOG_WARNING, "Memory allocation failure\n");
00999          return -1;
01000       }
01001 
01002       AST_LIST_HEAD_INIT_NOLOCK(&chan->spies->list);
01003       AST_LIST_INSERT_HEAD(&chan->spies->list, spy, list);
01004    } else {
01005       AST_LIST_INSERT_TAIL(&chan->spies->list, spy, list);
01006    }
01007 
01008    if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) {
01009       ast_cond_init(&spy->trigger, NULL);
01010       ast_set_flag(spy, CHANSPY_TRIGGER_READ);
01011       ast_clear_flag(spy, CHANSPY_TRIGGER_WRITE);
01012    }
01013 
01014    ast_log(LOG_DEBUG, "Spy %s added to channel %s\n",
01015       spy->type, chan->name);
01016 
01017    return 0;
01018 }

void ast_channel_spy_free ( struct ast_channel_spy spy  ) 

Free a spy.

Parameters:
spy The spy to free
Returns:
nothing
Note: This function MUST NOT be called with the spy locked.

Definition at line 1098 of file channel.c.

References ast_cond_destroy(), ast_frfree(), ast_mutex_destroy(), ast_test_flag, CHANSPY_DONE, CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_NONE, ast_channel_spy_queue::head, ast_channel_spy::lock, ast_frame::next, ast_channel_spy::read_queue, ast_channel_spy::status, ast_channel_spy::trigger, and ast_channel_spy::write_queue.

Referenced by channel_spy(), and mixmonitor_thread().

01099 {
01100    struct ast_frame *f = NULL;
01101 
01102    if (spy->status == CHANSPY_DONE)
01103       return;
01104 
01105    /* Switch status to done in case we get called twice */
01106    spy->status = CHANSPY_DONE;
01107 
01108    /* Drop any frames in the queue */
01109    for (f = spy->write_queue.head; f; f = spy->write_queue.head) {
01110       spy->write_queue.head = f->next;
01111       ast_frfree(f);
01112    }
01113    for (f = spy->read_queue.head; f; f= spy->read_queue.head) {
01114       spy->read_queue.head = f->next;
01115       ast_frfree(f);
01116    }
01117 
01118    /* Destroy the condition if in use */
01119    if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
01120       ast_cond_destroy(&spy->trigger);
01121 
01122    /* Destroy our mutex since it is no longer in use */
01123    ast_mutex_destroy(&spy->lock);
01124 
01125    return;
01126 }

struct ast_frame* ast_channel_spy_read_frame ( struct ast_channel_spy spy,
unsigned int  samples 
)

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

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 3975 of file channel.c.

References ast_clear_flag, ast_codec_get_len(), ast_frame_adjust_volume(), ast_frame_slinear_sum(), AST_FRAME_VOICE, ast_frdup(), ast_frfree(), ast_test_flag, CHANSPY_MIXAUDIO, CHANSPY_READ_VOLADJUST, CHANSPY_TRIGGER_FLUSH, CHANSPY_WRITE_VOLADJUST, copy_data_from_queue(), ast_channel_spy_queue::format, ast_frame::frametype, ast_channel_spy_queue::head, ast_frame::next, ast_channel_spy::read_queue, ast_channel_spy::read_vol_adjustment, result, ast_channel_spy_queue::samples, ast_frame::samples, ast_channel_spy::write_queue, and ast_channel_spy::write_vol_adjustment.

Referenced by mixmonitor_thread(), and spy_generate().

03976 {
03977    struct ast_frame *result;
03978    /* buffers are allocated to hold SLINEAR, which is the largest format */
03979         short read_buf[samples];
03980         short write_buf[samples];
03981    struct ast_frame *read_frame;
03982    struct ast_frame *write_frame;
03983    int need_dup;
03984    struct ast_frame stack_read_frame = { .frametype = AST_FRAME_VOICE,
03985                      .subclass = spy->read_queue.format,
03986                      .data = read_buf,
03987                      .samples = samples,
03988                      .datalen = ast_codec_get_len(spy->read_queue.format, samples),
03989    };
03990    struct ast_frame stack_write_frame = { .frametype = AST_FRAME_VOICE,
03991                       .subclass = spy->write_queue.format,
03992                       .data = write_buf,
03993                       .samples = samples,
03994                       .datalen = ast_codec_get_len(spy->write_queue.format, samples),
03995    };
03996 
03997    /* if a flush has been requested, dump everything in whichever queue is larger */
03998    if (ast_test_flag(spy, CHANSPY_TRIGGER_FLUSH)) {
03999       if (spy->read_queue.samples > spy->write_queue.samples) {
04000          if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST)) {
04001             for (result = spy->read_queue.head; result; result = result->next)
04002                ast_frame_adjust_volume(result, spy->read_vol_adjustment);
04003          }
04004          result = spy->read_queue.head;
04005          spy->read_queue.head = NULL;
04006          spy->read_queue.samples = 0;
04007          ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH);
04008          return result;
04009       } else {
04010          if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST)) {
04011             for (result = spy->write_queue.head; result; result = result->next)
04012                ast_frame_adjust_volume(result, spy->write_vol_adjustment);
04013          }
04014          result = spy->write_queue.head;
04015          spy->write_queue.head = NULL;
04016          spy->write_queue.samples = 0;
04017          ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH);
04018          return result;
04019       }
04020    }
04021 
04022    if ((spy->read_queue.samples < samples) || (spy->write_queue.samples < samples))
04023       return NULL;
04024 
04025    /* short-circuit if both head frames have exactly what we want */
04026    if ((spy->read_queue.head->samples == samples) &&
04027        (spy->write_queue.head->samples == samples)) {
04028       read_frame = spy->read_queue.head;
04029       spy->read_queue.head = read_frame->next;
04030       read_frame->next = NULL;
04031 
04032       write_frame = spy->write_queue.head;
04033       spy->write_queue.head = write_frame->next;
04034       write_frame->next = NULL;
04035 
04036       spy->read_queue.samples -= samples;
04037       spy->write_queue.samples -= samples;
04038 
04039       need_dup = 0;
04040    } else {
04041       copy_data_from_queue(&spy->read_queue, read_buf, samples);
04042       copy_data_from_queue(&spy->write_queue, write_buf, samples);
04043 
04044       read_frame = &stack_read_frame;
04045       write_frame = &stack_write_frame;
04046       need_dup = 1;
04047    }
04048    
04049    if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST))
04050       ast_frame_adjust_volume(read_frame, spy->read_vol_adjustment);
04051 
04052    if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST))
04053       ast_frame_adjust_volume(write_frame, spy->write_vol_adjustment);
04054 
04055    if (ast_test_flag(spy, CHANSPY_MIXAUDIO)) {
04056       ast_frame_slinear_sum(read_frame, write_frame);
04057 
04058       if (need_dup)
04059          result = ast_frdup(read_frame);
04060       else {
04061          result = read_frame;
04062          ast_frfree(write_frame);
04063       }
04064    } else {
04065       if (need_dup) {
04066          result = ast_frdup(read_frame);
04067          result->next = ast_frdup(write_frame);
04068       } else {
04069          result = read_frame;
04070          result->next = write_frame;
04071       }
04072    }
04073 
04074    return result;
04075 }

void ast_channel_spy_remove ( struct ast_channel chan,
struct ast_channel_spy spy 
)

Remove a spy from a channel.

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 1087 of file channel.c.

References AST_LIST_REMOVE, list, ast_channel::spies, spy_cleanup(), and spy_detach().

Referenced by channel_spy().

01088 {
01089    if (!chan->spies)
01090       return;
01091 
01092    AST_LIST_REMOVE(&chan->spies->list, spy, list);
01093 
01094    spy_detach(spy, chan);
01095    spy_cleanup(chan);
01096 }

void ast_channel_spy_stop_by_type ( struct ast_channel chan,
const char *  type 
)

Find all spies of a particular type on a channel and stop them.

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 1055 of file channel.c.

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock(), ast_mutex_unlock(), ast_channel_spy::chan, CHANSPY_RUNNING, list, ast_channel_spy::lock, ast_channel::spies, spy_cleanup(), spy_detach(), ast_channel_spy::status, and ast_channel_spy::type.

Referenced by mixmonitor_cli().

01056 {
01057    struct ast_channel_spy *spy = NULL;
01058    
01059    if (!chan->spies)
01060       return;
01061 
01062    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list) {
01063       ast_mutex_lock(&spy->lock);
01064       if ((spy->type == type) && (spy->status == CHANSPY_RUNNING)) {
01065          ast_mutex_unlock(&spy->lock);
01066          AST_LIST_REMOVE_CURRENT(&chan->spies->list, list);
01067          spy_detach(spy, chan);
01068       } else
01069          ast_mutex_unlock(&spy->lock);
01070    }
01071    AST_LIST_TRAVERSE_SAFE_END
01072    spy_cleanup(chan);
01073 }

void ast_channel_spy_trigger_wait ( struct ast_channel_spy spy  ) 

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

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 1075 of file channel.c.

References ast_cond_timedwait(), ast_tvadd(), ast_channel_spy::lock, and ast_channel_spy::trigger.

Referenced by mixmonitor_thread().

01076 {
01077    struct timeval tv;
01078    struct timespec ts;
01079 
01080    tv = ast_tvadd(ast_tvnow(), ast_samp2tv(50000, 1000));
01081    ts.tv_sec = tv.tv_sec;
01082    ts.tv_nsec = tv.tv_usec * 1000;
01083 
01084    ast_cond_timedwait(&spy->trigger, &spy->lock, &ts);
01085 }

struct ast_silence_generator* ast_channel_start_silence_generator ( struct ast_channel chan  ) 

Starts a silence generator on the given channel.

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 4133 of file channel.c.

References ast_activate_generator(), AST_FORMAT_SLINEAR, ast_log(), ast_set_write_format(), calloc, free, LOG_DEBUG, LOG_ERROR, LOG_WARNING, ast_channel::name, option_debug, silence_generator, and ast_channel::writeformat.

Referenced by ast_play_and_record_full().

04134 {
04135    struct ast_silence_generator *state;
04136 
04137    if (!(state = calloc(1, sizeof(*state)))) {
04138       ast_log(LOG_WARNING, "Could not allocate state structure\n");
04139       return NULL;
04140    }
04141 
04142    state->old_write_format = chan->writeformat;
04143 
04144    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
04145       ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
04146       free(state);
04147       return NULL;
04148    }
04149 
04150    ast_activate_generator(chan, &silence_generator, state);
04151 
04152    if (option_debug)
04153       ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name);
04154 
04155    return state;
04156 }

void ast_channel_stop_silence_generator ( struct ast_channel chan,
struct ast_silence_generator state 
)

Stops a previously-started silence generator on the given channel.

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 4158 of file channel.c.

References ast_deactivate_generator(), ast_log(), ast_set_write_format(), free, LOG_DEBUG, LOG_ERROR, ast_channel::name, ast_silence_generator::old_write_format, and option_debug.

Referenced by ast_play_and_record_full().

04159 {
04160    if (!state)
04161       return;
04162 
04163    ast_deactivate_generator(chan);
04164 
04165    if (option_debug)
04166       ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name);
04167 
04168    if (ast_set_write_format(chan, state->old_write_format) < 0)
04169       ast_log(LOG_ERROR, "Could not return write format to its original state\n");
04170 
04171    free(state);
04172 }

int ast_channel_supports_html ( struct ast_channel channel  ) 

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

Definition at line 2722 of file channel.c.

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

Referenced by dial_exec_full(), sendurl_exec(), and try_calling().

02723 {
02724    if (chan->tech->send_html)
02725       return 1;
02726    return 0;
02727 }

void ast_channel_undefer_dtmf ( struct ast_channel chan  ) 

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

Definition at line 702 of file channel.c.

References ast_clear_flag, and AST_FLAG_DEFER_DTMF.

Referenced by __adsi_transmit_messages(), find_cache(), and rpt_call().

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

void ast_channel_unregister ( const struct ast_channel_tech tech  ) 

Unregister a channel technology.

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 3905 of file channel.c.

References ast_cli_register(), and cli_show_channeltypes.

Referenced by main().

03906 {
03907    ast_cli_register(&cli_show_channeltypes);
03908 }

int ast_check_hangup ( struct ast_channel chan  ) 

Check to see if a channel is needing hang up.

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_channel_bridge(), ast_check_hangup_locked(), ast_feature_request_and_dial(), ast_indicate(), ast_read(), ast_readstring(), ast_readstring_full(), ast_recvtext(), ast_sendtext(), ast_transfer(), ast_waitfordigit(), ast_waitfordigit_full(), ast_write(), builtin_atxfer(), channel_spy(), chanspy_exec(), handle_sendimage(), rpt(), rpt_exec(), vpb_bridge(), zt_sendtext(), and zt_setoption().

00204 {
00205    time_t   myt;
00206 
00207    /* if soft hangup flag, return true */
00208    if (chan->_softhangup) 
00209       return 1;
00210    /* if no technology private data, return true */
00211    if (!chan->tech_pvt) 
00212       return 1;
00213    /* if no hangup scheduled, just return here */
00214    if (!chan->whentohangup) 
00215       return 0;
00216    time(&myt); /* get current time */
00217    /* return, if not yet */
00218    if (chan->whentohangup > myt) 
00219       return 0;
00220    chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
00221    return 1;
00222 }

static int ast_check_hangup_locked ( struct ast_channel chan  )  [static]

Definition at line 224 of file channel.c.

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

Referenced by ast_channel_bridge().

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

void ast_deactivate_generator ( struct ast_channel chan  ) 

Deactive an active generator

Definition at line 1427 of file channel.c.

References ast_clear_flag, AST_FLAG_WRITE_INT, ast_mutex_lock(), ast_mutex_unlock(), ast_settimeout(), ast_channel::generator, ast_channel::generatordata, ast_channel::lock, and ast_generator::release.

Referenced by app_exec(), ast_channel_stop_silence_generator(), ast_openstream_full(), ast_playtones_stop(), ast_quiet_chan(), ast_read(), ast_tonepair_stop(), ast_write(), channel_spy(), dial_exec_full(), generator_force(), local_ast_moh_stop(), milliwatt_exec(), moh_on_off(), and wait_for_answer().

01428 {
01429    ast_mutex_lock(&chan->lock);
01430    if (chan->generatordata) {
01431       if (chan->generator && chan->generator->release) 
01432          chan->generator->release(chan, chan->generatordata);
01433       chan->generatordata = NULL;
01434       chan->generator = NULL;
01435       ast_clear_flag(chan, AST_FLAG_WRITE_INT);
01436       ast_settimeout(chan, 0, NULL, NULL);
01437    }
01438    ast_mutex_unlock(&chan->lock);
01439 }

int ast_do_masquerade ( struct ast_channel chan  ) 

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

Parameters:
chan Channel to masquerade

Definition at line 2941 of file channel.c.

References ast_channel::_state, ast_channel::alertpipe, AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_channel_spy::chan, EVENT_FLAG_CALL, free_translation(), list, ast_channel::lock, ast_channel_spy::lock, LOG_DEBUG, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::name, option_debug, ast_frame::prev, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::readq, ast_channel::spies, t, ast_channel::tech, ast_channel::tech_pvt, ast_channel::uniqueid, and ast_channel::writeformat.

Referenced by ast_async_goto(), ast_hangup(), ast_read(), ast_waitfor_nandfds(), ast_write(), iax_park(), sip_park(), and sip_park_thread().

02942 {
02943    int x,i;
02944    int res=0;
02945    int origstate;
02946    struct ast_frame *cur, *prev;
02947    const struct ast_channel_tech *t;
02948    void *t_pvt;
02949    struct ast_callerid tmpcid;
02950    struct ast_channel *clone = original->masq;
02951    struct ast_channel_spy_list *spy_list;
02952    struct ast_channel_spy *spy = NULL;
02953    int rformat = original->readformat;
02954    int wformat = original->writeformat;
02955    char newn[100];
02956    char orig[100];
02957    char masqn[100];
02958    char zombn[100];
02959 
02960    if (option_debug > 3)
02961       ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
02962          clone->name, clone->_state, original->name, original->_state);
02963 
02964    /* XXX This is a seriously wacked out operation.  We're essentially putting the guts of
02965       the clone channel into the original channel.  Start by killing off the original
02966       channel's backend.   I'm not sure we're going to keep this function, because 
02967       while the features are nice, the cost is very high in terms of pure nastiness. XXX */
02968 
02969    /* We need the clone's lock, too */
02970    ast_mutex_lock(&clone->lock);
02971 
02972    ast_log(LOG_DEBUG, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock);
02973 
02974    /* Having remembered the original read/write formats, we turn off any translation on either
02975       one */
02976    free_translation(clone);
02977    free_translation(original);
02978 
02979 
02980    /* Unlink the masquerade */
02981    original->masq = NULL;
02982    clone->masqr = NULL;
02983    
02984    /* Save the original name */
02985    ast_copy_string(orig, original->name, sizeof(orig));
02986    /* Save the new name */
02987    ast_copy_string(newn, clone->name, sizeof(newn));
02988    /* Create the masq name */
02989    snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
02990       
02991    /* Copy the name from the clone channel */
02992    ast_copy_string(original->name, newn, sizeof(original->name));
02993 
02994    /* Mangle the name of the clone channel */
02995    ast_copy_string(clone->name, masqn, sizeof(clone->name));
02996    
02997    /* Notify any managers of the change, first the masq then the other */
02998    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid);
02999    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid);
03000 
03001    /* Swap the technlogies */ 
03002    t = original->tech;
03003    original->tech = clone->tech;
03004    clone->tech = t;
03005 
03006    t_pvt = original->tech_pvt;
03007    original->tech_pvt = clone->tech_pvt;
03008    clone->tech_pvt = t_pvt;
03009 
03010    /* Swap the readq's */
03011    cur = original->readq;
03012    original->readq = clone->readq;
03013    clone->readq = cur;
03014 
03015    /* Swap the alertpipes */
03016    for (i = 0; i < 2; i++) {
03017       x = original->alertpipe[i];
03018       original->alertpipe[i] = clone->alertpipe[i];
03019       clone->alertpipe[i] = x;
03020    }
03021 
03022    /* Swap the raw formats */
03023    x = original->rawreadformat;
03024    original->rawreadformat = clone->rawreadformat;
03025    clone->rawreadformat = x;
03026    x = original->rawwriteformat;
03027    original->rawwriteformat = clone->rawwriteformat;
03028    clone->rawwriteformat = x;
03029 
03030    /* Swap the spies */
03031    spy_list = original->spies;
03032    original->spies = clone->spies;
03033    clone->spies = spy_list;
03034 
03035    /* Update channel on respective spy lists if present */
03036    if (original->spies) {
03037       AST_LIST_TRAVERSE(&original->spies->list, spy, list) {
03038          ast_mutex_lock(&spy->lock);
03039          spy->chan = original;
03040          ast_mutex_unlock(&spy->lock);
03041       }
03042    }
03043    if (clone->spies) {
03044       AST_LIST_TRAVERSE(&clone->spies->list, spy, list) {
03045          ast_mutex_lock(&spy->lock);
03046          spy->chan = clone;
03047          ast_mutex_unlock(&spy->lock);
03048       }
03049    }
03050 
03051    /* Save any pending frames on both sides.  Start by counting
03052     * how many we're going to need... */
03053    prev = NULL;
03054    cur = clone->readq;
03055    x = 0;
03056    while(cur) {
03057       x++;
03058       prev = cur;
03059       cur = cur->next;
03060    }
03061    /* If we had any, prepend them to the ones already in the queue, and 
03062     * load up the alertpipe */
03063    if (prev) {
03064       prev->next = original->readq;
03065       original->readq = clone->readq;
03066       clone->readq = NULL;
03067       if (original->alertpipe[1] > -1) {
03068          for (i = 0; i < x; i++)
03069             write(original->alertpipe[1], &x, sizeof(x));
03070       }
03071    }
03072    clone->_softhangup = AST_SOFTHANGUP_DEV;
03073 
03074 
03075    /* And of course, so does our current state.  Note we need not
03076       call ast_setstate since the event manager doesn't really consider
03077       these separate.  We do this early so that the clone has the proper
03078       state of the original channel. */
03079    origstate = original->_state;
03080    original->_state = clone->_state;
03081    clone->_state = origstate;
03082 
03083    if (clone->tech->fixup){
03084       res = clone->tech->fixup(original, clone);
03085       if (res) 
03086          ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name);
03087    }
03088 
03089    /* Start by disconnecting the original's physical side */
03090    if (clone->tech->hangup)
03091       res = clone->tech->hangup(clone);
03092    if (res) {
03093       ast_log(LOG_WARNING, "Hangup failed!  Strange things may happen!\n");
03094       ast_mutex_unlock(&clone->lock);
03095       return -1;
03096    }
03097    
03098    snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
03099    /* Mangle the name of the clone channel */
03100    ast_copy_string(clone->name, zombn, sizeof(clone->name));
03101    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid);
03102 
03103    /* Update the type. */
03104    original->type = clone->type;
03105    t_pvt = original->monitor;
03106    original->monitor = clone->monitor;
03107    clone->monitor = t_pvt;
03108    
03109    /* Keep the same language.  */
03110    ast_copy_string(original->language, clone->language, sizeof(original->language));
03111    /* Copy the FD's */
03112    for (x = 0; x < AST_MAX_FDS; x++) {
03113       original->fds[x] = clone->fds[x];
03114    }
03115    clone_variables(original, clone);
03116    AST_LIST_HEAD_INIT_NOLOCK(&clone->varshead);
03117    /* Presense of ADSI capable CPE follows clone */
03118    original->adsicpe = clone->adsicpe;
03119    /* Bridge remains the same */
03120    /* CDR fields remain the same */
03121    /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
03122    /* Application and data remain the same */
03123    /* Clone exception  becomes real one, as with fdno */
03124    ast_copy_flags(original, clone, AST_FLAG_EXCEPTION);
03125    original->fdno = clone->fdno;
03126    /* Schedule context remains the same */
03127    /* Stream stuff stays the same */
03128    /* Keep the original state.  The fixup code will need to work with it most likely */
03129 
03130    /* Just swap the whole structures, nevermind the allocations, they'll work themselves
03131       out. */
03132    tmpcid = original->cid;
03133    original->cid = clone->cid;
03134    clone->cid = tmpcid;
03135    
03136    /* Restore original timing file descriptor */
03137    original->fds[AST_MAX_FDS - 2] = original->timingfd;
03138    
03139    /* Our native formats are different now */
03140    original->nativeformats = clone->nativeformats;
03141    
03142    /* Context, extension, priority, app data, jump table,  remain the same */
03143    /* pvt switches.  pbx stays the same, as does next */
03144    
03145    /* Set the write format */
03146    ast_set_write_format(original, wformat);
03147 
03148    /* Set the read format */
03149    ast_set_read_format(original, rformat);
03150 
03151    /* Copy the music class */
03152    ast_copy_string(original->musicclass, clone->musicclass, sizeof(original->musicclass));
03153 
03154    ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat);
03155 
03156    /* Okay.  Last thing is to let the channel driver know about all this mess, so he
03157       can fix up everything as best as possible */
03158    if (original->tech->fixup) {
03159       res = original->tech->fixup(clone, original);
03160       if (res) {
03161          ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n",
03162             original->type, original->name);
03163          ast_mutex_unlock(&clone->lock);
03164          return -1;
03165       }
03166    } else
03167       ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)!  Bad things may happen.\n",
03168          original->type, original->name);
03169    
03170    /* Now, at this point, the "clone" channel is totally F'd up.  We mark it as
03171       a zombie so nothing tries to touch it.  If it's already been marked as a
03172       zombie, then free it now (since it already is considered invalid). */
03173    if (ast_test_flag(clone, AST_FLAG_ZOMBIE)) {
03174       ast_log(LOG_DEBUG, "Destroying channel clone '%s'\n", clone->name);
03175       ast_mutex_unlock(&clone->lock);
03176       manager_event(EVENT_FLAG_CALL, "Hangup", 
03177          "Channel: %s\r\n"
03178          "Uniqueid: %s\r\n"
03179          "Cause: %d\r\n"
03180          "Cause-txt: %s\r\n",
03181          clone->name, 
03182          clone->uniqueid, 
03183          clone->hangupcause,
03184          ast_cause2str(clone->hangupcause)
03185          );
03186       ast_channel_free(clone);
03187    } else {
03188       struct ast_frame null_frame = { AST_FRAME_NULL, };
03189       ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
03190       ast_set_flag(clone, AST_FLAG_ZOMBIE);
03191       ast_queue_frame(clone, &null_frame);
03192       ast_mutex_unlock(&clone->lock);
03193    }
03194    
03195    /* Signal any blocker */
03196    if (ast_test_flag(original, AST_FLAG_BLOCKING))
03197       pthread_kill(original->blocker, SIGURG);
03198    ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n", original->name, original->_state);
03199    return 0;
03200 }

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

Definition at line 3318 of file channel.c.

References AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_RETRY, config, ast_channel::nativeformats, and ast_channel::tech_pvt.

Referenced by ast_channel_bridge().

03321 {
03322    /* Copy voice back and forth between the two channels. */
03323    struct ast_channel *cs[3];
03324    struct ast_frame *f;
03325    struct ast_channel *who = NULL;
03326    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
03327    int o0nativeformats;
03328    int o1nativeformats;
03329    int watch_c0_dtmf;
03330    int watch_c1_dtmf;
03331    void *pvt0, *pvt1;
03332    int to;
03333    
03334    cs[0] = c0;
03335    cs[1] = c1;
03336    pvt0 = c0->tech_pvt;
03337    pvt1 = c1->tech_pvt;
03338    o0nativeformats = c0->nativeformats;
03339    o1nativeformats = c1->nativeformats;
03340    watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
03341    watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
03342 
03343    for (;;) {
03344       if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
03345           (o0nativeformats != c0->nativeformats) ||
03346           (o1nativeformats != c1->nativeformats)) {
03347          /* Check for Masquerade, codec changes, etc */
03348          res = AST_BRIDGE_RETRY;
03349          break;
03350       }
03351       if (bridge_end.tv_sec) {
03352          to = ast_tvdiff_ms(bridge_end, ast_tvnow());
03353          if (to <= 0) {
03354             res = AST_BRIDGE_RETRY;
03355             break;
03356          }
03357       } else
03358          to = -1;
03359       who = ast_waitfor_n(cs, 2, &to);
03360       if (!who) {
03361          ast_log(LOG_DEBUG, "Nobody there, continuing...\n"); 
03362          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
03363             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03364                c0->_softhangup = 0;
03365             if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03366                c1->_softhangup = 0;
03367             c0->_bridge = c1;
03368             c1->_bridge = c0;
03369          }
03370          continue;
03371       }
03372       f = ast_read(who);
03373       if (!f) {
03374          *fo = NULL;
03375          *rc = who;
03376          res = AST_BRIDGE_COMPLETE;
03377          ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
03378          break;
03379       }
03380 
03381       if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
03382          if ((f->subclass == AST_CONTROL_HOLD) || (f->subclass == AST_CONTROL_UNHOLD) ||
03383              (f->subclass == AST_CONTROL_VIDUPDATE)) {
03384             ast_indicate(who == c0 ? c1 : c0, f->subclass);
03385          } else {
03386             *fo = f;
03387             *rc = who;
03388             res =  AST_BRIDGE_COMPLETE;
03389             ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
03390             break;
03391          }
03392       }
03393       if ((f->frametype == AST_FRAME_VOICE) ||
03394           (f->frametype == AST_FRAME_DTMF) ||
03395           (f->frametype == AST_FRAME_VIDEO) || 
03396           (f->frametype == AST_FRAME_IMAGE) ||
03397           (f->frametype == AST_FRAME_HTML) ||
03398           (f->frametype == AST_FRAME_TEXT)) {
03399          if (f->frametype == AST_FRAME_DTMF) {
03400             if (((who == c0) && watch_c0_dtmf) ||
03401                 ((who == c1) && watch_c1_dtmf)) {
03402                *rc = who;
03403                *fo = f;
03404                res = AST_BRIDGE_COMPLETE;
03405                ast_log(LOG_DEBUG, "Got DTMF on channel (%s)\n", who->name);
03406                break;
03407             } else {
03408                goto tackygoto;
03409             }
03410          } else {
03411 #if 0
03412             ast_log(LOG_DEBUG, "Read from %s\n", who->name);
03413             if (who == last) 
03414                ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name);
03415             last = who;
03416 #endif
03417 tackygoto:
03418             ast_write((who == c0) ? c1 : c0, f);
03419          }
03420       }
03421       ast_frfree(f);
03422 
03423       /* Swap who gets priority */
03424       cs[2] = cs[0];
03425       cs[0] = cs[1];
03426       cs[1] = cs[2];
03427    }
03428    return res;
03429 }

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

Definition at line 818 of file channel.c.

References channel_find_locked().

Referenced by pickup_exec().

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

struct ast_channel* ast_get_channel_by_name_locked ( const char *  chan  ) 

Get channel by name (locks channel)

Definition at line 800 of file channel.c.

References channel_find_locked().

Referenced by action_getvar(), action_hangup(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), ast_async_goto_by_name(), change_monitor_action(), get_zap_channel_locked(), handle_channelstatus(), handle_debugchan(), handle_getvariablefull(), handle_hangup(), handle_nodebugchan(), handle_showchan(), handle_softhangup(), pbx_builtin_importvar(), pickup_exec(), start_monitor_action(), and stop_monitor_action().

00801 {
00802    return channel_find_locked(NULL, name, 0, NULL, NULL);
00803 }

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

Get channel by name prefix (locks channel)

Definition at line 806 of file channel.c.

References channel_find_locked().

Referenced by ast_parse_device_state(), and mixmonitor_cli().

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

struct ast_channel_tech* ast_get_channel_tech ( const char *  name  ) 

Get a channel technology structure by name.

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 3823 of file channel.c.

References ast_log(), ast_strdupa, copy(), group, LOG_ERROR, LOG_WARNING, and strsep().

Referenced by _parse(), build_device(), build_gateway(), build_peer(), build_user(), load_module(), read_agent_config(), and setup_zap().

03824 {
03825    char *copy;
03826    char *piece;
03827    char *c=NULL;
03828    int start=0, finish=0, x;
03829    ast_group_t group = 0;
03830 
03831    copy = ast_strdupa(s);
03832    if (!copy) {
03833       ast_log(LOG_ERROR, "Out of memory\n");
03834       return 0;
03835    }
03836    c = copy;
03837    
03838    while((piece = strsep(&c, ","))) {
03839       if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
03840          /* Range */
03841       } else if (sscanf(piece, "%d", &start)) {
03842          /* Just one */
03843          finish = start;
03844       } else {
03845          ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
03846          continue;
03847       }
03848       for (x = start; x <= finish; x++) {
03849          if ((x > 63) || (x < 0)) {
03850             ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
03851          } else
03852             group |= ((ast_group_t) 1 << x);
03853       }
03854    }
03855    return group;
03856 }

int ast_hangup ( struct ast_channel chan  ) 

Hang up a channel.

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 1313 of file channel.c.

References ast_cause2str(), ast_cdr_detach(), ast_cdr_end(), ast_channel_free(), ast_closestream(), ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_channel::blocker, ast_channel::blockproc, ast_channel::cdr, CRASH, detach_spies(), EVENT_FLAG_CALL, free_translation(), ast_channel::generator, ast_channel::generatordata, ast_channel_tech::hangup, ast_channel::hangupcause, ast_channel::lock, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::name, option_debug, ast_generator::release, ast_channel::sched, sched_context_destroy(), ast_channel::stream, ast_channel::tech, ast_channel::uniqueid, and ast_channel::vstream.

Referenced by __ast_request_and_dial(), __oh323_new(), agent_hangup(), agent_read(), alsa_new(), ast_async_goto(), ast_bridge_call_thread(), ast_feature_request_and_dial(), ast_iax2_new(), ast_modem_new(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run_app(), async_wait(), build_conf(), builtin_atxfer(), chanavail_exec(), check_goto_on_transfer(), conf_free(), dial_exec_full(), do_parking_thread(), features_hangup(), function_ilink(), handle_hd_hf(), handle_init_event(), handle_message(), handle_request_invite(), hangup_chan(), hangupcalls(), hanguptree(), iax2_request(), iax_park(), iax_park_thread(), local_hangup(), mgcp_new(), mgcp_ss(), nbs_new(), oss_new(), park_exec(), parkandannounce_exec(), phone_new(), ring_entry(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), sip_new(), sip_park(), sip_park_thread(), skinny_new(), skinny_ss(), ss_thread(), try_calling(), vpb_new(), wait_for_answer(), zt_handle_event(), and zt_new().

01314 {
01315    int res = 0;
01316 
01317    /* Don't actually hang up a channel that will masquerade as someone else, or
01318       if someone is going to masquerade as us */
01319    ast_mutex_lock(&chan->lock);
01320 
01321    detach_spies(chan);     /* get rid of spies */
01322 
01323    if (chan->masq) {
01324       if (ast_do_masquerade(chan)) 
01325          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01326    }
01327 
01328    if (chan->masq) {
01329       ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
01330       ast_mutex_unlock(&chan->lock);
01331       return 0;
01332    }
01333    /* If this channel is one which will be masqueraded into something, 
01334       mark it as a zombie already, so we know to free it later */
01335    if (chan->masqr) {
01336       ast_set_flag(chan, AST_FLAG_ZOMBIE);
01337       ast_mutex_unlock(&chan->lock);
01338       return 0;
01339    }
01340    free_translation(chan);
01341    /* Close audio stream */
01342    if (chan->stream) {
01343       ast_closestream(chan->stream);
01344       chan->stream = NULL;
01345    }
01346    /* Close video stream */
01347    if (chan->vstream) {
01348       ast_closestream(chan->vstream);
01349       chan->vstream = NULL;
01350    }
01351    if (chan->sched) {
01352       sched_context_destroy(chan->sched);
01353       chan->sched = NULL;
01354    }
01355    
01356    if (chan->generatordata)   /* Clear any tone stuff remaining */ 
01357       chan->generator->release(chan, chan->generatordata);
01358    chan->generatordata = NULL;
01359    chan->generator = NULL;
01360    if (chan->cdr) {     /* End the CDR if it hasn't already */ 
01361       ast_cdr_end(chan->cdr);
01362       ast_cdr_detach(chan->cdr); /* Post and Free the CDR */ 
01363       chan->cdr = NULL;
01364    }
01365    if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
01366       ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
01367                "is blocked by thread %ld in procedure %s!  Expect a failure\n",
01368                (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
01369       CRASH;
01370    }
01371    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
01372       if (option_debug)
01373          ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
01374       if (chan->tech->hangup)
01375          res = chan->tech->hangup(chan);
01376    } else {
01377       if (option_debug)
01378          ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name);
01379    }
01380          
01381    ast_mutex_unlock(&chan->lock);
01382    manager_event(EVENT_FLAG_CALL, "Hangup", 
01383          "Channel: %s\r\n"
01384          "Uniqueid: %s\r\n"
01385          "Cause: %d\r\n"
01386          "Cause-txt: %s\r\n",
01387          chan->name, 
01388          chan->uniqueid, 
01389          chan->hangupcause,
01390          ast_cause2str(chan->hangupcause)
01391          );
01392    ast_channel_free(chan);
01393    return res;
01394 }

int ast_indicate ( struct ast_channel chan,
int  condition 
)

Indicates condition of channel.

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 2056 of file channel.c.

References ast_check_hangup(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_FLAG_ZOMBIE, ast_get_indication_tone(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_playtones_start(), ast_playtones_stop(), ast_test_flag, tone_zone_sound::data, ast_channel_tech::indicate, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_channel::tech, and ast_channel::zone.

Referenced by agent_indicate(), ast_bridge_call(), ast_feature_request_and_dial(), ast_park_call(), ast_play_and_record_full(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), conf_run(), dial_exec_full(), disa_exec(), do_parking_thread(), features_indicate(), function_remote(), handle_recordfile(), handle_remote_data(), handle_remote_phone_dtmf(), mgcp_ss(), park_exec(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_progress(), pbx_builtin_ringing(), queue_exec(), rmt_telem_finish(), rmt_telem_start(), rpt(), rpt_exec(), send_waveform_to_channel(), skinny_ss(), vpb_fixup(), and wait_for_answer().

02057 {
02058    int res = -1;
02059 
02060    ast_mutex_lock(&chan->lock);
02061    /* Stop if we're a zombie or need a soft hangup */
02062    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02063       ast_mutex_unlock(&chan->lock);
02064       return -1;
02065    }
02066    if (chan->tech->indicate)
02067       res = chan->tech->indicate(chan, condition);
02068    ast_mutex_unlock(&chan->lock);
02069    if (!chan->tech->indicate || res) {
02070       /*
02071        * Device does not support (that) indication, lets fake
02072        * it by doing our own tone generation. (PM2002)
02073        */
02074       if (condition >= 0) {
02075          const struct tone_zone_sound *ts = NULL;
02076          switch (condition) {
02077          case AST_CONTROL_RINGING:
02078             ts = ast_get_indication_tone(chan->zone, "ring");
02079             break;
02080          case AST_CONTROL_BUSY:
02081             ts = ast_get_indication_tone(chan->zone, "busy");
02082             break;
02083          case AST_CONTROL_CONGESTION:
02084             ts = ast_get_indication_tone(chan->zone, "congestion");
02085             break;
02086          }
02087          if (ts && ts->data[0]) {
02088             ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
02089             ast_playtones_start(chan,0,ts->data, 1);
02090             res = 0;
02091          } else if (condition == AST_CONTROL_PROGRESS) {
02092             /* ast_playtones_stop(chan); */
02093          } else if (condition == AST_CONTROL_PROCEEDING) {
02094             /* Do nothing, really */
02095          } else if (condition == AST_CONTROL_HOLD) {
02096             /* Do nothing.... */
02097          } else if (condition == AST_CONTROL_UNHOLD) {
02098             /* Do nothing.... */
02099          } else if (condition == AST_CONTROL_VIDUPDATE) {
02100             /* Do nothing.... */
02101          } else {
02102             /* not handled */
02103             ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
02104             res = -1;
02105          }
02106       }
02107       else ast_playtones_stop(chan);
02108    }
02109    return res;
02110 }

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

Definition at line 3863 of file channel.c.

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

Referenced by load_module(), and reload().

03867 {
03868    ast_moh_start_ptr = start_ptr;
03869    ast_moh_stop_ptr = stop_ptr;
03870    ast_moh_cleanup_ptr = cleanup_ptr;
03871 }

void ast_moh_cleanup ( struct ast_channel chan  ) 

Definition at line 3899 of file channel.c.

References ast_moh_cleanup_ptr.

Referenced by ast_channel_free().

03900 {
03901    if(ast_moh_cleanup_ptr)
03902         ast_moh_cleanup_ptr(chan);
03903 }

int ast_moh_start ( struct ast_channel chan,
char *  mclass 
)

Turn on music on hold on a given channel

Definition at line 3881 of file channel.c.

References ast_moh_start_ptr, ast_verbose(), option_verbose, and VERBOSE_PREFIX_3.

Referenced by __login_exec(), agent_hangup(), ast_park_call(), builtin_atxfer(), builtin_blindtransfer(), conf_run(), dial_exec_full(), do_parking_thread(), handle_request(), handle_setmusic(), moh0_exec(), moh1_exec(), moh3_exec(), pbx_builtin_waitexten(), process_sdp(), queue_exec(), retrydial_exec(), say_periodic_announcement(), say_position(), socket_read(), zt_handle_event(), and zt_hangup().

03882 {
03883    if (ast_moh_start_ptr)
03884       return ast_moh_start_ptr(chan, mclass);
03885 
03886    if (option_verbose > 2)
03887       ast_verbose(VERBOSE_PREFIX_3 "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : "default");
03888    
03889    return 0;
03890 }

void ast_moh_stop ( struct ast_channel chan  ) 

Turn off music on hold on a given channel

Definition at line 3893 of file channel.c.

References ast_moh_stop_ptr.

Referenced by __zt_exception(), agent_new(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), conf_run(), dial_exec_full(), do_parking_thread(), handle_hd_hf(), handle_request(), handle_request_bye(), handle_request_refer(), handle_setmusic(), misdn_transfer_bc(), moh0_exec(), moh1_exec(), moh4_exec(), park_exec(), pbx_builtin_waitexten(), process_sdp(), queue_exec(), retrydial_exec(), say_periodic_announcement(), say_position(), socket_read(), ss_thread(), try_calling(), zt_handle_event(), and zt_hangup().

03894 {
03895    if(ast_moh_stop_ptr)
03896       ast_moh_stop_ptr(chan);
03897 }

AST_MUTEX_DEFINE_STATIC ( chlock   ) 

AST_MUTEX_DEFINE_STATIC ( uniquelock   ) 

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

Definition at line 3911 of file channel.c.

Referenced by ast_serialize_showchan(), misdn_cfg_get_config_string(), print_group(), and read_config().

03912 {
03913    unsigned int i;
03914    int first=1;
03915    char num[3];
03916 
03917    buf[0] = '\0';
03918    
03919    if (!group) /* Return empty string if no group */
03920       return(buf);
03921 
03922    for (i=0; i<=63; i++) { /* Max group is 63 */
03923       if (group & ((ast_group_t) 1 << i)) {
03924             if (!first) {
03925             strncat(buf, ", ", buflen);
03926          } else {
03927             first=0;
03928          }
03929          snprintf(num, sizeof(num), "%u", i);
03930          strncat(buf, num, buflen);
03931       }
03932    }
03933    return(buf);
03934 }

int ast_prod ( struct ast_channel chan  ) 

Definition at line 2212 of file channel.c.

References ast_channel::_state, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), AST_STATE_UP, ast_write(), ast_frame::data, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_channel::rawwriteformat, ast_frame::src, and ast_frame::subclass.

Referenced by ast_activate_generator().

02213 {
02214    struct ast_frame a = { AST_FRAME_VOICE };
02215    char nothing[128];
02216 
02217    /* Send an empty audio frame to get things moving */
02218    if (chan->_state != AST_STATE_UP) {
02219       ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
02220       a.subclass = chan->rawwriteformat;
02221       a.data = nothing + AST_FRIENDLY_OFFSET;
02222       a.src = "ast_prod";
02223       if (ast_write(chan, &a))
02224          ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
02225    }
02226    return 0;
02227 }

int ast_queue_control ( struct ast_channel chan,
int  control 
)

Queue a control frame.

Definition at line 682 of file channel.c.

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

Referenced by __oh323_update_info(), ast_pickup_call(), auto_congest(), handle_message(), handle_request_info(), handle_response(), handle_response_invite(), mgcp_call(), nbs_call(), phone_call(), pickup_exec(), send_cause2ast(), setup_rtp_connection(), skinny_call(), and update_state().

00683 {
00684    struct ast_frame f = { AST_FRAME_CONTROL, };
00685    f.subclass = control;
00686    return ast_queue_frame(chan, &f);
00687 }

int ast_queue_frame ( struct ast_channel chan,
struct ast_frame fin 
)

Queue an outgoing frame.

Definition at line 611 of file channel.c.

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

Referenced by agent_new(), alsa_call(), ast_channel_masquerade(), ast_channel_setwhentohangup(), ast_dsp_process(), ast_queue_control(), ast_queue_hangup(), ast_softhangup_nolock(), cb_events(), console_answer(), console_dial(), console_flash(), console_sendtext(), dictate_exec(), do_chanreads(), do_immediate_setup(), handle_message(), handle_request_info(), handle_request_invite(), handle_response_invite(), iax2_queue_frame(), local_queue_frame(), mgcp_queue_frame(), monitor_handle_owned(), oss_call(), process_sdp(), receive_message(), send_digit(), wakeup_sub(), and zap_queue_frame().

00612 {
00613    struct ast_frame *f;
00614    struct ast_frame *prev, *cur;
00615    int blah = 1;
00616    int qlen = 0;
00617 
00618    /* Build us a copy and free the original one */
00619    f = ast_frdup(fin);
00620    if (!f) {
00621       ast_log(LOG_WARNING, "Unable to duplicate frame\n");
00622       return -1;
00623    }
00624    ast_mutex_lock(&chan->lock);
00625    prev = NULL;
00626    cur = chan->readq;
00627    while(cur) {
00628       if ((cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) {
00629          /* Don't bother actually queueing anything after a hangup */
00630          ast_frfree(f);
00631          ast_mutex_unlock(&chan->lock);
00632          return 0;
00633       }
00634       prev = cur;
00635       cur = cur->next;
00636       qlen++;
00637    }
00638    /* Allow up to 96 voice frames outstanding, and up to 128 total frames */
00639    if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen  > 128)) {
00640       if (fin->frametype != AST_FRAME_VOICE) {
00641          ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
00642          CRASH;
00643       } else {
00644          ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name);
00645          ast_frfree(f);
00646          ast_mutex_unlock(&chan->lock);
00647          return 0;
00648       }
00649    }
00650    if (prev)
00651       prev->next = f;
00652    else
00653       chan->readq = f;
00654    if (chan->alertpipe[1] > -1) {
00655       if (write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
00656          ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n",
00657             chan->name, f->frametype, f->subclass, qlen, strerror(errno));
00658 #ifdef ZAPTEL_OPTIMIZATIONS
00659    } else if (chan->timingfd > -1) {
00660       ioctl(chan->timingfd, ZT_TIMERPING, &blah);
00661 #endif            
00662    } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
00663       pthread_kill(chan->blocker, SIGURG);
00664    }
00665    ast_mutex_unlock(&chan->lock);
00666    return 0;
00667 }

int ast_queue_hangup ( struct ast_channel chan  ) 

Queue a hangup frame.

Definition at line 670 of file channel.c.

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

Referenced by __oh323_update_info(), __sip_autodestruct(), cleanup_connection(), console_hangup(), handle_message(), handle_request_bye(), handle_request_cancel(), handle_request_refer(), handle_response(), hangup_chan(), hangup_connection(), iax2_destroy(), iax2_predestroy(), mgcp_queue_hangup(), misdn_answer(), retrans_pkt(), and zt_handle_event().

00671 {
00672    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
00673    /* Yeah, let's not change a lock-critical value without locking */
00674    if (!ast_mutex_trylock(&chan->lock)) {
00675       chan->_softhangup |= AST_SOFTHANGUP_DEV;
00676       ast_mutex_unlock(&chan->lock);
00677    }
00678    return ast_queue_frame(chan, &f);
00679 }

struct ast_frame* ast_read ( struct ast_channel chan  ) 

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 1829 of file channel.c.

References ast_channel::_softhangup, ast_channel::_state, ast_channel::alertpipe, ast_cdr_answer(), ast_cdr_end(), ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, ast_deactivate_generator(), ast_do_masquerade(), AST_FLAG_DEFER_DTMF, AST_FLAG_EXCEPTION, AST_FLAG_ZOMBIE, AST_FRAME_CNG, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frame_dump(), AST_FRAME_NULL, AST_FRAME_VOICE, ast_frfree(), ast_getformatname(), ast_log(), AST_MAX_FDS, ast_mutex_lock(), ast_mutex_unlock(), ast_seekstream(), ast_setstate(), ast_settimeout(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_translate(), ast_writestream(), ast_channel::blocker, ast_channel::cdr, ast_frame::data, ast_frame::datalen, ast_channel::dtmff, ast_channel::dtmfq, ast_channel_tech::exception, ast_channel::fdno, ast_channel::fin, ast_frame::frametype, ast_generator::generate, ast_channel::generator, generator_force(), ast_channel::generatordata, ast_channel::insmpl, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::masq, ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, ast_frame::next, ast_channel::outsmpl, queue_frame_to_spies(), ast_channel_tech::read, ast_channel_monitor::read_stream, ast_channel::readq, ast_channel::readtrans, ast_frame::samples, SEEK_FORCECUR, ast_channel::spies, SPY_READ, ast_frame::subclass, ast_channel::tech, ast_channel::timingfd, and ast_channel::timingfunc.

Referenced by __adsi_transmit_messages(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), agent_read(), app_exec(), ast_app_getvoice(), ast_feature_request_and_dial(), ast_masq_park_call(), ast_play_and_prepend(), ast_play_and_record_full(), ast_recvtext(), ast_safe_sleep(), ast_safe_sleep_conditional(), ast_tonepair(), ast_waitfordigit(), ast_waitfordigit_full(), ast_waitstream(), ast_waitstream_exten(), ast_waitstream_fr(), ast_waitstream_full(), async_wait(), autoservice_run(), background_detect_exec(), builtin_atxfer(), channel_spy(), check_goto_on_transfer(), conf_exec(), conf_flush(), conf_run(), dictate_exec(), disa_exec(), do_parking_thread(), do_waiting(), echo_exec(), features_read(), find_cache(), handle_recordfile(), iax_park_thread(), ices_exec(), measurenoise(), misdn_bridge(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), recordthread(), rpt(), run_agi(), rxfax_exec(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), ss_thread(), txfax_exec(), vpb_bridge(), wait_for_answer(), wait_for_hangup(), waitforring_exec(), and zt_bridge().

01830 {
01831    struct ast_frame *f = NULL;
01832    int blah;
01833    int prestate;
01834 #ifdef ZAPTEL_OPTIMIZATIONS
01835    int (*func)(void *);
01836    void *data;
01837    int res;
01838 #endif
01839    static struct ast_frame null_frame = {
01840       AST_FRAME_NULL,
01841    };
01842    
01843    ast_mutex_lock(&chan->lock);
01844    if (chan->masq) {
01845       if (ast_do_masquerade(chan)) {
01846          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01847          f = NULL;
01848       } else
01849          f =  &null_frame;
01850       ast_mutex_unlock(&chan->lock);
01851       return f;
01852    }
01853 
01854    /* Stop if we're a zombie or need a soft hangup */
01855    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
01856       if (chan->generator)
01857          ast_deactivate_generator(chan);
01858       ast_mutex_unlock(&chan->lock);
01859       return NULL;
01860    }
01861    prestate = chan->_state;
01862 
01863    if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && !ast_strlen_zero(chan->dtmfq)) {
01864       /* We have DTMF that has been deferred.  Return it now */
01865       chan->dtmff.frametype = AST_FRAME_DTMF;
01866       chan->dtmff.subclass = chan->dtmfq[0];
01867       /* Drop first digit */
01868       memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1);
01869       ast_mutex_unlock(&chan->lock);
01870       return &chan->dtmff;
01871    }
01872    
01873    /* Read and ignore anything on the alertpipe, but read only
01874       one sizeof(blah) per frame that we send from it */
01875    if (chan->alertpipe[0] > -1) {
01876       read(chan->alertpipe[0], &blah, sizeof(blah));
01877    }
01878 #ifdef ZAPTEL_OPTIMIZATIONS
01879    if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
01880       ast_clear_flag(chan, AST_FLAG_EXCEPTION);
01881       blah = -1;
01882       /* IF we can't get event, assume it's an expired as-per the old interface */
01883       res = ioctl(chan->timingfd, ZT_GETEVENT, &blah);
01884       if (res) 
01885          blah = ZT_EVENT_TIMER_EXPIRED;
01886 
01887       if (blah == ZT_EVENT_TIMER_PING) {
01888 #if 0
01889          ast_log(LOG_NOTICE, "Oooh, there's a PING!\n");
01890 #endif         
01891          if (!chan->readq || !chan->readq->next) {
01892             /* Acknowledge PONG unless we need it again */
01893 #if 0
01894             ast_log(LOG_NOTICE, "Sending a PONG!\n");
01895 #endif            
01896             if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) {
01897                ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno));
01898             }
01899          }
01900       } else if (blah == ZT_EVENT_TIMER_EXPIRED) {
01901          ioctl(chan->timingfd, ZT_TIMERACK, &blah);
01902          func = chan->timingfunc;
01903          data = chan->timingdata;
01904          ast_mutex_unlock(&chan->lock);
01905          if (func) {
01906 #if 0
01907             ast_log(LOG_DEBUG, "Calling private function\n");
01908 #endif         
01909             func(data);
01910          } else {
01911             blah = 0;
01912             ast_mutex_lock(&chan->lock);
01913             ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
01914             chan->timingdata = NULL;
01915             ast_mutex_unlock(&chan->lock);
01916          }
01917          f =  &null_frame;
01918          return f;
01919       } else
01920          ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name);
01921    }
01922 #endif
01923    /* Check for pending read queue */
01924    if (chan->readq) {
01925       f = chan->readq;
01926       chan->readq = f->next;
01927       /* Interpret hangup and return NULL */
01928       if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
01929          ast_frfree(f);
01930          f = NULL;
01931       }
01932    } else {
01933       chan->blocker = pthread_self();
01934       if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
01935          if (chan->tech->exception) 
01936             f = chan->tech->exception(chan);
01937          else {
01938             ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
01939             f = &null_frame;
01940          }
01941          /* Clear the exception flag */
01942          ast_clear_flag(chan, AST_FLAG_EXCEPTION);
01943       } else {
01944          if (chan->tech->read)
01945             f = chan->tech->read(chan);
01946          else
01947             ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
01948       }
01949    }
01950 
01951 
01952    if (f && (f->frametype == AST_FRAME_VOICE)) {
01953       if (!(f->subclass & chan->nativeformats)) {
01954          /* This frame can't be from the current native formats -- drop it on the
01955             floor */
01956          ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n", chan->name, ast_getformatname(f->subclass), ast_getformatname(chan->nativeformats));
01957          ast_frfree(f);
01958          f = &null_frame;
01959       } else {
01960          if (chan->spies)
01961             queue_frame_to_spies(chan, f, SPY_READ);
01962 
01963          if (chan->monitor && chan->monitor->read_stream ) {
01964 #ifndef MONITOR_CONSTANT_DELAY
01965             int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
01966             if (jump >= 0) {
01967                if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1)
01968                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
01969                chan->insmpl += jump + 4 * f->samples;
01970             } else
01971                chan->insmpl+= f->samples;
01972 #else
01973             int jump = chan->outsmpl - chan->insmpl;
01974             if (jump - MONITOR_DELAY >= 0) {
01975                if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
01976                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
01977                chan->insmpl += jump;
01978             } else
01979                chan->insmpl += f->samples;
01980 #endif
01981             if (ast_writestream(chan->monitor->read_stream, f) < 0)
01982                ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
01983          }
01984          if (chan->readtrans) {
01985             f = ast_translate(chan->readtrans, f, 1);
01986             if (!f)
01987                f = &null_frame;
01988          }
01989       }
01990    }
01991 
01992    /* Make sure we always return NULL in the future */
01993    if (!f) {
01994       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01995       if (chan->generator)
01996          ast_deactivate_generator(chan);
01997       /* End the CDR if appropriate */
01998       if (chan->cdr)
01999          ast_cdr_end(chan->cdr);
02000    } else if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && f->frametype == AST_FRAME_DTMF) {
02001       if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
02002          chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
02003       else
02004          ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
02005       ast_frfree(f);
02006       f = &null_frame;
02007    } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) {
02008       if (prestate == AST_STATE_UP) {
02009          ast_log(LOG_DEBUG, "Dropping duplicate answer!\n");
02010          ast_frfree(f);
02011          f = &null_frame;
02012       }
02013       /* Answer the CDR */
02014       ast_setstate(chan, AST_STATE_UP);
02015       ast_cdr_answer(chan->cdr);
02016    } 
02017 
02018    /* Run any generator sitting on the line */
02019    if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) {
02020       /* Mask generator data temporarily and apply.  If there is a timing function, it
02021          will be calling the generator instead */
02022       void *tmp;
02023       int res;
02024       int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
02025 
02026       if (chan->timingfunc) {
02027          ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n");
02028          ast_settimeout(chan, 0, NULL, NULL);
02029       }
02030       tmp = chan->generatordata;
02031       chan->generatordata = NULL;
02032       generate = chan->generator->generate;
02033       res = generate(chan, tmp, f->datalen, f->samples);
02034       chan->generatordata = tmp;
02035       if (res) {
02036          ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
02037          ast_deactivate_generator(chan);
02038       }
02039    } else if (f && (f->frametype == AST_FRAME_CNG)) {
02040       if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
02041          ast_log(LOG_DEBUG, "Generator got CNG, switching to zap timed mode\n");
02042          ast_settimeout(chan, 160, generator_force, chan);
02043       }
02044    }
02045    /* High bit prints debugging */
02046    if (chan->fin & 0x80000000)
02047       ast_frame_dump(chan->name, f, "<<");
02048    if ((chan->fin & 0x7fffffff) == 0x7fffffff)
02049       chan->fin &= 0x80000000;
02050    else
02051       chan->fin++;
02052    ast_mutex_unlock(&chan->lock);
02053    return f;
02054 }

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

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 2639 of file channel.c.

References ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, ast_stopstream(), ast_test_flag, ast_waitfordigit(), ast_waitstream(), and ast_channel::stream.

Referenced by __adsi_transmit_messages(), adsi_begin_download(), adsi_get_cpeinfo(), adsi_load_session(), ast_app_getdata(), dialout(), do_directory(), forward_message(), privacy_exec(), vm_authenticate(), vm_newuser(), and vm_options().

02640 {
02641    int pos=0;
02642    int to = ftimeout;
02643    int d;
02644 
02645    /* XXX Merge with full version? XXX */
02646    /* Stop if we're a zombie or need a soft hangup */
02647    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 
02648       return -1;
02649    if (!len)
02650       return -1;
02651    do {
02652       if (c->stream) {
02653          d = ast_waitstream(c, AST_DIGIT_ANY);
02654          ast_stopstream(c);
02655          usleep(1000);
02656          if (!d)
02657             d = ast_waitfordigit(c, to);
02658       } else {
02659          d = ast_waitfordigit(c, to);
02660       }
02661       if (d < 0)
02662          return -1;
02663       if (d == 0) {
02664          s[pos]='\0';
02665          return 1;
02666       }
02667       if (!strchr(enders, d))
02668          s[pos++] = d;
02669       if (strchr(enders, d) || (pos >= len)) {
02670          s[pos]='\0';
02671          return 0;
02672       }
02673       to = timeout;
02674    } while(1);
02675    /* Never reached */
02676    return 0;
02677 }

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

Definition at line 2679 of file channel.c.

References ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, ast_stopstream(), ast_test_flag, ast_waitfordigit_full(), ast_waitstream_full(), and ast_channel::stream.

Referenced by ast_app_getdata_full().

02680 {
02681    int pos=0;
02682    int to = ftimeout;
02683    int d;
02684 
02685    /* Stop if we're a zombie or need a soft hangup */
02686    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 
02687       return -1;
02688    if (!len)
02689       return -1;
02690    do {
02691       if (c->stream) {
02692          d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
02693          ast_stopstream(c);
02694          usleep(1000);
02695          if (!d)
02696             d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
02697       } else {
02698          d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
02699       }
02700       if (d < 0)
02701          return -1;
02702       if (d == 0) {
02703          s[pos]='\0';
02704          return 1;
02705       }
02706       if (d == 1) {
02707          s[pos]='\0';
02708          return 2;
02709       }
02710       if (!strchr(enders, d))
02711          s[pos++] = d;
02712       if (strchr(enders, d) || (pos >= len)) {
02713          s[pos]='\0';
02714          return 0;
02715       }
02716       to = timeout;
02717    } while(1);
02718    /* Never reached */
02719    return 0;
02720 }

int ast_recvchar ( struct ast_channel chan,
int  timeout 
)

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 2112 of file channel.c.

References ast_recvtext(), and free.

Referenced by handle_recvchar().

02113 {
02114    int c;
02115    char *buf = ast_recvtext(chan, timeout);
02116    if (buf == NULL)
02117       return -1;  /* error or timeout */
02118    c = *(unsigned char *)buf;
02119    free(buf);
02120    return c;
02121 }

char* ast_recvtext ( struct ast_channel chan,
int  timeout 
)

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 2123 of file channel.c.

References ast_check_hangup(), AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_TEXT, ast_frfree(), ast_read(), ast_waitfor(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, strndup, and ast_frame::subclass.

Referenced by ast_recvchar(), and handle_recvtext().

02124 {
02125    int res, done = 0;
02126    char *buf = NULL;
02127    
02128    while (!done) {
02129       struct ast_frame *f;
02130       if (ast_check_hangup(chan))
02131          break;
02132       res = ast_waitfor(chan, timeout);
02133       if (res <= 0) /* timeout or error */
02134          break;
02135       timeout = res; /* update timeout */
02136       f = ast_read(chan);
02137       if (f == NULL)
02138          break; /* no frame */
02139       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP)
02140          done = 1;   /* force a break */
02141       else if (f->frametype == AST_FRAME_TEXT) {      /* what we want */
02142          buf = strndup((char *) f->data, f->datalen); /* dup and break */
02143          done = 1;
02144       }
02145       ast_frfree(f);
02146    }
02147    return buf;
02148 }

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

Requests a channel.

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 2545 of file channel.c.

References ast_channel::_state, AST_CAUSE_NOSUCHDRIVER, AST_CAUSE_NOTDEFINED, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_state2str(), AST_STATE_DOWN, ast_translator_best_choice(), backends, ast_channel_tech::capabilities, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, EVENT_FLAG_CALL, fmt, LOG_WARNING, manager_event(), ast_channel::name, chanlist::next, ast_channel_tech::requester, chanlist::tech, ast_channel_tech::type, and ast_channel::uniqueid.

Referenced by __ast_request_and_dial(), agent_request(), ast_feature_request_and_dial(), attempt_reconnect(), build_conf(), chanavail_exec(), dial_exec_full(), features_alloc(), function_ilink(), ring_entry(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), and wait_for_answer().

02546 {
02547    struct chanlist *chan;
02548    struct ast_channel *c;
02549    int capabilities;
02550    int fmt;
02551    int res;
02552    int foo;
02553 
02554    if (!cause)
02555       cause = &foo;
02556    *cause = AST_CAUSE_NOTDEFINED;
02557 
02558    if (ast_mutex_lock(&chlock)) {
02559       ast_log(LOG_WARNING, "Unable to lock channel list\n");
02560       return NULL;
02561    }
02562 
02563    for (chan = backends; chan; chan = chan->next) {
02564       if (strcasecmp(type, chan->tech->type))
02565          continue;
02566 
02567       capabilities = chan->tech->capabilities;
02568       fmt = format;
02569       res = ast_translator_best_choice(&fmt, &capabilities);
02570       if (res < 0) {
02571          ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format);
02572          ast_mutex_unlock(&chlock);
02573          return NULL;
02574       }
02575       ast_mutex_unlock(&chlock);
02576       if (!chan->tech->requester)
02577          return NULL;
02578       
02579       if (!(c = chan->tech->requester(type, capabilities, data, cause)))
02580          return NULL;
02581 
02582       if (c->_state == AST_STATE_DOWN) {
02583          manager_event(EVENT_FLAG_CALL, "Newchannel",
02584                   "Channel: %s\r\n"
02585                   "State: %s\r\n"
02586                   "CallerID: %s\r\n"
02587                   "CallerIDName: %s\r\n"
02588                   "Uniqueid: %s\r\n",
02589                   c->name, ast_state2str(c->_state),
02590                   c->cid.cid_num ? c->cid.cid_num : "<unknown>",
02591                   c->cid.cid_name ? c->cid.cid_name : "<unknown>",
02592                   c->uniqueid);
02593       }
02594       return c;
02595    }
02596 
02597    ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
02598    *cause = AST_CAUSE_NOSUCHDRIVER;
02599    ast_mutex_unlock(&chlock);
02600 
02601    return NULL;
02602 }

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

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

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 2540 of file channel.c.

References __ast_request_and_dial().

Referenced by ast_pbx_outgoing_exten().

02541 {
02542    return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL);
02543 }

int ast_safe_sleep ( struct ast_channel chan,
int  ms 
)

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

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(), rpt_exec(), rpt_tele_thread(), send_morse(), send_tone_telemetry(), skinny_ss(), testclient_exec(), testserver_exec(), try_calling(), wait_for_hangup(), wait_interval(), and zapateller_exec().

00847 {
00848    struct ast_frame *f;
00849    while(ms > 0) {
00850       ms = ast_waitfor(chan, ms);
00851       if (ms <0)
00852          return -1;
00853       if (ms > 0) {
00854          f = ast_read(chan);
00855          if (!f)
00856             return -1;
00857          ast_frfree(f);
00858       }
00859    }
00860    return 0;
00861 }

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

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

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 2207 of file channel.c.

References do_senddigit().

Referenced by dial_exec_full(), and features_digit().

02208 {
02209    return do_senddigit(chan, digit);
02210 }

int ast_sendtext ( struct ast_channel chan,
const char *  text 
)

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 2150 of file channel.c.

References ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_test_flag, CHECK_BLOCKING, ast_channel_tech::send_text, and ast_channel::tech.

Referenced by agent_sendtext(), handle_sendtext(), and sendtext_exec().

02151 {
02152    int res = 0;
02153    /* Stop if we're a zombie or need a soft hangup */
02154    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 
02155       return -1;
02156    CHECK_BLOCKING(chan);
02157    if (chan->tech->send_text)
02158       res = chan->tech->send_text(chan, text);
02159    ast_clear_flag(chan, AST_FLAG_BLOCKING);
02160    return res;
02161 }

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

Definition at line 3202 of file channel.c.

References ast_cdr_setcid(), ast_describe_caller_presentation(), ast_strlen_zero(), ast_channel::cdr, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, EVENT_FLAG_CALL, free, manager_event(), ast_channel::name, strdup, and ast_channel::uniqueid.

Referenced by __ast_request_and_dial(), agent_call(), ast_feature_request_and_dial(), callerid_write(), dial_exec_full(), disa_exec(), get_callerid(), handle_setcallerid(), local_call(), lookupcidname_exec(), mgcp_ss(), monitor_handle_notowned(), privacy_exec(), read_config(), rpt_exec(), setcallerid_exec(), skinny_ss(), ss_thread(), wait_for_answer(), and zt_read().

03203 {
03204    if (callerid) {
03205       if (chan->cid.cid_num)
03206          free(chan->cid.cid_num);
03207       if (ast_strlen_zero(callerid))
03208          chan->cid.cid_num = NULL;
03209       else
03210          chan->cid.cid_num = strdup(callerid);
03211    }
03212    if (calleridname) {
03213       if (chan->cid.cid_name)
03214          free(chan->cid.cid_name);
03215       if (ast_strlen_zero(calleridname))
03216          chan->cid.cid_name = NULL;
03217       else
03218          chan->cid.cid_name = strdup(calleridname);
03219    }
03220    if (ani) {
03221       if (chan->cid.cid_ani)
03222          free(chan->cid.cid_ani);
03223       if (ast_strlen_zero(ani))
03224          chan->cid.cid_ani = NULL;
03225       else
03226          chan->cid.cid_ani = strdup(ani);
03227    }
03228    if (chan->cdr)
03229       ast_cdr_setcid(chan->cdr, chan);
03230    manager_event(EVENT_FLAG_CALL, "Newcallerid", 
03231             "Channel: %s\r\n"
03232             "CallerID: %s\r\n"
03233             "CallerIDName: %s\r\n"
03234             "Uniqueid: %s\r\n"
03235             "CID-CallingPres: %d (%s)\r\n",
03236             chan->name, chan->cid.cid_num ? 
03237             chan->cid.cid_num : "<Unknown>",
03238             chan->cid.cid_name ? 
03239             chan->cid.cid_name : "<Unknown>",
03240             chan->uniqueid,
03241             chan->cid.cid_pres,
03242             ast_describe_caller_presentation(chan->cid.cid_pres)
03243             );
03244 }

int ast_set_read_format ( struct ast_channel chan,
int  format 
)

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 2414 of file channel.c.

References ast_channel::rawreadformat, ast_channel::readformat, ast_channel::readtrans, and set_format().

Referenced by __login_exec(), __oh323_update_info(), adsi_transmit_message_full(), agent_call(), alarmreceiver_exec(), ast_app_getvoice(), ast_channel_make_compatible(), ast_play_and_prepend(), ast_play_and_record_full(), attempt_reconnect(), background_detect_exec(), chanspy_exec(), conf_run(), dictate_exec(), disa_exec(), do_waiting(), eagi_exec(), echo_exec(), function_ilink(), handle_recordfile(), ices_exec(), measurenoise(), mgcp_rtp_read(), milliwatt_exec(), oh323_rtp_read(), process_sdp(), rpt(), rpt_exec(), rxfax_exec(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_read(), txfax_exec(), and update_features().

02415 {
02416    return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat,
02417            &chan->readtrans, 0);
02418 }

void ast_set_variables ( struct ast_channel chan,
struct ast_variable vars 
)

adds a list of channel variables to a channel

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 3936 of file channel.c.

References ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), and ast_variable::value.

Referenced by __ast_request_and_dial(), ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().

03937 {
03938    struct ast_variable *cur;
03939 
03940    for (cur = vars; cur; cur = cur->next)
03941       pbx_builtin_setvar_helper(chan, cur->name, cur->value);  
03942 }

int ast_set_write_format ( struct ast_channel chan,
int  format 
)

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 2420 of file channel.c.

References ast_channel::rawwriteformat, set_format(), ast_channel::writeformat, and ast_channel::writetrans.

Referenced by __login_exec(), __oh323_update_info(), adsi_transmit_message_full(), agent_call(), alarmreceiver_exec(), ast_channel_make_compatible(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_openstream_full(), ast_stopstream(), attempt_reconnect(), chanspy_exec(), conf_run(), disa_exec(), echo_exec(), function_ilink(), linear_alloc(), linear_release(), mgcp_rtp_read(), milliwatt_exec(), moh_alloc(), moh_files_release(), moh_release(), mp3_exec(), NBScat_exec(), oh323_rtp_read(), playtones_alloc(), playtones_release(), process_sdp(), rpt(), rpt_exec(), rxfax_exec(), send_waveform_to_channel(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_read(), tonepair_alloc(), tonepair_release(), txfax_exec(), and update_features().

02421 {
02422    return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat,
02423            &chan->writetrans, 1);
02424 }

int ast_setstate ( struct ast_channel chan,
int  state 
)

Change the state of a channel.

Definition at line 3246 of file channel.c.

References ast_channel::_state, ast_device_state_changed_literal(), ast_state2str(), AST_STATE_DOWN, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, EVENT_FLAG_CALL, manager_event(), ast_channel::name, and ast_channel::uniqueid.

Referenced by __oh323_new(), __oh323_update_info(), __zt_exception(), agent_call(), agent_new(), alsa_answer(), alsa_new(), aopen_handle_escape(), ast_answer(), ast_async_goto(), ast_iax2_new(), ast_modem_new(), ast_read(), bestdata_handle_escape(), cb_events(), check_availability(), features_new(), handle_message(), handle_request_invite(), handle_response_invite(), i4l_handle_escape(), iax2_call(), local_new(), mgcp_answer(), mgcp_call(), mgcp_new(), mgcp_ss(), misdn_call(), misdn_indication(), misdn_new(), modem_answer(), modem_call(), modem_hangup(), nbs_call(), nbs_hangup(), nbs_new(), oh323_answer(), oss_answer(), oss_new(), pbx_builtin_busy(), pbx_builtin_congestion(), phone_answer(), phone_call(), phone_exception(), phone_hangup(), phone_new(), phone_write(), release_chan(), sip_answer(), sip_new(), skinny_answer(), skinny_call(), skinny_new(), skinny_ss(), ss_thread(), update_state(), vpb_answer(), vpb_hangup(), vpb_new(), zt_answer(), zt_call(), zt_handle_event(), zt_indicate(), zt_new(), and zt_read().

03247 {
03248    int oldstate = chan->_state;
03249 
03250    if (oldstate == state)
03251       return 0;
03252 
03253    chan->_state = state;
03254    ast_device_state_changed_literal(chan->name);
03255    manager_event(EVENT_FLAG_CALL,
03256             (oldstate == AST_STATE_DOWN) ? "Newchannel" : "Newstate",
03257             "Channel: %s\r\n"
03258             "State: %s\r\n"
03259             "CallerID: %s\r\n"
03260             "CallerIDName: %s\r\n"
03261             "Uniqueid: %s\r\n",
03262             chan->name, ast_state2str(chan->_state), 
03263             chan->cid.cid_num ? chan->cid.cid_num : "<unknown>", 
03264             chan->cid.cid_name ? chan->cid.cid_name : "<unknown>", 
03265             chan->uniqueid);
03266 
03267    return 0;
03268 }

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

Definition at line 1752 of file channel.c.

References ast_log(), LOG_DEBUG, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.

Referenced by ast_activate_generator(), ast_closestream(), ast_deactivate_generator(), ast_read(), and ast_readaudio_callback().

01753 {
01754    int res = -1;
01755 #ifdef ZAPTEL_OPTIMIZATIONS
01756    if (c->timingfd > -1) {
01757       if (!func) {
01758          samples = 0;
01759          data = 0;
01760       }
01761       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01762       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01763       c->timingfunc = func;
01764       c->timingdata = data;
01765    }
01766 #endif   
01767    return res;
01768 }

int ast_shutting_down ( void   ) 

Returns non-zero if Asterisk is being shut down

Definition at line 271 of file channel.c.

References shutting_down.

00272 {
00273    return shutting_down;
00274 }

int ast_softhangup ( struct ast_channel chan,
int  cause 
)

Softly hangup up a channel.

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 1161 of file channel.c.

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

Referenced by __unload_module(), action_hangup(), agent_hangup(), agent_logoff(), ast_begin_shutdown(), function_ilink(), handle_hangup(), handle_link_data(), handle_softhangup(), read_agent_config(), rpt(), rpt_call(), softhangup_exec(), start_spying(), startmon(), unload_module(), and zt_handle_event().

01162 {
01163    int res;
01164    ast_mutex_lock(&chan->lock);
01165    res = ast_softhangup_nolock(chan, cause);
01166    ast_mutex_unlock(&chan->lock);
01167    return res;
01168 }

int ast_softhangup_nolock ( struct ast_channel chan,
int  cause 
)

Softly hangup up a channel (no channel lock).

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

Definition at line 1145 of file channel.c.

References ast_channel::_softhangup, AST_FLAG_BLOCKING, AST_FRAME_NULL, ast_log(), ast_queue_frame(), ast_test_flag, ast_channel::blocker, LOG_DEBUG, ast_channel::name, and option_debug.

Referenced by ast_async_goto(), ast_softhangup(), attempt_transfer(), do_monitor(), oh323_indicate(), sip_indicate(), and skinny_indicate().

01146 {
01147    int res = 0;
01148    struct ast_frame f = { AST_FRAME_NULL };
01149    if (option_debug)
01150       ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
01151    /* Inform channel driver that we need to be hung up, if it cares */
01152    chan->_softhangup |= cause;
01153    ast_queue_frame(chan, &f);
01154    /* Interrupt any poll call or such */
01155    if (ast_test_flag(chan, AST_FLAG_BLOCKING))
01156       pthread_kill(chan->blocker, SIGURG);
01157    return res;
01158 }

char* ast_state2str ( int  state  ) 

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_request(), ast_serialize_showchan(), ast_setstate(), handle_chanlist(), handle_showchan(), and mgcp_new().

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

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

Play a tone pair for a given amount of time

Definition at line 3804 of file channel.c.

References ast_frfree(), ast_read(), ast_tonepair_start(), ast_waitfor(), and ast_channel::generatordata.

Referenced by zapateller_exec().

03805 {
03806    struct ast_frame *f;
03807    int res;
03808 
03809    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
03810       return res;
03811 
03812    /* Give us some wiggle room */
03813    while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) {
03814       f = ast_read(chan);
03815       if (f)
03816          ast_frfree(f);
03817       else
03818          return -1;
03819    }
03820    return 0;
03821 }

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

Start a tone going

Definition at line 3783 of file channel.c.

References ast_activate_generator(), tonepair_def::duration, tonepair_def::freq1, tonepair_def::freq2, tonepair, and tonepair_def::vol.

Referenced by ast_tonepair(), play_dialtone(), play_tone_pair(), rpt_tele_thread(), and sendnoise().

03784 {
03785    struct tonepair_def d = { 0, };
03786 
03787    d.freq1 = freq1;
03788    d.freq2 = freq2;
03789    d.duration = duration;
03790    if (vol < 1)
03791       d.vol = 8192;
03792    else
03793       d.vol = vol;
03794    if (ast_activate_generator(chan, &tonepair, &d))
03795       return -1;
03796    return 0;
03797 }

void ast_tonepair_stop ( struct ast_channel chan  ) 

Stop a tone from playing

Definition at line 3799 of file channel.c.

References ast_deactivate_generator().

Referenced by sendnoise().

03800 {
03801    ast_deactivate_generator(chan);
03802 }

int ast_transfer ( struct ast_channel chan,
char *  dest 
)

Transfer a channel (if supported). Returns -1 on error, 0 if not supported and 1 if supported and requested.

Parameters:
chan current channel
dest destination extension for transfer

Definition at line 2621 of file channel.c.

References ast_check_hangup(), AST_FLAG_ZOMBIE, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_channel::lock, ast_channel::tech, and ast_channel_tech::transfer.

Referenced by transfer_exec().

02622 {
02623    int res = -1;
02624 
02625    /* Stop if we're a zombie or need a soft hangup */
02626    ast_mutex_lock(&chan->lock);
02627    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
02628       if (chan->tech->transfer) {
02629          res = chan->tech->transfer(chan, dest);
02630          if (!res)
02631             res = 1;
02632       } else
02633          res = 0;
02634    }
02635    ast_mutex_unlock(&chan->lock);
02636    return res;
02637 }

char* ast_transfercapability2str ( int  transfercapability  ) 

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 3873 of file channel.c.

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

03874 {
03875    ast_moh_start_ptr = NULL;
03876    ast_moh_stop_ptr = NULL;
03877    ast_moh_cleanup_ptr = NULL;
03878 }

int ast_waitfor ( struct ast_channel chan,
int  ms 
)

Wait for input on a channel.

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 1708 of file channel.c.

References ast_waitfor_n().

Referenced by __adsi_transmit_messages(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), ast_app_getvoice(), ast_dtmf_stream(), ast_play_and_prepend(), ast_play_and_record_full(), ast_recvtext(), ast_safe_sleep(), ast_safe_sleep_conditional(), ast_tonepair(), ast_waitfordigit(), ast_waitstream(), ast_waitstream_exten(), ast_waitstream_fr(), async_wait(), background_detect_exec(), channel_spy(), conf_exec(), conf_flush(), dictate_exec(), disa_exec(), do_waiting(), echo_exec(), handle_recordfile(), ices_exec(), measurenoise(), modem_call(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), recordthread(), rxfax_exec(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), ss_thread(), txfax_exec(), wait_for_hangup(), and waitforring_exec().

01709 {
01710    struct ast_channel *chan;
01711    int oldms = ms;
01712 
01713    chan = ast_waitfor_n(&c, 1, &ms);
01714    if (ms < 0) {
01715       if (oldms < 0)
01716          return 0;
01717       else
01718          return -1;
01719    }
01720    return ms;
01721 }

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

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

Definition at line 1703 of file channel.c.

References ast_waitfor_nandfds().

Referenced by ast_feature_request_and_dial(), ast_waitfor(), autoservice_run(), misdn_bridge(), rpt(), rpt_exec(), vpb_bridge(), wait_for_answer(), and zt_bridge().

01704 {
01705    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
01706 }

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

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

Definition at line 1489 of file channel.c.

References ast_fdisset(), ast_log(), pollfd::events, pollfd::fd, LOG_ERROR, poll(), POLLIN, and POLLPRI.

Referenced by ast_modem_expect(), ast_modem_read_response(), bestdata_read(), dundi_lookup_internal(), and dundi_precache_internal().

01490 {
01491    struct timeval start = { 0 , 0 };
01492    int res;
01493    int x, y;
01494    int winner = -1;
01495    int spoint;
01496    struct pollfd *pfds;
01497    
01498    pfds = alloca(sizeof(struct pollfd) * n);
01499    if (!pfds) {
01500       ast_log(LOG_ERROR, "Out of memory\n");
01501       return -1;
01502    }
01503    if (*ms > 0)
01504       start = ast_tvnow();
01505    y = 0;
01506    for (x=0; x < n; x++) {
01507       if (fds[x] > -1) {
01508          pfds[y].fd = fds[x];
01509          pfds[y].events = POLLIN | POLLPRI;
01510          y++;
01511       }
01512    }
01513    res = poll(pfds, y, *ms);
01514    if (res < 0) {
01515       /* Simulate a timeout if we were interrupted */
01516       if (errno != EINTR)
01517          *ms = -1;
01518       else
01519          *ms = 0;
01520       return -1;
01521    }
01522    spoint = 0;
01523    for (x=0; x < n; x++) {
01524       if (fds[x] > -1) {
01525          if ((res = ast_fdisset(pfds, fds[x], y, &spoint))) {
01526             winner = fds[x];
01527             if (exception) {
01528                if (res & POLLPRI)
01529                   *exception = -1;
01530                else
01531                   *exception = 0;
01532             }
01533          }
01534       }
01535    }
01536    if (*ms > 0) {
01537       *ms -= ast_tvdiff_ms(ast_tvnow(), start);
01538       if (*ms < 0)
01539          *ms = 0;
01540    }
01541    return winner;
01542 }

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

Waits for activity on a group of channels.

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 1545 of file channel.c.

References ast_channel::_softhangup, ast_clear_flag, ast_do_masquerade(), ast_fdisset(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, ast_log(), AST_MAX_FDS, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, AST_SOFTHANGUP_TIMEOUT, CHECK_BLOCKING, pollfd::events, ast_channel::fdno, lock, LOG_ERROR, LOG_WARNING, ast_channel::masq, poll(), POLLIN, POLLPRI, pollfd::revents, and ast_channel::whentohangup.

Referenced by app_exec(), ast_waitfor_n(), ast_waitfordigit_full(), ast_waitstream_full(), conf_run(), find_cache(), and run_agi().

01547 {
01548    struct timeval start = { 0 , 0 };
01549    struct pollfd *pfds;
01550    int res;
01551    long rms;
01552    int x, y, max;
01553    int spoint;
01554    time_t now = 0;
01555    long whentohangup = 0, havewhen = 0, diff;
01556    struct ast_channel *winner = NULL;
01557 
01558    pfds = alloca(sizeof(struct pollfd) * (n * AST_MAX_FDS + nfds));
01559    if (!pfds) {
01560       ast_log(LOG_ERROR, "Out of memory\n");
01561       *outfd = -1;
01562       return NULL;
01563    }
01564 
01565    if (outfd)
01566       *outfd = -99999;
01567    if (exception)
01568       *exception = 0;
01569    
01570    /* Perform any pending masquerades */
01571    for (x=0; x < n; x++) {
01572       ast_mutex_lock(&c[x]->lock);
01573       if (c[x]->whentohangup) {
01574          if (!havewhen)
01575             time(&now);
01576          diff = c[x]->whentohangup - now;
01577          if (!havewhen || (diff < whentohangup)) {
01578             havewhen++;
01579             whentohangup = diff;
01580          }
01581       }
01582       if (c[x]->masq) {
01583          if (ast_do_masquerade(c[x])) {
01584             ast_log(LOG_WARNING, "Masquerade failed\n");
01585             *ms = -1;
01586             ast_mutex_unlock(&c[x]->lock);
01587             return NULL;
01588          }
01589       }
01590       ast_mutex_unlock(&c[x]->lock);
01591    }
01592 
01593    rms = *ms;
01594    
01595    if (havewhen) {
01596       if ((*ms < 0) || (whentohangup * 1000 < *ms)) {
01597          rms =  whentohangup * 1000;
01598       }
01599    }
01600    max = 0;
01601    for (x=0; x < n; x++) {
01602       for (y=0; y< AST_MAX_FDS; y++) {
01603          if (c[x]->fds[y] > -1) {
01604             pfds[max].fd = c[x]->fds[y];
01605             pfds[max].events = POLLIN | POLLPRI;
01606             pfds[max].revents = 0;
01607             max++;
01608          }
01609       }
01610       CHECK_BLOCKING(c[x]);
01611    }
01612    for (x=0; x < nfds; x++) {
01613       if (fds[x] > -1) {
01614          pfds[max].fd = fds[x];
01615          pfds[max].events = POLLIN | POLLPRI;
01616          pfds[max].revents = 0;
01617          max++;
01618       }
01619    }
01620    if (*ms > 0) 
01621       start = ast_tvnow();
01622    
01623    if (sizeof(int) == 4) {
01624       do {
01625          int kbrms = rms;
01626          if (kbrms > 600000)
01627             kbrms = 600000;
01628          res = poll(pfds, max, kbrms);
01629          if (!res)
01630             rms -= kbrms;
01631       } while (!res && (rms > 0));
01632    } else {
01633       res = poll(pfds, max, rms);
01634    }
01635    
01636    if (res < 0) {
01637       for (x=0; x < n; x++) 
01638          ast_clear_flag(c[x], AST_FLAG_BLOCKING);
01639       /* Simulate a timeout if we were interrupted */
01640       if (errno != EINTR)
01641          *ms = -1;
01642       else {
01643          /* Just an interrupt */
01644 #if 0
01645          *ms = 0;
01646 #endif         
01647       }
01648       return NULL;
01649         } else {
01650          /* If no fds signalled, then timeout. So set ms = 0
01651          since we may not have an exact timeout.
01652       */
01653       if (res == 0)
01654          *ms = 0;
01655    }
01656 
01657    if (havewhen)
01658       time(&now);
01659    spoint = 0;
01660    for (x=0; x < n; x++) {
01661       ast_clear_flag(c[x], AST_FLAG_BLOCKING);
01662       if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) {
01663          c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
01664          if (!winner)
01665             winner = c[x];
01666       }
01667       for (y=0; y < AST_MAX_FDS; y++) {
01668          if (c[x]->fds[y] > -1) {
01669             if ((res = ast_fdisset(pfds, c[x]->fds[y], max, &spoint))) {
01670                if (res & POLLPRI)
01671                   ast_set_flag(c[x], AST_FLAG_EXCEPTION);
01672                else
01673                   ast_clear_flag(c[x], AST_FLAG_EXCEPTION);
01674                c[x]->fdno = y;
01675                winner = c[x];
01676             }
01677          }
01678       }
01679    }
01680    for (x=0; x < nfds; x++) {
01681       if (fds[x] > -1) {
01682          if ((res = ast_fdisset(pfds, fds[x], max, &spoint))) {
01683             if (outfd)
01684                *outfd = fds[x];
01685             if (exception) {  
01686                if (res & POLLPRI) 
01687                   *exception = -1;
01688                else
01689                   *exception = 0;
01690             }
01691             winner = NULL;
01692          }
01693       }  
01694    }
01695    if (*ms > 0) {
01696       *ms -= ast_tvdiff_ms(ast_tvnow(), start);
01697       if (*ms < 0)
01698          *ms = 0;
01699    }
01700    return winner;
01701 }

int ast_waitfordigit ( struct ast_channel c,
int  ms 
)

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 1723 of file channel.c.

References ast_check_hangup(), AST_FLAG_ZOMBIE, AST_FRAME_DTMF, ast_frfree(), ast_read(), ast_test_flag, ast_waitfor(), ast_frame::frametype, result, and ast_frame::subclass.

Referenced by _while_exec(), adsi_get_cpeid(), adsi_get_cpeinfo(), adsi_print(), adsi_read_encoded_dtmf(), adsi_transmit_message_full(), advanced_options(), ast_app_dtget(), ast_control_streamfile(), ast_readstring(), ast_record_review(), builtin_atxfer(), chanspy_exec(), cpeid_exec(), dialout(), directory_exec(), forward_message(), get_folder(), ivr_dispatch(), mgcp_ss(), my_getsigstr(), pbx_builtin_waitexten(), play_mailbox_owner(), play_record_review(), read_newoption(), retrydial_exec(), sendnoise(), skinny_ss(), ss_thread(), testclient_exec(), testserver_exec(), vm_execmain(), vm_forwardoptions(), vm_instructions(), vm_options(), vm_tempgreeting(), wait_a_bit(), and wait_our_turn().

01724 {
01725    /* XXX Should I be merged with waitfordigit_full XXX */
01726    struct ast_frame *f;
01727    int result = 0;
01728 
01729    /* Stop if we're a zombie or need a soft hangup */
01730    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 
01731       return -1;
01732 
01733    /* Wait for a digit, no more than ms milliseconds total. */
01734    while(ms && !result) {
01735       ms = ast_waitfor(c, ms);
01736       if (ms < 0) /* Error */
01737          result = -1; 
01738       else if (ms > 0) {
01739          /* Read something */
01740          f = ast_read(c);
01741          if (f) {
01742             if (f->frametype == AST_FRAME_DTMF) 
01743                result = f->subclass;
01744             ast_frfree(f);
01745          } else
01746             result = -1;
01747       }
01748    }
01749    return result;
01750 }

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

Definition at line 1770 of file channel.c.

References ast_check_hangup(), AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_read(), ast_test_flag, ast_waitfor_nandfds(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, and ast_frame::subclass.

Referenced by ast_readstring_full(), handle_getoption(), and handle_waitfordigit().

01771 {
01772    struct ast_frame *f;
01773    struct ast_channel *rchan;
01774    int outfd;
01775    int res;
01776 
01777    /* Stop if we're a zombie or need a soft hangup */
01778    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 
01779       return -1;
01780    /* Wait for a digit, no more than ms milliseconds total. */
01781    while(ms) {
01782       errno = 0;
01783       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01784       if ((!rchan) && (outfd < 0) && (ms)) { 
01785          if (errno == 0 || errno == EINTR)
01786             continue;
01787          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01788          return -1;
01789       } else if (outfd > -1) {
01790          /* The FD we were watching has something waiting */
01791          return 1;
01792       } else if (rchan) {
01793          f = ast_read(c);
01794          if(!f) {
01795             return -1;
01796          }
01797 
01798          switch(f->frametype) {
01799          case AST_FRAME_DTMF:
01800             res = f->subclass;
01801             ast_frfree(f);
01802             return res;
01803          case AST_FRAME_CONTROL:
01804             switch(f->subclass) {
01805             case AST_CONTROL_HANGUP:
01806                ast_frfree(f);
01807                return -1;
01808             case AST_CONTROL_RINGING:
01809             case AST_CONTROL_ANSWER:
01810                /* Unimportant */
01811                break;
01812             default:
01813                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01814                break;
01815             }
01816             break;
01817          case AST_FRAME_VOICE:
01818             /* Write audio if appropriate */
01819             if (audiofd > -1)
01820                write(audiofd, f->data, f->datalen);
01821          }
01822          /* Ignore */
01823          ast_frfree(f);
01824       }
01825    }
01826    return 0; /* Time is up */
01827 }

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

Get channel by name prefix (locks channel)

Definition at line 812 of file channel.c.

References channel_find_locked().

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

int ast_write ( struct ast_channel chan,
struct ast_frame frame 
)

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 2240 of file channel.c.

References ast_channel::_softhangup, ast_check_hangup(), ast_clear_flag, ast_deactivate_generator(), ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_WRITE_INT, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frame_dump(), AST_FRAME_HTML, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_seekstream(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_translate(), ast_writestream(), CHECK_BLOCKING, ast_frame::data, ast_frame::datalen, do_senddigit(), ast_channel::fout, ast_frame::frametype, ast_channel::generatordata, ast_channel::insmpl, ast_channel::lock, LOG_DTMF, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::outsmpl, queue_frame_to_spies(), ast_frame::samples, SEEK_FORCECUR, ast_channel_tech::send_html, ast_channel_tech::send_text, ast_channel::spies, SPY_WRITE, ast_frame::subclass, ast_channel::tech, ast_channel_tech::write, ast_channel_monitor::write_stream, ast_channel_tech::write_video, and ast_channel::writetrans.

Referenced by adsi_careful_send(), agent_write(), ast_dtmf_stream(), ast_prod(), ast_readaudio_callback(), ast_readvideo_callback(), ast_write_video(), conf_run(), dictate_exec(), echo_exec(), features_write(), function_ilink(), gen_generate(), handle_link_data(), linear_generator(), milliwatt_generate(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), NBScat_exec(), rpt(), rpt_call(), rxfax_exec(), send_link_dtmf(), send_tone_burst(), send_waveform_to_channel(), silence_generator_generate(), spy_generate(), tonepair_generator(), txfax_exec(), wait_for_answer(), and zt_bridge().

02241 {
02242    int res = -1;
02243    struct ast_frame *f = NULL;
02244    /* Stop if we're a zombie or need a soft hangup */
02245    ast_mutex_lock(&chan->lock);
02246    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))  {
02247       ast_mutex_unlock(&chan->lock);
02248       return -1;
02249    }
02250    /* Handle any pending masquerades */
02251    if (chan->masq) {
02252       if (ast_do_masquerade(chan)) {
02253          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02254          ast_mutex_unlock(&chan->lock);
02255          return -1;
02256       }
02257    }
02258    if (chan->masqr) {
02259       ast_mutex_unlock(&chan->lock);
02260       return 0;
02261    }
02262    if (chan->generatordata) {
02263       if (ast_test_flag(chan, AST_FLAG_WRITE_INT))
02264          ast_deactivate_generator(chan);
02265       else {
02266          ast_mutex_unlock(&chan->lock);
02267          return 0;
02268       }
02269    }
02270    /* High bit prints debugging */
02271    if (chan->fout & 0x80000000)
02272       ast_frame_dump(chan->name, fr, ">>");
02273    CHECK_BLOCKING(chan);
02274    switch(fr->frametype) {
02275    case AST_FRAME_CONTROL:
02276       /* XXX Interpret control frames XXX */
02277       ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n");
02278       break;
02279    case AST_FRAME_DTMF:
02280       ast_clear_flag(chan, AST_FLAG_BLOCKING);
02281       ast_mutex_unlock(&chan->lock);
02282       res = do_senddigit(chan,fr->subclass);
02283       ast_mutex_lock(&chan->lock);
02284       CHECK_BLOCKING(chan);
02285       break;
02286    case AST_FRAME_TEXT:
02287       if (chan->tech->send_text)
02288          res = chan->tech->send_text(chan, (char *) fr->data);
02289       else
02290          res = 0;
02291       break;
02292    case AST_FRAME_HTML:
02293       if (chan->tech->send_html)
02294          res = chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
02295       else
02296          res = 0;
02297       break;
02298    case AST_FRAME_VIDEO:
02299       /* XXX Handle translation of video codecs one day XXX */
02300       if (chan->tech->write_video)
02301          res = chan->tech->write_video(chan, fr);
02302       else
02303          res = 0;
02304       break;
02305    default:
02306       if (chan->tech->write) {
02307          f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
02308          if (f) {
02309             if (f->frametype == AST_FRAME_VOICE && chan->spies)
02310                queue_frame_to_spies(chan, f, SPY_WRITE);
02311 
02312             if( chan->monitor && chan->monitor->write_stream &&
02313                   f && ( f->frametype == AST_FRAME_VOICE ) ) {
02314 #ifndef MONITOR_CONSTANT_DELAY
02315                int jump = chan->insmpl - chan->outsmpl - 4 * f->samples;
02316                if (jump >= 0) {
02317                   if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1)
02318                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02319                   chan->outsmpl += jump + 4 * f->samples;
02320                } else
02321                   chan->outsmpl += f->samples;
02322 #else
02323                int jump = chan->insmpl - chan->outsmpl;
02324                if (jump - MONITOR_DELAY >= 0) {
02325                   if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
02326                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02327                   chan->outsmpl += jump;
02328                } else
02329                   chan->outsmpl += f->samples;
02330 #endif
02331                if (ast_writestream(chan->monitor->write_stream, f) < 0)
02332                   ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
02333             }
02334 
02335             res = chan->tech->write(chan, f);
02336          } else
02337             res = 0;
02338       }
02339    }
02340 
02341    /* It's possible this is a translated frame */
02342    if (f && f->frametype == AST_FRAME_DTMF) {
02343       ast_log(LOG_DTMF, "%s : %c\n", chan->name, f->subclass);
02344    } else if (fr->frametype == AST_FRAME_DTMF) {
02345       ast_log(LOG_DTMF, "%s : %c\n", chan->name, fr->subclass);
02346    }
02347 
02348    if (f && (f != fr))
02349       ast_frfree(f);
02350    ast_clear_flag(chan, AST_FLAG_BLOCKING);
02351    /* Consider a write failure to force a soft hangup */
02352    if (res < 0)
02353       chan->_softhangup |= AST_SOFTHANGUP_DEV;
02354    else {
02355       if ((chan->fout & 0x7fffffff) == 0x7fffffff)
02356          chan->fout &= 0x80000000;
02357       else
02358          chan->fout++;
02359    }
02360    ast_mutex_unlock(&chan->lock);
02361    return res;
02362 }

int ast_write_video ( struct ast_channel chan,
struct ast_frame frame 
)

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 2229 of file channel.c.

References ast_write(), ast_channel::tech, and ast_channel_tech::write_video.

02230 {
02231    int res;
02232    if (!chan->tech->write_video)
02233       return 0;
02234    res = ast_write(chan, fr);
02235    if (!res)
02236       res = 1;
02237    return res;
02238 }

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

Definition at line 3280 of file channel.c.

References ast_autoservice_start(), ast_autoservice_stop(), AST_DIGIT_ANY, ast_say_number(), ast_streamfile(), ast_waitstream(), and ast_channel::language.

Referenced by ast_channel_bridge().

03281 {
03282    int res=0, min=0, sec=0,check=0;
03283 
03284    check = ast_autoservice_start(peer);
03285    if(check) 
03286       return;
03287 
03288    if (remain > 0) {
03289       if (remain / 60 > 1) {
03290          min = remain / 60;
03291          sec = remain % 60;
03292       } else {
03293          sec = remain;
03294       }
03295    }
03296    
03297    if (!strcmp(sound,"timeleft")) { /* Queue support */
03298       res = ast_streamfile(chan, "vm-youhave", chan->language);
03299       res = ast_waitstream(chan, "");
03300       if (min) {
03301          res = ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, (char *) NULL);
03302          res = ast_streamfile(chan, "queue-minutes", chan->language);
03303          res = ast_waitstream(chan, "");
03304       }
03305       if (sec) {
03306          res = ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, (char *) NULL);
03307          res = ast_streamfile(chan, "queue-seconds", chan->language);
03308          res = ast_waitstream(chan, "");
03309       }
03310    } else {
03311       res = ast_streamfile(chan, sound, chan->language);
03312       res = ast_waitstream(chan, "");
03313    }
03314 
03315    check = ast_autoservice_stop(peer);
03316 }

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

Definition at line 730 of file channel.c.

References ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), channels, ast_channel::context, ast_channel::exten, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::macrocontext, ast_channel::macroexten, ast_channel::name, and ast_channel::next.

Referenced by ast_channel_walk_locked(), ast_get_channel_by_exten_locked(), ast_get_channel_by_name_locked(), ast_get_channel_by_name_prefix_locked(), and ast_walk_channel_by_name_prefix_locked().

00733 {
00734    const char *msg = prev ? "deadlock" : "initial deadlock";
00735    int retries, done;
00736    struct ast_channel *c;
00737 
00738    for (retries = 0; retries < 10; retries++) {
00739       ast_mutex_lock(&chlock);
00740       for (c = channels; c; c = c->next) {
00741          if (!prev) {
00742             /* want head of list */
00743             if (!name && !exten)
00744                break;
00745             if (name) {
00746                /* want match by full name */
00747                if (!namelen) {
00748                   if (!strcasecmp(c->name, name))
00749                      break;
00750                   else
00751                      continue;
00752                }
00753                /* want match by name prefix */
00754                if (!strncasecmp(c->name, name, namelen))
00755                   break;
00756             } else if (exten) {
00757                /* want match by context and exten */
00758                if (context && (strcasecmp(c->context, context) &&
00759                      strcasecmp(c->macrocontext, context)))
00760                   continue;
00761                /* match by exten */
00762                if (strcasecmp(c->exten, exten) &&
00763                    strcasecmp(c->macroexten, exten))
00764                   continue;
00765                else
00766                   break;
00767             }
00768          } else if (c == prev) { /* found, return c->next */
00769             c = c->next;
00770             break;
00771          }
00772       }
00773       /* exit if chan not found or mutex acquired successfully */
00774       done = (c == NULL) || (ast_mutex_trylock(&c->lock) == 0);
00775       /* this is slightly unsafe, as we _should_ hold the lock to access c->name */
00776       if (!done && c)
00777          ast_log(LOG_DEBUG, "Avoiding %s for '%s'\n", msg, c->name);
00778       ast_mutex_unlock(&chlock);
00779       if (done)
00780          return c;
00781       usleep(1);
00782    }
00783    /*
00784     * c is surely not null, but we don't have the lock so cannot
00785     * access c->name
00786     */
00787    ast_log(LOG_WARNING, "Avoided %s for '%p', %d retries!\n",
00788       msg, c, retries);
00789 
00790    return NULL;
00791 }

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

Definition at line 2915 of file channel.c.

References AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_var_delete(), ast_var_name(), GROUP_CATEGORY_PREFIX, and ast_channel::varshead.

02916 {
02917    struct ast_var_t *varptr;
02918 
02919    /* we need to remove all app_groupcount related variables from the original
02920       channel before merging in the clone's variables; any groups assigned to the
02921       original channel should be released, only those assigned to the clone
02922       should remain
02923    */
02924 
02925    AST_LIST_TRAVERSE_SAFE_BEGIN(&original->varshead, varptr, entries) {
02926       if (!strncmp(ast_var_name(varptr), GROUP_CATEGORY_PREFIX, strlen(GROUP_CATEGORY_PREFIX))) {
02927          AST_LIST_REMOVE_CURRENT(&original->varshead, entries);
02928          ast_var_delete(varptr);
02929       }
02930    }
02931    AST_LIST_TRAVERSE_SAFE_END;
02932 
02933    /* Append variables from clone channel into original channel */
02934    /* XXX Is this always correct?  We have to in order to keep MACROS working XXX */
02935    if (AST_LIST_FIRST(&clone->varshead))
02936       AST_LIST_APPEND_LIST(&original->varshead, &clone->varshead, entries);
02937 }

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

Definition at line 3944 of file channel.c.

References ast_codec_get_len(), ast_frfree(), ast_log(), ast_frame::data, ast_frame::datalen, ast_channel_spy_queue::format, ast_channel_spy_queue::head, LOG_ERROR, ast_frame::next, ast_frame::offset, ast_channel_spy_queue::samples, and ast_frame::samples.

Referenced by ast_channel_spy_read_frame().

03945 {
03946    struct ast_frame *f;
03947    int tocopy;
03948    int bytestocopy;
03949 
03950    while (samples) {
03951       f = queue->head;
03952 
03953       if (!f) {
03954          ast_log(LOG_ERROR, "Ran out of frames before buffer filled!\n");
03955          break;
03956       }
03957 
03958       tocopy = (f->samples > samples) ? samples : f->samples;
03959       bytestocopy = ast_codec_get_len(queue->format, tocopy);
03960       memcpy(buf, f->data, bytestocopy);
03961       samples -= tocopy;
03962       buf += tocopy;
03963       f->samples -= tocopy;
03964       f->data += bytestocopy;
03965       f->datalen -= bytestocopy;
03966       f->offset += bytestocopy;
03967       queue->samples -= tocopy;
03968       if (!f->samples) {
03969          queue->head = f->next;
03970          ast_frfree(f);
03971       }
03972    }
03973 }

static void detach_spies ( struct ast_channel chan  )  [static]

Definition at line 1128 of file channel.c.

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_channel_spy::chan, list, ast_channel::spies, spy_cleanup(), and spy_detach().

Referenced by ast_hangup().

01129 {
01130    struct ast_channel_spy *spy = NULL;
01131 
01132    if (!chan->spies)
01133       return;
01134 
01135    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list) {
01136       AST_LIST_REMOVE_CURRENT(&chan->spies->list, list);
01137       spy_detach(spy, chan);
01138    }
01139    AST_LIST_TRAVERSE_SAFE_END
01140 
01141    spy_cleanup(chan);
01142 }

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

Definition at line 2163 of file channel.c.

References ast_log(), ast_playtones_start(), LOG_DEBUG, ast_channel::name, ast_channel_tech::send_digit, and ast_channel::tech.

Referenced by ast_senddigit(), and ast_write().

02164 {
02165    int res = -1;
02166 
02167    if (chan->tech->send_digit)
02168       res = chan->tech->send_digit(chan, digit);
02169    if (!chan->tech->send_digit || res) {
02170       /*
02171        * Device does not support DTMF tones, lets fake
02172        * it by doing our own generation. (PM2002)
02173        */
02174       static const char* dtmf_tones[] = {
02175          "!941+1336/100,!0/100", /* 0 */
02176          "!697+1209/100,!0/100", /* 1 */
02177          "!697+1336/100,!0/100", /* 2 */
02178          "!697+1477/100,!0/100", /* 3 */
02179          "!770+1209/100,!0/100", /* 4 */
02180          "!770+1336/100,!0/100", /* 5 */
02181          "!770+1477/100,!0/100", /* 6 */
02182          "!852+1209/100,!0/100", /* 7 */
02183          "!852+1336/100,!0/100", /* 8 */
02184          "!852+1477/100,!0/100", /* 9 */
02185          "!697+1633/100,!0/100", /* A */
02186          "!770+1633/100,!0/100", /* B */
02187          "!852+1633/100,!0/100", /* C */
02188          "!941+1633/100,!0/100", /* D */
02189          "!941+1209/100,!0/100", /* * */
02190          "!941+1477/100,!0/100" };  /* # */
02191       if (digit >= '0' && digit <='9')
02192          ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
02193       else if (digit >= 'A' && digit <= 'D')
02194          ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
02195       else if (digit == '*')
02196          ast_playtones_start(chan, 0, dtmf_tones[14], 0);
02197       else if (digit == '#')
02198          ast_playtones_start(chan, 0, dtmf_tones[15], 0);
02199       else {
02200          /* not handled */
02201          ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
02202       }
02203    }
02204    return 0;
02205 }

static void free_cid ( struct ast_callerid cid  )  [static]

Definition at line 863 of file channel.c.

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

Referenced by ast_channel_free().

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

static void free_translation ( struct ast_channel clone  )  [static]

Definition at line 1300 of file channel.c.

References ast_translator_free_path(), ast_channel::nativeformats, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readtrans, and ast_channel::writetrans.

Referenced by ast_do_masquerade(), and ast_hangup().

01301 {
01302    if (clone->writetrans)
01303       ast_translator_free_path(clone->writetrans);
01304    if (clone->readtrans)
01305       ast_translator_free_path(clone->readtrans);
01306    clone->writetrans = NULL;
01307    clone->readtrans = NULL;
01308    clone->rawwriteformat = clone->nativeformats;
01309    clone->rawreadformat = clone->nativeformats;
01310 }

static int generator_force ( void *  data  )  [static]

Definition at line 1441 of file channel.c.

References ast_deactivate_generator(), ast_log(), ast_generator::generate, ast_channel::generator, ast_channel::generatordata, and LOG_DEBUG.

Referenced by ast_activate_generator(), and ast_read().

01442 {
01443    /* Called if generator doesn't have data */
01444    void *tmp;
01445    int res;
01446    int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
01447    struct ast_channel *chan = data;
01448    tmp = chan->generatordata;
01449    chan->generatordata = NULL;
01450    generate = chan->generator->generate;
01451    res = generate(chan, tmp, 0, 160);
01452    chan->generatordata = tmp;
01453    if (res) {
01454       ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
01455       ast_deactivate_generator(chan);
01456    }
01457    return 0;
01458 }

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

Definition at line 1177 of file channel.c.

References ast_clear_flag, ast_cond_signal(), AST_FORMAT_SLINEAR, ast_frdup(), ast_frfree(), ast_getformatname(), AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_translate(), ast_translator_build_path(), ast_translator_free_path(), CHANSPY_TRIGGER_FLUSH, CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_NONE, CHANSPY_TRIGGER_READ, CHANSPY_TRIGGER_WRITE, ast_channel_spy_queue::format, ast_channel_spy_queue::head, last, channel_spy_trans::last_format, list, ast_channel_spy::lock, LOG_DEBUG, LOG_ERROR, LOG_WARNING, ast_channel::name, ast_frame::next, msglist::next, option_debug, channel_spy_trans::path, ast_channel_spy::read_queue, ast_channel_spy_list::read_translator, ast_frame::samples, ast_channel_spy_queue::samples, ast_channel::spies, SPY_QUEUE_SAMPLE_LIMIT, SPY_READ, SPY_WRITE, ast_frame::subclass, ast_channel_spy::trigger, ast_channel_spy::type, ast_channel_spy::write_queue, and ast_channel_spy_list::write_translator.

Referenced by ast_read(), and ast_write().

01178 {
01179    struct ast_frame *translated_frame = NULL;
01180    struct ast_channel_spy *spy;
01181    struct ast_channel_spy_queue *queue;
01182    struct channel_spy_trans *trans;
01183    struct ast_frame *last;
01184 
01185    trans = (dir == SPY_READ) ? &chan->spies->read_translator : &chan->spies->write_translator;
01186 
01187    AST_LIST_TRAVERSE(&chan->spies->list, spy, list) {
01188       ast_mutex_lock(&spy->lock);
01189 
01190       queue = (dir == SPY_READ) ? &spy->read_queue : &spy->write_queue;
01191 
01192       if ((queue->format == AST_FORMAT_SLINEAR) && (f->subclass != AST_FORMAT_SLINEAR)) {
01193          if (!translated_frame) {
01194             if (trans->path && (trans->last_format != f->subclass)) {
01195                ast_translator_free_path(trans->path);
01196                trans->path = NULL;
01197             }
01198             if (!trans->path) {
01199                ast_log(LOG_DEBUG, "Building translator from %s to SLINEAR for spies on channel %s\n",
01200                   ast_getformatname(f->subclass), chan->name);
01201                if ((trans->path = ast_translator_build_path(AST_FORMAT_SLINEAR, f->subclass)) == NULL) {
01202                   ast_log(LOG_WARNING, "Cannot build a path from %s to %s\n",
01203                      ast_getformatname(f->subclass), ast_getformatname(AST_FORMAT_SLINEAR));
01204                   ast_mutex_unlock(&spy->lock);
01205                   continue;
01206                } else {
01207                   trans->last_format = f->subclass;
01208                }
01209             }
01210             if (!(translated_frame = ast_translate(trans->path, f, 0))) {
01211                ast_log(LOG_ERROR, "Translation to %s failed, dropping frame for spies\n",
01212                   ast_getformatname(AST_FORMAT_SLINEAR));
01213                ast_mutex_unlock(&spy->lock);
01214                break;
01215             }
01216          }
01217 
01218          for (last = queue->head; last && last->next; last = last->next);
01219          if (last)
01220             last->next = ast_frdup(translated_frame);
01221          else
01222             queue->head = ast_frdup(translated_frame);
01223       } else {
01224          if (f->subclass != queue->format) {
01225             ast_log(LOG_WARNING, "Spy '%s' on channel '%s' wants format '%s', but frame is '%s', dropping\n",
01226                spy->type, chan->name,
01227                ast_getformatname(queue->format), ast_getformatname(f->subclass));
01228             ast_mutex_unlock(&spy->lock);
01229             continue;
01230          }
01231 
01232          for (last = queue->head; last && last->next; last = last->next);
01233          if (last)
01234             last->next = ast_frdup(f);
01235          else
01236             queue->head = ast_frdup(f);
01237       }
01238 
01239       queue->samples += f->samples;
01240 
01241       if (queue->samples > SPY_QUEUE_SAMPLE_LIMIT) {
01242          if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) {
01243             switch (ast_test_flag(spy, CHANSPY_TRIGGER_MODE)) {
01244             case CHANSPY_TRIGGER_READ:
01245                if (dir == SPY_WRITE) {
01246                   ast_set_flag(spy, CHANSPY_TRIGGER_WRITE);
01247                   ast_clear_flag(spy, CHANSPY_TRIGGER_READ);
01248                   if (option_debug)
01249                      ast_log(LOG_DEBUG, "Switching spy '%s' on '%s' to write-trigger mode\n",
01250                         spy->type, chan->name);
01251                }
01252                break;
01253             case CHANSPY_TRIGGER_WRITE:
01254                if (dir == SPY_READ) {
01255                   ast_set_flag(spy, CHANSPY_TRIGGER_READ);
01256                   ast_clear_flag(spy, CHANSPY_TRIGGER_WRITE);
01257                   if (option_debug)
01258                      ast_log(LOG_DEBUG, "Switching spy '%s' on '%s' to read-trigger mode\n",
01259                         spy->type, chan->name);
01260                }
01261                break;
01262             }
01263             if (option_debug)
01264                ast_log(LOG_DEBUG, "Triggering queue flush for spy '%s' on '%s'\n",
01265                   spy->type, chan->name);
01266             ast_set_flag(spy, CHANSPY_TRIGGER_FLUSH);
01267             ast_cond_signal(&spy->trigger);
01268          } else {
01269             if (option_debug)
01270                ast_log(LOG_DEBUG, "Spy '%s' on channel '%s' %s queue too long, dropping frames\n",
01271                   spy->type, chan->name, (dir == SPY_READ) ? "read" : "write");
01272             while (queue->samples > SPY_QUEUE_SAMPLE_LIMIT) {
01273                struct ast_frame *drop = queue->head;
01274                
01275                queue->samples -= drop->samples;
01276                queue->head = drop->next;
01277                ast_frfree(drop);
01278             }
01279          }
01280       } else {
01281          switch (ast_test_flag(spy, CHANSPY_TRIGGER_MODE)) {
01282          case CHANSPY_TRIGGER_READ:
01283             if (dir == SPY_READ)
01284                ast_cond_signal(&spy->trigger);
01285             break;
01286          case CHANSPY_TRIGGER_WRITE:
01287             if (dir == SPY_WRITE)
01288                ast_cond_signal(&spy->trigger);
01289             break;
01290          }
01291       }
01292 
01293       ast_mutex_unlock(&spy->lock);
01294    }
01295 
01296    if (translated_frame)
01297       ast_frfree(translated_frame);
01298 }

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

Definition at line 2364 of file channel.c.

References ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_translator_best_choice(), ast_translator_build_path(), ast_translator_free_path(), ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, and option_debug.

Referenced by ast_set_read_format(), and ast_set_write_format().

02366 {
02367    int native;
02368    int res;
02369    
02370    native = chan->nativeformats;
02371    /* Find a translation path from the native format to one of the desired formats */
02372    if (!direction)
02373       /* reading */
02374       res = ast_translator_best_choice(&fmt, &native);
02375    else
02376       /* writing */
02377       res = ast_translator_best_choice(&native, &fmt);
02378 
02379    if (res < 0) {
02380       ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
02381          ast_getformatname(native), ast_getformatname(fmt));
02382       return -1;
02383    }
02384    
02385    /* Now we have a good choice for both. */
02386    ast_mutex_lock(&chan->lock);
02387 
02388    if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) {
02389       /* the channel is already in these formats, so nothing to do */
02390       ast_mutex_unlock(&chan->lock);
02391       return 0;
02392    }
02393 
02394    *rawformat = native;
02395    /* User perspective is fmt */
02396    *format = fmt;
02397    /* Free any read translation we have right now */
02398    if (*trans)
02399       ast_translator_free_path(*trans);
02400    /* Build a translation path from the raw format to the desired format */
02401    if (!direction)
02402       /* reading */
02403       *trans = ast_translator_build_path(*format, *rawformat);
02404    else
02405       /* writing */
02406       *trans = ast_translator_build_path(*rawformat, *format);
02407    ast_mutex_unlock(&chan->lock);
02408    if (option_debug)
02409       ast_log(LOG_DEBUG, "Set channel %s to %s format %s\n", chan->name,
02410          direction ? "write" : "read", ast_getformatname(fmt));
02411    return 0;
02412 }

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

Definition at line 171 of file channel.c.

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

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

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

Definition at line 4077 of file channel.c.

04078 {
04079    /* just store the data pointer in the channel structure */
04080    return data;
04081 }

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

Definition at line 4088 of file channel.c.

References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_write(), and ast_frame::frametype.

04089 {
04090    if (samples == 160) {
04091       short buf[160] = { 0, };
04092       struct ast_frame frame = {
04093          .frametype = AST_FRAME_VOICE,
04094          .subclass = AST_FORMAT_SLINEAR,
04095          .data = buf,
04096          .samples = 160,
04097          .datalen = sizeof(buf),
04098       };
04099 
04100       if (ast_write(chan, &frame))
04101          return -1;
04102    } else {
04103       short buf[samples];
04104       int x;
04105       struct ast_frame frame = {
04106          .frametype = AST_FRAME_VOICE,
04107          .subclass = AST_FORMAT_SLINEAR,
04108          .data = buf,
04109          .samples = samples,
04110          .datalen = sizeof(buf),
04111       };
04112 
04113       for (x = 0; x < samples; x++)
04114          buf[x] = 0;
04115 
04116       if (ast_write(chan, &frame))
04117          return -1;
04118    }
04119 
04120    return 0;
04121 }

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

Definition at line 4083 of file channel.c.

04084 {
04085    /* nothing to do */
04086 }

static void spy_cleanup ( struct ast_channel chan  )  [static]

Definition at line 1021 of file channel.c.

References AST_LIST_EMPTY, ast_translator_free_path(), free, channel_spy_trans::path, ast_channel_spy_list::read_translator, ast_channel::spies, and ast_channel_spy_list::write_translator.

Referenced by ast_channel_spy_remove(), ast_channel_spy_stop_by_type(), and detach_spies().

01022 {
01023    if (AST_LIST_EMPTY(&chan->spies->list))
01024       return;
01025    if (chan->spies->read_translator.path)
01026       ast_translator_free_path(chan->spies->read_translator.path);
01027    if (chan->spies->write_translator.path)
01028       ast_translator_free_path(chan->spies->write_translator.path);
01029    free(chan->spies);
01030    chan->spies = NULL;
01031    return;
01032 }

static void spy_detach ( struct ast_channel_spy spy,
struct ast_channel chan 
) [static]

Definition at line 1035 of file channel.c.

References ast_cond_signal(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_channel_spy::chan, CHANSPY_DONE, CHANSPY_STOP, CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_NONE, ast_channel_spy::lock, LOG_DEBUG, ast_channel::name, ast_channel_spy::status, ast_channel_spy::trigger, and ast_channel_spy::type.

Referenced by ast_channel_spy_remove(), ast_channel_spy_stop_by_type(), and detach_spies().

01036 {
01037    ast_mutex_lock(&spy->lock);
01038 
01039    /* We only need to poke them if they aren't already done */
01040    if (spy->status != CHANSPY_DONE) {
01041       spy->status = CHANSPY_STOP;
01042       spy->chan = NULL;
01043       if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
01044          ast_cond_signal(&spy->trigger);
01045    }
01046    
01047    /* Print it out while we still have a lock so the structure can't go away (if signalled above) */
01048    ast_log(LOG_DEBUG, "Spy %s removed from channel %s\n", spy->type, chan->name);
01049 
01050    ast_mutex_unlock(&spy->lock);
01051 
01052    return;
01053 }

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

Definition at line 3716 of file channel.c.

References AST_FLAG_WRITE_INT, AST_FORMAT_SLINEAR, ast_log(), ast_set_flag, ast_set_write_format(), tonepair_def::duration, tonepair_state::duration, tonepair_def::freq1, tonepair_state::freq1, tonepair_def::freq2, tonepair_state::freq2, LOG_WARNING, malloc, ast_channel::name, tonepair_state::origwfmt, tonepair_release(), tonepair_def::vol, tonepair_state::vol, and ast_channel::writeformat.

03717 {
03718    struct tonepair_state *ts;
03719    struct tonepair_def *td = params;
03720 
03721    ts = malloc(sizeof(struct tonepair_state));
03722    if (!ts)
03723       return NULL;
03724    memset(ts, 0, sizeof(struct tonepair_state));
03725    ts->origwfmt = chan->writeformat;
03726    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
03727       ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
03728       tonepair_release(NULL, ts);
03729       ts = NULL;
03730    } else {
03731       ts->freq1 = td->freq1;
03732       ts->freq2 = td->freq2;
03733       ts->duration = td->duration;
03734       ts->vol = td->vol;
03735    }
03736    /* Let interrupts interrupt :) */
03737    ast_set_flag(chan, AST_FLAG_WRITE_INT);
03738    return ts;
03739 }

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

Definition at line 3741 of file channel.c.

References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_write(), ast_frame::data, tonepair_state::data, ast_frame::datalen, tonepair_state::duration, tonepair_state::f, ast_frame::frametype, tonepair_state::freq1, tonepair_state::freq2, LOG_WARNING, ast_frame::offset, tonepair_state::pos, ast_frame::samples, ast_frame::subclass, and tonepair_state::vol.

03742 {
03743    struct tonepair_state *ts = data;
03744    int x;
03745 
03746    /* we need to prepare a frame with 16 * timelen samples as we're 
03747     * generating SLIN audio
03748     */
03749    len = samples * 2;
03750 
03751    if (len > sizeof(ts->data) / 2 - 1) {
03752       ast_log(LOG_WARNING, "Can't generate that much data!\n");
03753       return -1;
03754    }
03755    memset(&ts->f, 0, sizeof(ts->f));
03756    for (x = 0; x < (len / 2); x++) {
03757       ts->data[x] = ts->vol * (
03758             sin((ts->freq1 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) +
03759             sin((ts->freq2 * 2.0 * M_PI / 8000.0) * (ts->pos + x))
03760          );
03761    }
03762    ts->f.frametype = AST_FRAME_VOICE;
03763    ts->f.subclass = AST_FORMAT_SLINEAR;
03764    ts->f.datalen = len;
03765    ts->f.samples = samples;
03766    ts->f.offset = AST_FRIENDLY_OFFSET;
03767    ts->f.data = ts->data;
03768    ast_write(chan, &ts->f);
03769    ts->pos += x;
03770    if (ts->duration > 0) {
03771       if (ts->pos >= ts->duration * 8)
03772          return -1;
03773    }
03774    return 0;
03775 }

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

Definition at line 3706 of file channel.c.

References ast_set_write_format(), free, and tonepair_state::origwfmt.

Referenced by tonepair_alloc().

03707 {
03708    struct tonepair_state *ts = params;
03709 
03710    if (chan) {
03711       ast_set_write_format(chan, ts->origwfmt);
03712    }
03713    free(ts);
03714 }


Variable Documentation

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

Definition at line 3860 of file channel.c.

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

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

Definition at line 3858 of file channel.c.

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

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

Definition at line 3859 of file channel.c.

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

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

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.

unsigned long global_fout = 0

Definition at line 100 of file channel.c.

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 4123 of file channel.c.

Referenced by ast_channel_start_silence_generator().

struct ast_generator tonepair [static]

Initial value:

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

Definition at line 3777 of file channel.c.

Referenced by ast_tonepair_start().

int uniqueint = 0 [static]

Definition at line 98 of file channel.c.


Generated on Sat Sep 16 05:47:59 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7