Sun Aug 6 15:06:41 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

channel.c File Reference

Channel Management. More...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <math.h>
#include "asterisk.h"
#include "asterisk/pbx.h"
#include "asterisk/frame.h"
#include "asterisk/sched.h"
#include "asterisk/options.h"
#include "asterisk/channel.h"
#include "asterisk/chanspy.h"
#include "asterisk/musiconhold.h"
#include "asterisk/logger.h"
#include "asterisk/say.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/manager.h"
#include "asterisk/chanvars.h"
#include "asterisk/linkedlists.h"
#include "asterisk/indications.h"
#include "asterisk/monitor.h"
#include "asterisk/causes.h"
#include "asterisk/callerid.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/app.h"
#include "asterisk/transcap.h"
#include "asterisk/devicestate.h"

Include dependency graph for channel.c:

Go to the source code of this file.

Defines

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

Enumerations

enum  spy_direction { SPY_READ, SPY_WRITE }

Functions

ast_channel__ast_request_and_dial (const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
int ast_activate_generator (struct ast_channel *chan, struct ast_generator *gen, void *params)
int ast_active_channels (void)
int ast_answer (struct ast_channel *chan)
 Answer a ringing call.
void ast_begin_shutdown (int hangup)
int ast_best_codec (int fmts)
ast_channelast_bridged_channel (struct ast_channel *chan)
 Find bridged channel.
int ast_call (struct ast_channel *chan, char *addr, int timeout)
 Make a call.
void ast_cancel_shutdown (void)
const char * ast_cause2str (int cause)
void ast_change_name (struct ast_channel *chan, char *newname)
 Change channel name.
ast_channelast_channel_alloc (int needqueue)
 Create a channel structure.
enum ast_bridge_result ast_channel_bridge (struct ast_channel *c0, struct ast_channel *c1, struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
int ast_channel_cmpwhentohangup (struct ast_channel *chan, time_t offset)
 Compare a offset with the settings of when to hang a channel up.
int ast_channel_defer_dtmf (struct ast_channel *chan)
void ast_channel_free (struct ast_channel *chan)
 Free a channel structure.
void ast_channel_inherit_variables (const struct ast_channel *parent, struct ast_channel *child)
 Inherits channel variable from parent to child channel.
int ast_channel_make_compatible (struct ast_channel *chan, struct ast_channel *peer)
int ast_channel_masquerade (struct ast_channel *original, struct ast_channel *clone)
int ast_channel_register (const struct ast_channel_tech *tech)
 Register a channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports.
int ast_channel_sendhtml (struct ast_channel *chan, int subclass, const char *data, int datalen)
int ast_channel_sendurl (struct ast_channel *chan, const char *url)
int ast_channel_setoption (struct ast_channel *chan, int option, void *data, int datalen, int block)
void ast_channel_setwhentohangup (struct ast_channel *chan, time_t offset)
 Set when to hang a channel up.
int ast_channel_spy_add (struct ast_channel *chan, struct ast_channel_spy *spy)
 Adds a spy to a channel, to begin receiving copies of the channel's audio frames.
ast_frameast_channel_spy_read_frame (struct ast_channel_spy *spy, unsigned int samples)
 Read one (or more) frames of audio from a channel being spied upon.
void ast_channel_spy_remove (struct ast_channel *chan, struct ast_channel_spy *spy)
 Remove a spy from a channel.
void ast_channel_spy_stop_by_type (struct ast_channel *chan, const char *type)
 Find all spies of a particular type on a channel and stop them.
void ast_channel_spy_trigger_wait (struct ast_channel_spy *spy)
 Efficiently wait until audio is available for a spy, or an exception occurs.
ast_silence_generatorast_channel_start_silence_generator (struct ast_channel *chan)
 Starts a silence generator on the given channel.
void ast_channel_stop_silence_generator (struct ast_channel *chan, struct ast_silence_generator *state)
 Stops a previously-started silence generator on the given channel.
int ast_channel_supports_html (struct ast_channel *chan)
void ast_channel_undefer_dtmf (struct ast_channel *chan)
void ast_channel_unregister (const struct ast_channel_tech *tech)
 Unregister a channel technology.
ast_channelast_channel_walk_locked (const struct ast_channel *prev)
void ast_channels_init (void)
int ast_check_hangup (struct ast_channel *chan)
 Check to see if a channel is needing hang up.
static int ast_check_hangup_locked (struct ast_channel *chan)
void ast_deactivate_generator (struct ast_channel *chan)
int ast_do_masquerade (struct ast_channel *original)
 Start masquerading a channel XXX This is a seriously wacked out operation. We're essentially putting the guts of the clone channel into the original channel. Start by killing off the original channel's backend. I'm not sure we're going to keep this function, because while the features are nice, the cost is very high in terms of pure nastiness. XXX.
static enum ast_bridge_result ast_generic_bridge (struct ast_channel *c0, struct ast_channel *c1, struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc, struct timeval bridge_end)
ast_channelast_get_channel_by_exten_locked (const char *exten, const char *context)
ast_channelast_get_channel_by_name_locked (const char *name)
ast_channelast_get_channel_by_name_prefix_locked (const char *name, const int namelen)
const struct ast_channel_techast_get_channel_tech (const char *name)
 Get a channel technology structure by name.
ast_group_t ast_get_group (char *s)
int ast_hangup (struct ast_channel *chan)
 Hang up a channel.
int ast_indicate (struct ast_channel *chan, int condition)
 Indicates condition of channel.
void ast_install_music_functions (int(*start_ptr)(struct ast_channel *, char *), void(*stop_ptr)(struct ast_channel *), void(*cleanup_ptr)(struct ast_channel *))
void ast_moh_cleanup (struct ast_channel *chan)
int ast_moh_start (struct ast_channel *chan, char *mclass)
void ast_moh_stop (struct ast_channel *chan)
 AST_MUTEX_DEFINE_STATIC (chlock)
 AST_MUTEX_DEFINE_STATIC (uniquelock)
char * ast_print_group (char *buf, int buflen, ast_group_t group)
int ast_prod (struct ast_channel *chan)
int ast_queue_control (struct ast_channel *chan, int control)
 Queue a control frame.
int ast_queue_frame (struct ast_channel *chan, struct ast_frame *fin)
 Queue an outgoing frame.
int ast_queue_hangup (struct ast_channel *chan)
 Queue a hangup frame.
ast_frameast_read (struct ast_channel *chan)
int ast_readstring (struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
int ast_readstring_full (struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
int ast_recvchar (struct ast_channel *chan, int timeout)
char * ast_recvtext (struct ast_channel *chan, int timeout)
ast_channelast_request (const char *type, int format, void *data, int *cause)
 Requests a channel.
ast_channelast_request_and_dial (const char *type, int format, void *data, int timeout, int *outstate, const char *cidnum, const char *cidname)
 Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.
int ast_safe_sleep (struct ast_channel *chan, int ms)
 Wait for a specied amount of time, looking for hangups.
int ast_safe_sleep_conditional (struct ast_channel *chan, int ms, int(*cond)(void *), void *data)
 Wait for a specied amount of time, looking for hangups and a condition argument.
int ast_senddigit (struct ast_channel *chan, char digit)
int ast_sendtext (struct ast_channel *chan, const char *text)
void ast_set_callerid (struct ast_channel *chan, const char *callerid, const char *calleridname, const char *ani)
int ast_set_read_format (struct ast_channel *chan, int fmt)
void ast_set_variables (struct ast_channel *chan, struct ast_variable *vars)
 adds a list of channel variables to a channel
int ast_set_write_format (struct ast_channel *chan, int fmt)
int ast_setstate (struct ast_channel *chan, int state)
 Change the state of a channel.
int ast_settimeout (struct ast_channel *c, int samples, int(*func)(void *data), void *data)
int ast_shutting_down (void)
int ast_softhangup (struct ast_channel *chan, int cause)
 Softly hangup up a channel.
int ast_softhangup_nolock (struct ast_channel *chan, int cause)
 Softly hangup up a channel (no channel lock).
char * ast_state2str (int state)
int ast_tonepair (struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
int ast_tonepair_start (struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
void ast_tonepair_stop (struct ast_channel *chan)
int ast_transfer (struct ast_channel *chan, char *dest)
 Transfer a channel (if supported). Returns -1 on error, 0 if not supported and 1 if supported and requested.
char * ast_transfercapability2str (int transfercapability)
void ast_uninstall_music_functions (void)
int ast_waitfor (struct ast_channel *c, int ms)
 Wait for input on a channel.
ast_channelast_waitfor_n (struct ast_channel **c, int n, int *ms)
int ast_waitfor_n_fd (int *fds, int n, int *ms, int *exception)
ast_channelast_waitfor_nandfds (struct ast_channel **c, int n, int *fds, int nfds, int *exception, int *outfd, int *ms)
 Waits for activity on a group of channels.
int ast_waitfordigit (struct ast_channel *c, int ms)
int ast_waitfordigit_full (struct ast_channel *c, int ms, int audiofd, int cmdfd)
ast_channelast_walk_channel_by_name_prefix_locked (struct ast_channel *chan, const char *name, const int namelen)
int ast_write (struct ast_channel *chan, struct ast_frame *fr)
int ast_write_video (struct ast_channel *chan, struct ast_frame *fr)
static void bridge_playfile (struct ast_channel *chan, struct ast_channel *peer, char *sound, int remain)
static struct ast_channelchannel_find_locked (const struct ast_channel *prev, const char *name, const int namelen, const char *context, const char *exten)
static void clone_variables (struct ast_channel *original, struct ast_channel *clone)
static void copy_data_from_queue (struct ast_channel_spy_queue *queue, short *buf, unsigned int samples)
static void detach_spies (struct ast_channel *chan)
static int do_senddigit (struct ast_channel *chan, char digit)
static void free_cid (struct ast_callerid *cid)
static void free_translation (struct ast_channel *clone)
static int generator_force (void *data)
static void queue_frame_to_spies (struct ast_channel *chan, struct ast_frame *f, enum spy_direction dir)
static int set_format (struct ast_channel *chan, int fmt, int *rawformat, int *format, struct ast_trans_pvt **trans, const int direction)
static int show_channeltypes (int fd, int argc, char *argv[])
static void * silence_generator_alloc (struct ast_channel *chan, void *data)
static int silence_generator_generate (struct ast_channel *chan, void *data, int len, int samples)
static void silence_generator_release (struct ast_channel *chan, void *data)
static void * tonepair_alloc (struct ast_channel *chan, void *params)
static int tonepair_generator (struct ast_channel *chan, void *data, int len, int samples)
static void tonepair_release (struct ast_channel *chan, void *params)

Variables

static void(* ast_moh_cleanup_ptr )(struct ast_channel *) = NULL
static int(* ast_moh_start_ptr )(struct ast_channel *, char *) = NULL
static void(* ast_moh_stop_ptr )(struct ast_channel *) = NULL
static struct chanlistbackends = NULL
const struct ast_cause causes []
static struct ast_channelchannels = NULL
static struct ast_cli_entry cli_show_channeltypes
unsigned long global_fin = 0
unsigned long global_fout = 0
static const struct ast_channel_tech null_tech
static char show_channeltypes_usage []
static int shutting_down = 0
static struct ast_generator silence_generator
static struct ast_generator tonepair
static int uniqueint = 0


Detailed Description

Channel Management.

Definition in file channel.c.


Define Documentation

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

#define SPY_QUEUE_SAMPLE_LIMIT   4000
 

Definition at line 1144 of file channel.c.

Referenced by queue_frame_to_spies().


Enumeration Type Documentation

enum spy_direction
 

Enumeration values:
SPY_READ 
SPY_WRITE 

Definition at line 1139 of file channel.c.

01139                    {
01140    SPY_READ,
01141    SPY_WRITE,
01142 };


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

02381 {
02382    int state = 0;
02383    int cause = 0;
02384    struct ast_channel *chan;
02385    struct ast_frame *f;
02386    int res = 0;
02387    
02388    chan = ast_request(type, format, data, &cause);
02389    if (chan) {
02390       if (oh) {
02391          if (oh->vars)  
02392             ast_set_variables(chan, oh->vars);
02393          if (oh->cid_num && *oh->cid_num && oh->cid_name && *oh->cid_name)
02394             ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
02395          if (oh->parent_channel)
02396             ast_channel_inherit_variables(oh->parent_channel, chan);
02397          if (oh->account)
02398             ast_cdr_setaccount(chan, oh->account); 
02399       }
02400       ast_set_callerid(chan, cid_num, cid_name, cid_num);
02401 
02402       if (!ast_call(chan, data, 0)) {
02403          res = 1; /* in case chan->_state is already AST_STATE_UP */
02404          while (timeout && (chan->_state != AST_STATE_UP)) {
02405             res = ast_waitfor(chan, timeout);
02406             if (res < 0) {
02407                /* Something not cool, or timed out */
02408                break;
02409             }
02410             /* If done, break out */
02411             if (!res)
02412                break;
02413             if (timeout > -1)
02414                timeout = res;
02415             f = ast_read(chan);
02416             if (!f) {
02417                state = AST_CONTROL_HANGUP;
02418                res = 0;
02419                break;
02420             }
02421             if (f->frametype == AST_FRAME_CONTROL) {
02422                if (f->subclass == AST_CONTROL_RINGING)
02423                   state = AST_CONTROL_RINGING;
02424                else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
02425                   state = f->subclass;
02426                   ast_frfree(f);
02427                   break;
02428                } else if (f->subclass == AST_CONTROL_ANSWER) {
02429                   state = f->subclass;
02430                   ast_frfree(f);
02431                   break;
02432                } else if (f->subclass == AST_CONTROL_PROGRESS) {
02433                   /* Ignore */
02434                } else if (f->subclass == -1) {
02435                   /* Ignore -- just stopping indications */
02436                } else {
02437                   ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
02438                }
02439             }
02440             ast_frfree(f);
02441          }
02442       } else
02443          ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
02444    } else {
02445       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
02446       switch(cause) {
02447       case AST_CAUSE_BUSY:
02448          state = AST_CONTROL_BUSY;
02449          break;
02450       case AST_CAUSE_CONGESTION:
02451          state = AST_CONTROL_CONGESTION;
02452          break;
02453       }
02454    }
02455    if (chan) {
02456       /* Final fixups */
02457       if (oh) {
02458          if (oh->context && *oh->context)
02459             ast_copy_string(chan->context, oh->context, sizeof(chan->context));
02460          if (oh->exten && *oh->exten)
02461             ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
02462          if (oh->priority) 
02463             chan->priority = oh->priority;
02464       }
02465       if (chan->_state == AST_STATE_UP) 
02466          state = AST_CONTROL_ANSWER;
02467    }
02468    if (outstate)
02469       *outstate = state;
02470    if (chan && res <= 0) {
02471       if (!chan->cdr) {
02472          chan->cdr = ast_cdr_alloc();
02473          if (chan->cdr)
02474             ast_cdr_init(chan->cdr, chan);
02475       }
02476       if (chan->cdr) {
02477          char tmp[256];
02478          snprintf(tmp, 256, "%s/%s", type, (char *)data);
02479          ast_cdr_setapp(chan->cdr,"Dial",tmp);
02480          ast_cdr_update(chan);
02481          ast_cdr_start(chan->cdr);
02482          ast_cdr_end(chan->cdr);
02483          /* If the cause wasn't handled properly */
02484          if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
02485             ast_cdr_failed(chan->cdr);
02486       } else 
02487          ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
02488       ast_hangup(chan);
02489       chan = NULL;
02490    }
02491    return chan;
02492 }

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

Activate a given generator

Definition at line 1423 of file channel.c.

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

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

01424 {
01425    int res = 0;
01426 
01427    ast_mutex_lock(&chan->lock);
01428 
01429    if (chan->generatordata) {
01430       if (chan->generator && chan->generator->release)
01431          chan->generator->release(chan, chan->generatordata);
01432       chan->generatordata = NULL;
01433    }
01434 
01435    ast_prod(chan);
01436    if (gen->alloc) {
01437       if (!(chan->generatordata = gen->alloc(chan, params)))
01438          res = -1;
01439    }
01440    
01441    if (!res) {
01442       ast_settimeout(chan, 160, generator_force, chan);
01443       chan->generator = gen;
01444    }
01445 
01446    ast_mutex_unlock(&chan->lock);
01447 
01448    return res;
01449 }

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 1359 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::lock, and ast_channel::tech.

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

01360 {
01361    int res = 0;
01362    ast_mutex_lock(&chan->lock);
01363    /* Stop if we're a zombie or need a soft hangup */
01364    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
01365       ast_mutex_unlock(&chan->lock);
01366       return -1;
01367    }
01368    switch(chan->_state) {
01369    case AST_STATE_RINGING:
01370    case AST_STATE_RING:
01371       if (chan->tech->answer)
01372          res = chan->tech->answer(chan);
01373       ast_setstate(chan, AST_STATE_UP);
01374       if (chan->cdr)
01375          ast_cdr_answer(chan->cdr);
01376       ast_mutex_unlock(&chan->lock);
01377       return res;
01378       break;
01379    case AST_STATE_UP:
01380       if (chan->cdr)
01381          ast_cdr_answer(chan->cdr);
01382       break;
01383    }
01384    ast_mutex_unlock(&chan->lock);
01385    return 0;
01386 }

void ast_begin_shutdown int  hangup  ) 
 

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

Definition at line 234 of file channel.c.

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

Referenced by quit_handler().

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

int ast_best_codec int  fmts  ) 
 

Pick the best codec

Definition at line 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(), 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 3202 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(), schedule_delivery(), skinny_ss(), socket_read(), ss_thread(), start_spying(), startmon(), zt_handle_event(), and zt_hangup().

03203 {
03204    struct ast_channel *bridged;
03205    bridged = chan->_bridge;
03206    if (bridged && bridged->tech->bridged_channel) 
03207       bridged = bridged->tech->bridged_channel(chan, bridged);
03208    return bridged;
03209 }

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

02559 {
02560    /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 
02561       If the remote end does not answer within the timeout, then do NOT hang up, but 
02562       return anyway.  */
02563    int res = -1;
02564    /* Stop if we're a zombie or need a soft hangup */
02565    ast_mutex_lock(&chan->lock);
02566    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) 
02567       if (chan->tech->call)
02568          res = chan->tech->call(chan, addr, timeout);
02569    ast_mutex_unlock(&chan->lock);
02570    return res;
02571 }

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.

Referenced by __transmit_response(), ast_do_masquerade(), 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 2811 of file channel.c.

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

02812 {
02813    char tmp[256];
02814    ast_copy_string(tmp, chan->name, sizeof(tmp));
02815    ast_copy_string(chan->name, newname, sizeof(chan->name));
02816    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid);
02817 }

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_channel::_state, ast_channel::accountcode, ast_channel::alertpipe, ast_channel::amaflags, ast_channel::appl, ast_default_accountcode, ast_default_amaflags, AST_LIST_HEAD_INIT_NOLOCK, ast_log(), AST_MAX_FDS, ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DOWN, channels, ast_channel::context, ast_channel::data, defaultlanguage, ast_channel::exten, ast_channel::fds, ast_channel::fin, ast_channel::flags, ast_channel::fout, free, global_fin, global_fout, ast_channel::language, ast_channel::lock, LOG_WARNING, malloc, ast_channel::name, ast_channel::next, ast_channel::priority, ast_channel::sched, sched_context_create(), shutting_down, ast_channel::streamid, ast_channel::tech, ast_channel::timingfd, ast_channel::uniqueid, uniqueint, and ast_channel::varshead.

Referenced by __oh323_new(), acf_odbc_write(), 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 3363 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, ast_bridge_config::end_sound, EVENT_FLAG_CALL, ast_bridge_config::features_callee, ast_bridge_config::features_caller, ast_bridge_config::firstpass, ast_bridge_config::flags, ast_channel::generator, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, option_verbose, ast_bridge_config::play_warning, ast_channel::readformat, ast_channel::spies, ast_bridge_config::start_sound, ast_bridge_config::start_time, ast_channel::tech, ast_bridge_config::timelimit, ast_channel::uniqueid, VERBOSE_PREFIX_3, ast_bridge_config::warning_freq, ast_bridge_config::warning_sound, and ast_channel::writeformat.

Referenced by ast_bridge_call().

03365 {
03366    struct ast_channel *who = NULL;
03367    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
03368    int nativefailed=0;
03369    int firstpass;
03370    int o0nativeformats;
03371    int o1nativeformats;
03372    long time_left_ms=0;
03373    struct timeval nexteventts = { 0, };
03374    char caller_warning = 0;
03375    char callee_warning = 0;
03376    int to;
03377 
03378    if (c0->_bridge) {
03379       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
03380          c0->name, c0->_bridge->name);
03381       return -1;
03382    }
03383    if (c1->_bridge) {
03384       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
03385          c1->name, c1->_bridge->name);
03386       return -1;
03387    }
03388    
03389    /* Stop if we're a zombie or need a soft hangup */
03390    if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
03391        ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 
03392       return -1;
03393 
03394    *fo = NULL;
03395    firstpass = config->firstpass;
03396    config->firstpass = 0;
03397 
03398    if (ast_tvzero(config->start_time))
03399       config->start_time = ast_tvnow();
03400    time_left_ms = config->timelimit;
03401 
03402    caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
03403    callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
03404 
03405    if (config->start_sound && firstpass) {
03406       if (caller_warning)
03407          bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000);
03408       if (callee_warning)
03409          bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000);
03410    }
03411 
03412    /* Keep track of bridge */
03413    c0->_bridge = c1;
03414    c1->_bridge = c0;
03415    
03416    manager_event(EVENT_FLAG_CALL, "Link", 
03417             "Channel1: %s\r\n"
03418             "Channel2: %s\r\n"
03419             "Uniqueid1: %s\r\n"
03420             "Uniqueid2: %s\r\n"
03421             "CallerID1: %s\r\n"
03422             "CallerID2: %s\r\n",
03423             c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
03424                                                                         
03425    o0nativeformats = c0->nativeformats;
03426    o1nativeformats = c1->nativeformats;
03427 
03428    if (config->timelimit) {
03429       nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
03430       if (caller_warning || callee_warning)
03431          nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000));
03432    }
03433 
03434    for (/* ever */;;) {
03435       to = -1;
03436       if (config->timelimit) {
03437          struct timeval now;
03438          now = ast_tvnow();
03439          to = ast_tvdiff_ms(nexteventts, now);
03440          if (to < 0)
03441             to = 0;
03442          time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
03443          if (time_left_ms < to)
03444             to = time_left_ms;
03445 
03446          if (time_left_ms <= 0) {
03447             if (caller_warning && config->end_sound)
03448                bridge_playfile(c0, c1, config->end_sound, 0);
03449             if (callee_warning && config->end_sound)
03450                bridge_playfile(c1, c0, config->end_sound, 0);
03451             *fo = NULL;
03452             if (who) 
03453                *rc = who;
03454             res = 0;
03455             break;
03456          }
03457          
03458          if (!to) {
03459             if (time_left_ms >= 5000) {
03460                /* force the time left to round up if appropriate */
03461                if (caller_warning && config->warning_sound && config->play_warning)
03462                   bridge_playfile(c0, c1, config->warning_sound,
03463                         (time_left_ms + 500) / 1000);
03464                if (callee_warning && config->warning_sound && config->play_warning)
03465                   bridge_playfile(c1, c0, config->warning_sound,
03466                         (time_left_ms + 500) / 1000);
03467             }
03468             if (config->warning_freq) {
03469                nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000));
03470             } else
03471                nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
03472          }
03473       }
03474 
03475       if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
03476          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03477             c0->_softhangup = 0;
03478          if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03479             c1->_softhangup = 0;
03480          c0->_bridge = c1;
03481          c1->_bridge = c0;
03482          ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n");
03483          continue;
03484       }
03485       
03486       /* Stop if we're a zombie or need a soft hangup */
03487       if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
03488           ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
03489          *fo = NULL;
03490          if (who)
03491             *rc = who;
03492          res = 0;
03493          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",
03494             c0->name, c1->name,
03495             ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
03496             ast_check_hangup(c0) ? "Yes" : "No",
03497             ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
03498             ast_check_hangup(c1) ? "Yes" : "No");
03499          break;
03500       }
03501 
03502       if (c0->tech->bridge &&
03503           (config->timelimit == 0) &&
03504           (c0->tech->bridge == c1->tech->bridge) &&
03505           !nativefailed && !c0->monitor && !c1->monitor &&
03506           !c0->spies && !c1->spies && !ast_test_flag(&(config->features_callee),AST_FEATURE_REDIRECT) &&
03507           !ast_test_flag(&(config->features_caller),AST_FEATURE_REDIRECT) ) {
03508          /* Looks like they share a bridge method and nothing else is in the way */
03509          if (option_verbose > 2) 
03510             ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name);
03511          ast_set_flag(c0, AST_FLAG_NBRIDGE);
03512          ast_set_flag(c1, AST_FLAG_NBRIDGE);
03513          if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) {
03514             manager_event(EVENT_FLAG_CALL, "Unlink", 
03515                      "Channel1: %s\r\n"
03516                      "Channel2: %s\r\n"
03517                      "Uniqueid1: %s\r\n"
03518                      "Uniqueid2: %s\r\n"
03519                      "CallerID1: %s\r\n"
03520                      "CallerID2: %s\r\n",
03521                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
03522             ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
03523 
03524             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
03525             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
03526 
03527             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03528                continue;
03529 
03530             c0->_bridge = NULL;
03531             c1->_bridge = NULL;
03532 
03533             return res;
03534          } else {
03535             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
03536             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
03537          }
03538          switch (res) {
03539          case AST_BRIDGE_RETRY:
03540             continue;
03541          default:
03542             ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name);
03543             /* fallthrough */
03544          case AST_BRIDGE_FAILED_NOWARN:
03545             nativefailed++;
03546             break;
03547          }
03548       }
03549    
03550       if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
03551           (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
03552           !(c0->generator || c1->generator)) {
03553          if (ast_channel_make_compatible(c0, c1)) {
03554             ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
03555                                 manager_event(EVENT_FLAG_CALL, "Unlink",
03556                      "Channel1: %s\r\n"
03557                      "Channel2: %s\r\n"
03558                      "Uniqueid1: %s\r\n"
03559                      "Uniqueid2: %s\r\n"
03560                      "CallerID1: %s\r\n"
03561                      "CallerID2: %s\r\n",
03562                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
03563             return AST_BRIDGE_FAILED;
03564          }
03565          o0nativeformats = c0->nativeformats;
03566          o1nativeformats = c1->nativeformats;
03567       }
03568       res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts);
03569       if (res != AST_BRIDGE_RETRY)
03570          break;
03571    }
03572 
03573    c0->_bridge = NULL;
03574    c1->_bridge = NULL;
03575 
03576    manager_event(EVENT_FLAG_CALL, "Unlink",
03577             "Channel1: %s\r\n"
03578             "Channel2: %s\r\n"
03579             "Uniqueid1: %s\r\n"
03580             "Uniqueid2: %s\r\n"
03581             "CallerID1: %s\r\n"
03582             "CallerID2: %s\r\n",
03583             c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
03584    ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
03585 
03586    return res;
03587 }

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, 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 acf_odbc_write(), agent_cleanup(), agent_new(), ast_do_masquerade(), 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 2819 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().

02820 {
02821    struct ast_var_t *current, *newvar;
02822    char *varname;
02823 
02824    AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
02825       int vartype = 0;
02826 
02827       varname = ast_var_full_name(current);
02828       if (!varname)
02829          continue;
02830 
02831       if (varname[0] == '_') {
02832          vartype = 1;
02833          if (varname[1] == '_')
02834             vartype = 2;
02835       }
02836 
02837       switch (vartype) {
02838       case 1:
02839          newvar = ast_var_assign(&varname[1], ast_var_value(current));
02840          if (newvar) {
02841             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
02842             if (option_debug)
02843                ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
02844          }
02845          break;
02846       case 2:
02847          newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current));
02848          if (newvar) {
02849             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
02850             if (option_debug)
02851                ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
02852          }
02853          break;
02854       default:
02855          if (option_debug)
02856             ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current));
02857          break;
02858       }
02859    }
02860 }

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

02698 {
02699    int src;
02700    int dst;
02701 
02702    /* Set up translation from the chan to the peer */
02703    src = chan->nativeformats;
02704    dst = peer->nativeformats;
02705    if (ast_translator_best_choice(&dst, &src) < 0) {
02706       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst);
02707       return -1;
02708    }
02709 
02710    /* if the best path is not 'pass through', then
02711       transcoding is needed; if desired, force transcode path
02712       to use SLINEAR between channels */
02713    if ((src != dst) && option_transcode_slin)
02714       dst = AST_FORMAT_SLINEAR;
02715    if (ast_set_read_format(chan, dst) < 0) {
02716       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst);
02717       return -1;
02718    }
02719    if (ast_set_write_format(peer, dst) < 0) {
02720       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, dst);
02721       return -1;
02722    }
02723 
02724    /* Set up translation from the peer to the chan */
02725    src = peer->nativeformats;
02726    dst = chan->nativeformats;
02727    if (ast_translator_best_choice(&dst, &src) < 0) {
02728       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst);
02729       return -1;
02730    }
02731    /* if the best path is not 'pass through', then
02732       transcoding is needed; if desired, force transcode path
02733       to use SLINEAR between channels */
02734    if ((src != dst) && option_transcode_slin)
02735       dst = AST_FORMAT_SLINEAR;
02736    if (ast_set_read_format(peer, dst) < 0) {
02737       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst);
02738       return -1;
02739    }
02740    if (ast_set_write_format(chan, dst) < 0) {
02741       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, dst);
02742       return -1;
02743    }
02744    return 0;
02745 }

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

02748 {
02749    struct ast_frame null = { AST_FRAME_NULL, };
02750    int res = -1;
02751    struct ast_channel *final_orig = original, *final_clone = clone;
02752 
02753    ast_mutex_lock(&original->lock);
02754    while(ast_mutex_trylock(&clone->lock)) {
02755       ast_mutex_unlock(&original->lock);
02756       usleep(1);
02757       ast_mutex_lock(&original->lock);
02758    }
02759 
02760    /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent)
02761       and if so, we don't really want to masquerade it, but its proxy */
02762    if (original->_bridge && (original->_bridge != ast_bridged_channel(original)))
02763       final_orig = original->_bridge;
02764 
02765    if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone)))
02766       final_clone = clone->_bridge;
02767 
02768    if ((final_orig != original) || (final_clone != clone)) {
02769       ast_mutex_lock(&final_orig->lock);
02770       while(ast_mutex_trylock(&final_clone->lock)) {
02771          ast_mutex_unlock(&final_orig->lock);
02772          usleep(1);
02773          ast_mutex_lock(&final_orig->lock);
02774       }
02775       ast_mutex_unlock(&clone->lock);
02776       ast_mutex_unlock(&original->lock);
02777       original = final_orig;
02778       clone = final_clone;
02779    }
02780 
02781    if (original == clone) {
02782       ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
02783       ast_mutex_unlock(&clone->lock);
02784       ast_mutex_unlock(&original->lock);
02785       return -1;
02786    }
02787 
02788    ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n",
02789       clone->name, original->name);
02790    if (original->masq) {
02791       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
02792          original->masq->name, original->name);
02793    } else if (clone->masqr) {
02794       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
02795          clone->name, clone->masqr->name);
02796    } else {
02797       original->masq = clone;
02798       clone->masqr = original;
02799       ast_queue_frame(original, &null);
02800       ast_queue_frame(clone, &null);
02801       ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name);
02802       res = 0;
02803    }
02804 
02805    ast_mutex_unlock(&clone->lock);
02806    ast_mutex_unlock(&original->lock);
02807 
02808    return res;
02809 }

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

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

Referenced by agent_sendhtml(), and wait_for_answer().

02684 {
02685    if (chan->tech->send_html)
02686       return chan->tech->send_html(chan, subclass, data, datalen);
02687    return -1;
02688 }

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

References AST_HTML_URL.

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

02691 {
02692    if (chan->tech->send_html)
02693       return chan->tech->send_html(chan, AST_HTML_URL, url, strlen(url) + 1);
02694    return -1;
02695 }

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

03591 {
03592    int res;
03593 
03594    if (chan->tech->setoption) {
03595       res = chan->tech->setoption(chan, option, data, datalen);
03596       if (res < 0)
03597          return res;
03598    } else {
03599       errno = ENOSYS;
03600       return -1;
03601    }
03602    if (block) {
03603       /* XXX Implement blocking -- just wait for our option frame reply, discarding
03604          intermediate packets. XXX */
03605       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
03606       return -1;
03607    }
03608    return 0;
03609 }

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 }

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

03900 {
03901    struct ast_frame *result;
03902    /* buffers are allocated to hold SLINEAR, which is the largest format */
03903         short read_buf[samples];
03904         short write_buf[samples];
03905    struct ast_frame *read_frame;
03906    struct ast_frame *write_frame;
03907    int need_dup;
03908    struct ast_frame stack_read_frame = { .frametype = AST_FRAME_VOICE,
03909                      .subclass = spy->read_queue.format,
03910                      .data = read_buf,
03911                      .samples = samples,
03912                      .datalen = ast_codec_get_len(spy->read_queue.format, samples),
03913    };
03914    struct ast_frame stack_write_frame = { .frametype = AST_FRAME_VOICE,
03915                       .subclass = spy->write_queue.format,
03916                       .data = write_buf,
03917                       .samples = samples,
03918                       .datalen = ast_codec_get_len(spy->write_queue.format, samples),
03919    };
03920 
03921    /* if a flush has been requested, dump everything in whichever queue is larger */
03922    if (ast_test_flag(spy, CHANSPY_TRIGGER_FLUSH)) {
03923       if (spy->read_queue.samples > spy->write_queue.samples) {
03924          if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST)) {
03925             for (result = spy->read_queue.head; result; result = result->next)
03926                ast_frame_adjust_volume(result, spy->read_vol_adjustment);
03927          }
03928          result = spy->read_queue.head;
03929          spy->read_queue.head = NULL;
03930          spy->read_queue.samples = 0;
03931          ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH);
03932          return result;
03933       } else {
03934          if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST)) {
03935             for (result = spy->write_queue.head; result; result = result->next)
03936                ast_frame_adjust_volume(result, spy->write_vol_adjustment);
03937          }
03938          result = spy->write_queue.head;
03939          spy->write_queue.head = NULL;
03940          spy->write_queue.samples = 0;
03941          ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH);
03942          return result;
03943       }
03944    }
03945 
03946    if ((spy->read_queue.samples < samples) || (spy->write_queue.samples < samples))
03947       return NULL;
03948 
03949    /* short-circuit if both head frames have exactly what we want */
03950    if ((spy->read_queue.head->samples == samples) &&
03951        (spy->write_queue.head->samples == samples)) {
03952       read_frame = spy->read_queue.head;
03953       spy->read_queue.head = read_frame->next;
03954       read_frame->next = NULL;
03955 
03956       write_frame = spy->write_queue.head;
03957       spy->write_queue.head = write_frame->next;
03958       write_frame->next = NULL;
03959 
03960       spy->read_queue.samples -= samples;
03961       spy->write_queue.samples -= samples;
03962 
03963       need_dup = 0;
03964    } else {
03965       copy_data_from_queue(&spy->read_queue, read_buf, samples);
03966       copy_data_from_queue(&spy->write_queue, write_buf, samples);
03967 
03968       read_frame = &stack_read_frame;
03969       write_frame = &stack_write_frame;
03970       need_dup = 1;
03971    }
03972    
03973    if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST))
03974       ast_frame_adjust_volume(read_frame, spy->read_vol_adjustment);
03975 
03976    if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST))
03977       ast_frame_adjust_volume(write_frame, spy->write_vol_adjustment);
03978 
03979    if (ast_test_flag(spy, CHANSPY_MIXAUDIO)) {
03980       ast_frame_slinear_sum(read_frame, write_frame);
03981 
03982       if (need_dup)
03983          result = ast_frdup(read_frame);
03984       else {
03985          result = read_frame;
03986          ast_frfree(write_frame);
03987       }
03988    } else {
03989       if (need_dup) {
03990          result = ast_frdup(read_frame);
03991          result->next = ast_frdup(write_frame);
03992       } else {
03993          result = read_frame;
03994          result->next = write_frame;
03995       }
03996    }
03997 
03998    return result;
03999 }

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

References ast_cond_destroy(), ast_frfree(), AST_LIST_EMPTY, AST_LIST_REMOVE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_translator_free_path(), ast_channel_spy::chan, CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_NONE, free, ast_channel_spy_queue::head, list, ast_channel_spy::lock, LOG_DEBUG, ast_channel::name, ast_frame::next, channel_spy_trans::path, ast_channel_spy::read_queue, ast_channel_spy_list::read_translator, ast_channel::spies, ast_channel_spy::trigger, ast_channel_spy::type, ast_channel_spy::write_queue, and ast_channel_spy_list::write_translator.

Referenced by detach_spies(), stop_spying(), and stopmon().

01051 {
01052    struct ast_frame *f;
01053 
01054    if (!chan->spies)
01055       return;
01056 
01057    AST_LIST_REMOVE(&chan->spies->list, spy, list);
01058 
01059    ast_mutex_lock(&spy->lock);
01060 
01061    spy->chan = NULL;
01062 
01063    for (f = spy->read_queue.head; f; f = spy->read_queue.head) {
01064       spy->read_queue.head = f->next;
01065       ast_frfree(f);
01066    }
01067    for (f = spy->write_queue.head; f; f = spy->write_queue.head) {
01068       spy->write_queue.head = f->next;
01069       ast_frfree(f);
01070    }
01071 
01072    if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
01073       ast_cond_destroy(&spy->trigger);
01074 
01075    ast_mutex_unlock(&spy->lock);
01076 
01077    ast_log(LOG_DEBUG, "Spy %s removed from channel %s\n",
01078       spy->type, chan->name);
01079 
01080    if (AST_LIST_EMPTY(&chan->spies->list)) {
01081       if (chan->spies->read_translator.path)
01082          ast_translator_free_path(chan->spies->read_translator.path);
01083       if (chan->spies->write_translator.path)
01084          ast_translator_free_path(chan->spies->write_translator.path);
01085       free(chan->spies);
01086       chan->spies = NULL;
01087    }
01088 }

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

References ast_cond_signal(), AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, CHANSPY_RUNNING, CHANSPY_STOP, CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_NONE, list, ast_channel_spy::lock, ast_channel::spies, ast_channel_spy::status, and ast_channel_spy::type.

Referenced by mixmonitor_cli().

01021 {
01022    struct ast_channel_spy *spy;
01023    
01024    if (!chan->spies)
01025       return;
01026 
01027    AST_LIST_TRAVERSE(&chan->spies->list, spy, list) {
01028       ast_mutex_lock(&spy->lock);
01029       if ((spy->type == type) && (spy->status == CHANSPY_RUNNING)) {
01030          spy->status = CHANSPY_STOP;
01031          if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
01032             ast_cond_signal(&spy->trigger);
01033       }
01034       ast_mutex_unlock(&spy->lock);
01035    }
01036 }

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

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

Referenced by mixmonitor_thread().

01039 {
01040    struct timeval tv;
01041    struct timespec ts;
01042 
01043    tv = ast_tvadd(ast_tvnow(), ast_samp2tv(50000, 1000));
01044    ts.tv_sec = tv.tv_sec;
01045    ts.tv_nsec = tv.tv_usec * 1000;
01046 
01047    ast_cond_timedwait(&spy->trigger, &spy->lock, &ts);
01048 }

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 4057 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, and option_debug.

Referenced by ast_play_and_record_full(), and record_exec().

04058 {
04059    struct ast_silence_generator *state;
04060 
04061    if (!(state = calloc(1, sizeof(*state)))) {
04062       ast_log(LOG_WARNING, "Could not allocate state structure\n");
04063       return NULL;
04064    }
04065 
04066    state->old_write_format = chan->writeformat;
04067 
04068    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
04069       ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
04070       free(state);
04071       return NULL;
04072    }
04073 
04074    ast_activate_generator(chan, &silence_generator, state);
04075 
04076    if (option_debug)
04077       ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name);
04078 
04079    return state;
04080 }

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

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

Referenced by ast_play_and_record_full(), and record_exec().

04083 {
04084    if (!state)
04085       return;
04086 
04087    ast_deactivate_generator(chan);
04088 
04089    if (option_debug)
04090       ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name);
04091 
04092    if (ast_set_write_format(chan, state->old_write_format) < 0)
04093       ast_log(LOG_ERROR, "Could not return write format to its original state\n");
04094 
04095    free(state);
04096 }

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

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

02677 {
02678    if (chan->tech->send_html)
02679       return 1;
02680    return 0;
02681 }

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

References ast_cli_register().

Referenced by main().

03830 {
03831    ast_cli_register(&cli_show_channeltypes);
03832 }

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_rtp_bridge(), ast_sendtext(), ast_transfer(), ast_waitfordigit(), ast_waitfordigit_full(), ast_write(), builtin_atxfer(), channel_spy(), chanspy_exec(), handle_sendimage(), iax2_bridge(), 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(), and ast_mutex_unlock().

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

01391 {
01392    ast_mutex_lock(&chan->lock);
01393    if (chan->generatordata) {
01394       if (chan->generator && chan->generator->release) 
01395          chan->generator->release(chan, chan->generatordata);
01396       chan->generatordata = NULL;
01397       chan->generator = NULL;
01398       ast_clear_flag(chan, AST_FLAG_WRITE_INT);
01399       ast_settimeout(chan, 0, NULL, NULL);
01400    }
01401    ast_mutex_unlock(&chan->lock);
01402 }

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

References ast_channel::_softhangup, ast_channel::_state, ast_channel::adsicpe, ast_channel::alertpipe, ast_cause2str(), ast_channel_free(), ast_copy_flags, AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FLAG_ZOMBIE, AST_FRAME_NULL, AST_LIST_HEAD_INIT_NOLOCK, ast_log(), AST_MAX_FDS, ast_mutex_lock(), ast_mutex_unlock(), ast_queue_frame(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_channel::blocker, ast_channel::cid, clone_variables(), EVENT_FLAG_CALL, ast_channel::fdno, ast_channel::fds, ast_channel_tech::fixup, free_translation(), ast_channel_tech::hangup, ast_channel::hangupcause, ast_channel::language, ast_channel::lock, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::musicclass, ast_channel::name, ast_channel::nativeformats, ast_frame::next, option_debug, ast_frame::prev, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::readq, t, ast_channel::tech, ast_channel::tech_pvt, ast_channel::timingfd, ast_channel::type, ast_channel::uniqueid, ast_channel::varshead, 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().

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

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

References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_HTML, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree(), ast_indicate(), ast_log(), ast_read(), AST_SOFTHANGUP_UNBRIDGE, ast_waitfor_n(), ast_write(), ast_bridge_config::flags, ast_frame::frametype, last, LOG_DEBUG, ast_channel::nativeformats, ast_frame::subclass, and ast_channel::tech_pvt.

Referenced by ast_channel_bridge().

03252 {
03253    /* Copy voice back and forth between the two channels. */
03254    struct ast_channel *cs[3];
03255    struct ast_frame *f;
03256    struct ast_channel *who = NULL;
03257    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
03258    int o0nativeformats;
03259    int o1nativeformats;
03260    int watch_c0_dtmf;
03261    int watch_c1_dtmf;
03262    void *pvt0, *pvt1;
03263    int to;
03264    
03265    cs[0] = c0;
03266    cs[1] = c1;
03267    pvt0 = c0->tech_pvt;
03268    pvt1 = c1->tech_pvt;
03269    o0nativeformats = c0->nativeformats;
03270    o1nativeformats = c1->nativeformats;
03271    watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
03272    watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
03273 
03274    for (;;) {
03275       if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
03276           (o0nativeformats != c0->nativeformats) ||
03277           (o1nativeformats != c1->nativeformats)) {
03278          /* Check for Masquerade, codec changes, etc */
03279          res = AST_BRIDGE_RETRY;
03280          break;
03281       }
03282       if (bridge_end.tv_sec) {
03283          to = ast_tvdiff_ms(bridge_end, ast_tvnow());
03284          if (to <= 0) {
03285             res = AST_BRIDGE_RETRY;
03286             break;
03287          }
03288       } else
03289          to = -1;
03290       who = ast_waitfor_n(cs, 2, &to);
03291       if (!who) {
03292          ast_log(LOG_DEBUG, "Nobody there, continuing...\n"); 
03293          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
03294             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03295                c0->_softhangup = 0;
03296             if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03297                c1->_softhangup = 0;
03298             c0->_bridge = c1;
03299             c1->_bridge = c0;
03300          }
03301          continue;
03302       }
03303       f = ast_read(who);
03304       if (!f) {
03305          *fo = NULL;
03306          *rc = who;
03307          res = AST_BRIDGE_COMPLETE;
03308          ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
03309          break;
03310       }
03311 
03312       if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
03313          if ((f->subclass == AST_CONTROL_HOLD) || (f->subclass == AST_CONTROL_UNHOLD) ||
03314              (f->subclass == AST_CONTROL_VIDUPDATE)) {
03315             ast_indicate(who == c0 ? c1 : c0, f->subclass);
03316          } else {
03317             *fo = f;
03318             *rc = who;
03319             res =  AST_BRIDGE_COMPLETE;
03320             ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
03321             break;
03322          }
03323       }
03324       if ((f->frametype == AST_FRAME_VOICE) ||
03325           (f->frametype == AST_FRAME_DTMF) ||
03326           (f->frametype == AST_FRAME_VIDEO) || 
03327           (f->frametype == AST_FRAME_IMAGE) ||
03328           (f->frametype == AST_FRAME_HTML) ||
03329           (f->frametype == AST_FRAME_TEXT)) {
03330          if (f->frametype == AST_FRAME_DTMF) {
03331             if (((who == c0) && watch_c0_dtmf) ||
03332                 ((who == c1) && watch_c1_dtmf)) {
03333                *rc = who;
03334                *fo = f;
03335                res = AST_BRIDGE_COMPLETE;
03336                ast_log(LOG_DEBUG, "Got DTMF on channel (%s)\n", who->name);
03337                break;
03338             } else {
03339                goto tackygoto;
03340             }
03341          } else {
03342 #if 0
03343             ast_log(LOG_DEBUG, "Read from %s\n", who->name);
03344             if (who == last) 
03345                ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name);
03346             last = who;
03347 #endif
03348 tackygoto:
03349             ast_write((who == c0) ? c1 : c0, f);
03350          }
03351       }
03352       ast_frfree(f);
03353 
03354       /* Swap who gets priority */
03355       cs[2] = cs[0];
03356       cs[0] = cs[1];
03357       cs[1] = cs[2];
03358    }
03359    return res;
03360 }

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

Definition at line 818 of file channel.c.

References channel_find_locked().

Referenced by pickup_exec().

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

struct ast_channel* ast_get_channel_by_name_locked const char *  chan  ) 
 

Get channel by name (locks channel)

Definition at line 800 of file channel.c.

References channel_find_locked().

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

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

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

Get channel by name prefix (locks channel)

Definition at line 806 of file channel.c.

References channel_find_locked().

Referenced by ast_parse_device_state(), and mixmonitor_cli().

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

const struct ast_channel_tech* ast_get_channel_tech const char *  name  ) 
 

Get a channel technology structure by name.

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

Definition at line 385 of file channel.c.

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

Referenced by ast_device_state().

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

ast_group_t ast_get_group char *  s  ) 
 

Definition at line 3747 of file channel.c.

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

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

03748 {
03749    char *copy;
03750    char *piece;
03751    char *c=NULL;
03752    int start=0, finish=0, x;
03753    ast_group_t group = 0;
03754 
03755    copy = ast_strdupa(s);
03756    if (!copy) {
03757       ast_log(LOG_ERROR, "Out of memory\n");
03758       return 0;
03759    }
03760    c = copy;
03761    
03762    while((piece = strsep(&c, ","))) {
03763       if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
03764          /* Range */
03765       } else if (sscanf(piece, "%d", &start)) {
03766          /* Just one */
03767          finish = start;
03768       } else {
03769          ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
03770          continue;
03771       }
03772       for (x = start; x <= finish; x++) {
03773          if ((x > 63) || (x < 0)) {
03774             ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
03775          } else
03776             group |= ((ast_group_t) 1 << x);
03777       }
03778    }
03779    return group;
03780 }

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

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

Referenced by __ast_pbx_run(), __ast_request_and_dial(), __oh323_new(), agent_hangup(), agent_read(), alsa_new(), ast_async_goto(), ast_bridge_call_thread(), ast_feature_request_and_dial(), ast_iax2_new(), ast_modem_new(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run_app(), async_wait(), build_conf(), builtin_atxfer(), cb_events(), 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(), hangupcalls(), hanguptree(), iax2_request(), iax_park(), iax_park_thread(), local_hangup(), mgcp_new(), mgcp_ss(), nbs_new(), oss_new(), park_exec(), parkandannounce_exec(), phone_new(), release_chan(), ring_entry(), rpt(), rpt_call(), rpt_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().

01283 {
01284    int res = 0;
01285 
01286    /* Don't actually hang up a channel that will masquerade as someone else, or
01287       if someone is going to masquerade as us */
01288    ast_mutex_lock(&chan->lock);
01289 
01290    detach_spies(chan);     /* get rid of spies */
01291 
01292    if (chan->masq) {
01293       if (ast_do_masquerade(chan)) 
01294          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01295    }
01296 
01297    if (chan->masq) {
01298       ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
01299       ast_mutex_unlock(&chan->lock);
01300       return 0;
01301    }
01302    /* If this channel is one which will be masqueraded into something, 
01303       mark it as a zombie already, so we know to free it later */
01304    if (chan->masqr) {
01305       ast_set_flag(chan, AST_FLAG_ZOMBIE);
01306       ast_mutex_unlock(&chan->lock);
01307       return 0;
01308    }
01309    free_translation(chan);
01310    if (chan->stream)       /* Close audio stream */
01311       ast_closestream(chan->stream);
01312    if (chan->vstream)      /* Close video stream */
01313       ast_closestream(chan->vstream);
01314    if (chan->sched) {
01315       sched_context_destroy(chan->sched);
01316       chan->sched = NULL;
01317    }
01318    
01319    if (chan->generatordata)   /* Clear any tone stuff remaining */ 
01320       chan->generator->release(chan, chan->generatordata);
01321    chan->generatordata = NULL;
01322    chan->generator = NULL;
01323    if (chan->cdr) {     /* End the CDR if it hasn't already */ 
01324       ast_cdr_end(chan->cdr);
01325       ast_cdr_detach(chan->cdr); /* Post and Free the CDR */ 
01326       chan->cdr = NULL;
01327    }
01328    if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
01329       ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
01330                "is blocked by thread %ld in procedure %s!  Expect a failure\n",
01331                (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
01332       CRASH;
01333    }
01334    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
01335       if (option_debug)
01336          ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
01337       if (chan->tech->hangup)
01338          res = chan->tech->hangup(chan);
01339    } else {
01340       if (option_debug)
01341          ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name);
01342    }
01343          
01344    ast_mutex_unlock(&chan->lock);
01345    manager_event(EVENT_FLAG_CALL, "Hangup", 
01346          "Channel: %s\r\n"
01347          "Uniqueid: %s\r\n"
01348          "Cause: %d\r\n"
01349          "Cause-txt: %s\r\n",
01350          chan->name, 
01351          chan->uniqueid, 
01352          chan->hangupcause,
01353          ast_cause2str(chan->hangupcause)
01354          );
01355    ast_channel_free(chan);
01356    return res;
01357 }

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 2017 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_generic_bridge(), ast_park_call(), ast_play_and_record_full(), ast_rtp_bridge(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), conf_run(), dial_exec_full(), disa_exec(), do_parking_thread(), features_indicate(), function_remote(), handle_recordfile(), handle_remote_data(), handle_remote_phone_dtmf(), mgcp_ss(), park_exec(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_progress(), pbx_builtin_ringing(), queue_exec(), record_exec(), rmt_telem_finish(), rmt_telem_start(), rpt(), rpt_exec(), send_waveform_to_channel(), skinny_ss(), vpb_fixup(), and wait_for_answer().

02018 {
02019    int res = -1;
02020 
02021    ast_mutex_lock(&chan->lock);
02022    /* Stop if we're a zombie or need a soft hangup */
02023    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02024       ast_mutex_unlock(&chan->lock);
02025       return -1;
02026    }
02027    if (chan->tech->indicate)
02028       res = chan->tech->indicate(chan, condition);
02029    ast_mutex_unlock(&chan->lock);
02030    if (!chan->tech->indicate || res) {
02031       /*
02032        * Device does not support (that) indication, lets fake
02033        * it by doing our own tone generation. (PM2002)
02034        */
02035       if (condition >= 0) {
02036          const struct tone_zone_sound *ts = NULL;
02037          switch (condition) {
02038          case AST_CONTROL_RINGING:
02039             ts = ast_get_indication_tone(chan->zone, "ring");
02040             break;
02041          case AST_CONTROL_BUSY:
02042             ts = ast_get_indication_tone(chan->zone, "busy");
02043             break;
02044          case AST_CONTROL_CONGESTION:
02045             ts = ast_get_indication_tone(chan->zone, "congestion");
02046             break;
02047          }
02048          if (ts && ts->data[0]) {
02049             ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
02050             ast_playtones_start(chan,0,ts->data, 1);
02051             res = 0;
02052          } else if (condition == AST_CONTROL_PROGRESS) {
02053             /* ast_playtones_stop(chan); */
02054          } else if (condition == AST_CONTROL_PROCEEDING) {
02055             /* Do nothing, really */
02056          } else if (condition == AST_CONTROL_HOLD) {
02057             /* Do nothing.... */
02058          } else if (condition == AST_CONTROL_UNHOLD) {
02059             /* Do nothing.... */
02060          } else if (condition == AST_CONTROL_VIDUPDATE) {
02061             /* Do nothing.... */
02062          } else {
02063             /* not handled */
02064             ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
02065             res = -1;
02066          }
02067       }
02068       else ast_playtones_stop(chan);
02069    }
02070    return res;
02071 }

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

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

Referenced by load_module(), and reload().

03791 {
03792    ast_moh_start_ptr = start_ptr;
03793    ast_moh_stop_ptr = stop_ptr;
03794    ast_moh_cleanup_ptr = cleanup_ptr;
03795 }

void ast_moh_cleanup struct ast_channel chan  ) 
 

Definition at line 3823 of file channel.c.

References ast_moh_cleanup_ptr.

Referenced by ast_channel_free().

03824 {
03825    if(ast_moh_cleanup_ptr)
03826         ast_moh_cleanup_ptr(chan);
03827 }

int ast_moh_start struct ast_channel chan,
char *  mclass
 

Turn on music on hold on a given channel

Definition at line 3805 of file channel.c.

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

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

03806 {
03807    if (ast_moh_start_ptr)
03808       return ast_moh_start_ptr(chan, mclass);
03809 
03810    if (option_verbose > 2)
03811       ast_verbose(VERBOSE_PREFIX_3 "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : "default");
03812    
03813    return 0;
03814 }

void ast_moh_stop struct ast_channel chan  ) 
 

Turn off music on hold on a given channel

Definition at line 3817 of file channel.c.

References ast_moh_stop_ptr.

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

03818 {
03819    if(ast_moh_stop_ptr)
03820       ast_moh_stop_ptr(chan);
03821 }

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

Referenced by ast_serialize_showchan(), misdn_new(), and print_group().

03836 {
03837    unsigned int i;
03838    int first=1;
03839    char num[3];
03840 
03841    buf[0] = '\0';
03842    
03843    if (!group) /* Return empty string if no group */
03844       return(buf);
03845 
03846    for (i=0; i<=63; i++) { /* Max group is 63 */
03847       if (group & ((ast_group_t) 1 << i)) {
03848             if (!first) {
03849             strncat(buf, ", ", buflen);
03850          } else {
03851             first=0;
03852          }
03853          snprintf(num, sizeof(num), "%u", i);
03854          strncat(buf, num, buflen);
03855       }
03856    }
03857    return(buf);
03858 }

int ast_prod struct ast_channel chan  ) 
 

Definition at line 2173 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().

02174 {
02175    struct ast_frame a = { AST_FRAME_VOICE };
02176    char nothing[128];
02177 
02178    /* Send an empty audio frame to get things moving */
02179    if (chan->_state != AST_STATE_UP) {
02180       ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
02181       a.subclass = chan->rawwriteformat;
02182       a.data = nothing + AST_FRIENDLY_OFFSET;
02183       a.src = "ast_prod";
02184       if (ast_write(chan, &a))
02185          ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
02186    }
02187    return 0;
02188 }

int ast_queue_control struct ast_channel chan,
int  control
 

Queue a control frame.

Definition at line 682 of file channel.c.

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

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

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_do_masquerade(), ast_dsp_process(), ast_queue_control(), ast_queue_hangup(), ast_softhangup_nolock(), cb_events(), console_answer(), console_dial(), console_flash(), console_sendtext(), dictate_exec(), do_chanreads(), do_immediate_setup(), handle_message(), handle_request_info(), handle_request_invite(), handle_response_invite(), iax2_queue_frame(), local_queue_frame(), mgcp_queue_frame(), misdn_tx2ast_frm(), 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_connection(), iax2_destroy(), iax2_predestroy(), mgcp_queue_hangup(), misdn_answer(), release_chan(), retrans_pkt(), and zt_handle_event().

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

struct ast_frame* ast_read struct ast_channel chan  ) 
 

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

Definition at line 1790 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_generic_bridge(), ast_masq_park_call(), ast_play_and_prepend(), ast_play_and_record_full(), ast_recvtext(), ast_rtp_bridge(), ast_safe_sleep(), ast_safe_sleep_conditional(), ast_tonepair(), ast_waitfordigit(), ast_waitfordigit_full(), ast_waitstream(), ast_waitstream_exten(), ast_waitstream_fr(), ast_waitstream_full(), async_wait(), autoservice_run(), background_detect_exec(), builtin_atxfer(), channel_spy(), check_goto_on_transfer(), conf_exec(), conf_flush(), conf_run(), dictate_exec(), disa_exec(), do_parking_thread(), do_waiting(), echo_exec(), features_read(), find_cache(), handle_recordfile(), iax2_bridge(), iax_park_thread(), ices_exec(), measurenoise(), misdn_bridge(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), record_exec(), recordthread(), rpt(), rpt_exec(), run_agi(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), sms_exec(), ss_thread(), vpb_bridge(), wait_for_answer(), wait_for_hangup(), waitforring_exec(), and zt_bridge().

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

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

02594 {
02595    int pos=0;
02596    int to = ftimeout;
02597    int d;
02598 
02599    /* XXX Merge with full version? XXX */
02600    /* Stop if we're a zombie or need a soft hangup */
02601    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 
02602       return -1;
02603    if (!len)
02604       return -1;
02605    do {
02606       if (c->stream) {
02607          d = ast_waitstream(c, AST_DIGIT_ANY);
02608          ast_stopstream(c);
02609          usleep(1000);
02610          if (!d)
02611             d = ast_waitfordigit(c, to);
02612       } else {
02613          d = ast_waitfordigit(c, to);
02614       }
02615       if (d < 0)
02616          return -1;
02617       if (d == 0) {
02618          s[pos]='\0';
02619          return 1;
02620       }
02621       if (!strchr(enders, d))
02622          s[pos++] = d;
02623       if (strchr(enders, d) || (pos >= len)) {
02624          s[pos]='\0';
02625          return 0;
02626       }
02627       to = timeout;
02628    } while(1);
02629    /* Never reached */
02630    return 0;
02631 }

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

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

Referenced by ast_app_getdata_full().

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

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

References ast_recvtext(), and free.

Referenced by handle_recvchar().

02074 {
02075    int c;
02076    char *buf = ast_recvtext(chan, timeout);
02077    if (buf == NULL)
02078       return -1;  /* error or timeout */
02079    c = *(unsigned char *)buf;
02080    free(buf);
02081    return c;
02082 }

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

02085 {
02086    int res, done = 0;
02087    char *buf = NULL;
02088    
02089    while (!done) {
02090       struct ast_frame *f;
02091       if (ast_check_hangup(chan))
02092          break;
02093       res = ast_waitfor(chan, timeout);
02094       if (res <= 0) /* timeout or error */
02095          break;
02096       timeout = res; /* update timeout */
02097       f = ast_read(chan);
02098       if (f == NULL)
02099          break; /* no frame */
02100       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP)
02101          done = 1;   /* force a break */
02102       else if (f->frametype == AST_FRAME_TEXT) {      /* what we want */
02103          buf = strndup((char *) f->data, f->datalen); /* dup and break */
02104          done = 1;
02105       }
02106       ast_frfree(f);
02107    }
02108    return buf;
02109 }

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 2499 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(), dial_exec_full(), features_alloc(), function_ilink(), ring_entry(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), and wait_for_answer().

02500 {
02501    struct chanlist *chan;
02502    struct ast_channel *c;
02503    int capabilities;
02504    int fmt;
02505    int res;
02506    int foo;
02507 
02508    if (!cause)
02509       cause = &foo;
02510    *cause = AST_CAUSE_NOTDEFINED;
02511 
02512    if (ast_mutex_lock(&chlock)) {
02513       ast_log(LOG_WARNING, "Unable to lock channel list\n");
02514       return NULL;
02515    }
02516 
02517    for (chan = backends; chan; chan = chan->next) {
02518       if (strcasecmp(type, chan->tech->type))
02519          continue;
02520 
02521       capabilities = chan->tech->capabilities;
02522       fmt = format;
02523       res = ast_translator_best_choice(&fmt, &capabilities);
02524       if (res < 0) {
02525          ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format);
02526          ast_mutex_unlock(&chlock);
02527          return NULL;
02528       }
02529       ast_mutex_unlock(&chlock);
02530       if (!chan->tech->requester)
02531          return NULL;
02532       
02533       if (!(c = chan->tech->requester(type, capabilities, data, cause)))
02534          return NULL;
02535 
02536       if (c->_state == AST_STATE_DOWN) {
02537          manager_event(EVENT_FLAG_CALL, "Newchannel",
02538                   "Channel: %s\r\n"
02539                   "State: %s\r\n"
02540                   "CallerID: %s\r\n"
02541                   "CallerIDName: %s\r\n"
02542                   "Uniqueid: %s\r\n",
02543                   c->name, ast_state2str(c->_state),
02544                   c->cid.cid_num ? c->cid.cid_num : "<unknown>",
02545                   c->cid.cid_name ? c->cid.cid_name : "<unknown>",
02546                   c->uniqueid);
02547       }
02548       return c;
02549    }
02550 
02551    ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
02552    *cause = AST_CAUSE_NOSUCHDRIVER;
02553    ast_mutex_unlock(&chlock);
02554 
02555    return NULL;
02556 }

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

References __ast_request_and_dial().

Referenced by ast_pbx_outgoing_exten().

02495 {
02496    return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL);
02497 }

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

References do_senddigit().

Referenced by dial_exec_full(), features_digit(), and manager_play_dtmf().

02169 {
02170    return do_senddigit(chan, digit);
02171 }

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

References ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_test_flag, and CHECK_BLOCKING.

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

02112 {
02113    int res = 0;
02114    /* Stop if we're a zombie or need a soft hangup */
02115    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 
02116       return -1;
02117    CHECK_BLOCKING(chan);
02118    if (chan->tech->send_text)
02119       res = chan->tech->send_text(chan, text);
02120    ast_clear_flag(chan, AST_FLAG_BLOCKING);
02121    return res;
02122 }

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

Definition at line 3133 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(), __oh323_new(), agent_call(), ast_feature_request_and_dial(), ast_iax2_new(), ast_modem_new(), callerid_write(), dial_exec_full(), disa_exec(), features_call(), get_callerid(), handle_setcallerid(), local_call(), lookupcidname_exec(), mgcp_new(), mgcp_ss(), misdn_new(), monitor_handle_notowned(), phone_new(), privacy_exec(), rpt_exec(), setcallerid_exec(), sip_new(), skinny_new(), skinny_ss(), ss_thread(), vpb_new(), wait_for_answer(), zt_new(), and zt_read().

03134 {
03135    if (callerid) {
03136       if (chan->cid.cid_num)
03137          free(chan->cid.cid_num);
03138       if (ast_strlen_zero(callerid))
03139          chan->cid.cid_num = NULL;
03140       else
03141          chan->cid.cid_num = strdup(callerid);
03142    }
03143    if (calleridname) {
03144       if (chan->cid.cid_name)
03145          free(chan->cid.cid_name);
03146       if (ast_strlen_zero(calleridname))
03147          chan->cid.cid_name = NULL;
03148       else
03149          chan->cid.cid_name = strdup(calleridname);
03150    }
03151    if (ani) {
03152       if (chan->cid.cid_ani)
03153          free(chan->cid.cid_ani);
03154       if (ast_strlen_zero(ani))
03155          chan->cid.cid_ani = NULL;
03156       else
03157          chan->cid.cid_ani = strdup(ani);
03158    }
03159    if (chan->cdr)
03160       ast_cdr_setcid(chan->cdr, chan);
03161    manager_event(EVENT_FLAG_CALL, "Newcallerid", 
03162             "Channel: %s\r\n"
03163             "CallerID: %s\r\n"
03164             "CallerIDName: %s\r\n"
03165             "Uniqueid: %s\r\n"
03166             "CID-CallingPres: %d (%s)\r\n",
03167             chan->name, chan->cid.cid_num ? 
03168             chan->cid.cid_num : "<Unknown>",
03169             chan->cid.cid_name ? 
03170             chan->cid.cid_name : "<Unknown>",
03171             chan->uniqueid,
03172             chan->cid.cid_pres,
03173             ast_describe_caller_presentation(chan->cid.cid_pres)
03174             );
03175 }

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

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

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

02369 {
02370    return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat,
02371            &chan->readtrans, 0);
02372 }

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

03861 {
03862    struct ast_variable *cur;
03863 
03864    for (cur = vars; cur; cur = cur->next)
03865       pbx_builtin_setvar_helper(chan, cur->name, cur->value);  
03866 }

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

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

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

02375 {
02376    return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat,
02377            &chan->writetrans, 1);
02378 }

int ast_setstate struct ast_channel chan,
int  state
 

Change the state of a channel.

Definition at line 3177 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_call(), vpb_hangup(), vpb_new(), zt_answer(), zt_call(), zt_handle_event(), zt_indicate(), zt_new(), and zt_read().

03178 {
03179    int oldstate = chan->_state;
03180 
03181    if (oldstate == state)
03182       return 0;
03183 
03184    chan->_state = state;
03185    ast_device_state_changed_literal(chan->name);
03186    manager_event(EVENT_FLAG_CALL,
03187             (oldstate == AST_STATE_DOWN) ? "Newchannel" : "Newstate",
03188             "Channel: %s\r\n"
03189             "State: %s\r\n"
03190             "CallerID: %s\r\n"
03191             "CallerIDName: %s\r\n"
03192             "Uniqueid: %s\r\n",
03193             chan->name, ast_state2str(chan->_state), 
03194             chan->cid.cid_num ? chan->cid.cid_num : "<unknown>", 
03195             chan->cid.cid_name ? chan->cid.cid_name : "<unknown>", 
03196             chan->uniqueid);
03197 
03198    return 0;
03199 }

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

Definition at line 1715 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().

01716 {
01717    int res = -1;
01718 #ifdef ZAPTEL_OPTIMIZATIONS
01719    if (c->timingfd > -1) {
01720       if (!func) {
01721          samples = 0;
01722          data = 0;
01723       }
01724       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01725       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01726       c->timingfunc = func;
01727       c->timingdata = data;
01728    }
01729 #endif   
01730    return res;
01731 }

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

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

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

01131 {
01132    int res;
01133    ast_mutex_lock(&chan->lock);
01134    res = ast_softhangup_nolock(chan, cause);
01135    ast_mutex_unlock(&chan->lock);
01136    return res;
01137 }

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 1114 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(), oh323_indicate(), sip_indicate(), and skinny_indicate().

01115 {
01116    int res = 0;
01117    struct ast_frame f = { AST_FRAME_NULL };
01118    if (option_debug)
01119       ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
01120    /* Inform channel driver that we need to be hung up, if it cares */
01121    chan->_softhangup |= cause;
01122    ast_queue_frame(chan, &f);
01123    /* Interrupt any poll call or such */
01124    if (ast_test_flag(chan, AST_FLAG_BLOCKING))
01125       pthread_kill(chan->blocker, SIGURG);
01126    return res;
01127 }

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

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

Referenced by zapateller_exec().

03729 {
03730    struct ast_frame *f;
03731    int res;
03732 
03733    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
03734       return res;
03735 
03736    /* Give us some wiggle room */
03737    while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) {
03738       f = ast_read(chan);
03739       if (f)
03740          ast_frfree(f);
03741       else
03742          return -1;
03743    }
03744    return 0;
03745 }

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

Start a tone going

Definition at line 3707 of file channel.c.

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

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

03708 {
03709    struct tonepair_def d = { 0, };
03710 
03711    d.freq1 = freq1;
03712    d.freq2 = freq2;
03713    d.duration = duration;
03714    if (vol < 1)
03715       d.vol = 8192;
03716    else
03717       d.vol = vol;
03718    if (ast_activate_generator(chan, &tonepair, &d))
03719       return -1;
03720    return 0;
03721 }

void ast_tonepair_stop struct ast_channel chan  ) 
 

Stop a tone from playing

Definition at line 3723 of file channel.c.

References ast_deactivate_generator().

Referenced by sendnoise().

03724 {
03725    ast_deactivate_generator(chan);
03726 }

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

02576 {
02577    int res = -1;
02578 
02579    /* Stop if we're a zombie or need a soft hangup */
02580    ast_mutex_lock(&chan->lock);
02581    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
02582       if (chan->tech->transfer) {
02583          res = chan->tech->transfer(chan, dest);
02584          if (!res)
02585             res = 1;
02586       } else
02587          res = 0;
02588    }
02589    ast_mutex_unlock(&chan->lock);
02590    return res;
02591 }

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

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

03798 {
03799    ast_moh_start_ptr = NULL;
03800    ast_moh_stop_ptr = NULL;
03801    ast_moh_cleanup_ptr = NULL;
03802 }

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

References ast_waitfor_n().

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

01672 {
01673    struct ast_channel *chan;
01674    int oldms = ms;
01675 
01676    chan = ast_waitfor_n(&c, 1, &ms);
01677    if (ms < 0) {
01678       if (oldms < 0)
01679          return 0;
01680       else
01681          return -1;
01682    }
01683    return ms;
01684 }

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

References ast_waitfor_nandfds().

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

01667 {
01668    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
01669 }

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

01453 {
01454    struct timeval start = { 0 , 0 };
01455    int res;
01456    int x, y;
01457    int winner = -1;
01458    int spoint;
01459    struct pollfd *pfds;
01460    
01461    pfds = alloca(sizeof(struct pollfd) * n);
01462    if (!pfds) {
01463       ast_log(LOG_ERROR, "Out of memory\n");
01464       return -1;
01465    }
01466    if (*ms > 0)
01467       start = ast_tvnow();
01468    y = 0;
01469    for (x=0; x < n; x++) {
01470       if (fds[x] > -1) {
01471          pfds[y].fd = fds[x];
01472          pfds[y].events = POLLIN | POLLPRI;
01473          y++;
01474       }
01475    }
01476    res = poll(pfds, y, *ms);
01477    if (res < 0) {
01478       /* Simulate a timeout if we were interrupted */
01479       if (errno != EINTR)
01480          *ms = -1;
01481       else
01482          *ms = 0;
01483       return -1;
01484    }
01485    spoint = 0;
01486    for (x=0; x < n; x++) {
01487       if (fds[x] > -1) {
01488          if ((res = ast_fdisset(pfds, fds[x], y, &spoint))) {
01489             winner = fds[x];
01490             if (exception) {
01491                if (res & POLLPRI)
01492                   *exception = -1;
01493                else
01494                   *exception = 0;
01495             }
01496          }
01497       }
01498    }
01499    if (*ms > 0) {
01500       *ms -= ast_tvdiff_ms(ast_tvnow(), start);
01501       if (*ms < 0)
01502          *ms = 0;
01503    }
01504    return winner;
01505 }

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

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

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

01510 {
01511    struct timeval start = { 0 , 0 };
01512    struct pollfd *pfds;
01513    int res;
01514    long rms;
01515    int x, y, max;
01516    int spoint;
01517    time_t now = 0;
01518    long whentohangup = 0, havewhen = 0, diff;
01519    struct ast_channel *winner = NULL;
01520 
01521    pfds = alloca(sizeof(struct pollfd) * (n * AST_MAX_FDS + nfds));
01522    if (!pfds) {
01523       ast_log(LOG_ERROR, "Out of memory\n");
01524       *outfd = -1;
01525       return NULL;
01526    }
01527 
01528    if (outfd)
01529       *outfd = -99999;
01530    if (exception)
01531       *exception = 0;
01532    
01533    /* Perform any pending masquerades */
01534    for (x=0; x < n; x++) {
01535       ast_mutex_lock(&c[x]->lock);
01536       if (c[x]->whentohangup) {
01537          if (!havewhen)
01538             time(&now);
01539          diff = c[x]->whentohangup - now;
01540          if (!havewhen || (diff < whentohangup)) {
01541             havewhen++;
01542             whentohangup = diff;
01543          }
01544       }
01545       if (c[x]->masq) {
01546          if (ast_do_masquerade(c[x])) {
01547             ast_log(LOG_WARNING, "Masquerade failed\n");
01548             *ms = -1;
01549             ast_mutex_unlock(&c[x]->lock);
01550             return NULL;
01551          }
01552       }
01553       ast_mutex_unlock(&c[x]->lock);
01554    }
01555 
01556    rms = *ms;
01557    
01558    if (havewhen) {
01559       if ((*ms < 0) || (whentohangup * 1000 < *ms)) {
01560          rms =  whentohangup * 1000;
01561       }
01562    }
01563    max = 0;
01564    for (x=0; x < n; x++) {
01565       for (y=0; y< AST_MAX_FDS; y++) {
01566          if (c[x]->fds[y] > -1) {
01567             pfds[max].fd = c[x]->fds[y];
01568             pfds[max].events = POLLIN | POLLPRI;
01569             pfds[max].revents = 0;
01570             max++;
01571          }
01572       }
01573       CHECK_BLOCKING(c[x]);
01574    }
01575    for (x=0; x < nfds; x++) {
01576       if (fds[x] > -1) {
01577          pfds[max].fd = fds[x];
01578          pfds[max].events = POLLIN | POLLPRI;
01579          pfds[max].revents = 0;
01580          max++;
01581       }
01582    }
01583    if (*ms > 0) 
01584       start = ast_tvnow();
01585    
01586    if (sizeof(int) == 4) {
01587       do {
01588          int kbrms = rms;
01589          if (kbrms > 600000)
01590             kbrms = 600000;
01591          res = poll(pfds, max, kbrms);
01592          if (!res)
01593             rms -= kbrms;
01594       } while (!res && (rms > 0));
01595    } else {
01596       res = poll(pfds, max, rms);
01597    }
01598    
01599    if (res < 0) {
01600       for (x=0; x < n; x++) 
01601          ast_clear_flag(c[x], AST_FLAG_BLOCKING);
01602       /* Simulate a timeout if we were interrupted */
01603       if (errno != EINTR)
01604          *ms = -1;
01605       else {
01606          /* Just an interrupt */
01607 #if 0
01608          *ms = 0;
01609 #endif         
01610       }
01611       return NULL;
01612         } else {
01613          /* If no fds signalled, then timeout. So set ms = 0
01614          since we may not have an exact timeout.
01615       */
01616       if (res == 0)
01617          *ms = 0;
01618    }
01619 
01620    if (havewhen)
01621       time(&now);
01622    spoint = 0;
01623    for (x=0; x < n; x++) {
01624       ast_clear_flag(c[x], AST_FLAG_BLOCKING);
01625       if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) {
01626          c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
01627          if (!winner)
01628             winner = c[x];
01629       }
01630       for (y=0; y < AST_MAX_FDS; y++) {
01631          if (c[x]->fds[y] > -1) {
01632             if ((res = ast_fdisset(pfds, c[x]->fds[y], max, &spoint))) {
01633                if (res & POLLPRI)
01634                   ast_set_flag(c[x], AST_FLAG_EXCEPTION);
01635                else
01636                   ast_clear_flag(c[x], AST_FLAG_EXCEPTION);
01637                c[x]->fdno = y;
01638                winner = c[x];
01639             }
01640          }
01641       }
01642    }
01643    for (x=0; x < nfds; x++) {
01644       if (fds[x] > -1) {
01645          if ((res = ast_fdisset(pfds, fds[x], max, &spoint))) {
01646             if (outfd)
01647                *outfd = fds[x];
01648             if (exception) {  
01649                if (res & POLLPRI) 
01650                   *exception = -1;
01651                else
01652                   *exception = 0;
01653             }
01654             winner = NULL;
01655          }
01656       }  
01657    }
01658    if (*ms > 0) {
01659       *ms -= ast_tvdiff_ms(ast_tvnow(), start);
01660       if (*ms < 0)
01661          *ms = 0;
01662    }
01663    return winner;
01664 }

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

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

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

01687 {
01688    /* XXX Should I be merged with waitfordigit_full XXX */
01689    struct ast_frame *f;
01690    int result = 0;
01691 
01692    /* Stop if we're a zombie or need a soft hangup */
01693    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 
01694       return -1;
01695 
01696    /* Wait for a digit, no more than ms milliseconds total. */
01697    while(ms && !result) {
01698       ms = ast_waitfor(c, ms);
01699       if (ms < 0) /* Error */
01700          result = -1; 
01701       else if (ms > 0) {
01702          /* Read something */
01703          f = ast_read(c);
01704          if (f) {
01705             if (f->frametype == AST_FRAME_DTMF) 
01706                result = f->subclass;
01707             ast_frfree(f);
01708          } else
01709             result = -1;
01710       }
01711    }
01712    return result;
01713 }

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

Definition at line 1733 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().

01734 {
01735    struct ast_frame *f;
01736    struct ast_channel *rchan;
01737    int outfd;
01738    int res;
01739 
01740    /* Stop if we're a zombie or need a soft hangup */
01741    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c)) 
01742       return -1;
01743    /* Wait for a digit, no more than ms milliseconds total. */
01744    while(ms) {
01745       errno = 0;
01746       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01747       if ((!rchan) && (outfd < 0) && (ms)) { 
01748          if (errno == 0 || errno == EINTR)
01749             continue;
01750          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01751          return -1;
01752       } else if (outfd > -1) {
01753          /* The FD we were watching has something waiting */
01754          return 1;
01755       } else if (rchan) {
01756          f = ast_read(c);
01757          if(!f) {
01758             return -1;
01759          }
01760 
01761          switch(f->frametype) {
01762          case AST_FRAME_DTMF:
01763             res = f->subclass;
01764             ast_frfree(f);
01765             return res;
01766          case AST_FRAME_CONTROL:
01767             switch(f->subclass) {
01768             case AST_CONTROL_HANGUP:
01769                ast_frfree(f);
01770                return -1;
01771             case AST_CONTROL_RINGING:
01772             case AST_CONTROL_ANSWER:
01773                /* Unimportant */
01774                break;
01775             default:
01776                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01777             }
01778          case AST_FRAME_VOICE:
01779             /* Write audio if appropriate */
01780             if (audiofd > -1)
01781                write(audiofd, f->data, f->datalen);
01782          }
01783          /* Ignore */
01784          ast_frfree(f);
01785       }
01786    }
01787    return 0; /* Time is up */
01788 }

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

References 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_frame::frametype, LOG_DTMF, LOG_WARNING, queue_frame_to_spies(), ast_frame::samples, SEEK_FORCECUR, SPY_WRITE, and ast_frame::subclass.

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

02202 {
02203    int res = -1;
02204    struct ast_frame *f = NULL;
02205    /* Stop if we're a zombie or need a soft hangup */
02206    ast_mutex_lock(&chan->lock);
02207    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))  {
02208       ast_mutex_unlock(&chan->lock);
02209       return -1;
02210    }
02211    /* Handle any pending masquerades */
02212    if (chan->masq) {
02213       if (ast_do_masquerade(chan)) {
02214          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02215          ast_mutex_unlock(&chan->lock);
02216          return -1;
02217       }
02218    }
02219    if (chan->masqr) {
02220       ast_mutex_unlock(&chan->lock);
02221       return 0;
02222    }
02223    if (chan->generatordata) {
02224       if (ast_test_flag(chan, AST_FLAG_WRITE_INT))
02225          ast_deactivate_generator(chan);
02226       else {
02227          ast_mutex_unlock(&chan->lock);
02228          return 0;
02229       }
02230    }
02231    /* High bit prints debugging */
02232    if (chan->fout & 0x80000000)
02233       ast_frame_dump(chan->name, fr, ">>");
02234    CHECK_BLOCKING(chan);
02235    switch(fr->frametype) {
02236    case AST_FRAME_CONTROL:
02237       /* XXX Interpret control frames XXX */
02238       ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n");
02239       break;
02240    case AST_FRAME_DTMF:
02241       ast_clear_flag(chan, AST_FLAG_BLOCKING);
02242       ast_mutex_unlock(&chan->lock);
02243       res = do_senddigit(chan,fr->subclass);
02244       ast_mutex_lock(&chan->lock);
02245       CHECK_BLOCKING(chan);
02246       break;
02247    case AST_FRAME_TEXT:
02248       if (chan->tech->send_text)
02249          res = chan->tech->send_text(chan, (char *) fr->data);
02250       else
02251          res = 0;
02252       break;
02253    case AST_FRAME_HTML:
02254       if (chan->tech->send_html)
02255          res = chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
02256       else
02257          res = 0;
02258       break;
02259    case AST_FRAME_VIDEO:
02260       /* XXX Handle translation of video codecs one day XXX */
02261       if (chan->tech->write_video)
02262          res = chan->tech->write_video(chan, fr);
02263       else
02264          res = 0;
02265       break;
02266    default:
02267       if (chan->tech->write) {
02268          f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
02269          if (f) {
02270             if (f->frametype == AST_FRAME_VOICE && chan->spies)
02271                queue_frame_to_spies(chan, f, SPY_WRITE);
02272 
02273             if( chan->monitor && chan->monitor->write_stream &&
02274                   f && ( f->frametype == AST_FRAME_VOICE ) ) {
02275 #ifndef MONITOR_CONSTANT_DELAY
02276                int jump = chan->insmpl - chan->outsmpl - 4 * f->samples;
02277                if (jump >= 0) {
02278                   if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1)
02279                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02280                   chan->outsmpl += jump + 4 * f->samples;
02281                } else
02282                   chan->outsmpl += f->samples;
02283 #else
02284                int jump = chan->insmpl - chan->outsmpl;
02285                if (jump - MONITOR_DELAY >= 0) {
02286                   if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
02287                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02288                   chan->outsmpl += jump;
02289                } else
02290                   chan->outsmpl += f->samples;
02291 #endif
02292                if (ast_writestream(chan->monitor->write_stream, f) < 0)
02293                   ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
02294             }
02295 
02296             res = chan->tech->write(chan, f);
02297          } else
02298             res = 0;
02299       }
02300    }
02301 
02302    /* It's possible this is a translated frame */
02303    if (f && f->frametype == AST_FRAME_DTMF) {
02304       ast_log(LOG_DTMF, "%s : %c\n", chan->name, f->subclass);
02305    } else if (fr->frametype == AST_FRAME_DTMF) {
02306       ast_log(LOG_DTMF, "%s : %c\n", chan->name, fr->subclass);
02307    }
02308 
02309    if (f && (f != fr))
02310       ast_frfree(f);
02311    ast_clear_flag(chan, AST_FLAG_BLOCKING);
02312    /* Consider a write failure to force a soft hangup */
02313    if (res < 0)
02314       chan->_softhangup |= AST_SOFTHANGUP_DEV;
02315    else {
02316       if ((chan->fout & 0x7fffffff) == 0x7fffffff)
02317          chan->fout &= 0x80000000;
02318       else
02319          chan->fout++;
02320    }
02321    ast_mutex_unlock(&chan->lock);
02322    return res;
02323 }

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

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

02191 {
02192    int res;
02193    if (!chan->tech->write_video)
02194       return 0;
02195    res = ast_write(chan, fr);
02196    if (!res)
02197       res = 1;
02198    return res;
02199 }

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

Definition at line 3211 of file channel.c.

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

Referenced by ast_channel_bridge().

03212 {
03213    int res=0, min=0, sec=0,check=0;
03214 
03215    check = ast_autoservice_start(peer);
03216    if(check) 
03217       return;
03218 
03219    if (remain > 0) {
03220       if (remain / 60 > 1) {
03221          min = remain / 60;
03222          sec = remain % 60;
03223       } else {
03224          sec = remain;
03225       }
03226    }
03227    
03228    if (!strcmp(sound,"timeleft")) { /* Queue support */
03229       res = ast_streamfile(chan, "vm-youhave", chan->language);
03230       res = ast_waitstream(chan, "");
03231       if (min) {
03232          res = ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, (char *) NULL);
03233          res = ast_streamfile(chan, "queue-minutes", chan->language);
03234          res = ast_waitstream(chan, "");
03235       }
03236       if (sec) {
03237          res = ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, (char *) NULL);
03238          res = ast_streamfile(chan, "queue-seconds", chan->language);
03239          res = ast_waitstream(chan, "");
03240       }
03241    } else {
03242       res = ast_streamfile(chan, sound, chan->language);
03243       res = ast_waitstream(chan, "");
03244    }
03245 
03246    check = ast_autoservice_stop(peer);
03247 }

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

References AST_LIST_FIRST, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_var_delete(), ast_var_name(), GROUP_CATEGORY_PREFIX, and ast_channel::varshead.

Referenced by ast_do_masquerade().

02870 {
02871    struct ast_var_t *varptr;
02872 
02873    /* we need to remove all app_groupcount related variables from the original
02874       channel before merging in the clone's variables; any groups assigned to the
02875       original channel should be released, only those assigned to the clone
02876       should remain
02877    */
02878 
02879    AST_LIST_TRAVERSE_SAFE_BEGIN(&original->varshead, varptr, entries) {
02880       if (!strncmp(ast_var_name(varptr), GROUP_CATEGORY_PREFIX, strlen(GROUP_CATEGORY_PREFIX))) {
02881          AST_LIST_REMOVE(&original->varshead, varptr, entries);
02882          ast_var_delete(varptr);
02883       }
02884    }
02885    AST_LIST_TRAVERSE_SAFE_END;
02886 
02887    /* Append variables from clone channel into original channel */
02888    /* XXX Is this always correct?  We have to in order to keep MACROS working XXX */
02889    if (AST_LIST_FIRST(&clone->varshead))
02890       AST_LIST_INSERT_TAIL(&original->varshead, AST_LIST_FIRST(&clone->varshead), entries);
02891 }

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

Definition at line 3868 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().

03869 {
03870    struct ast_frame *f;
03871    int tocopy;
03872    int bytestocopy;
03873 
03874    while (samples) {
03875       f = queue->head;
03876 
03877       if (!f) {
03878          ast_log(LOG_ERROR, "Ran out of frames before buffer filled!\n");
03879          break;
03880       }
03881 
03882       tocopy = (f->samples > samples) ? samples : f->samples;
03883       bytestocopy = ast_codec_get_len(queue->format, tocopy);
03884       memcpy(buf, f->data, bytestocopy);
03885       samples -= tocopy;
03886       buf += tocopy;
03887       f->samples -= tocopy;
03888       f->data += bytestocopy;
03889       f->datalen -= bytestocopy;
03890       f->offset += bytestocopy;
03891       queue->samples -= tocopy;
03892       if (!f->samples) {
03893          queue->head = f->next;
03894          ast_frfree(f);
03895       }
03896    }
03897 }

static void detach_spies struct ast_channel chan  )  [static]
 

Definition at line 1090 of file channel.c.

References ast_channel_spy_remove(), ast_cond_signal(), AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_channel_spy::chan, CHANSPY_DONE, CHANSPY_RUNNING, CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_NONE, list, ast_channel_spy::lock, ast_channel::spies, and ast_channel_spy::status.

Referenced by ast_hangup().

01091 {
01092    struct ast_channel_spy *spy;
01093 
01094    if (!chan->spies)
01095       return;
01096 
01097    /* Marking the spies as done is sufficient.  Chanspy or spy users will get the picture. */
01098    AST_LIST_TRAVERSE(&chan->spies->list, spy, list) {
01099       ast_mutex_lock(&spy->lock);
01100       spy->chan = NULL;
01101       if (spy->status == CHANSPY_RUNNING)
01102          spy->status = CHANSPY_DONE;
01103       if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
01104          ast_cond_signal(&spy->trigger);
01105       ast_mutex_unlock(&spy->lock);
01106    }
01107 
01108    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list)
01109       ast_channel_spy_remove(chan, spy);
01110    AST_LIST_TRAVERSE_SAFE_END;
01111 }

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

Definition at line 2124 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().

02125 {
02126    int res = -1;
02127 
02128    if (chan->tech->send_digit)
02129       res = chan->tech->send_digit(chan, digit);
02130    if (!chan->tech->send_digit || res) {
02131       /*
02132        * Device does not support DTMF tones, lets fake
02133        * it by doing our own generation. (PM2002)
02134        */
02135       static const char* dtmf_tones[] = {
02136          "!941+1336/100,!0/100", /* 0 */
02137          "!697+1209/100,!0/100", /* 1 */
02138          "!697+1336/100,!0/100", /* 2 */
02139          "!697+1477/100,!0/100", /* 3 */
02140          "!770+1209/100,!0/100", /* 4 */
02141          "!770+1336/100,!0/100", /* 5 */
02142          "!770+1477/100,!0/100", /* 6 */
02143          "!852+1209/100,!0/100", /* 7 */
02144          "!852+1336/100,!0/100", /* 8 */
02145          "!852+1477/100,!0/100", /* 9 */
02146          "!697+1633/100,!0/100", /* A */
02147          "!770+1633/100,!0/100", /* B */
02148          "!852+1633/100,!0/100", /* C */
02149          "!941+1633/100,!0/100", /* D */
02150          "!941+1209/100,!0/100", /* * */
02151          "!941+1477/100,!0/100" };  /* # */
02152       if (digit >= '0' && digit <='9')
02153          ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
02154       else if (digit >= 'A' && digit <= 'D')
02155          ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
02156       else if (digit == '*')
02157          ast_playtones_start(chan, 0, dtmf_tones[14], 0);
02158       else if (digit == '#')
02159          ast_playtones_start(chan, 0, dtmf_tones[15], 0);
02160       else {
02161          /* not handled */
02162          ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
02163       }
02164    }
02165    return 0;
02166 }

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

01270 {
01271    if (clone->writetrans)
01272       ast_translator_free_path(clone->writetrans);
01273    if (clone->readtrans)
01274       ast_translator_free_path(clone->readtrans);
01275    clone->writetrans = NULL;
01276    clone->readtrans = NULL;
01277    clone->rawwriteformat = clone->nativeformats;
01278    clone->rawreadformat = clone->nativeformats;
01279 }

static int generator_force void *  data  )  [static]
 

Definition at line 1404 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().

01405 {
01406    /* Called if generator doesn't have data */
01407    void *tmp;
01408    int res;
01409    int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
01410    struct ast_channel *chan = data;
01411    tmp = chan->generatordata;
01412    chan->generatordata = NULL;
01413    generate = chan->generator->generate;
01414    res = generate(chan, tmp, 0, 160);
01415    chan->generatordata = tmp;
01416    if (res) {
01417       ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
01418       ast_deactivate_generator(chan);
01419    }
01420    return 0;
01421 }

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

Definition at line 1146 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, 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().

01147 {
01148    struct ast_frame *translated_frame = NULL;
01149    struct ast_channel_spy *spy;
01150    struct ast_channel_spy_queue *queue;
01151    struct channel_spy_trans *trans;
01152    struct ast_frame *last;
01153 
01154    trans = (dir == SPY_READ) ? &chan->spies->read_translator : &chan->spies->write_translator;
01155 
01156    AST_LIST_TRAVERSE(&chan->spies->list, spy, list) {
01157       ast_mutex_lock(&spy->lock);
01158 
01159       queue = (dir == SPY_READ) ? &spy->read_queue : &spy->write_queue;
01160 
01161       if ((queue->format == AST_FORMAT_SLINEAR) && (f->subclass != AST_FORMAT_SLINEAR)) {
01162          if (!translated_frame) {
01163             if (trans->path && (trans->last_format != f->subclass)) {
01164                ast_translator_free_path(trans->path);
01165                trans->path = NULL;
01166             }
01167             if (!trans->path) {
01168                ast_log(LOG_DEBUG, "Building translator from %s to SLINEAR for spies on channel %s\n",
01169                   ast_getformatname(f->subclass), chan->name);
01170                if ((trans->path = ast_translator_build_path(AST_FORMAT_SLINEAR, f->subclass)) == NULL) {
01171                   ast_log(LOG_WARNING, "Cannot build a path from %s to %s\n",
01172                      ast_getformatname(f->subclass), ast_getformatname(AST_FORMAT_SLINEAR));
01173                   ast_mutex_unlock(&spy->lock);
01174                   continue;
01175                } else {
01176                   trans->last_format = f->subclass;
01177                }
01178             }
01179             if (!(translated_frame = ast_translate(trans->path, f, 0))) {
01180                ast_log(LOG_ERROR, "Translation to %s failed, dropping frame for spies\n",
01181                   ast_getformatname(AST_FORMAT_SLINEAR));
01182                ast_mutex_unlock(&spy->lock);
01183                break;
01184             }
01185          }
01186 
01187          for (last = queue->head; last && last->next; last = last->next);
01188          if (last)
01189             last->next = ast_frdup(translated_frame);
01190          else
01191             queue->head = ast_frdup(translated_frame);
01192       } else {
01193          if (f->subclass != queue->format) {
01194             ast_log(LOG_WARNING, "Spy '%s' on channel '%s' wants format '%s', but frame is '%s', dropping\n",
01195                spy->type, chan->name,
01196                ast_getformatname(queue->format), ast_getformatname(f->subclass));
01197             ast_mutex_unlock(&spy->lock);
01198             continue;
01199          }
01200 
01201          for (last = queue->head; last && last->next; last = last->next);
01202          if (last)
01203             last->next = ast_frdup(f);
01204          else
01205             queue->head = ast_frdup(f);
01206       }
01207 
01208       queue->samples += f->samples;
01209 
01210       if (queue->samples > SPY_QUEUE_SAMPLE_LIMIT) {
01211          if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) {
01212             switch (ast_test_flag(spy, CHANSPY_TRIGGER_MODE)) {
01213             case CHANSPY_TRIGGER_READ:
01214                if (dir == SPY_WRITE) {
01215                   ast_set_flag(spy, CHANSPY_TRIGGER_WRITE);
01216                   ast_clear_flag(spy, CHANSPY_TRIGGER_READ);
01217                   if (option_debug)
01218                      ast_log(LOG_DEBUG, "Switching spy '%s' on '%s' to write-trigger mode\n",
01219                         spy->type, chan->name);
01220                }
01221                break;
01222             case CHANSPY_TRIGGER_WRITE:
01223                if (dir == SPY_READ) {
01224                   ast_set_flag(spy, CHANSPY_TRIGGER_READ);
01225                   ast_clear_flag(spy, CHANSPY_TRIGGER_WRITE);
01226                   if (option_debug)
01227                      ast_log(LOG_DEBUG, "Switching spy '%s' on '%s' to read-trigger mode\n",
01228                         spy->type, chan->name);
01229                }
01230                break;
01231             }
01232             if (option_debug)
01233                ast_log(LOG_DEBUG, "Triggering queue flush for spy '%s' on '%s'\n",
01234                   spy->type, chan->name);
01235             ast_set_flag(spy, CHANSPY_TRIGGER_FLUSH);
01236             ast_cond_signal(&spy->trigger);
01237          } else {
01238             if (option_debug)
01239                ast_log(LOG_DEBUG, "Spy '%s' on channel '%s' %s queue too long, dropping frames\n",
01240                   spy->type, chan->name, (dir == SPY_READ) ? "read" : "write");
01241             while (queue->samples > SPY_QUEUE_SAMPLE_LIMIT) {
01242                struct ast_frame *drop = queue->head;
01243                
01244                queue->samples -= drop->samples;
01245                queue->head = drop->next;
01246                ast_frfree(drop);
01247             }
01248          }
01249       } else {
01250          switch (ast_test_flag(spy, CHANSPY_TRIGGER_MODE)) {
01251          case CHANSPY_TRIGGER_READ:
01252             if (dir == SPY_READ)
01253                ast_cond_signal(&spy->trigger);
01254             break;
01255          case CHANSPY_TRIGGER_WRITE:
01256             if (dir == SPY_WRITE)
01257                ast_cond_signal(&spy->trigger);
01258             break;
01259          }
01260       }
01261 
01262       ast_mutex_unlock(&spy->lock);
01263    }
01264 
01265    if (translated_frame)
01266       ast_frfree(translated_frame);
01267 }

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

02327 {
02328    int native;
02329    int res;
02330    
02331    native = chan->nativeformats;
02332    /* Find a translation path from the native format to one of the desired formats */
02333    if (!direction)
02334       /* reading */
02335       res = ast_translator_best_choice(&fmt, &native);
02336    else
02337       /* writing */
02338       res = ast_translator_best_choice(&native, &fmt);
02339 
02340    if (res < 0) {
02341       ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
02342          ast_getformatname(native), ast_getformatname(fmt));
02343       return -1;
02344    }
02345    
02346    /* Now we have a good choice for both. */
02347    ast_mutex_lock(&chan->lock);
02348    *rawformat = native;
02349    /* User perspective is fmt */
02350    *format = fmt;
02351    /* Free any read translation we have right now */
02352    if (*trans)
02353       ast_translator_free_path(*trans);
02354    /* Build a translation path from the raw format to the desired format */
02355    if (!direction)
02356       /* reading */
02357       *trans = ast_translator_build_path(*format, *rawformat);
02358    else
02359       /* writing */
02360       *trans = ast_translator_build_path(*rawformat, *format);
02361    ast_mutex_unlock(&chan->lock);
02362    if (option_debug)
02363       ast_log(LOG_DEBUG, "Set channel %s to %s format %s\n", chan->name,
02364          direction ? "write" : "read", ast_getformatname(fmt));
02365    return 0;
02366 }

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

04002 {
04003    /* just store the data pointer in the channel structure */
04004    return data;
04005 }

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

Definition at line 4012 of file channel.c.

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

04013 {
04014    if (samples == 160) {
04015       short buf[160] = { 0, };
04016       struct ast_frame frame = {
04017          .frametype = AST_FRAME_VOICE,
04018          .subclass = AST_FORMAT_SLINEAR,
04019          .data = buf,
04020          .samples = 160,
04021          .datalen = sizeof(buf),
04022       };
04023 
04024       if (ast_write(chan, &frame))
04025          return -1;
04026    } else {
04027       short buf[samples];
04028       int x;
04029       struct ast_frame frame = {
04030          .frametype = AST_FRAME_VOICE,
04031          .subclass = AST_FORMAT_SLINEAR,
04032          .data = buf,
04033          .samples = samples,
04034          .datalen = sizeof(buf),
04035       };
04036 
04037       for (x = 0; x < samples; x++)
04038          buf[x] = 0;
04039 
04040       if (ast_write(chan, &frame))
04041          return -1;
04042    }
04043 
04044    return 0;
04045 }

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

Definition at line 4007 of file channel.c.

04008 {
04009    /* nothing to do */
04010 }

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

Definition at line 3640 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_def::freq1, tonepair_def::freq2, LOG_WARNING, malloc, ast_channel::name, tonepair_release(), tonepair_def::vol, and ast_channel::writeformat.

03641 {
03642    struct tonepair_state *ts;
03643    struct tonepair_def *td = params;
03644 
03645    ts = malloc(sizeof(struct tonepair_state));
03646    if (!ts)
03647       return NULL;
03648    memset(ts, 0, sizeof(struct tonepair_state));
03649    ts->origwfmt = chan->writeformat;
03650    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
03651       ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
03652       tonepair_release(NULL, ts);
03653       ts = NULL;
03654    } else {
03655       ts->freq1 = td->freq1;
03656       ts->freq2 = td->freq2;
03657       ts->duration = td->duration;
03658       ts->vol = td->vol;
03659    }
03660    /* Let interrupts interrupt :) */
03661    ast_set_flag(chan, AST_FLAG_WRITE_INT);
03662    return ts;
03663 }

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

Definition at line 3665 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.

03666 {
03667    struct tonepair_state *ts = data;
03668    int x;
03669 
03670    /* we need to prepare a frame with 16 * timelen samples as we're 
03671     * generating SLIN audio
03672     */
03673    len = samples * 2;
03674 
03675    if (len > sizeof(ts->data) / 2 - 1) {
03676       ast_log(LOG_WARNING, "Can't generate that much data!\n");
03677       return -1;
03678    }
03679    memset(&ts->f, 0, sizeof(ts->f));
03680    for (x = 0; x < (len / 2); x++) {
03681       ts->data[x] = ts->vol * (
03682             sin((ts->freq1 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) +
03683             sin((ts->freq2 * 2.0 * M_PI / 8000.0) * (ts->pos + x))
03684          );
03685    }
03686    ts->f.frametype = AST_FRAME_VOICE;
03687    ts->f.subclass = AST_FORMAT_SLINEAR;
03688    ts->f.datalen = len;
03689    ts->f.samples = samples;
03690    ts->f.offset = AST_FRIENDLY_OFFSET;
03691    ts->f.data = ts->data;
03692    ast_write(chan, &ts->f);
03693    ts->pos += x;
03694    if (ts->duration > 0) {
03695       if (ts->pos >= ts->duration * 8)
03696          return -1;
03697    }
03698    return 0;
03699 }

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

Definition at line 3630 of file channel.c.

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

Referenced by tonepair_alloc().

03631 {
03632    struct tonepair_state *ts = params;
03633 
03634    if (chan) {
03635       ast_set_write_format(chan, ts->origwfmt);
03636    }
03637    free(ts);
03638 }


Variable Documentation

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

Definition at line 3784 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 3782 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 3783 of file channel.c.

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

struct chanlist* backends = NULL [static]
 

Definition at line 109 of file channel.c.

Referenced by ast_channel_register(), ast_channel_unregister(), ast_get_channel_tech(), ast_request(), and show_channeltypes().

const struct ast_cause causes[]
 

Referenced by ast_cause2str(), and dump_cause().

struct ast_channel* channels = NULL [static]
 

Definition at line 114 of file channel.c.

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

struct ast_cli_entry cli_show_channeltypes [static]
 

Initial value:

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

Definition at line 199 of file channel.c.

unsigned long global_fin = 0
 

Definition at line 100 of file channel.c.

Referenced by ast_channel_alloc(), handle_debugchan(), and handle_nodebugchan().

unsigned long global_fout = 0
 

Definition at line 100 of file channel.c.

Referenced by ast_channel_alloc(), handle_debugchan(), and handle_nodebugchan().

const struct ast_channel_tech null_tech [static]
 

Initial value:

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

Definition at line 510 of file channel.c.

char show_channeltypes_usage[] [static]
 

Initial value:

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

Definition at line 195 of file channel.c.

int shutting_down = 0 [static]
 

Definition at line 95 of file channel.c.

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

struct ast_generator silence_generator [static]
 

Initial value:

Definition at line 4047 of file channel.c.

struct ast_generator tonepair [static]
 

Initial value:

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

Definition at line 3701 of file channel.c.

int uniqueint = 0 [static]
 

Definition at line 98 of file channel.c.

Referenced by ast_channel_alloc().


Generated on Sun Aug 6 15:06:45 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.2