Mon Mar 20 08:25:56 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"

Go to the source code of this file.

Data Structures

struct  ast_cause
struct  ast_channel_spy_list
struct  ast_silence_generator
struct  chanlist
struct  channel_spy_trans
struct  tonepair_def
struct  tonepair_state

Defines

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

Enumerations

enum  spy_direction { SPY_READ, SPY_WRITE }

Functions

ast_channel__ast_request_and_dial (const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
int ast_activate_generator (struct ast_channel *chan, struct ast_generator *gen, void *params)
int ast_active_channels (void)
int ast_answer (struct ast_channel *chan)
 Answer a ringing call.
void ast_begin_shutdown (int hangup)
int ast_best_codec (int fmts)
ast_channelast_bridged_channel (struct ast_channel *chan)
 Find bridged channel.
int ast_call (struct ast_channel *chan, char *addr, int timeout)
 Make a call.
void ast_cancel_shutdown (void)
const char * ast_cause2str (int cause)
void ast_change_name (struct ast_channel *chan, char *newname)
 Change channel name.
ast_channelast_channel_alloc (int needqueue)
 Create a channel structure.
enum ast_bridge_result ast_channel_bridge (struct ast_channel *c0, struct ast_channel *c1, struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
int ast_channel_cmpwhentohangup (struct ast_channel *chan, time_t offset)
 Compare a offset with the settings of when to hang a channel up.
int ast_channel_defer_dtmf (struct ast_channel *chan)
void ast_channel_free (struct ast_channel *chan)
 Free a channel structure.
void ast_channel_inherit_variables (const struct ast_channel *parent, struct ast_channel *child)
 Inherits channel variable from parent to child channel.
int ast_channel_make_compatible (struct ast_channel *chan, struct ast_channel *peer)
int ast_channel_masquerade (struct ast_channel *original, struct ast_channel *clone)
int ast_channel_register (const struct ast_channel_tech *tech)
 Register a channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports.
int ast_channel_sendhtml (struct ast_channel *chan, int subclass, const char *data, int datalen)
int ast_channel_sendurl (struct ast_channel *chan, const char *url)
int ast_channel_setoption (struct ast_channel *chan, int option, void *data, int datalen, int block)
void ast_channel_setwhentohangup (struct ast_channel *chan, time_t offset)
 Set when to hang a channel up.
int ast_channel_spy_add (struct ast_channel *chan, struct ast_channel_spy *spy)
 Adds a spy to a channel, to begin receiving copies of the channel's audio frames.
ast_frameast_channel_spy_read_frame (struct ast_channel_spy *spy, unsigned int samples)
 Read one (or more) frames of audio from a channel being spied upon.
void ast_channel_spy_remove (struct ast_channel *chan, struct ast_channel_spy *spy)
 Remove a spy from a channel.
void ast_channel_spy_stop_by_type (struct ast_channel *chan, const char *type)
 Find all spies of a particular type on a channel and stop them.
void ast_channel_spy_trigger_wait (struct ast_channel_spy *spy)
 Efficiently wait until audio is available for a spy, or an exception occurs.
ast_silence_generatorast_channel_start_silence_generator (struct ast_channel *chan)
 Starts a silence generator on the given channel.
void ast_channel_stop_silence_generator (struct ast_channel *chan, struct ast_silence_generator *state)
 Stops a previously-started silence generator on the given channel.
int ast_channel_supports_html (struct ast_channel *chan)
void ast_channel_undefer_dtmf (struct ast_channel *chan)
void ast_channel_unregister (const struct ast_channel_tech *tech)
 Unregister a channel technology.
ast_channelast_channel_walk_locked (const struct ast_channel *prev)
void ast_channels_init (void)
int ast_check_hangup (struct ast_channel *chan)
 Check to see if a channel is needing hang up.
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.
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)
void bridge_playfile (struct ast_channel *chan, struct ast_channel *peer, char *sound, int remain)
ast_channelchannel_find_locked (const struct ast_channel *prev, const char *name, const int namelen, const char *context, const char *exten)
void clone_variables (struct ast_channel *original, struct ast_channel *clone)
void copy_data_from_queue (struct ast_channel_spy_queue *queue, short *buf, unsigned int samples)
void detach_spies (struct ast_channel *chan)
int do_senddigit (struct ast_channel *chan, char digit)
void free_cid (struct ast_callerid *cid)
void free_translation (struct ast_channel *clone)
int generator_force (void *data)
void queue_frame_to_spies (struct ast_channel *chan, struct ast_frame *f, enum spy_direction dir)
int set_format (struct ast_channel *chan, int fmt, int *rawformat, int *format, struct ast_trans_pvt **trans, const int direction)
int show_channeltypes (int fd, int argc, char *argv[])
void * silence_generator_alloc (struct ast_channel *chan, void *data)
int silence_generator_generate (struct ast_channel *chan, void *data, int len, int samples)
void silence_generator_release (struct ast_channel *chan, void *data)
void * tonepair_alloc (struct ast_channel *chan, void *params)
int tonepair_generator (struct ast_channel *chan, void *data, int len, int samples)
void tonepair_release (struct ast_channel *chan, void *params)

Variables

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


Detailed Description

Channel Management.

Definition in file channel.c.


Define Documentation

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

#define SPY_QUEUE_SAMPLE_LIMIT   4000
 

Definition at line 1131 of file channel.c.


Enumeration Type Documentation

enum spy_direction
 

Enumeration values:
SPY_READ 
SPY_WRITE 

Definition at line 1126 of file channel.c.

01126                    {
01127    SPY_READ,
01128    SPY_WRITE,
01129 };


Function Documentation

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

Definition at line 2372 of file channel.c.

References ast_channel::_state, outgoing_helper::account, 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_frfree(), ast_hangup(), ast_log(), ast_read(), ast_request(), ast_set_callerid(), ast_set_variables(), ast_waitfor(), ast_channel::cdr, outgoing_helper::cid_name, outgoing_helper::cid_num, outgoing_helper::context, ast_channel::context, outgoing_helper::exten, ast_channel::exten, ast_frame::frametype, ast_channel::hangupcause, LOG_NOTICE, LOG_WARNING, outgoing_helper::parent_channel, outgoing_helper::priority, ast_channel::priority, ast_frame::subclass, type, and outgoing_helper::vars.

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

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

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

Activate a given generator

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

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

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(), 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 1353 of file channel.c.

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

Referenced by __login_exec(), agi_exec_full(), alarmreceiver_exec(), app_exec(), ast_bridge_call(), ast_control_streamfile(), ast_pickup_call(), auth_exec(), background_detect_exec(), chanspy_exec(), conf_exec(), count_exec(), datetime_exec(), dictate_exec(), directory_exec(), disa_exec(), features_answer(), handle_answer(), ices_exec(), milliwatt_exec(), park_call_exec(), park_exec(), pbx_builtin_answer(), pbx_builtin_background(), pickup_exec(), playback_exec(), privacy_exec(), read_exec(), record_exec(), 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().

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

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, 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_log(), and LOG_WARNING.

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

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

Referenced by __zt_exception(), agents_show(), attempt_transfer(), 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().

03167 {
03168    struct ast_channel *bridged;
03169    bridged = chan->_bridge;
03170    if (bridged && bridged->tech->bridged_channel) 
03171       bridged = bridged->tech->bridged_channel(chan, bridged);
03172    return bridged;
03173 }

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

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

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 ast_cause::cause, causes, and ast_cause::desc.

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

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

02776 {
02777    char tmp[256];
02778    ast_copy_string(tmp, chan->name, sizeof(tmp));
02779    ast_copy_string(chan->name, newname, sizeof(chan->name));
02780    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid);
02781 }

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_LIST_HEAD_INIT_NOLOCK, ast_log(), AST_MAX_FDS, ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), channels, ast_channel::context, ast_channel::data, defaultlanguage, ast_channel::exten, ast_channel::fds, ast_channel::fin, ast_channel::fout, free, ast_channel::language, ast_channel::lock, LOG_WARNING, malloc, ast_channel::name, ast_channel::next, ast_channel::priority, ast_channel::sched, sched_context_create(), ast_channel::streamid, ast_channel::tech, ast_channel::timingfd, ast_channel::uniqueid, uniqueint, and ast_channel::varshead.

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

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

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

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

Definition at line 3327 of file channel.c.

References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_FAILED_NOWARN, ast_bridge_result, AST_BRIDGE_RETRY, ast_channel_make_compatible(), ast_check_hangup(), ast_check_hangup_locked(), ast_clear_flag, AST_FEATURE_PLAY_WARNING, 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().

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

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_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(), 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 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 2783 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, and ast_channel::varshead.

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

02784 {
02785    struct ast_var_t *current, *newvar;
02786    char *varname;
02787 
02788    AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
02789       int vartype = 0;
02790 
02791       varname = ast_var_full_name(current);
02792       if (!varname)
02793          continue;
02794 
02795       if (varname[0] == '_') {
02796          vartype = 1;
02797          if (varname[1] == '_')
02798             vartype = 2;
02799       }
02800 
02801       switch (vartype) {
02802       case 1:
02803          newvar = ast_var_assign(&varname[1], ast_var_value(current));
02804          if (newvar) {
02805             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
02806             if (option_debug)
02807                ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
02808          }
02809          break;
02810       case 2:
02811          newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current));
02812          if (newvar) {
02813             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
02814             if (option_debug)
02815                ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
02816          }
02817          break;
02818       default:
02819          if (option_debug)
02820             ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current));
02821          break;
02822       }
02823    }
02824 }

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

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

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

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

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

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

02740 {
02741    struct ast_frame null = { AST_FRAME_NULL, };
02742    int res = -1;
02743 
02744    if (original == clone) {
02745       ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
02746       return -1;
02747    }
02748    ast_mutex_lock(&original->lock);
02749    while(ast_mutex_trylock(&clone->lock)) {
02750       ast_mutex_unlock(&original->lock);
02751       usleep(1);
02752       ast_mutex_lock(&original->lock);
02753    }
02754    ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n",
02755       clone->name, original->name);
02756    if (original->masq) {
02757       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
02758          original->masq->name, original->name);
02759    } else if (clone->masqr) {
02760       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
02761          clone->name, clone->masqr->name);
02762    } else {
02763       original->masq = clone;
02764       clone->masqr = original;
02765       ast_queue_frame(original, &null);
02766       ast_queue_frame(clone, &null);
02767       ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name);
02768       res = 0;
02769    }
02770    ast_mutex_unlock(&clone->lock);
02771    ast_mutex_unlock(&original->lock);
02772    return res;
02773 }

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

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

Referenced by agent_sendhtml(), and wait_for_answer().

02676 {
02677    if (chan->tech->send_html)
02678       return chan->tech->send_html(chan, subclass, data, datalen);
02679    return -1;
02680 }

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

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

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

02683 {
02684    if (chan->tech->send_html)
02685       return chan->tech->send_html(chan, AST_HTML_URL, url, strlen(url) + 1);
02686    return -1;
02687 }

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

03554 {
03555    int res;
03556 
03557    if (chan->tech->setoption) {
03558       res = chan->tech->setoption(chan, option, data, datalen);
03559       if (res < 0)
03560          return res;
03561    } else {
03562       errno = ENOSYS;
03563       return -1;
03564    }
03565    if (block) {
03566       /* XXX Implement blocking -- just wait for our option frame reply, discarding
03567          intermediate packets. XXX */
03568       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
03569       return -1;
03570    }
03571    return 0;
03572 }

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

struct ast_frame* ast_channel_spy_read_frame struct ast_channel_spy spy,
unsigned int  samples
 

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

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

Note: This function performs no locking; you must hold the spy's lock before calling this function. You must not hold the channel's lock at the same time.

Definition at line 3862 of file channel.c.

References ast_clear_flag, ast_codec_get_len(), ast_frame_adjust_volume(), ast_frame_slinear_sum(), 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_frame::subclass, ast_channel_spy::write_queue, and ast_channel_spy::write_vol_adjustment.

Referenced by mixmonitor_thread(), and spy_generate().

03863 {
03864    struct ast_frame *result;
03865    /* buffers are allocated to hold SLINEAR, which is the largest format */
03866         short read_buf[samples];
03867         short write_buf[samples];
03868    struct ast_frame *read_frame;
03869    struct ast_frame *write_frame;
03870    int need_dup;
03871    struct ast_frame stack_read_frame = { .frametype = AST_FRAME_VOICE,
03872                      .subclass = spy->read_queue.format,
03873                      .data = read_buf,
03874                      .samples = samples,
03875                      .datalen = ast_codec_get_len(spy->read_queue.format, samples),
03876    };
03877    struct ast_frame stack_write_frame = { .frametype = AST_FRAME_VOICE,
03878                       .subclass = spy->write_queue.format,
03879                       .data = write_buf,
03880                       .samples = samples,
03881                       .datalen = ast_codec_get_len(spy->write_queue.format, samples),
03882    };
03883 
03884    /* if a flush has been requested, dump everything in whichever queue is larger */
03885    if (ast_test_flag(spy, CHANSPY_TRIGGER_FLUSH)) {
03886       if (spy->read_queue.samples > spy->write_queue.samples) {
03887          if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST)) {
03888             for (result = spy->read_queue.head; result; result = result->next)
03889                ast_frame_adjust_volume(result, spy->read_vol_adjustment);
03890          }
03891          result = spy->read_queue.head;
03892          spy->read_queue.head = NULL;
03893          spy->read_queue.samples = 0;
03894          ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH);
03895          return result;
03896       } else {
03897          if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST)) {
03898             for (result = spy->write_queue.head; result; result = result->next)
03899                ast_frame_adjust_volume(result, spy->write_vol_adjustment);
03900          }
03901          result = spy->write_queue.head;
03902          spy->write_queue.head = NULL;
03903          spy->write_queue.samples = 0;
03904          ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH);
03905          return result;
03906       }
03907    }
03908 
03909    if ((spy->read_queue.samples < samples) || (spy->write_queue.samples < samples))
03910       return NULL;
03911 
03912    /* short-circuit if both head frames have exactly what we want */
03913    if ((spy->read_queue.head->samples == samples) &&
03914        (spy->write_queue.head->samples == samples)) {
03915       read_frame = spy->read_queue.head;
03916       spy->read_queue.head = read_frame->next;
03917       read_frame->next = NULL;
03918 
03919       write_frame = spy->write_queue.head;
03920       spy->write_queue.head = write_frame->next;
03921       write_frame->next = NULL;
03922 
03923       spy->read_queue.samples -= samples;
03924       spy->write_queue.samples -= samples;
03925 
03926       need_dup = 0;
03927    } else {
03928       copy_data_from_queue(&spy->read_queue, read_buf, samples);
03929       copy_data_from_queue(&spy->write_queue, write_buf, samples);
03930 
03931       read_frame = &stack_read_frame;
03932       write_frame = &stack_write_frame;
03933       need_dup = 1;
03934    }
03935    
03936    if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST))
03937       ast_frame_adjust_volume(read_frame, spy->read_vol_adjustment);
03938 
03939    if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST))
03940       ast_frame_adjust_volume(write_frame, spy->write_vol_adjustment);
03941 
03942    if (ast_test_flag(spy, CHANSPY_MIXAUDIO)) {
03943       ast_frame_slinear_sum(read_frame, write_frame);
03944 
03945       if (need_dup)
03946          result = ast_frdup(read_frame);
03947       else {
03948          result = read_frame;
03949          ast_frfree(write_frame);
03950       }
03951    } else {
03952       if (need_dup) {
03953          result = ast_frdup(read_frame);
03954          result->next = ast_frdup(write_frame);
03955       } else {
03956          result = read_frame;
03957          result->next = write_frame;
03958       }
03959    }
03960 
03961    return result;
03962 }

void ast_channel_spy_remove struct ast_channel chan,
struct ast_channel_spy spy
 

Remove a spy from a channel.

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

Definition at line 1040 of file channel.c.

References ast_cond_destroy(), ast_frfree(), AST_LIST_EMPTY, AST_LIST_REMOVE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_translator_free_path(), CHANSPY_TRIGGER_MODE, free, ast_channel_spy_queue::head, 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().

01041 {
01042    struct ast_frame *f;
01043 
01044    if (!chan->spies)
01045       return;
01046 
01047    AST_LIST_REMOVE(&chan->spies->list, spy, list);
01048 
01049    ast_mutex_lock(&spy->lock);
01050 
01051    for (f = spy->read_queue.head; f; f = spy->read_queue.head) {
01052       spy->read_queue.head = f->next;
01053       ast_frfree(f);
01054    }
01055    for (f = spy->write_queue.head; f; f = spy->write_queue.head) {
01056       spy->write_queue.head = f->next;
01057       ast_frfree(f);
01058    }
01059 
01060    if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
01061       ast_cond_destroy(&spy->trigger);
01062 
01063    ast_mutex_unlock(&spy->lock);
01064 
01065    ast_log(LOG_DEBUG, "Spy %s removed from channel %s\n",
01066       spy->type, chan->name);
01067 
01068    if (AST_LIST_EMPTY(&chan->spies->list)) {
01069       if (chan->spies->read_translator.path)
01070          ast_translator_free_path(chan->spies->read_translator.path);
01071       if (chan->spies->write_translator.path)
01072          ast_translator_free_path(chan->spies->write_translator.path);
01073       free(chan->spies);
01074       chan->spies = NULL;
01075    }
01076 }

void ast_channel_spy_stop_by_type struct ast_channel chan,
const char *  type
 

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

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

Definition at line 1017 of file channel.c.

References ast_cond_signal(), AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, CHANSPY_TRIGGER_MODE, ast_channel_spy::lock, ast_channel::spies, ast_channel_spy::trigger, and ast_channel_spy::type.

Referenced by mixmonitor_cli().

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

void ast_channel_spy_trigger_wait struct ast_channel_spy spy  ) 
 

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

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

Definition at line 1035 of file channel.c.

References ast_cond_wait(), ast_channel_spy::lock, and ast_channel_spy::trigger.

Referenced by mixmonitor_thread().

01036 {
01037    ast_cond_wait(&spy->trigger, &spy->lock);
01038 }

struct ast_silence_generator* ast_channel_start_silence_generator struct ast_channel chan  ) 
 

Starts a silence generator on the given channel.

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

The pointer returned by this function must be preserved and passed to ast_channel_stop_silence_generator when you wish to stop the silence generation.

Definition at line 4020 of file channel.c.

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

Referenced by ast_play_and_record(), and record_exec().

04021 {
04022    struct ast_silence_generator *state;
04023 
04024    if (!(state = calloc(1, sizeof(*state)))) {
04025       ast_log(LOG_WARNING, "Could not allocate state structure\n");
04026       return NULL;
04027    }
04028 
04029    state->old_write_format = chan->writeformat;
04030 
04031    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
04032       ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
04033       free(state);
04034       return NULL;
04035    }
04036 
04037    ast_activate_generator(chan, &silence_generator, state);
04038 
04039    if (option_debug)
04040       ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name);
04041 
04042    return state;
04043 }

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

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

Referenced by ast_play_and_record(), and record_exec().

04046 {
04047    if (!state)
04048       return;
04049 
04050    ast_deactivate_generator(chan);
04051 
04052    if (option_debug)
04053       ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name);
04054 
04055    if (ast_set_write_format(chan, state->old_write_format) < 0)
04056       ast_log(LOG_ERROR, "Could not return write format to its original state\n");
04057 
04058    free(state);
04059 }

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

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

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

02669 {
02670    if (chan->tech->send_html)
02671       return 1;
02672    return 0;
02673 }

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, LOG_DEBUG, chanlist::next, 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 3792 of file channel.c.

References ast_cli_register(), and cli_show_channeltypes.

Referenced by main().

03793 {
03794    ast_cli_register(&cli_show_channeltypes);
03795 }

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_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(), mixmonitor_thread(), 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 }

int ast_check_hangup_locked struct ast_channel chan  )  [static]
 

Definition at line 224 of file channel.c.

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

Referenced by ast_channel_bridge().

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

void ast_deactivate_generator struct ast_channel chan  ) 
 

Deactive an active generator

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

01385 {
01386    ast_mutex_lock(&chan->lock);
01387    if (chan->generatordata) {
01388       if (chan->generator && chan->generator->release) 
01389          chan->generator->release(chan, chan->generatordata);
01390       chan->generatordata = NULL;
01391       chan->generator = NULL;
01392       ast_clear_flag(chan, AST_FLAG_WRITE_INT);
01393       ast_settimeout(chan, 0, NULL, NULL);
01394    }
01395    ast_mutex_unlock(&chan->lock);
01396 }

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 2859 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_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_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_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::readq, 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().

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

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

References ast_channel::_bridge, ast_channel::_softhangup, ast_bridge_result, ast_frfree(), ast_indicate(), ast_log(), ast_read(), AST_SOFTHANGUP_UNBRIDGE, ast_waitfor_n(), ast_write(), ast_bridge_config::flags, ast_frame::frametype, LOG_DEBUG, ast_channel::name, ast_channel::nativeformats, ast_frame::subclass, and ast_channel::tech_pvt.

Referenced by ast_channel_bridge().

03216 {
03217    /* Copy voice back and forth between the two channels. */
03218    struct ast_channel *cs[3];
03219    struct ast_frame *f;
03220    struct ast_channel *who = NULL;
03221    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
03222    int o0nativeformats;
03223    int o1nativeformats;
03224    int watch_c0_dtmf;
03225    int watch_c1_dtmf;
03226    void *pvt0, *pvt1;
03227    int to;
03228    
03229    cs[0] = c0;
03230    cs[1] = c1;
03231    pvt0 = c0->tech_pvt;
03232    pvt1 = c1->tech_pvt;
03233    o0nativeformats = c0->nativeformats;
03234    o1nativeformats = c1->nativeformats;
03235    watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
03236    watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
03237 
03238    for (;;) {
03239       if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
03240           (o0nativeformats != c0->nativeformats) ||
03241           (o1nativeformats != c1->nativeformats)) {
03242          /* Check for Masquerade, codec changes, etc */
03243          res = AST_BRIDGE_RETRY;
03244          break;
03245       }
03246       if (bridge_end.tv_sec) {
03247          to = ast_tvdiff_ms(bridge_end, ast_tvnow());
03248          if (to <= 0) {
03249             res = AST_BRIDGE_RETRY;
03250             break;
03251          }
03252       } else
03253          to = -1;
03254       who = ast_waitfor_n(cs, 2, &to);
03255       if (!who) {
03256          ast_log(LOG_DEBUG, "Nobody there, continuing...\n"); 
03257          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
03258             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03259                c0->_softhangup = 0;
03260             if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03261                c1->_softhangup = 0;
03262             c0->_bridge = c1;
03263             c1->_bridge = c0;
03264          }
03265          continue;
03266       }
03267       f = ast_read(who);
03268       if (!f) {
03269          *fo = NULL;
03270          *rc = who;
03271          res = AST_BRIDGE_COMPLETE;
03272          ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
03273          break;
03274       }
03275 
03276       if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
03277          if ((f->subclass == AST_CONTROL_HOLD) || (f->subclass == AST_CONTROL_UNHOLD) ||
03278              (f->subclass == AST_CONTROL_VIDUPDATE)) {
03279             ast_indicate(who == c0 ? c1 : c0, f->subclass);
03280          } else {
03281             *fo = f;
03282             *rc = who;
03283             res =  AST_BRIDGE_COMPLETE;
03284             ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
03285             break;
03286          }
03287       }
03288       if ((f->frametype == AST_FRAME_VOICE) ||
03289           (f->frametype == AST_FRAME_DTMF) ||
03290           (f->frametype == AST_FRAME_VIDEO) || 
03291           (f->frametype == AST_FRAME_IMAGE) ||
03292           (f->frametype == AST_FRAME_HTML) ||
03293           (f->frametype == AST_FRAME_TEXT)) {
03294          if (f->frametype == AST_FRAME_DTMF) {
03295             if (((who == c0) && watch_c0_dtmf) ||
03296                 ((who == c1) && watch_c1_dtmf)) {
03297                *rc = who;
03298                *fo = f;
03299                res = AST_BRIDGE_COMPLETE;
03300                ast_log(LOG_DEBUG, "Got DTMF on channel (%s)\n", who->name);
03301                break;
03302             } else {
03303                goto tackygoto;
03304             }
03305          } else {
03306 #if 0
03307             ast_log(LOG_DEBUG, "Read from %s\n", who->name);
03308             if (who == last) 
03309                ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name);
03310             last = who;
03311 #endif
03312 tackygoto:
03313             ast_write((who == c0) ? c1 : c0, f);
03314          }
03315       }
03316       ast_frfree(f);
03317 
03318       /* Swap who gets priority */
03319       cs[2] = cs[0];
03320       cs[0] = cs[1];
03321       cs[1] = cs[2];
03322    }
03323    return res;
03324 }

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

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

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

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

Get channel by name prefix (locks channel)

Definition at line 806 of file channel.c.

References channel_find_locked(), and name.

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(), LOG_WARNING, name, 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 3710 of file channel.c.

References ast_group_t, ast_log(), ast_strdupa, LOG_ERROR, LOG_WARNING, s, and strsep().

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

03711 {
03712    char *copy;
03713    char *piece;
03714    char *c=NULL;
03715    int start=0, finish=0, x;
03716    ast_group_t group = 0;
03717 
03718    copy = ast_strdupa(s);
03719    if (!copy) {
03720       ast_log(LOG_ERROR, "Out of memory\n");
03721       return 0;
03722    }
03723    c = copy;
03724    
03725    while((piece = strsep(&c, ","))) {
03726       if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
03727          /* Range */
03728       } else if (sscanf(piece, "%d", &start)) {
03729          /* Just one */
03730          finish = start;
03731       } else {
03732          ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
03733          continue;
03734       }
03735       for (x = start; x <= finish; x++) {
03736          if ((x > 63) || (x < 0)) {
03737             ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
03738          } else
03739             group |= ((ast_group_t) 1 << x);
03740       }
03741    }
03742    return group;
03743 }

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

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

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

References ast_check_hangup(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_RINGING, 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(), ast_rtp_bridge(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), conf_run(), dial_exec_full(), disa_exec(), do_parking_thread(), features_indicate(), function_remote(), 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().

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

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

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

Referenced by load_module(), and reload().

03754 {
03755    ast_moh_start_ptr = start_ptr;
03756    ast_moh_stop_ptr = stop_ptr;
03757    ast_moh_cleanup_ptr = cleanup_ptr;
03758 }

void ast_moh_cleanup struct ast_channel chan  ) 
 

Definition at line 3786 of file channel.c.

References ast_moh_cleanup_ptr.

Referenced by ast_channel_free().

03787 {
03788    if(ast_moh_cleanup_ptr)
03789         ast_moh_cleanup_ptr(chan);
03790 }

int ast_moh_start struct ast_channel chan,
char *  mclass
 

Turn on music on hold on a given channel

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

03769 {
03770    if (ast_moh_start_ptr)
03771       return ast_moh_start_ptr(chan, mclass);
03772 
03773    if (option_verbose > 2)
03774       ast_verbose(VERBOSE_PREFIX_3 "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : "default");
03775    
03776    return 0;
03777 }

void ast_moh_stop struct ast_channel chan  ) 
 

Turn off music on hold on a given channel

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

03781 {
03782    if(ast_moh_stop_ptr)
03783       ast_moh_stop_ptr(chan);
03784 }

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

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

03799 {
03800    unsigned int i;
03801    int first=1;
03802    char num[3];
03803 
03804    buf[0] = '\0';
03805    
03806    if (!group) /* Return empty string if no group */
03807       return(buf);
03808 
03809    for (i=0; i<=63; i++) { /* Max group is 63 */
03810       if (group & ((ast_group_t) 1 << i)) {
03811             if (!first) {
03812             strncat(buf, ", ", buflen);
03813          } else {
03814             first=0;
03815          }
03816          snprintf(num, sizeof(num), "%u", i);
03817          strncat(buf, num, buflen);
03818       }
03819    }
03820    return(buf);
03821 }

int ast_prod struct ast_channel chan  ) 
 

Definition at line 2165 of file channel.c.

References ast_channel::_state, AST_FRAME_VOICE, ast_log(), 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().

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

int ast_queue_control struct ast_channel chan,
int  control
 

Queue a control frame.

Definition at line 682 of file channel.c.

References 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_FLAG_BLOCKING, ast_frdup(), ast_frfree(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_channel::blocker, ast_frame::frametype, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_frame::next, 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_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), 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 1784 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_deactivate_generator(), ast_do_masquerade(), AST_FLAG_DEFER_DTMF, AST_FLAG_EXCEPTION, AST_FLAG_ZOMBIE, ast_frame_dump(), ast_frfree(), ast_getformatname(), ast_log(), AST_MAX_FDS, ast_mutex_lock(), ast_mutex_unlock(), ast_seekstream(), ast_setstate(), ast_settimeout(), AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_translate(), ast_writestream(), ast_channel::blocker, ast_channel::cdr, 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::timingdata, 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(), 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().

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

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

References ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, ast_stopstream(), ast_test_flag, ast_waitfordigit(), ast_waitstream(), s, 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().

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

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

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

Referenced by ast_app_getdata_full().

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

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

References ast_recvtext(), and free.

Referenced by handle_recvchar().

02066 {
02067    int c;
02068    char *buf = ast_recvtext(chan, timeout);
02069    if (buf == NULL)
02070       return -1;  /* error or timeout */
02071    c = *(unsigned char *)buf;
02072    free(buf);
02073    return c;
02074 }

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

References ast_check_hangup(), AST_FRAME_CONTROL, 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().

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

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

References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_state2str(), ast_translator_best_choice(), 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, type, ast_channel_tech::type, and ast_channel::uniqueid.

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

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

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

References __ast_request_and_dial(), and type.

Referenced by ast_pbx_outgoing_exten().

02487 {
02488    return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL);
02489 }

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

References do_senddigit().

Referenced by dial_exec_full(), and features_digit().

02161 {
02162    return do_senddigit(chan, digit);
02163 }

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

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

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

02104 {
02105    int res = 0;
02106    /* Stop if we're a zombie or need a soft hangup */
02107    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) 
02108       return -1;
02109    CHECK_BLOCKING(chan);
02110    if (chan->tech->send_text)
02111       res = chan->tech->send_text(chan, text);
02112    ast_clear_flag(chan, AST_FLAG_BLOCKING);
02113    return res;
02114 }

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

Definition at line 3097 of file channel.c.

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

Referenced by __ast_request_and_dial(), ast_feature_request_and_dial(), callerid_write(), dial_exec_full(), disa_exec(), get_callerid(), handle_setcallerid(), lookupcidname_exec(), monitor_handle_notowned(), privacy_exec(), rpt_exec(), setcallerid_exec(), ss_thread(), vpb_new(), wait_for_answer(), zt_new(), and zt_read().

03098 {
03099    if (callerid) {
03100       if (chan->cid.cid_num)
03101          free(chan->cid.cid_num);
03102       if (ast_strlen_zero(callerid))
03103          chan->cid.cid_num = NULL;
03104       else
03105          chan->cid.cid_num = strdup(callerid);
03106    }
03107    if (calleridname) {
03108       if (chan->cid.cid_name)
03109          free(chan->cid.cid_name);
03110       if (ast_strlen_zero(calleridname))
03111          chan->cid.cid_name = NULL;
03112       else
03113          chan->cid.cid_name = strdup(calleridname);
03114    }
03115    if (ani) {
03116       if (chan->cid.cid_ani)
03117          free(chan->cid.cid_ani);
03118       if (ast_strlen_zero(ani))
03119          chan->cid.cid_ani = NULL;
03120       else
03121          chan->cid.cid_ani = strdup(ani);
03122    }
03123    if (chan->cdr)
03124       ast_cdr_setcid(chan->cdr, chan);
03125    manager_event(EVENT_FLAG_CALL, "Newcallerid", 
03126             "Channel: %s\r\n"
03127             "CallerID: %s\r\n"
03128             "CallerIDName: %s\r\n"
03129             "Uniqueid: %s\r\n"
03130             "CID-CallingPres: %d (%s)\r\n",
03131             chan->name, chan->cid.cid_num ? 
03132             chan->cid.cid_num : "<Unknown>",
03133             chan->cid.cid_name ? 
03134             chan->cid.cid_name : "<Unknown>",
03135             chan->uniqueid,
03136             chan->cid.cid_pres,
03137             ast_describe_caller_presentation(chan->cid.cid_pres)
03138             );
03139 }

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

References fmt, 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(), 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().

02361 {
02362    return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat,
02363            &chan->readtrans, 0);
02364 }

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

03824 {
03825    struct ast_variable *cur;
03826 
03827    for (cur = vars; cur; cur = cur->next)
03828       pbx_builtin_setvar_helper(chan, cur->name, cur->value);  
03829 }

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

References fmt, 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_moh_files_next(), ast_openstream_full(), ast_stopstream(), attempt_reconnect(), chanspy_exec(), conf_run(), disa_exec(), echo_exec(), function_ilink(), linear_alloc(), linear_release(), mgcp_rtp_read(), milliwatt_exec(), moh_alloc(), moh_files_alloc(), moh_files_release(), moh_release(), mp3_exec(), NBScat_exec(), oh323_rtp_read(), playtones_alloc(), playtones_release(), process_sdp(), rpt(), 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().

02367 {
02368    return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat,
02369            &chan->writetrans, 1);
02370 }

int ast_setstate struct ast_channel chan,
int  state
 

Change the state of a channel.

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

03142 {
03143    int oldstate = chan->_state;
03144 
03145    if (oldstate == state)
03146       return 0;
03147 
03148    chan->_state = state;
03149    ast_device_state_changed_literal(chan->name);
03150    manager_event(EVENT_FLAG_CALL,
03151             (oldstate == AST_STATE_DOWN) ? "Newchannel" : "Newstate",
03152             "Channel: %s\r\n"
03153             "State: %s\r\n"
03154             "CallerID: %s\r\n"
03155             "CallerIDName: %s\r\n"
03156             "Uniqueid: %s\r\n",
03157             chan->name, ast_state2str(chan->_state), 
03158             chan->cid.cid_num ? chan->cid.cid_num : "<unknown>", 
03159             chan->cid.cid_name ? chan->cid.cid_name : "<unknown>", 
03160             chan->uniqueid);
03161 
03162    return 0;
03163 }

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

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

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

int ast_shutting_down void   ) 
 

Returns non-zero if Asterisk is being shut down

Definition at line 271 of file channel.c.

00272 {
00273    return shutting_down;
00274 }

int ast_softhangup struct ast_channel chan,
int  cause
 

Softly hangup up a channel.

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

Definition at line 1117 of file channel.c.

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

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

01118 {
01119    int res;
01120    ast_mutex_lock(&chan->lock);
01121    res = ast_softhangup_nolock(chan, cause);
01122    ast_mutex_unlock(&chan->lock);
01123    return res;
01124 }

int ast_softhangup_nolock struct ast_channel chan,
int  cause
 

Softly hangup up a channel (no channel lock).

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

Definition at line 1101 of file channel.c.

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

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

01102 {
01103    int res = 0;
01104    struct ast_frame f = { AST_FRAME_NULL };
01105    if (option_debug)
01106       ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
01107    /* Inform channel driver that we need to be hung up, if it cares */
01108    chan->_softhangup |= cause;
01109    ast_queue_frame(chan, &f);
01110    /* Interrupt any poll call or such */
01111    if (ast_test_flag(chan, AST_FLAG_BLOCKING))
01112       pthread_kill(chan->blocker, SIGURG);
01113    return res;
01114 }

char* ast_state2str int  state  ) 
 

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

Definition at line 419 of file channel.c.

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

Referenced by action_status(), agent_hangup(), ast_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 3691 of file channel.c.

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

Referenced by zapateller_exec().

03692 {
03693    struct ast_frame *f;
03694    int res;
03695 
03696    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
03697       return res;
03698 
03699    /* Give us some wiggle room */
03700    while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) {
03701       f = ast_read(chan);
03702       if (f)
03703          ast_frfree(f);
03704       else
03705          return -1;
03706    }
03707    return 0;
03708 }

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

Start a tone going

Definition at line 3670 of file channel.c.

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

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

03671 {
03672    struct tonepair_def d = { 0, };
03673 
03674    d.freq1 = freq1;
03675    d.freq2 = freq2;
03676    d.duration = duration;
03677    if (vol < 1)
03678       d.vol = 8192;
03679    else
03680       d.vol = vol;
03681    if (ast_activate_generator(chan, &tonepair, &d))
03682       return -1;
03683    return 0;
03684 }

void ast_tonepair_stop struct ast_channel chan  ) 
 

Stop a tone from playing

Definition at line 3686 of file channel.c.

References ast_deactivate_generator().

Referenced by sendnoise().

03687 {
03688    ast_deactivate_generator(chan);
03689 }

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

02568 {
02569    int res = -1;
02570 
02571    /* Stop if we're a zombie or need a soft hangup */
02572    ast_mutex_lock(&chan->lock);
02573    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
02574       if (chan->tech->transfer) {
02575          res = chan->tech->transfer(chan, dest);
02576          if (!res)
02577             res = 1;
02578       } else
02579          res = 0;
02580    }
02581    ast_mutex_unlock(&chan->lock);
02582    return res;
02583 }

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

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

03761 {
03762    ast_moh_start_ptr = NULL;
03763    ast_moh_stop_ptr = NULL;
03764    ast_moh_cleanup_ptr = NULL;
03765 }

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

01666 {
01667    struct ast_channel *chan;
01668    int oldms = ms;
01669 
01670    chan = ast_waitfor_n(&c, 1, &ms);
01671    if (ms < 0) {
01672       if (oldms < 0)
01673          return 0;
01674       else
01675          return -1;
01676    }
01677    return ms;
01678 }

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

01661 {
01662    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
01663 }

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

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

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

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

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 1502 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, CHECK_BLOCKING, pollfd::events, pollfd::fd, ast_channel::fdno, ast_channel::fds, lock, LOG_ERROR, LOG_WARNING, ast_channel::masq, poll(), POLLIN, 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().

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

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

References ast_check_hangup(), AST_FLAG_ZOMBIE, 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().

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

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

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

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

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

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

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

Referenced by adsi_careful_send(), agent_write(), ast_dtmf_stream(), ast_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().

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

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

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

02183 {
02184    int res;
02185    if (!chan->tech->write_video)
02186       return 0;
02187    res = ast_write(chan, fr);
02188    if (!res)
02189       res = 1;
02190    return res;
02191 }

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

Definition at line 3175 of file channel.c.

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

Referenced by ast_channel_bridge().

03176 {
03177    int res=0, min=0, sec=0,check=0;
03178 
03179    check = ast_autoservice_start(peer);
03180    if(check) 
03181       return;
03182 
03183    if (remain > 0) {
03184       if (remain / 60 > 1) {
03185          min = remain / 60;
03186          sec = remain % 60;
03187       } else {
03188          sec = remain;
03189       }
03190    }
03191    
03192    if (!strcmp(sound,"timeleft")) { /* Queue support */
03193       res = ast_streamfile(chan, "vm-youhave", chan->language);
03194       res = ast_waitstream(chan, "");
03195       if (min) {
03196          res = ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, (char *) NULL);
03197          res = ast_streamfile(chan, "queue-minutes", chan->language);
03198          res = ast_waitstream(chan, "");
03199       }
03200       if (sec) {
03201          res = ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, (char *) NULL);
03202          res = ast_streamfile(chan, "queue-seconds", chan->language);
03203          res = ast_waitstream(chan, "");
03204       }
03205    } else {
03206       res = ast_streamfile(chan, sound, chan->language);
03207       res = ast_waitstream(chan, "");
03208    }
03209 
03210    check = ast_autoservice_stop(peer);
03211 }

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(), ast_channel::context, ast_channel::exten, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::macrocontext, ast_channel::macroexten, ast_channel::name, 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 }

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

Definition at line 2833 of file channel.c.

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

Referenced by ast_do_masquerade().

02834 {
02835    struct ast_var_t *varptr;
02836 
02837    /* we need to remove all app_groupcount related variables from the original
02838       channel before merging in the clone's variables; any groups assigned to the
02839       original channel should be released, only those assigned to the clone
02840       should remain
02841    */
02842 
02843    AST_LIST_TRAVERSE_SAFE_BEGIN(&original->varshead, varptr, entries) {
02844       if (!strncmp(ast_var_name(varptr), GROUP_CATEGORY_PREFIX, strlen(GROUP_CATEGORY_PREFIX))) {
02845          AST_LIST_REMOVE(&original->varshead, varptr, entries);
02846          ast_var_delete(varptr);
02847       }
02848    }
02849    AST_LIST_TRAVERSE_SAFE_END;
02850 
02851    /* Append variables from clone channel into original channel */
02852    /* XXX Is this always correct?  We have to in order to keep MACROS working XXX */
02853    if (AST_LIST_FIRST(&clone->varshead))
02854       AST_LIST_INSERT_TAIL(&original->varshead, AST_LIST_FIRST(&clone->varshead), entries);
02855 }

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

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

03832 {
03833    struct ast_frame *f;
03834    int tocopy;
03835    int bytestocopy;
03836 
03837    while (samples) {
03838       f = queue->head;
03839 
03840       if (!f) {
03841          ast_log(LOG_ERROR, "Ran out of frames before buffer filled!\n");
03842          break;
03843       }
03844 
03845       tocopy = (f->samples > samples) ? samples : f->samples;
03846       bytestocopy = ast_codec_get_len(queue->format, tocopy);
03847       memcpy(buf, f->data, bytestocopy);
03848       samples -= tocopy;
03849       buf += tocopy;
03850       f->samples -= tocopy;
03851       f->data += bytestocopy;
03852       f->datalen -= bytestocopy;
03853       f->offset += bytestocopy;
03854       queue->samples -= tocopy;
03855       if (!f->samples) {
03856          queue->head = f->next;
03857          ast_frfree(f);
03858       }
03859    }
03860 }

void detach_spies struct ast_channel chan  )  [static]
 

Definition at line 1078 of file channel.c.

References ast_channel_spy_remove(), ast_cond_signal(), AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, CHANSPY_TRIGGER_MODE, ast_channel_spy::lock, ast_channel::spies, and ast_channel_spy::trigger.

Referenced by ast_hangup().

01079 {
01080    struct ast_channel_spy *spy;
01081 
01082    if (!chan->spies)
01083       return;
01084 
01085    /* Marking the spies as done is sufficient.  Chanspy or spy users will get the picture. */
01086    AST_LIST_TRAVERSE(&chan->spies->list, spy, list) {
01087       ast_mutex_lock(&spy->lock);
01088       if (spy->status == CHANSPY_RUNNING)
01089          spy->status = CHANSPY_DONE;
01090       if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
01091          ast_cond_signal(&spy->trigger);
01092       ast_mutex_unlock(&spy->lock);
01093    }
01094 
01095    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list)
01096       ast_channel_spy_remove(chan, spy);
01097    AST_LIST_TRAVERSE_SAFE_END;
01098 }

int do_senddigit struct ast_channel chan,
char  digit
[static]
 

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

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

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 }

void free_translation struct ast_channel clone  )  [static]
 

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

01264 {
01265    if (clone->writetrans)
01266       ast_translator_free_path(clone->writetrans);
01267    if (clone->readtrans)
01268       ast_translator_free_path(clone->readtrans);
01269    clone->writetrans = NULL;
01270    clone->readtrans = NULL;
01271    clone->rawwriteformat = clone->nativeformats;
01272    clone->rawreadformat = clone->nativeformats;
01273 }

int generator_force void *  data  )  [static]
 

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

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

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

Definition at line 1133 of file channel.c.

References ast_clear_flag, ast_cond_signal(), AST_FORMAT_SLINEAR, ast_frdup(), ast_frfree(), ast_getformatname(), AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_translate(), ast_translator_build_path(), ast_translator_free_path(), CHANSPY_TRIGGER_FLUSH, CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_READ, CHANSPY_TRIGGER_WRITE, ast_channel_spy_queue::format, ast_channel_spy_queue::head, channel_spy_trans::last_format, ast_channel_spy::lock, LOG_DEBUG, LOG_ERROR, LOG_WARNING, ast_channel::name, ast_frame::next, 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_READ, ast_frame::subclass, ast_channel_spy::trigger, ast_channel_spy::type, ast_channel_spy::write_queue, and ast_channel_spy_list::write_translator.

Referenced by ast_read(), and ast_write().

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

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 2317 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(), fmt, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, and ast_channel::nativeformats.

Referenced by ast_set_read_format(), and ast_set_write_format().

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

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(), ast_channel_tech::description, ast_channel_tech::devicestate, FORMAT, ast_channel_tech::indicate, LOG_WARNING, chanlist::next, 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 }

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

Definition at line 3964 of file channel.c.

03965 {
03966    /* just store the data pointer in the channel structure */
03967    return data;
03968 }

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

Definition at line 3975 of file channel.c.

References ast_write(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, ast_frame::samples, and ast_frame::subclass.

03976 {
03977    if (samples == 160) {
03978       short buf[160] = { 0, };
03979       struct ast_frame frame = {
03980          .frametype = AST_FRAME_VOICE,
03981          .subclass = AST_FORMAT_SLINEAR,
03982          .data = buf,
03983          .samples = 160,
03984          .datalen = sizeof(buf),
03985       };
03986 
03987       if (ast_write(chan, &frame))
03988          return -1;
03989    } else {
03990       short buf[samples];
03991       int x;
03992       struct ast_frame frame = {
03993          .frametype = AST_FRAME_VOICE,
03994          .subclass = AST_FORMAT_SLINEAR,
03995          .data = buf,
03996          .samples = samples,
03997          .datalen = sizeof(buf),
03998       };
03999 
04000       for (x = 0; x < samples; x++)
04001          buf[x] = 0;
04002 
04003       if (ast_write(chan, &frame))
04004          return -1;
04005    }
04006 
04007    return 0;
04008 }

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

Definition at line 3970 of file channel.c.

03971 {
03972    /* nothing to do */
03973 }

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

Definition at line 3603 of file channel.c.

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

03604 {
03605    struct tonepair_state *ts;
03606    struct tonepair_def *td = params;
03607 
03608    ts = malloc(sizeof(struct tonepair_state));
03609    if (!ts)
03610       return NULL;
03611    memset(ts, 0, sizeof(struct tonepair_state));
03612    ts->origwfmt = chan->writeformat;
03613    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
03614       ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
03615       tonepair_release(NULL, ts);
03616       ts = NULL;
03617    } else {
03618       ts->freq1 = td->freq1;
03619       ts->freq2 = td->freq2;
03620       ts->duration = td->duration;
03621       ts->vol = td->vol;
03622    }
03623    /* Let interrupts interrupt :) */
03624    ast_set_flag(chan, AST_FLAG_WRITE_INT);
03625    return ts;
03626 }

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

Definition at line 3628 of file channel.c.

References 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.

03629 {
03630    struct tonepair_state *ts = data;
03631    int x;
03632 
03633    /* we need to prepare a frame with 16 * timelen samples as we're 
03634     * generating SLIN audio
03635     */
03636    len = samples * 2;
03637 
03638    if (len > sizeof(ts->data) / 2 - 1) {
03639       ast_log(LOG_WARNING, "Can't generate that much data!\n");
03640       return -1;
03641    }
03642    memset(&ts->f, 0, sizeof(ts->f));
03643    for (x = 0; x < (len / 2); x++) {
03644       ts->data[x] = ts->vol * (
03645             sin((ts->freq1 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) +
03646             sin((ts->freq2 * 2.0 * M_PI / 8000.0) * (ts->pos + x))
03647          );
03648    }
03649    ts->f.frametype = AST_FRAME_VOICE;
03650    ts->f.subclass = AST_FORMAT_SLINEAR;
03651    ts->f.datalen = len;
03652    ts->f.samples = samples;
03653    ts->f.offset = AST_FRIENDLY_OFFSET;
03654    ts->f.data = ts->data;
03655    ast_write(chan, &ts->f);
03656    ts->pos += x;
03657    if (ts->duration > 0) {
03658       if (ts->pos >= ts->duration * 8)
03659          return -1;
03660    }
03661    return 0;
03662 }

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

Definition at line 3593 of file channel.c.

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

Referenced by tonepair_alloc().

03594 {
03595    struct tonepair_state *ts = params;
03596 
03597    if (chan) {
03598       ast_set_write_format(chan, ts->origwfmt);
03599    }
03600    free(ts);
03601 }


Variable Documentation

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

Definition at line 3747 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 3745 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 3746 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(), and ast_channel_unregister().

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 ast_channel_alloc(), and ast_channel_free().

struct ast_cli_entry cli_show_channeltypes [static]
 

Initial value:

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

Definition at line 199 of file channel.c.

Referenced by ast_channels_init().

unsigned long global_fin = 0 global_fout = 0
 

Definition at line 100 of file channel.c.

Referenced by handle_debugchan(), and handle_nodebugchan().

const struct ast_channel_tech null_tech [static]
 

Initial value:

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

Definition at line 510 of file channel.c.

char show_channeltypes_usage[] [static]
 

Initial value:

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

Definition at line 195 of file channel.c.

int shutting_down = 0 [static]
 

Definition at line 95 of file channel.c.

Referenced by ast_begin_shutdown(), and ast_cancel_shutdown().

struct ast_generator silence_generator [static]
 

Initial value:

 {
   .alloc = silence_generator_alloc,
   .release = silence_generator_release,
   .generate = silence_generator_generate, 
}

Definition at line 4010 of file channel.c.

Referenced by ast_channel_start_silence_generator().

struct ast_generator tonepair [static]
 

Initial value:

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

Definition at line 3664 of file channel.c.

Referenced by ast_tonepair_start().

int uniqueint = 0 [static]
 

Definition at line 98 of file channel.c.

Referenced by ast_channel_alloc().


Generated on Mon Mar 20 08:25:57 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1