Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

channel.h File Reference

#include <asterisk/frame.h>
#include <asterisk/sched.h>
#include <asterisk/chanvars.h>
#include <unistd.h>
#include <setjmp.h>
#include <pthread.h>
#include <asterisk/lock.h>
#include <asterisk/cdr.h>
#include <asterisk/monitor.h>

Go to the source code of this file.

Data Structures

struct  ast_channel
 Main Channel structure associated with a channel. More...

struct  ast_generator

Defines

#define AST_MAX_EXTENSION   80
 Max length of an extension.

#define AST_CHANNEL_NAME   80
#define AST_CHANNEL_MAX_STACK   32
#define MAX_LANGUAGE   20
#define AST_MAX_FDS   8
#define AST_CDR_TRANSFER   (1 << 0)
#define AST_CDR_FORWARD   (1 << 1)
#define AST_CDR_CALLWAIT   (1 << 2)
#define AST_CDR_CONFERENCE   (1 << 3)
#define AST_ADSI_UNKNOWN   (0)
#define AST_ADSI_AVAILABLE   (1)
#define AST_ADSI_UNAVAILABLE   (2)
#define AST_ADSI_OFFHOOKONLY   (3)
#define AST_SOFTHANGUP_DEV   (1 << 0)
#define AST_SOFTHANGUP_ASYNCGOTO   (1 << 1)
#define AST_SOFTHANGUP_SHUTDOWN   (1 << 2)
#define AST_SOFTHANGUP_TIMEOUT   (1 << 3)
#define AST_SOFTHANGUP_APPUNLOAD   (1 << 4)
#define AST_SOFTHANGUP_EXPLICIT   (1 << 5)
#define AST_STATE_DOWN   0
#define AST_STATE_RESERVED   1
#define AST_STATE_OFFHOOK   2
#define AST_STATE_DIALING   3
#define AST_STATE_RING   4
#define AST_STATE_RINGING   5
#define AST_STATE_UP   6
#define AST_STATE_BUSY   7
#define AST_STATE_MUTE   (1 << 16)
#define AST_DEVICE_UNKNOWN   0
#define AST_DEVICE_NOT_INUSE   1
#define AST_DEVICE_INUSE   2
#define AST_DEVICE_BUSY   3
#define AST_DEVICE_INVALID   4
#define AST_DEVICE_UNAVAILABLE   5
#define AST_BRIDGE_DTMF_CHANNEL_0   (1 << 0)
#define AST_BRIDGE_DTMF_CHANNEL_1   (1 << 1)
#define AST_BRIDGE_REC_CHANNEL_0   (1 << 2)
#define AST_BRIDGE_REC_CHANNEL_1   (1 << 3)
#define AST_BRIDGE_IGNORE_SIGS   (1 << 4)
#define CRASH   do { } while(0)
#define CHECK_BLOCKING(c)

Functions

ast_channelast_request (char *type, int format, void *data)
 Requests a channel.

int ast_parse_device_state (char *device)
 Search the Channels by Name.

int ast_device_state (char *device)
 Asks a channel for device state.

ast_channelast_request_and_dial (char *type, int format, void *data, int timeout, int *reason, char *callerid)
int ast_channel_register (char *type, char *description, int capabilities, struct ast_channel *(*requester)(char *type, int format, void *data))
 Registers a channel.

int ast_channel_register_ex (char *type, char *description, int capabilities, struct ast_channel *(*requester)(char *type, int format, void *data), int(*devicestate)(void *data))
void ast_channel_unregister (char *type)
 Unregister a channel class.

int ast_hangup (struct ast_channel *chan)
 Hang up a channel.

int ast_softhangup (struct ast_channel *chan, int cause)
 Softly hangup up a channel.

int ast_softhangup_nolock (struct ast_channel *chan, int cause)
int ast_check_hangup (struct ast_channel *chan)
 Check to see if a channel is needing hang up.

void ast_channel_setwhentohangup (struct ast_channel *chan, time_t offset)
 Set when to hang a channel up.

int ast_answer (struct ast_channel *chan)
 Answer a ringing call.

int ast_call (struct ast_channel *chan, char *addr, int timeout)
 Make a call.

int ast_indicate (struct ast_channel *chan, int condition)
 Indicates condition of channel.

int ast_waitfor (struct ast_channel *chan, int ms)
 Wait for input on a channel.

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.

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

ast_channelast_waitfor_n (struct ast_channel **chan, int n, int *ms)
 Waits for input on a group of channels.

int ast_waitfor_n_fd (int *fds, int n, int *ms, int *exception)
 Waits for input on an fd.

ast_frameast_read (struct ast_channel *chan)
 Reads a frame.

int ast_write (struct ast_channel *chan, struct ast_frame *frame)
 Write a frame to a channel.

int ast_write_video (struct ast_channel *chan, struct ast_frame *frame)
 Write video frame to a channel.

int ast_prod (struct ast_channel *chan)
int ast_set_read_format (struct ast_channel *chan, int format)
 Sets read format on channel chan.

int ast_set_write_format (struct ast_channel *chan, int format)
 Sets write format on channel chan.

int ast_sendtext (struct ast_channel *chan, char *text)
 Sends text to a channel.

int ast_recvchar (struct ast_channel *chan, int timeout)
 Receives a text character from a channel.

ast_channelast_channel_walk (struct ast_channel *prev)
 Browse channels in use.

char ast_waitfordigit (struct ast_channel *c, int ms)
 Waits for a digit.

char ast_waitfordigit_full (struct ast_channel *c, int ms, int audiofd, int ctrlfd)
int ast_readstring (struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders)
 Reads multiple digits.

int ast_readstring_full (struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders, int audiofd, int ctrlfd)
int ast_channel_make_compatible (struct ast_channel *c0, struct ast_channel *c1)
 Makes two channel formats compatible.

int ast_channel_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
 Bridge two channels together.

int ast_channel_masquerade (struct ast_channel *original, struct ast_channel *clone)
 Weird function made for call transfers.

char * ast_state2str (int state)
 Gives the string form of a given state.

int ast_channel_setoption (struct ast_channel *channel, int option, void *data, int datalen, int block)
 Sets an option on a channel.

ast_frameast_channel_queryoption (struct ast_channel *channel, int option, void *data, int *datalen, int block)
 Checks the value of an option.

int ast_channel_supports_html (struct ast_channel *channel)
 Checks for HTML support on a channel.

int ast_channel_sendhtml (struct ast_channel *channel, int subclass, char *data, int datalen)
 Sends HTML on given channel.

int ast_channel_sendurl (struct ast_channel *channel, char *url)
 Sends a URL on a given link.

int ast_channel_defer_dtmf (struct ast_channel *chan)
 Defers DTMF.

void ast_channel_undefer_dtmf (struct ast_channel *chan)
 Undeos a defer.

void ast_begin_shutdown (int hangup)
void ast_cancel_shutdown (void)
int ast_active_channels (void)
int ast_shutting_down (void)
int ast_activate_generator (struct ast_channel *chan, struct ast_generator *gen, void *params)
void ast_deactivate_generator (struct ast_channel *chan)
void ast_set_callerid (struct ast_channel *chan, char *callerid, int anitoo)
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_tonepair (struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
int ast_autoservice_start (struct ast_channel *chan)
int ast_autoservice_stop (struct ast_channel *chan)
int ast_settimeout (struct ast_channel *c, int samples, int(*func)(void *data), void *data)
int ast_transfer (struct ast_channel *chan, char *dest)


Define Documentation

#define AST_ADSI_AVAILABLE   (1)
 

Definition at line 236 of file channel.h.

#define AST_ADSI_OFFHOOKONLY   (3)
 

Definition at line 238 of file channel.h.

#define AST_ADSI_UNAVAILABLE   (2)
 

Definition at line 237 of file channel.h.

#define AST_ADSI_UNKNOWN   (0)
 

Definition at line 235 of file channel.h.

#define AST_BRIDGE_DTMF_CHANNEL_0   (1 << 0)
 

Report DTMF on channel 0

Definition at line 577 of file channel.h.

Referenced by ast_channel_bridge(), and ast_rtp_bridge().

#define AST_BRIDGE_DTMF_CHANNEL_1   (1 << 1)
 

Report DTMF on channel 1

Definition at line 579 of file channel.h.

Referenced by ast_channel_bridge(), and ast_rtp_bridge().

#define AST_BRIDGE_IGNORE_SIGS   (1 << 4)
 

Ignore all signal frames except NULL

Definition at line 585 of file channel.h.

Referenced by ast_channel_bridge().

#define AST_BRIDGE_REC_CHANNEL_0   (1 << 2)
 

Return all voice frames on channel 0

Definition at line 581 of file channel.h.

#define AST_BRIDGE_REC_CHANNEL_1   (1 << 3)
 

Return all voice frames on channel 1

Definition at line 583 of file channel.h.

#define AST_CDR_CALLWAIT   (1 << 2)
 

Definition at line 232 of file channel.h.

#define AST_CDR_CONFERENCE   (1 << 3)
 

Definition at line 233 of file channel.h.

#define AST_CDR_FORWARD   (1 << 1)
 

Definition at line 231 of file channel.h.

#define AST_CDR_TRANSFER   (1 << 0)
 

Definition at line 230 of file channel.h.

#define AST_CHANNEL_MAX_STACK   32
 

Definition at line 38 of file channel.h.

Referenced by pbx_exec().

#define AST_CHANNEL_NAME   80
 

Definition at line 37 of file channel.h.

Referenced by ast_channel_free(), and ast_parse_device_state().

#define AST_DEVICE_BUSY   3
 

Device is busy

Definition at line 276 of file channel.h.

#define AST_DEVICE_INUSE   2
 

Device is in use

Definition at line 274 of file channel.h.

Referenced by ast_parse_device_state().

#define AST_DEVICE_INVALID   4
 

Device is invalid

Definition at line 278 of file channel.h.

Referenced by ast_device_state().

#define AST_DEVICE_NOT_INUSE   1
 

Device is not used

Definition at line 272 of file channel.h.

#define AST_DEVICE_UNAVAILABLE   5
 

Device is unavailable

Definition at line 280 of file channel.h.

#define AST_DEVICE_UNKNOWN   0
 

Device is valid but channel didn't know state

Definition at line 270 of file channel.h.

Referenced by ast_device_state(), and ast_parse_device_state().

#define AST_MAX_EXTENSION   80
 

Max length of an extension.

Definition at line 31 of file channel.h.

Referenced by ast_cdr_init(), ast_cdr_setcid(), ast_cdr_update(), ast_device_state(), and ast_device_state_changed().

#define AST_MAX_FDS   8
 

Definition at line 43 of file channel.h.

Referenced by ast_channel_alloc(), ast_read(), and ast_waitfor_nandfds().

#define AST_SOFTHANGUP_APPUNLOAD   (1 << 4)
 

Definition at line 244 of file channel.h.

#define AST_SOFTHANGUP_ASYNCGOTO   (1 << 1)
 

Definition at line 241 of file channel.h.

Referenced by ast_async_goto(), and ast_pbx_run().

#define AST_SOFTHANGUP_DEV   (1 << 0)
 

Definition at line 240 of file channel.h.

Referenced by ast_dsp_process(), ast_queue_hangup(), ast_read(), and ast_write().

#define AST_SOFTHANGUP_EXPLICIT   (1 << 5)
 

Definition at line 245 of file channel.h.

#define AST_SOFTHANGUP_SHUTDOWN   (1 << 2)
 

Definition at line 242 of file channel.h.

Referenced by ast_begin_shutdown().

#define AST_SOFTHANGUP_TIMEOUT   (1 << 3)
 

Definition at line 243 of file channel.h.

Referenced by ast_check_hangup(), and ast_pbx_run().

#define AST_STATE_BUSY   7
 

Line is busy

Definition at line 263 of file channel.h.

Referenced by ast_state2str().

#define AST_STATE_DIALING   3
 

Digits (or equivalent) have been dialed

Definition at line 255 of file channel.h.

Referenced by ast_state2str().

#define AST_STATE_DOWN   0
 

Channel is down and available

Definition at line 249 of file channel.h.

Referenced by ast_channel_alloc(), ast_request(), ast_setstate(), and ast_state2str().

#define AST_STATE_MUTE   (1 << 16)
 

Do not transmit voice data

Definition at line 267 of file channel.h.

#define AST_STATE_OFFHOOK   2
 

Channel is off hook

Definition at line 253 of file channel.h.

Referenced by ast_state2str().

#define AST_STATE_RESERVED   1
 

Channel is down, but reserved

Definition at line 251 of file channel.h.

Referenced by ast_state2str().

#define AST_STATE_RING   4
 

Line is ringing

Definition at line 257 of file channel.h.

Referenced by ast_answer(), and ast_state2str().

#define AST_STATE_RINGING   5
 

Remote end is ringing

Definition at line 259 of file channel.h.

Referenced by ast_answer(), and ast_state2str().

#define AST_STATE_UP   6
 

Line is up

Definition at line 261 of file channel.h.

Referenced by ast_answer(), ast_cdr_init(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_prod(), ast_read(), ast_request_and_dial(), and ast_state2str().

#define CHECK_BLOCKING  ) 
 

Definition at line 773 of file channel.h.

Referenced by ast_sendtext(), ast_waitfor_nandfds(), and ast_write().

#define CRASH   do { } while(0)
 

Definition at line 770 of file channel.h.

Referenced by ast_hangup(), ast_queue_frame(), ast_rtcp_read(), ast_rtp_read(), and ast_sched_del().

#define MAX_LANGUAGE   20
 

Definition at line 40 of file channel.h.

Referenced by ast_fileexists(), ast_openstream(), and ast_openvstream().


Function Documentation

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

Activate a given generator

Definition at line 739 of file channel.c.

References ast_generator::alloc, ast_prod(), ast_channel::generator, ast_channel::generatordata, and ast_generator::release.

Referenced by ast_playtones_start(), and ast_tonepair_start().

00740 {
00741    if (chan->generatordata) {
00742       chan->generator->release(chan, chan->generatordata);
00743       chan->generatordata = NULL;
00744    }
00745    ast_prod(chan);
00746    if ((chan->generatordata = gen->alloc(chan, params))) {
00747       chan->generator = gen;
00748    } else {
00749       return -1;
00750    }
00751    return 0;
00752 }

int ast_active_channels void   ) 
 

Returns number of active/allocated channels

Definition at line 109 of file channel.c.

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

00110 {
00111    struct ast_channel *c;
00112    int cnt = 0;
00113    ast_mutex_lock(&chlock);
00114    c = channels;
00115    while(c) {
00116       cnt++;
00117       c = c->next;
00118    }
00119    ast_mutex_unlock(&chlock);
00120    return cnt;
00121 }

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 0 on success, -1 on failure

Definition at line 703 of file channel.c.

References ast_channel::_state, ast_channel_pvt::answer, ast_cdr_answer(), ast_check_hangup(), ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_channel::cdr, ast_channel::lock, ast_channel::pvt, and ast_channel::zombie.

00704 {
00705    int res = 0;
00706    /* Stop if we're a zombie or need a soft hangup */
00707    if (chan->zombie || ast_check_hangup(chan)) 
00708       return -1;
00709    switch(chan->_state) {
00710    case AST_STATE_RINGING:
00711    case AST_STATE_RING:
00712       ast_mutex_lock(&chan->lock);
00713       if (chan->pvt->answer)
00714          res = chan->pvt->answer(chan);
00715       ast_mutex_unlock(&chan->lock);
00716       ast_setstate(chan, AST_STATE_UP);
00717       if (chan->cdr)
00718          ast_cdr_answer(chan->cdr);
00719       return res;
00720       break;
00721    case AST_STATE_UP:
00722       if (chan->cdr)
00723          ast_cdr_answer(chan->cdr);
00724       break;
00725    }
00726    return 0;
00727 }

int ast_autoservice_start struct ast_channel chan  ) 
 

Automatically service a channel for us...

Definition at line 87 of file autoservice.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, free, LOG_WARNING, malloc, ast_channel::next, and asent::next.

Referenced by ast_get_enum(), ast_get_srv(), and ast_rtp_bridge().

00088 {
00089    int res = -1;
00090    struct asent *as;
00091    int needstart;
00092    ast_mutex_lock(&autolock);
00093    needstart = (asthread == (pthread_t) -1) ? 1 : 0 /* aslist ? 0 : 1 */;
00094    as = aslist;
00095    while(as) {
00096       if (as->chan == chan)
00097          break;
00098       as = as->next;
00099    }
00100    if (!as) {
00101       as = malloc(sizeof(struct asent));
00102       if (as) {
00103          memset(as, 0, sizeof(struct asent));
00104          as->chan = chan;
00105          as->next = aslist;
00106          aslist = as;
00107          res = 0;
00108          if (needstart) {
00109             if (pthread_create(&asthread, NULL, autoservice_run, NULL)) {
00110                ast_log(LOG_WARNING, "Unable to create autoservice thread :(\n");
00111                free(aslist);
00112                aslist = NULL;
00113                res = -1;
00114             } else
00115                pthread_kill(asthread, SIGURG);
00116          }
00117       }
00118    }
00119    ast_mutex_unlock(&autolock);
00120    return res;
00121 }

int ast_autoservice_stop struct ast_channel chan  ) 
 

Stop servicing a channel for us... Returns -1 on error or if channel has been hungup

Definition at line 123 of file autoservice.c.

References ast_channel::_softhangup, ast_mutex_lock, ast_mutex_unlock, ast_channel::blocking, free, and asent::next.

Referenced by ast_get_enum(), ast_get_srv(), and ast_rtp_bridge().

00124 {
00125    int res = -1;
00126    struct asent *as, *prev;
00127    ast_mutex_lock(&autolock);
00128    as = aslist;
00129    prev = NULL;
00130    while(as) {
00131       if (as->chan == chan)
00132          break;
00133       prev = as;
00134       as = as->next;
00135    }
00136    if (as) {
00137       if (prev)
00138          prev->next = as->next;
00139       else
00140          aslist = as->next;
00141       free(as);
00142       if (!chan->_softhangup)
00143          res = 0;
00144    }
00145    if (asthread != (pthread_t) -1) 
00146       pthread_kill(asthread, SIGURG);
00147    ast_mutex_unlock(&autolock);
00148    /* Wait for it to un-block */
00149    while(chan->blocking)
00150       usleep(1000);
00151    return res;
00152 }

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

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

00095 {
00096    struct ast_channel *c;
00097    shutting_down = 1;
00098    if (hangup) {
00099       ast_mutex_lock(&chlock);
00100       c = channels;
00101       while(c) {
00102          ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
00103          c = c->next;
00104       }
00105       ast_mutex_unlock(&chlock);
00106    }
00107 }

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 -1 on failure, 0 on not enough time (does not auto matically stop ringing), and the number of seconds the connect took otherwise. Returns 0 on success, -1 on failure

Definition at line 1657 of file channel.c.

References ast_check_hangup(), ast_mutex_lock, ast_mutex_unlock, ast_channel_pvt::call, ast_channel::lock, ast_channel::pvt, and ast_channel::zombie.

Referenced by ast_request_and_dial().

01658 {
01659    /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 
01660       If the remote end does not answer within the timeout, then do NOT hang up, but 
01661       return anyway.  */
01662    int res = -1;
01663    /* Stop if we're a zombie or need a soft hangup */
01664    ast_mutex_lock(&chan->lock);
01665    if (!chan->zombie && !ast_check_hangup(chan)) 
01666       if (chan->pvt->call)
01667          res = chan->pvt->call(chan, addr, timeout);
01668    ast_mutex_unlock(&chan->lock);
01669    return res;
01670 }

void ast_cancel_shutdown void   ) 
 

Cancels an existing shutdown and returns to normal operation

Definition at line 123 of file channel.c.

00124 {
00125    shutting_down = 0;
00126 }

int ast_channel_bridge struct ast_channel c0,
struct ast_channel c1,
int  flags,
struct ast_frame **  fo,
struct ast_channel **  rc
 

Bridge two channels together.

Parameters:
c0 first channel to bridge
c1 second channel to bridge
flags 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 2121 of file channel.c.

References AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_IGNORE_SIGS, ast_channel_make_compatible(), ast_check_hangup(), AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_read(), ast_verbose(), ast_waitfor_n(), ast_write(), ast_channel::bridge, EVENT_FLAG_CALL, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::name, option_verbose, VERBOSE_PREFIX_3, and ast_channel::zombie.

02122 {
02123    /* Copy voice back and forth between the two channels.  Give the peer
02124       the ability to transfer calls with '#<extension' syntax. */
02125    struct ast_channel *cs[3];
02126    int to = -1;
02127    struct ast_frame *f;
02128    struct ast_channel *who = NULL;
02129    int res;
02130    int nativefailed=0;
02131 
02132    /* Stop if we're a zombie or need a soft hangup */
02133    if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) 
02134       return -1;
02135    if (c0->bridge) {
02136       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
02137          c0->name, c0->bridge->name);
02138       return -1;
02139    }
02140    if (c1->bridge) {
02141       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
02142          c1->name, c1->bridge->name);
02143       return -1;
02144    }
02145    
02146    /* Keep track of bridge */
02147    c0->bridge = c1;
02148    c1->bridge = c0;
02149    cs[0] = c0;
02150    cs[1] = c1;
02151    
02152    manager_event(EVENT_FLAG_CALL, "Link", 
02153          "Channel1: %s\r\n"
02154          "Channel2: %s\r\n",
02155          c0->name, c1->name);
02156 
02157    for (/* ever */;;) {
02158       /* Stop if we're a zombie or need a soft hangup */
02159       if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) {
02160          *fo = NULL;
02161          if (who) *rc = who;
02162          res = 0;
02163          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",c0->name,c1->name,c0->zombie?"Yes":"No",ast_check_hangup(c0)?"Yes":"No",c1->zombie?"Yes":"No",ast_check_hangup(c1)?"Yes":"No");
02164          break;
02165       }
02166       if (c0->pvt->bridge && 
02167          (c0->pvt->bridge == c1->pvt->bridge) && !nativefailed && !c0->monitor && !c1->monitor) {
02168             /* Looks like they share a bridge code */
02169          if (option_verbose > 2) 
02170             ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name);
02171          if (!(res = c0->pvt->bridge(c0, c1, flags, fo, rc))) {
02172             c0->bridge = NULL;
02173             c1->bridge = NULL;
02174             manager_event(EVENT_FLAG_CALL, "Unlink", 
02175                "Channel1: %s\r\n"
02176                "Channel2: %s\r\n",
02177                c0->name, c1->name);
02178             ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n",c0->name ,c1->name);
02179             return 0;
02180          }
02181          /* If they return non-zero then continue on normally.  Let "-2" mean don't worry about
02182             my not wanting to bridge */
02183          if ((res != -2) && (res != -3))
02184             ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name);
02185          if (res != -3) nativefailed++;
02186       }
02187    
02188          
02189       if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat)) &&
02190          !(c0->generator || c1->generator))  {
02191          if (ast_channel_make_compatible(c0, c1)) {
02192             ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
02193             manager_event(EVENT_FLAG_CALL, "Unlink", 
02194                "Channel1: %s\r\n"
02195                "Channel2: %s\r\n",
02196                c0->name, c1->name);
02197             return -1;
02198          }
02199       }
02200       who = ast_waitfor_n(cs, 2, &to);
02201       if (!who) {
02202          ast_log(LOG_DEBUG, "Nobody there, continuing...\n"); 
02203          continue;
02204       }
02205       f = ast_read(who);
02206       if (!f) {
02207          *fo = NULL;
02208          *rc = who;
02209          res = 0;
02210          ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
02211          break;
02212       }
02213 
02214       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
02215          *fo = f;
02216          *rc = who;
02217          res =  0;
02218          ast_log(LOG_DEBUG, "Got a FRAME_CONTROL frame on channel %s\n",who->name);
02219          break;
02220       }
02221       if ((f->frametype == AST_FRAME_VOICE) ||
02222          (f->frametype == AST_FRAME_TEXT) ||
02223          (f->frametype == AST_FRAME_VIDEO) || 
02224          (f->frametype == AST_FRAME_IMAGE) ||
02225          (f->frametype == AST_FRAME_DTMF)) {
02226          if ((f->frametype == AST_FRAME_DTMF) && 
02227             (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
02228             if ((who == c0)) {
02229                if  ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) {
02230                   *rc = c0;
02231                   *fo = f;
02232                   /* Take out of conference mode */
02233                   res = 0;
02234                   ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_0 on c0 (%s)\n",c0->name);
02235                   break;
02236                } else 
02237                   goto tackygoto;
02238             } else
02239             if ((who == c1)) {
02240                if (flags & AST_BRIDGE_DTMF_CHANNEL_1) {
02241                   *rc = c1;
02242                   *fo = f;
02243                   res =  0;
02244                   ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_1 on c1 (%s)\n",c1->name);
02245                   break;
02246                } else
02247                   goto tackygoto;
02248             }
02249          } else {
02250 #if 0
02251             ast_log(LOG_DEBUG, "Read from %s\n", who->name);
02252             if (who == last) 
02253                ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name);
02254             last = who;
02255 #endif
02256 tackygoto:
02257             /* Don't copy packets if there is a generator on either one, since they're
02258                not supposed to be listening anyway */
02259             if (who == c0) 
02260                ast_write(c1, f);
02261             else 
02262                ast_write(c0, f);
02263          }
02264          ast_frfree(f);
02265       } else
02266          ast_frfree(f);
02267       /* Swap who gets priority */
02268       cs[2] = cs[0];
02269       cs[0] = cs[1];
02270       cs[1] = cs[2];
02271    }
02272    c0->bridge = NULL;
02273    c1->bridge = NULL;
02274    manager_event(EVENT_FLAG_CALL, "Unlink", 
02275                "Channel1: %s\r\n"
02276                "Channel2: %s\r\n",
02277                c0->name, c1->name);
02278    ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n",c0->name,c1->name);
02279    return res;
02280 }

int ast_channel_defer_dtmf struct ast_channel chan  ) 
 

Defers DTMF.

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

References ast_channel::deferdtmf.

00417 {
00418    int pre = 0;
00419    if (chan) {
00420       pre = chan->deferdtmf;
00421       chan->deferdtmf = 1;
00422    }
00423    return pre;
00424 }

int ast_channel_make_compatible struct ast_channel c0,
struct ast_channel c1
 

Makes two channel formats compatible.

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

01795 {
01796    int peerf;
01797    int chanf;
01798    int res;
01799    peerf = peer->nativeformats;
01800    chanf = chan->nativeformats;
01801    res = ast_translator_best_choice(&peerf, &chanf);
01802    if (res < 0) {
01803       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, chan->nativeformats, peer->name, peer->nativeformats);
01804       return -1;
01805    }
01806    /* Set read format on channel */
01807    res = ast_set_read_format(chan, peerf);
01808    if (res < 0) {
01809       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, chanf);
01810       return -1;
01811    }
01812    /* Set write format on peer channel */
01813    res = ast_set_write_format(peer, peerf);
01814    if (res < 0) {
01815       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, peerf);
01816       return -1;
01817    }
01818    /* Now we go the other way */
01819    peerf = peer->nativeformats;
01820    chanf = chan->nativeformats;
01821    res = ast_translator_best_choice(&chanf, &peerf);
01822    if (res < 0) {
01823       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, peer->nativeformats, chan->name, chan->nativeformats);
01824       return -1;
01825    }
01826    /* Set writeformat on channel */
01827    res = ast_set_write_format(chan, chanf);
01828    if (res < 0) {
01829       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, chanf);
01830       return -1;
01831    }
01832    /* Set read format on peer channel */
01833    res = ast_set_read_format(peer, chanf);
01834    if (res < 0) {
01835       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, peerf);
01836       return -1;
01837    }
01838    return 0;
01839 }

int ast_channel_masquerade struct ast_channel original,
struct ast_channel clone
 

Weird function made for call transfers.

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

References AST_FRAME_NULL, ast_log(), ast_queue_frame(), LOG_DEBUG, LOG_WARNING, ast_channel::masq, ast_channel::masqr, and ast_channel::name.

Referenced by ast_async_goto().

01842 {
01843    struct ast_frame null = { AST_FRAME_NULL, };
01844    ast_log(LOG_DEBUG, "Planning to masquerade %s into the structure of %s\n",
01845       clone->name, original->name);
01846    if (original->masq) {
01847       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
01848          original->masq->name, original->name);
01849       return -1;
01850    }
01851    if (clone->masqr) {
01852       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
01853          clone->name, clone->masqr->name);
01854       return -1;
01855    }
01856    original->masq = clone;
01857    clone->masqr = original;
01858    /* XXX can't really hold the lock here, but at the same time, it' s
01859       not really safe not to XXX */
01860    ast_queue_frame(original, &null, 0);
01861    ast_queue_frame(clone, &null, 0);
01862    ast_log(LOG_DEBUG, "Done planning to masquerade %s into the structure of %s\n", original->name, clone->name);
01863    return 0;
01864 }

struct ast_frame* ast_channel_queryoption struct ast_channel channel,
int  option,
void *  data,
int *  datalen,
int  block
 

Checks the value of an option.

Query the value of an option, optionally blocking until a reply is received Works similarly to setoption except only reads the options.

int ast_channel_register char *  type,
char *  description,
int  capabilities,
struct ast_channel *(*  requester)(char *type, int format, void *data)
 

Registers a channel.

Parameters:
type type of channel you are registering
description short description of the channel
capabilities a bit mask of the capabilities of the channel
requester a function pointer that properly responds to a call. See one of the channel drivers for details. Called by a channel module to register the kind of channels it supports. It supplies a brief type, a longer, but still short description, and a routine that creates a channel Returns 0 on success, -1 on failure.

Definition at line 145 of file channel.c.

References ast_channel_register_ex(), description(), and type.

00147 {
00148     return ast_channel_register_ex(type, description, capabilities, requester, NULL);
00149 }

int ast_channel_register_ex char *  type,
char *  description,
int  capabilities,
struct ast_channel *(*  requester)(char *type, int format, void *data),
int(*  devicestate)(void *data)
 

Definition at line 151 of file channel.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), backends, description(), LOG_DEBUG, LOG_WARNING, malloc, option_debug, option_verbose, type, and VERBOSE_PREFIX_2.

Referenced by ast_channel_register().

00154 {
00155    struct chanlist *chan, *last=NULL;
00156    if (ast_mutex_lock(&chlock)) {
00157       ast_log(LOG_WARNING, "Unable to lock channel list\n");
00158       return -1;
00159    }
00160    chan = backends;
00161    while(chan) {
00162       if (!strcasecmp(type, chan->type)) {
00163          ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", type);
00164          ast_mutex_unlock(&chlock);
00165          return -1;
00166       }
00167       last = chan;
00168       chan = chan->next;
00169    }
00170    chan = malloc(sizeof(struct chanlist));
00171    if (!chan) {
00172       ast_log(LOG_WARNING, "Out of memory\n");
00173       ast_mutex_unlock(&chlock);
00174       return -1;
00175    }
00176    strncpy(chan->type, type, sizeof(chan->type)-1);
00177    strncpy(chan->description, description, sizeof(chan->description)-1);
00178    chan->capabilities = capabilities;
00179    chan->requester = requester;
00180    chan->devicestate = devicestate;
00181    chan->next = NULL;
00182    if (last)
00183       last->next = chan;
00184    else
00185       backends = chan;
00186    if (option_debug)
00187       ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->type, chan->description);
00188    else if (option_verbose > 1)
00189       ast_verbose( VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->type, chan->description);
00190    ast_mutex_unlock(&chlock);
00191    return 0;
00192 }

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

Sends HTML on given channel.

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

Definition at line 1780 of file channel.c.

References ast_channel::pvt, and ast_channel_pvt::send_html.

01781 {
01782    if (chan->pvt->send_html)
01783       return chan->pvt->send_html(chan, subclass, data, datalen);
01784    return -1;
01785 }

int ast_channel_sendurl struct ast_channel channel,
char *  url
 

Sends a URL on a given link.

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

Definition at line 1787 of file channel.c.

References AST_HTML_URL, ast_channel::pvt, and ast_channel_pvt::send_html.

01788 {
01789    if (chan->pvt->send_html)
01790       return chan->pvt->send_html(chan, AST_HTML_URL, url, strlen(url) + 1);
01791    return -1;
01792 }

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

Sets an option on a channel.

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

References ast_log(), LOG_ERROR, ast_channel::pvt, and ast_channel_pvt::setoption.

02283 {
02284    int res;
02285    if (chan->pvt->setoption) {
02286       res = chan->pvt->setoption(chan, option, data, datalen);
02287       if (res < 0)
02288          return res;
02289    } else {
02290       errno = ENOSYS;
02291       return -1;
02292    }
02293    if (block) {
02294       /* XXX Implement blocking -- just wait for our option frame reply, discarding
02295          intermediate packets. XXX */
02296       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
02297       return -1;
02298    }
02299    return 0;
02300 }

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

References ast_channel::whentohangup.

00134 {
00135 time_t   myt;
00136 
00137    time(&myt);
00138         if (offset)
00139      chan->whentohangup = myt + offset;
00140         else
00141           chan->whentohangup = 0;
00142    return;
00143 }

int ast_channel_supports_html struct ast_channel channel  ) 
 

Checks for HTML support on a channel.

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

Definition at line 1773 of file channel.c.

References ast_channel::pvt, and ast_channel_pvt::send_html.

01774 {
01775    if (chan->pvt->send_html)
01776       return 1;
01777    return 0;
01778 }

void ast_channel_undefer_dtmf struct ast_channel chan  ) 
 

Undeos a defer.

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

Definition at line 426 of file channel.c.

References ast_channel::deferdtmf.

00427 {
00428    if (chan)
00429       chan->deferdtmf = 0;
00430 }

void ast_channel_unregister char *  type  ) 
 

Unregister a channel class.

Definition at line 677 of file channel.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, backends, free, LOG_DEBUG, LOG_WARNING, ast_channel::next, chanlist::next, option_debug, ast_channel::type, and type.

00678 {
00679    struct chanlist *chan, *last=NULL;
00680    if (option_debug)
00681       ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", type);
00682    if (ast_mutex_lock(&chlock)) {
00683       ast_log(LOG_WARNING, "Unable to lock channel list\n");
00684       return;
00685    }
00686    chan = backends;
00687    while(chan) {
00688       if (!strcasecmp(chan->type, type)) {
00689          if (last)
00690             last->next = chan->next;
00691          else
00692             backends = backends->next;
00693          free(chan);
00694          ast_mutex_unlock(&chlock);
00695          return;
00696       }
00697       last = chan;
00698       chan = chan->next;
00699    }
00700    ast_mutex_unlock(&chlock);
00701 }

struct ast_channel* ast_channel_walk struct ast_channel prev  ) 
 

Browse channels in use.

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.

Definition at line 432 of file channel.c.

References ast_mutex_lock, ast_mutex_unlock, and channels.

Referenced by ast_async_goto_by_name(), and ast_parse_device_state().

00433 {
00434    struct ast_channel *l, *ret=NULL;
00435    ast_mutex_lock(&chlock);
00436    l = channels;
00437    if (!prev) {
00438       ast_mutex_unlock(&chlock);
00439       return l;
00440    }
00441    while(l) {
00442       if (l == prev)
00443          ret = l->next;
00444       l = l->next;
00445    }
00446    ast_mutex_unlock(&chlock);
00447    return ret;
00448    
00449 }

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 0 if not, or 1 if hang up is requested (including time-out).

Definition at line 68 of file channel.c.

References ast_channel::_softhangup, AST_SOFTHANGUP_TIMEOUT, ast_channel_pvt::pvt, ast_channel::pvt, and ast_channel::whentohangup.

Referenced by ast_answer(), ast_call(), ast_channel_bridge(), ast_indicate(), ast_read(), ast_readstring(), ast_readstring_full(), ast_recvchar(), ast_sendtext(), ast_transfer(), ast_waitfordigit(), ast_waitfordigit_full(), and ast_write().

00069 {
00070 time_t   myt;
00071 
00072      /* if soft hangup flag, return true */
00073    if (chan->_softhangup) return 1;
00074      /* if no private structure, return true */
00075    if (!chan->pvt->pvt) return 1;
00076      /* if no hangup scheduled, just return here */
00077    if (!chan->whentohangup) return 0;
00078    time(&myt); /* get current time */
00079      /* return, if not yet */
00080    if (chan->whentohangup > myt) return 0;
00081    chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
00082    return 1;
00083 }

void ast_deactivate_generator struct ast_channel chan  ) 
 

Deactive an active generator

Definition at line 729 of file channel.c.

References ast_channel::generator, ast_channel::generatordata, ast_generator::release, and ast_channel::writeinterrupt.

Referenced by ast_openstream(), ast_playtones_stop(), ast_read(), ast_tonepair_stop(), and ast_write().

00730 {
00731    if (chan->generatordata) {
00732       chan->generator->release(chan, chan->generatordata);
00733       chan->generatordata = NULL;
00734       chan->generator = NULL;
00735       chan->writeinterrupt = 0;
00736    }
00737 }

int ast_device_state char *  device  ) 
 

Asks a channel for device state.

Parameters:
device like a dialstring Asks a channel for device state, data is normaly a number from dialstring used by the low level module Trys the channel devicestate callback if not supported search in the active channels list for the device. Returns an AST_DEVICE_??? state -1 on failure

Definition at line 1618 of file channel.c.

References AST_DEVICE_INVALID, AST_DEVICE_UNKNOWN, ast_log(), AST_MAX_EXTENSION, ast_mutex_lock, ast_mutex_unlock, ast_parse_device_state(), backends, and LOG_WARNING.

01619 {
01620    char tech[AST_MAX_EXTENSION] = "";
01621    char *number;
01622    struct chanlist *chanls;
01623    int res = 0;
01624    
01625    strncpy(tech, device, sizeof(tech)-1);
01626    number = strchr(tech, '/');
01627    if (!number) {
01628        return AST_DEVICE_INVALID;
01629    }
01630    *number = 0;
01631    number++;
01632       
01633    if (ast_mutex_lock(&chlock)) {
01634       ast_log(LOG_WARNING, "Unable to lock channel list\n");
01635       return -1;
01636    }
01637    chanls = backends;
01638    while(chanls) {
01639       if (!strcasecmp(tech, chanls->type)) {
01640          ast_mutex_unlock(&chlock);
01641          if (!chanls->devicestate) 
01642             return ast_parse_device_state(device);
01643          else {
01644             res = chanls->devicestate(number);
01645             if (res == AST_DEVICE_UNKNOWN)
01646                return ast_parse_device_state(device);
01647             else
01648                return res;
01649          }
01650       }
01651       chanls = chanls->next;
01652    }
01653    ast_mutex_unlock(&chlock);
01654    return AST_DEVICE_INVALID;
01655 }

int ast_hangup struct ast_channel chan  ) 
 

Hang up a channel.

Parameters:
chan channel to hang up 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. Returns 0 on success, -1 on failure.

Definition at line 613 of file channel.c.

References ast_cdr_end(), ast_cdr_free(), ast_cdr_post(), ast_channel_free(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_stopstream(), ast_channel::blocker, ast_channel::blocking, ast_channel::blockproc, ast_channel::cdr, CRASH, EVENT_FLAG_CALL, ast_channel::generator, ast_channel::generatordata, ast_channel_pvt::hangup, ast_channel::lock, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::name, option_debug, ast_channel::pvt, ast_generator::release, ast_channel::sched, sched_context_destroy(), ast_channel::stream, ast_channel::uniqueid, and ast_channel::zombie.

Referenced by ast_async_goto(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run(), and ast_request_and_dial().

00614 {
00615    int res = 0;
00616    /* Don't actually hang up a channel that will masquerade as someone else, or
00617       if someone is going to masquerade as us */
00618    ast_mutex_lock(&chan->lock);
00619    if (chan->masq) {
00620       if (ast_do_masquerade(chan)) 
00621          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
00622    }
00623 
00624    if (chan->masq) {
00625       ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
00626       ast_mutex_unlock(&chan->lock);
00627       return 0;
00628    }
00629    /* If this channel is one which will be masqueraded into something, 
00630       mark it as a zombie already, so we know to free it later */
00631    if (chan->masqr) {
00632       ast_mutex_unlock(&chan->lock);
00633       chan->zombie=1;
00634       return 0;
00635    }
00636    free_translation(chan);
00637    if (chan->stream)
00638       ast_stopstream(chan);
00639    if (chan->sched)
00640       sched_context_destroy(chan->sched);
00641    /* Clear any tone stuff remaining */
00642    if (chan->generatordata)
00643       chan->generator->release(chan, chan->generatordata);
00644    chan->generatordata = NULL;
00645    chan->generator = NULL;
00646    if (chan->cdr) {
00647       /* End the CDR if it hasn't already */
00648       ast_cdr_end(chan->cdr);
00649       /* Post and Free the CDR */
00650       ast_cdr_post(chan->cdr);
00651       ast_cdr_free(chan->cdr);
00652    }
00653    if (chan->blocking) {
00654       ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
00655                "is blocked by thread %ld in procedure %s!  Expect a failure\n",
00656                (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
00657       CRASH;
00658    }
00659    if (!chan->zombie) {
00660       if (option_debug)
00661          ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
00662       if (chan->pvt->hangup)
00663          res = chan->pvt->hangup(chan);
00664    } else
00665       if (option_debug)
00666          ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name);
00667          
00668    ast_mutex_unlock(&chan->lock);
00669    manager_event(EVENT_FLAG_CALL, "Hangup", 
00670          "Channel: %s\r\n"
00671          "Uniqueid: %s\r\n",
00672          chan->name, chan->uniqueid);
00673    ast_channel_free(chan);
00674    return res;
00675 }

int ast_indicate struct ast_channel chan,
int  condition
 

Indicates condition of channel.

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

Definition at line 1168 of file channel.c.

References ast_check_hangup(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_get_indication_tone(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_playtones_start(), ast_playtones_stop(), ast_channel::data, ast_channel_pvt::indicate, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_channel::pvt, ast_channel::zombie, and ast_channel::zone.

01169 {
01170    int res = -1;
01171    /* Stop if we're a zombie or need a soft hangup */
01172    if (chan->zombie || ast_check_hangup(chan)) 
01173       return -1;
01174    ast_mutex_lock(&chan->lock);
01175    if (chan->pvt->indicate)
01176       res = chan->pvt->indicate(chan, condition);
01177    ast_mutex_unlock(&chan->lock);
01178    if (!chan->pvt->indicate || res) {
01179       /*
01180        * Device does not support (that) indication, lets fake
01181        * it by doing our own tone generation. (PM2002)
01182        */
01183       if (condition >= 0) {
01184          const struct tone_zone_sound *ts = NULL;
01185          switch (condition) {
01186           case AST_CONTROL_RINGING:
01187             ts = ast_get_indication_tone(chan->zone, "ring");
01188             break;
01189           case AST_CONTROL_BUSY:
01190             ts = ast_get_indication_tone(chan->zone, "busy");
01191             break;
01192           case AST_CONTROL_CONGESTION:
01193             ts = ast_get_indication_tone(chan->zone, "congestion");
01194             break;
01195          }
01196          if (ts && ts->data[0]) {
01197             ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
01198             ast_playtones_start(chan,0,ts->data, 1);
01199             res = 0;
01200          } else if (condition == AST_CONTROL_PROGRESS) {
01201             /* ast_playtones_stop(chan); */
01202          } else {
01203             /* not handled */
01204             ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
01205             res = -1;
01206          }
01207       }
01208       else ast_playtones_stop(chan);
01209    }
01210    return res;
01211 }

int ast_parse_device_state char *  device  ) 
 

Search the Channels by Name.

Parameters:
device like a dialstring Search the Device in active channels by compare the channelname against the devicename. Compared are only the first chars to the first '-' char. Returns an AST_DEVICE_UNKNOWN if no channel found or AST_DEVICE_INUSE if a channel is found

Definition at line 1599 of file channel.c.

References AST_CHANNEL_NAME, ast_channel_walk(), AST_DEVICE_INUSE, AST_DEVICE_UNKNOWN, and ast_channel::name.

Referenced by ast_device_state().

01600 {
01601    char name[AST_CHANNEL_NAME] = "";
01602    char *cut;
01603    struct ast_channel *chan;
01604 
01605    chan = ast_channel_walk(NULL);
01606    while (chan) {
01607       strncpy(name, chan->name, sizeof(name)-1);
01608       cut = strchr(name,'-');
01609       if (cut)
01610               *cut = 0;
01611       if (!strcmp(name, device))
01612               return AST_DEVICE_INUSE;
01613       chan = ast_channel_walk(chan);
01614    }
01615    return AST_DEVICE_UNKNOWN;
01616 }

int ast_prod struct ast_channel chan  ) 
 

Definition at line 1300 of file channel.c.

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

Referenced by ast_activate_generator().

01301 {
01302    struct ast_frame a = { AST_FRAME_VOICE };
01303    char nothing[128];
01304    /* Send an empty audio frame to get things moving */
01305    if (chan->_state != AST_STATE_UP) {
01306       ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
01307       a.subclass = chan->pvt->rawwriteformat;
01308       a.data = nothing + AST_FRIENDLY_OFFSET;
01309       if (ast_write(chan, &a))
01310          ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
01311    }
01312    return 0;
01313 }

struct ast_frame* ast_read struct ast_channel chan  ) 
 

Reads a frame.

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

References ast_channel::_softhangup, ast_channel_pvt::alertpipe, ast_cdr_answer(), ast_cdr_end(), ast_check_hangup(), AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, ast_deactivate_generator(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frame_dump(), AST_FRAME_NULL, AST_FRAME_VOICE, ast_frfree(), ast_getformatname(), ast_log(), AST_MAX_FDS, ast_mutex_lock, ast_mutex_unlock, ast_seekstream(), ast_setstate(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_translate(), ast_writestream(), ast_channel::blocker, ast_channel::cdr, ast_channel::deferdtmf, ast_channel::dtmff, ast_channel::dtmfq, ast_channel_pvt::exception, ast_channel::exception, ast_channel::fdno, ast_channel::fin, ast_frame::frametype, ast_generator::generate, ast_channel::generator, 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, ast_channel::pvt, ast_channel_pvt::read, ast_channel_monitor::read_stream, ast_channel_pvt::readq, ast_channel_pvt::readtrans, SEEK_FORCECUR, ast_frame::subclass, ast_channel::timingdata, ast_channel::timingfd, ast_channel::timingfunc, and ast_channel::zombie.

Referenced by ast_app_getvoice(), ast_async_goto(), ast_channel_bridge(), ast_recvchar(), ast_request_and_dial(), ast_rtp_bridge(), ast_safe_sleep(), ast_safe_sleep_conditional(), ast_tonepair(), ast_waitfordigit(), ast_waitfordigit_full(), ast_waitstream(), ast_waitstream_fr(), and ast_waitstream_full().

00991 {
00992    struct ast_frame *f = NULL;
00993    int blah;
00994 #ifdef ZAPTEL_OPTIMIZATIONS
00995    int (*func)(void *);
00996    void *data;
00997 #endif
00998    static struct ast_frame null_frame = 
00999    {
01000       AST_FRAME_NULL,
01001    };
01002    
01003    ast_mutex_lock(&chan->lock);
01004    if (chan->masq) {
01005       if (ast_do_masquerade(chan)) {
01006          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01007          f = NULL;
01008       } else
01009          f =  &null_frame;
01010       ast_mutex_unlock(&chan->lock);
01011       return f;
01012    }
01013 
01014    /* Stop if we're a zombie or need a soft hangup */
01015    if (chan->zombie || ast_check_hangup(chan)) {
01016       if (chan->generator)
01017          ast_deactivate_generator(chan);
01018       ast_mutex_unlock(&chan->lock);
01019       return NULL;
01020    }
01021 
01022    if (!chan->deferdtmf && strlen(chan->dtmfq)) {
01023       /* We have DTMF that has been deferred.  Return it now */
01024       chan->dtmff.frametype = AST_FRAME_DTMF;
01025       chan->dtmff.subclass = chan->dtmfq[0];
01026       /* Drop first digit */
01027       memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1);
01028       ast_mutex_unlock(&chan->lock);
01029       return &chan->dtmff;
01030    }
01031    
01032    /* Read and ignore anything on the alertpipe, but read only
01033       one sizeof(blah) per frame that we send from it */
01034    if (chan->pvt->alertpipe[0] > -1) {
01035       read(chan->pvt->alertpipe[0], &blah, sizeof(blah));
01036    }
01037 #ifdef ZAPTEL_OPTIMIZATIONS
01038    if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && chan->exception) {
01039       chan->exception = 0;
01040       blah = -1;
01041       ioctl(chan->timingfd, ZT_TIMERACK, &blah);
01042       func = chan->timingfunc;
01043       data = chan->timingdata;
01044       ast_mutex_unlock(&chan->lock);
01045       if (func) {
01046 #if 0
01047          ast_log(LOG_DEBUG, "Calling private function\n");
01048 #endif         
01049          func(data);
01050       } else {
01051          blah = 0;
01052          ast_mutex_lock(&chan->lock);
01053          ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
01054          chan->timingdata = NULL;
01055          ast_mutex_unlock(&chan->lock);
01056       }
01057       f =  &null_frame;
01058       return f;
01059    }
01060 #endif
01061    /* Check for pending read queue */
01062    if (chan->pvt->readq) {
01063       f = chan->pvt->readq;
01064       chan->pvt->readq = f->next;
01065       /* Interpret hangup and return NULL */
01066       if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))
01067          f = NULL;
01068    } else {
01069       chan->blocker = pthread_self();
01070       if (chan->exception) {
01071          if (chan->pvt->exception) 
01072             f = chan->pvt->exception(chan);
01073          else {
01074             ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
01075             f = &null_frame;
01076          }
01077          /* Clear the exception flag */
01078          chan->exception = 0;
01079       } else
01080       if (chan->pvt->read)
01081          f = chan->pvt->read(chan);
01082       else
01083          ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
01084    }
01085 
01086 
01087    if (f && (f->frametype == AST_FRAME_VOICE)) {
01088       if (!(f->subclass & chan->nativeformats)) {
01089          /* This frame can't be from the current native formats -- drop it on the
01090             floor */
01091          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));
01092          ast_frfree(f);
01093          f = &null_frame;
01094       } else {
01095          if (chan->monitor && chan->monitor->read_stream ) {
01096 #ifndef MONITOR_CONSTANT_DELAY
01097             int jump = chan->outsmpl - chan->insmpl - 2 * f->samples;
01098             if (jump >= 0) {
01099                if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1)
01100                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
01101                chan->insmpl += jump + 2 * f->samples;
01102             } else
01103                chan->insmpl+= f->samples;
01104 #else
01105             int jump = chan->outsmpl - chan->insmpl;
01106             if (jump - MONITOR_DELAY >= 0) {
01107                if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
01108                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
01109                chan->insmpl += jump;
01110             } else
01111                chan->insmpl += f->samples;
01112 #endif
01113             if (ast_writestream(chan->monitor->read_stream, f) < 0)
01114                ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
01115          }
01116          if (chan->pvt->readtrans) {
01117             f = ast_translate(chan->pvt->readtrans, f, 1);
01118             if (!f)
01119                f = &null_frame;
01120          }
01121       }
01122    }
01123 
01124    /* Make sure we always return NULL in the future */
01125    if (!f) {
01126       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01127       if (chan->generator)
01128          ast_deactivate_generator(chan);
01129       /* End the CDR if appropriate */
01130       if (chan->cdr)
01131          ast_cdr_end(chan->cdr);
01132    } else if (chan->deferdtmf && f->frametype == AST_FRAME_DTMF) {
01133       if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
01134          chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
01135       else
01136          ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
01137       f = &null_frame;
01138    } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) {
01139       /* Answer the CDR */
01140       ast_setstate(chan, AST_STATE_UP);
01141       ast_cdr_answer(chan->cdr);
01142    } 
01143    ast_mutex_unlock(&chan->lock);
01144 
01145    /* Run any generator sitting on the line */
01146    if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) {
01147       /* Mask generator data temporarily */
01148       void *tmp;
01149       int res;
01150       tmp = chan->generatordata;
01151       chan->generatordata = NULL;
01152       res = chan->generator->generate(chan, tmp, f->datalen, f->samples);
01153       chan->generatordata = tmp;
01154       if (res) {
01155          ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
01156          ast_deactivate_generator(chan);
01157       }
01158    }
01159    if (chan->fin & 0x80000000)
01160       ast_frame_dump(chan->name, f, "<<");
01161    if ((chan->fin & 0x7fffffff) == 0x7fffffff)
01162       chan->fin &= 0x80000000;
01163    else
01164       chan->fin++;
01165    return f;
01166 }

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

Reads multiple digits.

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

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

Referenced by ast_app_getdata().

01693 {
01694    int pos=0;
01695    int to = ftimeout;
01696    char d;
01697    /* XXX Merge with full version? XXX */
01698    /* Stop if we're a zombie or need a soft hangup */
01699    if (c->zombie || ast_check_hangup(c)) 
01700       return -1;
01701    if (!len)
01702       return -1;
01703    do {
01704       if (c->stream) {
01705          d = ast_waitstream(c, AST_DIGIT_ANY);
01706          ast_stopstream(c);
01707          usleep(1000);
01708          if (!d)
01709             d = ast_waitfordigit(c, to);
01710       } else {
01711          d = ast_waitfordigit(c, to);
01712       }
01713       if (d < 0)
01714          return -1;
01715       if (d == 0) {
01716          s[pos]='\0';
01717          return 1;
01718       }
01719       if (!strchr(enders, d))
01720          s[pos++] = d;
01721       if (strchr(enders, d) || (pos >= len)) {
01722          s[pos]='\0';
01723          return 0;
01724       }
01725       to = timeout;
01726    } while(1);
01727    /* Never reached */
01728    return 0;
01729 }

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

Definition at line 1731 of file channel.c.

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

Referenced by ast_app_getdata_full().

01732 {
01733    int pos=0;
01734    int to = ftimeout;
01735    char d;
01736    /* Stop if we're a zombie or need a soft hangup */
01737    if (c->zombie || ast_check_hangup(c)) 
01738       return -1;
01739    if (!len)
01740       return -1;
01741    do {
01742       if (c->stream) {
01743          d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
01744          ast_stopstream(c);
01745          usleep(1000);
01746          if (!d)
01747             d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
01748       } else {
01749          d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
01750       }
01751       if (d < 0)
01752          return -1;
01753       if (d == 0) {
01754          s[pos]='\0';
01755          return 1;
01756       }
01757       if (d == 1) {
01758          s[pos]='\0';
01759          return 2;
01760       }
01761       if (!strchr(enders, d))
01762          s[pos++] = d;
01763       if (strchr(enders, d) || (pos >= len)) {
01764          s[pos]='\0';
01765          return 0;
01766       }
01767       to = timeout;
01768    } while(1);
01769    /* Never reached */
01770    return 0;
01771 }

int ast_recvchar struct ast_channel chan,
int  timeout
 

Receives a text character from a channel.

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

References ast_check_hangup(), AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_TEXT, ast_frfree(), ast_read(), and ast_waitfor().

01214 {
01215    int res,ourto,c;
01216    struct ast_frame *f;
01217    
01218    ourto = timeout;
01219    for(;;)
01220       {
01221       if (ast_check_hangup(chan)) return -1;
01222       res = ast_waitfor(chan,ourto);
01223       if (res <= 0) /* if timeout */
01224          {
01225          return 0;
01226          }
01227       ourto = res;
01228       f = ast_read(chan);
01229       if (f == NULL) return -1; /* if hangup */
01230       if ((f->frametype == AST_FRAME_CONTROL) &&
01231           (f->subclass == AST_CONTROL_HANGUP)) return -1; /* if hangup */
01232       if (f->frametype == AST_FRAME_TEXT)  /* if a text frame */
01233          {
01234          c = *((char *)f->data);  /* get the data */
01235          ast_frfree(f);
01236          return(c);
01237          }
01238       ast_frfree(f);
01239    }
01240 }

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

Requests a channel.

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

Definition at line 1554 of file channel.c.

References ast_channel::_state, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_state2str(), AST_STATE_DOWN, ast_translator_best_choice(), backends, ast_channel::callerid, EVENT_FLAG_CALL, LOG_WARNING, manager_event(), ast_channel::name, ast_channel::next, ast_channel::type, type, and ast_channel::uniqueid.

Referenced by ast_request_and_dial().

01555 {
01556    struct chanlist *chan;
01557    struct ast_channel *c = NULL;
01558    int capabilities;
01559    int fmt;
01560    int res;
01561    if (ast_mutex_lock(&chlock)) {
01562       ast_log(LOG_WARNING, "Unable to lock channel list\n");
01563       return NULL;
01564    }
01565    chan = backends;
01566    while(chan) {
01567       if (!strcasecmp(type, chan->type)) {
01568          capabilities = chan->capabilities;
01569          fmt = format;
01570          res = ast_translator_best_choice(&fmt, &capabilities);
01571          if (res < 0) {
01572             ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->capabilities, format);
01573             ast_mutex_unlock(&chlock);
01574             return NULL;
01575          }
01576          ast_mutex_unlock(&chlock);
01577          if (chan->requester)
01578             c = chan->requester(type, capabilities, data);
01579          if (c) {
01580             if (c->_state == AST_STATE_DOWN) {
01581                manager_event(EVENT_FLAG_CALL, "Newchannel",
01582                "Channel: %s\r\n"
01583                "State: %s\r\n"
01584                "Callerid: %s\r\n"
01585                "Uniqueid: %s\r\n",
01586                c->name, ast_state2str(c->_state), c->callerid ? c->callerid : "<unknown>", c->uniqueid);
01587             }
01588          }
01589          return c;
01590       }
01591       chan = chan->next;
01592    }
01593    if (!chan)
01594       ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
01595    ast_mutex_unlock(&chlock);
01596    return c;
01597 }

struct ast_channel* ast_request_and_dial char *  type,
int  format,
void *  data,
int  timeout,
int *  reason,
char *  callerid
 

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
why unsuccessful (if unsuceessful) 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 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 1491 of file channel.c.

References ast_channel::_state, ast_call(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_FRAME_CONTROL, ast_frfree(), ast_hangup(), ast_log(), ast_read(), ast_request(), ast_set_callerid(), AST_STATE_UP, ast_waitfor(), LOG_NOTICE, and type.

Referenced by ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().

01492 {
01493    int state = 0;
01494    struct ast_channel *chan;
01495    struct ast_frame *f;
01496    int res;
01497    
01498    chan = ast_request(type, format, data);
01499    if (chan) {
01500       if (callerid)
01501          ast_set_callerid(chan, callerid, 1);
01502       if (!ast_call(chan, data, 0)) {
01503          while(timeout && (chan->_state != AST_STATE_UP)) {
01504             res = ast_waitfor(chan, timeout);
01505             if (res < 0) {
01506                /* Something not cool, or timed out */
01507                ast_hangup(chan);
01508                chan = NULL;
01509                break;
01510             }
01511             /* If done, break out */
01512             if (!res)
01513                break;
01514             if (timeout > -1)
01515                timeout = res;
01516             f = ast_read(chan);
01517             if (!f) {
01518                state = AST_CONTROL_HANGUP;
01519                ast_hangup(chan);
01520                chan = NULL;
01521                break;
01522             }
01523             if (f->frametype == AST_FRAME_CONTROL) {
01524                if (f->subclass == AST_CONTROL_RINGING)
01525                   state = AST_CONTROL_RINGING;
01526                else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
01527                   state = f->subclass;
01528                   ast_frfree(f);
01529                   break;
01530                } else if (f->subclass == AST_CONTROL_ANSWER) {
01531                   state = f->subclass;
01532                   ast_frfree(f);
01533                   break;
01534                } else {
01535                   ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
01536                }
01537             }
01538             ast_frfree(f);
01539          }
01540       } else {
01541          ast_hangup(chan);
01542          chan = NULL;
01543          ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
01544       }
01545    } else
01546       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
01547    if (chan && (chan->_state == AST_STATE_UP))
01548       state = AST_CONTROL_ANSWER;
01549    if (outstate)
01550       *outstate = state;
01551    return chan;
01552 }

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 -1 on hangup, otherwise 0.

Definition at line 472 of file channel.c.

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

00473 {
00474    struct ast_frame *f;
00475    while(ms > 0) {
00476       ms = ast_waitfor(chan, ms);
00477       if (ms <0)
00478          return -1;
00479       if (ms > 0) {
00480          f = ast_read(chan);
00481          if (!f)
00482             return -1;
00483          ast_frfree(f);
00484       }
00485    }
00486    return 0;
00487 }

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.

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 Waits for a specified amount of time, servicing the channel as required. If cond returns 0, this function returns. returns -1 on hangup, otherwise 0.

Definition at line 451 of file channel.c.

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

00453 {
00454    struct ast_frame *f;
00455 
00456    while(ms > 0) {
00457       if( cond && ((*cond)(data) == 0 ) )
00458          return 0;
00459       ms = ast_waitfor(chan, ms);
00460       if (ms <0)
00461          return -1;
00462       if (ms > 0) {
00463          f = ast_read(chan);
00464          if (!f)
00465             return -1;
00466          ast_frfree(f);
00467       }
00468    }
00469    return 0;
00470 }

int ast_sendtext struct ast_channel chan,
char *  text
 

Sends text to a channel.

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

References ast_check_hangup(), ast_channel::blocking, CHECK_BLOCKING, ast_channel::pvt, ast_channel_pvt::send_text, and ast_channel::zombie.

01243 {
01244    int res = 0;
01245    /* Stop if we're a zombie or need a soft hangup */
01246    if (chan->zombie || ast_check_hangup(chan)) 
01247       return -1;
01248    CHECK_BLOCKING(chan);
01249    if (chan->pvt->send_text)
01250       res = chan->pvt->send_text(chan, text);
01251    chan->blocking = 0;
01252    return res;
01253 }

void ast_set_callerid struct ast_channel chan,
char *  callerid,
int  anitoo
 

Definition at line 2070 of file channel.c.

References ast_channel::ani, ast_cdr_setcid(), ast_channel::callerid, ast_channel::cdr, EVENT_FLAG_CALL, free, manager_event(), ast_channel::name, strdup, and ast_channel::uniqueid.

Referenced by ast_request_and_dial().

02071 {
02072    if (chan->callerid)
02073       free(chan->callerid);
02074    if (anitoo && chan->ani)
02075       free(chan->ani);
02076    if (callerid) {
02077       chan->callerid = strdup(callerid);
02078       if (anitoo)
02079          chan->ani = strdup(callerid);
02080    } else {
02081       chan->callerid = NULL;
02082       if (anitoo)
02083          chan->ani = NULL;
02084    }
02085    if (chan->cdr)
02086       ast_cdr_setcid(chan->cdr, chan);
02087    manager_event(EVENT_FLAG_CALL, "Newcallerid", 
02088             "Channel: %s\r\n"
02089             "Callerid: %s\r\n"
02090             "Uniqueid: %s\r\n",
02091             chan->name, chan->callerid ? 
02092             chan->callerid : "<Unknown>",
02093             chan->uniqueid);
02094 }

int ast_set_read_format struct ast_channel chan,
int  format
 

Sets read format on channel chan.

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

References ast_getformatname(), ast_log(), ast_translator_best_choice(), ast_translator_build_path(), ast_translator_free_path(), LOG_DEBUG, LOG_NOTICE, ast_channel::name, ast_channel::nativeformats, option_debug, ast_channel::pvt, ast_channel_pvt::rawreadformat, ast_channel::readformat, and ast_channel_pvt::readtrans.

Referenced by ast_app_getvoice(), and ast_channel_make_compatible().

01461 {
01462    int fmt;
01463    int native;
01464    int res;
01465    
01466    native = chan->nativeformats;
01467    fmt = fmts;
01468    /* Find a translation path from the native read format to one of the user's read formats */
01469    res = ast_translator_best_choice(&fmt, &native);
01470    if (res < 0) {
01471       ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n",
01472          ast_getformatname(chan->nativeformats), ast_getformatname(fmts));
01473       return -1;
01474    }
01475    
01476    /* Now we have a good choice for both.  We'll write using our native format. */
01477    chan->pvt->rawreadformat = native;
01478    /* User perspective is fmt */
01479    chan->readformat = fmt;
01480    /* Free any read translation we have right now */
01481    if (chan->pvt->readtrans)
01482       ast_translator_free_path(chan->pvt->readtrans);
01483    /* Build a translation path from the raw read format to the user reading format */
01484    chan->pvt->readtrans = ast_translator_build_path(chan->readformat, chan->pvt->rawreadformat);
01485    if (option_debug)
01486       ast_log(LOG_DEBUG, "Set channel %s to read format %s\n", 
01487          chan->name, ast_getformatname(chan->readformat));
01488    return 0;
01489 }

int ast_set_write_format struct ast_channel chan,
int  format
 

Sets write format on channel chan.

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

References ast_getformatname(), ast_log(), ast_translator_best_choice(), ast_translator_build_path(), ast_translator_free_path(), LOG_DEBUG, LOG_NOTICE, ast_channel::name, ast_channel::nativeformats, option_debug, ast_channel::pvt, ast_channel_pvt::rawwriteformat, ast_channel::writeformat, and ast_channel_pvt::writetrans.

Referenced by ast_channel_make_compatible(), ast_openstream(), and ast_stopstream().

01431 {
01432    int fmt;
01433    int native;
01434    int res;
01435    
01436    native = chan->nativeformats;
01437    fmt = fmts;
01438    
01439    res = ast_translator_best_choice(&native, &fmt);
01440    if (res < 0) {
01441       ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n",
01442          ast_getformatname(fmts), ast_getformatname(chan->nativeformats));
01443       return -1;
01444    }
01445    
01446    /* Now we have a good choice for both.  We'll write using our native format. */
01447    chan->pvt->rawwriteformat = native;
01448    /* User perspective is fmt */
01449    chan->writeformat = fmt;
01450    /* Free any write translation we have right now */
01451    if (chan->pvt->writetrans)
01452       ast_translator_free_path(chan->pvt->writetrans);
01453    /* Build a translation path from the user write format to the raw writing format */
01454    chan->pvt->writetrans = ast_translator_build_path(chan->pvt->rawwriteformat, chan->writeformat);
01455    if (option_debug)
01456       ast_log(LOG_DEBUG, "Set channel %s to write format %s\n", chan->name, ast_getformatname(chan->writeformat));
01457    return 0;
01458 }

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

Definition at line 943 of file channel.c.

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

Referenced by ast_closestream().

00944 {
00945    int res = -1;
00946 #ifdef ZAPTEL_OPTIMIZATIONS
00947    if (c->timingfd > -1) {
00948       if (!func) {
00949          samples = 0;
00950          data = 0;
00951       }
00952       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
00953       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
00954       c->timingfunc = func;
00955       c->timingdata = data;
00956    }
00957 #endif   
00958    return res;
00959 }

int ast_shutting_down void   ) 
 

Returns non-zero if Asterisk is being shut down

Definition at line 128 of file channel.c.

00129 {
00130    return shutting_down;
00131 }

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. Returns 0 regardless

Definition at line 590 of file channel.c.

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

Referenced by ast_begin_shutdown().

00591 {
00592    int res;
00593    ast_mutex_lock(&chan->lock);
00594    res = ast_softhangup_nolock(chan, cause);
00595    ast_mutex_unlock(&chan->lock);
00596    return res;
00597 }

int ast_softhangup_nolock struct ast_channel chan,
int  cause
 

Definition at line 575 of file channel.c.

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

Referenced by ast_async_goto(), and ast_softhangup().

00576 {
00577    int res = 0;
00578    struct ast_frame f = { AST_FRAME_NULL };
00579    if (option_debug)
00580       ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
00581    /* Inform channel driver that we need to be hung up, if it cares */
00582    chan->_softhangup |= cause;
00583    ast_queue_frame(chan, &f, 0);
00584    /* Interrupt any select call or such */
00585    if (chan->blocking)
00586       pthread_kill(chan->blocker, SIGURG);
00587    return res;
00588 }

char* ast_state2str int  state  ) 
 

Gives the string form of a given state.

Parameters:
state state to get the name of Give a name to a state Pretty self explanatory. Returns the text form of the binary state given

Definition at line 194 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 ast_request(), and ast_setstate().

00195 {
00196    /* XXX Not reentrant XXX */
00197    static char localtmp[256];
00198    switch(state) {
00199    case AST_STATE_DOWN:
00200       return "Down";
00201    case AST_STATE_RESERVED:
00202       return "Rsrvd";
00203    case AST_STATE_OFFHOOK:
00204       return "OffHook";
00205    case AST_STATE_DIALING:
00206       return "Dialing";
00207    case AST_STATE_RING:
00208       return "Ring";
00209    case AST_STATE_RINGING:
00210       return "Ringing";
00211    case AST_STATE_UP:
00212       return "Up";
00213    case AST_STATE_BUSY:
00214       return "Busy";
00215    default:
00216       snprintf(localtmp, sizeof(localtmp), "Unknown (%d)\n", state);
00217       return localtmp;
00218    }
00219 }

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

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

02417 {
02418    struct ast_frame *f;
02419    int res;
02420    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
02421       return res;
02422 
02423    /* Give us some wiggle room */
02424    while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) {
02425       f = ast_read(chan);
02426       if (f)
02427          ast_frfree(f);
02428       else
02429          return -1;
02430    }
02431    return 0;
02432 }

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

Start a tone going

Definition at line 2396 of file channel.c.

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

Referenced by ast_tonepair().

02397 {
02398    struct tonepair_def d = { 0, };
02399    d.freq1 = freq1;
02400    d.freq2 = freq2;
02401    d.duration = duration;
02402    if (vol < 1)
02403       d.vol = 8192;
02404    else
02405       d.vol = vol;
02406    if (ast_activate_generator(chan, &tonepair, &d))
02407       return -1;
02408    return 0;
02409 }

void ast_tonepair_stop struct ast_channel chan  ) 
 

Stop a tone from playing

Definition at line 2411 of file channel.c.

References ast_deactivate_generator().

02412 {
02413    ast_deactivate_generator(chan);
02414 }

int ast_transfer struct ast_channel chan,
char *  dest
 

Definition at line 1672 of file channel.c.

References ast_check_hangup(), ast_mutex_lock, ast_mutex_unlock, ast_channel::lock, ast_channel::pvt, ast_channel_pvt::transfer, and ast_channel::zombie.

01673 {
01674    /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 
01675       If the remote end does not answer within the timeout, then do NOT hang up, but 
01676       return anyway.  */
01677    int res = -1;
01678    /* Stop if we're a zombie or need a soft hangup */
01679    ast_mutex_lock(&chan->lock);
01680    if (!chan->zombie && !ast_check_hangup(chan)) {
01681       if (chan->pvt->transfer) {
01682          res = chan->pvt->transfer(chan, dest);
01683          if (!res)
01684             res = 1;
01685       } else
01686          res = 0;
01687    }
01688    ast_mutex_unlock(&chan->lock);
01689    return res;
01690 }

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 < 0 on failure, 0 if nothing ever arrived, and the # of ms remaining otherwise

Definition at line 902 of file channel.c.

References ast_waitfor_n().

Referenced by ast_app_getvoice(), ast_recvchar(), ast_request_and_dial(), ast_safe_sleep(), ast_safe_sleep_conditional(), ast_tonepair(), ast_waitfordigit(), ast_waitstream(), and ast_waitstream_fr().

00903 {
00904    struct ast_channel *chan;
00905    int oldms = ms;
00906    chan = ast_waitfor_n(&c, 1, &ms);
00907    if (ms < 0) {
00908       if (oldms < 0)
00909          return 0;
00910       else
00911          return -1;
00912    }
00913    return ms;
00914 }

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

Waits for input on a group of channels.

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

References ast_waitfor_nandfds().

Referenced by ast_channel_bridge(), ast_rtp_bridge(), and ast_waitfor().

00898 {
00899    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
00900 }

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

Waits for input on an fd.

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

Definition at line 754 of file channel.c.

00755 {
00756    /* Wait for x amount of time on a file descriptor to have input.  */
00757    struct timeval tv;
00758    fd_set rfds, efds;
00759    int res;
00760    int x, max=-1;
00761    int winner = -1;
00762    
00763    tv.tv_sec = *ms / 1000;
00764    tv.tv_usec = (*ms % 1000) * 1000;
00765    FD_ZERO(&rfds);
00766    FD_ZERO(&efds);
00767    for (x=0;x<n;x++) {
00768       if (fds[x] > -1) {
00769          FD_SET(fds[x], &rfds);
00770          FD_SET(fds[x], &efds);
00771          if (fds[x] > max)
00772             max = fds[x];
00773       }
00774    }
00775    if (*ms >= 0)
00776       res = ast_select(max + 1, &rfds, NULL, &efds, &tv);
00777    else
00778       res = ast_select(max + 1, &rfds, NULL, &efds, NULL);
00779 
00780    if (res < 0) {
00781       /* Simulate a timeout if we were interrupted */
00782       if (errno != EINTR)
00783          *ms = -1;
00784       else
00785          *ms = 0;
00786       return -1;
00787    }
00788 
00789    for (x=0;x<n;x++) {
00790       if ((fds[x] > -1) && (FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && (winner < 0)) {
00791          if (exception)
00792             *exception = FD_ISSET(fds[x], &efds);
00793          winner = fds[x];
00794       }
00795    }
00796    *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
00797    return winner;
00798 }

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

References ast_log(), AST_MAX_FDS, ast_mutex_lock, ast_mutex_unlock, ast_channel::blocking, CHECK_BLOCKING, ast_channel::exception, ast_channel::fdno, ast_channel::fds, LOG_WARNING, and ast_channel::masq.

Referenced by ast_waitfor_n(), ast_waitfordigit_full(), and ast_waitstream_full().

00802 {
00803    /* Wait for x amount of time on a file descriptor to have input.  */
00804    struct timeval tv;
00805    fd_set rfds, efds;
00806    int res;
00807    int x, y, max=-1;
00808    struct ast_channel *winner = NULL;
00809    if (outfd)
00810       *outfd = -1;
00811    if (exception)
00812       *exception = 0;
00813    
00814    /* Perform any pending masquerades */
00815    for (x=0;x<n;x++) {
00816       ast_mutex_lock(&c[x]->lock);
00817       if (c[x]->masq) {
00818          if (ast_do_masquerade(c[x])) {
00819             ast_log(LOG_WARNING, "Masquerade failed\n");
00820             *ms = -1;
00821             ast_mutex_unlock(&c[x]->lock);
00822             return NULL;
00823          }
00824       }
00825       ast_mutex_unlock(&c[x]->lock);
00826    }
00827    
00828    tv.tv_sec = *ms / 1000;
00829    tv.tv_usec = (*ms % 1000) * 1000;
00830    FD_ZERO(&rfds);
00831    FD_ZERO(&efds);
00832 
00833    for (x=0;x<n;x++) {
00834       for (y=0;y<AST_MAX_FDS;y++) {
00835          if (c[x]->fds[y] > -1) {
00836             FD_SET(c[x]->fds[y], &rfds);
00837             FD_SET(c[x]->fds[y], &efds);
00838             if (c[x]->fds[y] > max)
00839                max = c[x]->fds[y];
00840          }
00841       }
00842       CHECK_BLOCKING(c[x]);
00843    }
00844    for (x=0;x<nfds; x++) {
00845       FD_SET(fds[x], &rfds);
00846       FD_SET(fds[x], &efds);
00847       if (fds[x] > max)
00848          max = fds[x];
00849    }
00850    if (*ms >= 0)
00851       res = ast_select(max + 1, &rfds, NULL, &efds, &tv);
00852    else
00853       res = ast_select(max + 1, &rfds, NULL, &efds, NULL);
00854 
00855    if (res < 0) {
00856       for (x=0;x<n;x++) 
00857          c[x]->blocking = 0;
00858       /* Simulate a timeout if we were interrupted */
00859       if (errno != EINTR)
00860          *ms = -1;
00861       else {
00862          /* Just an interrupt */
00863 #if 0
00864          *ms = 0;
00865 #endif         
00866       }
00867       return NULL;
00868    }
00869 
00870    for (x=0;x<n;x++) {
00871       c[x]->blocking = 0;
00872       for (y=0;y<AST_MAX_FDS;y++) {
00873          if (c[x]->fds[y] > -1) {
00874             if ((FD_ISSET(c[x]->fds[y], &rfds) || FD_ISSET(c[x]->fds[y], &efds)) && !winner) {
00875                /* Set exception flag if appropriate */
00876                if (FD_ISSET(c[x]->fds[y], &efds))
00877                   c[x]->exception = 1;
00878                c[x]->fdno = y;
00879                winner = c[x];
00880             }
00881          }
00882       }
00883    }
00884    for (x=0;x<nfds;x++) {
00885       if ((FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && !winner) {
00886          if (outfd)
00887             *outfd = fds[x];
00888          if (FD_ISSET(fds[x], &efds) && exception)
00889             *exception = 1;
00890          winner = NULL;
00891       }
00892    }
00893    *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
00894    return winner;
00895 }

char ast_waitfordigit struct ast_channel c,
int  ms
 

Waits for a digit.

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

References ast_check_hangup(), AST_FRAME_DTMF, ast_frfree(), ast_read(), ast_waitfor(), and ast_channel::zombie.

Referenced by ast_pbx_run(), and ast_readstring().

00917 {
00918    /* XXX Should I be merged with waitfordigit_full XXX */
00919    struct ast_frame *f;
00920    char result = 0;
00921    /* Stop if we're a zombie or need a soft hangup */
00922    if (c->zombie || ast_check_hangup(c)) 
00923       return -1;
00924    /* Wait for a digit, no more than ms milliseconds total. */
00925    while(ms && !result) {
00926       ms = ast_waitfor(c, ms);
00927       if (ms < 0) /* Error */
00928          result = -1; 
00929       else if (ms > 0) {
00930          /* Read something */
00931          f = ast_read(c);
00932          if (f) {
00933             if (f->frametype == AST_FRAME_DTMF) 
00934                result = f->subclass;
00935             ast_frfree(f);
00936          } else
00937             result = -1;
00938       }
00939    }
00940    return result;
00941 }

char ast_waitfordigit_full struct ast_channel c,
int  ms,
int  audiofd,
int  ctrlfd
 

Definition at line 960 of file channel.c.

References ast_check_hangup(), AST_FRAME_DTMF, ast_frfree(), ast_read(), ast_waitfor_nandfds(), and ast_channel::zombie.

Referenced by ast_readstring_full().

00961 {
00962    struct ast_frame *f;
00963    char result = 0;
00964    struct ast_channel *rchan;
00965    int outfd;
00966    /* Stop if we're a zombie or need a soft hangup */
00967    if (c->zombie || ast_check_hangup(c)) 
00968       return -1;
00969    /* Wait for a digit, no more than ms milliseconds total. */
00970    while(ms && !result) {
00971       rchan = ast_waitfor_nandfds(&c, 1, &audio, (audio > -1) ? 1 : 0, NULL, &outfd, &ms);
00972       if ((!rchan) && (outfd < 0) && (ms)) /* Error */
00973          result = -1; 
00974       else if (outfd > -1) {
00975          result = 1;
00976       } else if (rchan) {
00977          /* Read something */
00978          f = ast_read(c);
00979          if (f) {
00980             if (f->frametype == AST_FRAME_DTMF) 
00981                result = f->subclass;
00982             ast_frfree(f);
00983          } else
00984             result = -1;
00985       }
00986    }
00987    return result;
00988 }

int ast_write struct ast_channel chan,
struct ast_frame frame
 

Write a frame to a channel.

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

References ast_channel::_softhangup, ast_check_hangup(), ast_deactivate_generator(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frame_dump(), AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_seekstream(), AST_SOFTHANGUP_DEV, ast_translate(), ast_writestream(), ast_channel::blocking, CHECK_BLOCKING, ast_frame::data, ast_channel::fout, ast_frame::frametype, ast_channel::generatordata, ast_channel::insmpl, ast_channel::lock, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::outsmpl, ast_channel::pvt, SEEK_FORCECUR, ast_channel_pvt::send_text, ast_frame::subclass, ast_channel_pvt::write, ast_channel_monitor::write_stream, ast_channel_pvt::write_video, ast_channel::writeinterrupt, ast_channel_pvt::writetrans, and ast_channel::zombie.

Referenced by ast_channel_bridge(), ast_prod(), ast_rtp_bridge(), and ast_write_video().

01327 {
01328    int res = -1;
01329    struct ast_frame *f = NULL;
01330    /* Stop if we're a zombie or need a soft hangup */
01331    ast_mutex_lock(&chan->lock);
01332    if (chan->zombie || ast_check_hangup(chan))  {
01333       ast_mutex_unlock(&chan->lock);
01334       return -1;
01335    }
01336    /* Handle any pending masquerades */
01337    if (chan->masq) {
01338       if (ast_do_masquerade(chan)) {
01339          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01340          ast_mutex_unlock(&chan->lock);
01341          return -1;
01342       }
01343    }
01344    if (chan->masqr) {
01345       ast_mutex_unlock(&chan->lock);
01346       return 0;
01347    }
01348    if (chan->generatordata) {
01349       if (chan->writeinterrupt)
01350          ast_deactivate_generator(chan);
01351       else {
01352          ast_mutex_unlock(&chan->lock);
01353          return 0;
01354       }
01355    }
01356    if (chan->fout & 0x80000000)
01357       ast_frame_dump(chan->name, fr, ">>");
01358    CHECK_BLOCKING(chan);
01359    switch(fr->frametype) {
01360    case AST_FRAME_CONTROL:
01361       /* XXX Interpret control frames XXX */
01362       ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n");
01363       break;
01364    case AST_FRAME_DTMF:
01365       res = do_senddigit(chan,fr->subclass);
01366       break;
01367    case AST_FRAME_TEXT:
01368       if (chan->pvt->send_text)
01369          res = chan->pvt->send_text(chan, (char *) fr->data);
01370       break;
01371    case AST_FRAME_VIDEO:
01372       /* XXX Handle translation of video codecs one day XXX */
01373       if (chan->pvt->write_video)
01374          res = chan->pvt->write_video(chan, fr);
01375       else
01376          res = 0;
01377       break;
01378    default:
01379       if (chan->pvt->write) {
01380          if (chan->pvt->writetrans) {
01381             f = ast_translate(chan->pvt->writetrans, fr, 0);
01382          } else
01383             f = fr;
01384          if (f) {
01385             res = chan->pvt->write(chan, f);
01386             if( chan->monitor &&
01387                   chan->monitor->write_stream &&
01388                   f && ( f->frametype == AST_FRAME_VOICE ) ) {
01389 #ifndef MONITOR_CONSTANT_DELAY
01390                int jump = chan->insmpl - chan->outsmpl - 2 * f->samples;
01391                if (jump >= 0) {
01392                   if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1)
01393                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
01394                   chan->outsmpl += jump + 2 * f->samples;
01395                } else
01396                   chan->outsmpl += f->samples;
01397 #else
01398                int jump = chan->insmpl - chan->outsmpl;
01399                if (jump - MONITOR_DELAY >= 0) {
01400                   if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
01401                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
01402                   chan->outsmpl += jump;
01403                } else
01404                   chan->outsmpl += f->samples;
01405 #endif
01406             if (ast_writestream(chan->monitor->write_stream, f) < 0)
01407                   ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
01408             }
01409          } else
01410             res = 0;
01411       }
01412    }
01413    if (f && (f != fr))
01414       ast_frfree(f);
01415    chan->blocking = 0;
01416    /* Consider a write failure to force a soft hangup */
01417    if (res < 0)
01418       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01419    else {
01420       if ((chan->fout & 0x7fffffff) == 0x7fffffff)
01421          chan->fout &= 0x80000000;
01422       else
01423          chan->fout++;
01424       chan->fout++;
01425    }
01426    ast_mutex_unlock(&chan->lock);
01427    return res;
01428 }

int ast_write_video struct ast_channel chan,
struct ast_frame frame
 

Write video frame to a channel.

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

References ast_write(), ast_channel::pvt, and ast_channel_pvt::write_video.

01316 {
01317    int res;
01318    if (!chan->pvt->write_video)
01319       return 0;
01320    res = ast_write(chan, fr);
01321    if (!res)
01322       res = 1;
01323    return res;
01324 }


Generated on Fri Oct 31 07:05:11 2003 for Asterisk by doxygen 1.3.4