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
struct  outgoing_helper

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_FLAG_DIGITAL   1
#define LOAD_OH(oh)
#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_DIALING_OFFHOOK   8
#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)
ast_channel__ast_request_and_dial (char *type, int format, void *data, int timeout, int *reason, char *callerid, struct outgoing_helper *oh)
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 295 of file channel.h.

#define AST_ADSI_OFFHOOKONLY   (3)
 

Definition at line 297 of file channel.h.

#define AST_ADSI_UNAVAILABLE   (2)
 

Definition at line 296 of file channel.h.

#define AST_ADSI_UNKNOWN   (0)
 

Definition at line 294 of file channel.h.

#define AST_BRIDGE_DTMF_CHANNEL_0   (1 << 0)
 

Report DTMF on channel 0

Definition at line 640 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 642 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 648 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 644 of file channel.h.

#define AST_BRIDGE_REC_CHANNEL_1   (1 << 3)
 

Return all voice frames on channel 1

Definition at line 646 of file channel.h.

#define AST_CDR_CALLWAIT   (1 << 2)
 

Definition at line 291 of file channel.h.

#define AST_CDR_CONFERENCE   (1 << 3)
 

Definition at line 292 of file channel.h.

#define AST_CDR_FORWARD   (1 << 1)
 

Definition at line 290 of file channel.h.

#define AST_CDR_TRANSFER   (1 << 0)
 

Definition at line 289 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 337 of file channel.h.

#define AST_DEVICE_INUSE   2
 

Device is in use

Definition at line 335 of file channel.h.

Referenced by ast_parse_device_state().

#define AST_DEVICE_INVALID   4
 

Device is invalid

Definition at line 339 of file channel.h.

Referenced by ast_device_state().

#define AST_DEVICE_NOT_INUSE   1
 

Device is not used

Definition at line 333 of file channel.h.

#define AST_DEVICE_UNAVAILABLE   5
 

Device is unavailable

Definition at line 341 of file channel.h.

#define AST_DEVICE_UNKNOWN   0
 

Device is valid but channel didn't know state

Definition at line 331 of file channel.h.

Referenced by ast_device_state(), and ast_parse_device_state().

#define AST_FLAG_DIGITAL   1
 

Definition at line 236 of file channel.h.

#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 303 of file channel.h.

#define AST_SOFTHANGUP_ASYNCGOTO   (1 << 1)
 

Definition at line 300 of file channel.h.

Referenced by ast_pbx_run().

#define AST_SOFTHANGUP_DEV   (1 << 0)
 

Definition at line 299 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 304 of file channel.h.

#define AST_SOFTHANGUP_SHUTDOWN   (1 << 2)
 

Definition at line 301 of file channel.h.

Referenced by ast_begin_shutdown().

#define AST_SOFTHANGUP_TIMEOUT   (1 << 3)
 

Definition at line 302 of file channel.h.

Referenced by ast_check_hangup(), and ast_pbx_run().

#define AST_STATE_BUSY   7
 

Line is busy

Definition at line 322 of file channel.h.

Referenced by ast_state2str().

#define AST_STATE_DIALING   3
 

Digits (or equivalent) have been dialed

Definition at line 314 of file channel.h.

Referenced by ast_state2str().

#define AST_STATE_DIALING_OFFHOOK   8
 

Digits (or equivalent) have been dialed while offhook

Definition at line 324 of file channel.h.

#define AST_STATE_DOWN   0
 

Channel is down and available

Definition at line 308 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 328 of file channel.h.

#define AST_STATE_OFFHOOK   2
 

Channel is off hook

Definition at line 312 of file channel.h.

Referenced by ast_state2str().

#define AST_STATE_RESERVED   1
 

Channel is down, but reserved

Definition at line 310 of file channel.h.

Referenced by ast_state2str().

#define AST_STATE_RING   4
 

Line is ringing

Definition at line 316 of file channel.h.

Referenced by ast_answer(), and ast_state2str().

#define AST_STATE_RINGING   5
 

Remote end is ringing

Definition at line 318 of file channel.h.

Referenced by ast_answer(), and ast_state2str().

#define AST_STATE_UP   6
 

Line is up

Definition at line 320 of file channel.h.

Referenced by __ast_request_and_dial(), ast_answer(), ast_cdr_init(), ast_prod(), ast_read(), and ast_state2str().

#define CHECK_BLOCKING  ) 
 

Definition at line 836 of file channel.h.

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

#define CRASH   do { } while(0)
 

Definition at line 833 of file channel.h.

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

#define LOAD_OH oh   ) 
 

Definition at line 271 of file channel.h.

#define MAX_LANGUAGE   20
 

Definition at line 40 of file channel.h.

Referenced by ast_fileexists(), and ast_openvstream().


Function Documentation

struct ast_channel* __ast_request_and_dial char *  type,
int  format,
void *  data,
int  timeout,
int *  reason,
char *  callerid,
struct outgoing_helper oh
 

Definition at line 1501 of file channel.c.

References ast_channel::_state, outgoing_helper::account, ast_call(), ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_setapp(), ast_cdr_start(), ast_cdr_update(), AST_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(), outgoing_helper::callerid, ast_channel::cdr, ast_channel::context, outgoing_helper::context, ast_channel::exten, outgoing_helper::exten, ast_channel::hangupcause, LOG_NOTICE, LOG_WARNING, pbx_builtin_setvar(), outgoing_helper::priority, ast_channel::priority, type, and outgoing_helper::variable.

Referenced by ast_request_and_dial().

01502 {
01503    int state = 0;
01504    struct ast_channel *chan;
01505    struct ast_frame *f;
01506    int res = 0;
01507    chan = ast_request(type, format, data);
01508    if (chan) {
01509       if (oh) {
01510          char *tmp, *var;
01511          /* JDG chanvar */
01512          tmp = oh->variable;
01513          /* FIXME replace this call with strsep  NOT*/
01514          while( (var = strtok_r(NULL, "|", &tmp)) ) {
01515             pbx_builtin_setvar( chan, var );
01516          } /* /JDG */
01517          if (oh->callerid && *oh->callerid)
01518             ast_set_callerid(chan, oh->callerid, 1);
01519          if (oh->account && *oh->account)
01520             ast_cdr_setaccount(chan, oh->account);
01521       }
01522       if (callerid && strlen(callerid))
01523          ast_set_callerid(chan, callerid, 1);
01524 
01525       if (!ast_call(chan, data, 0)) {
01526          while(timeout && (chan->_state != AST_STATE_UP)) {
01527             res = ast_waitfor(chan, timeout);
01528             if (res < 0) {
01529                /* Something not cool, or timed out */
01530                break;
01531             }
01532             /* If done, break out */
01533             if (!res)
01534                break;
01535             if (timeout > -1)
01536                timeout = res;
01537             f = ast_read(chan);
01538             if (!f) {
01539                state = AST_CONTROL_HANGUP;
01540                res = 0;
01541                break;
01542             }
01543             if (f->frametype == AST_FRAME_CONTROL) {
01544                if (f->subclass == AST_CONTROL_RINGING)
01545                   state = AST_CONTROL_RINGING;
01546                else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
01547                   state = f->subclass;
01548                   ast_frfree(f);
01549                   break;
01550                } else if (f->subclass == AST_CONTROL_ANSWER) {
01551                   state = f->subclass;
01552                   ast_frfree(f);
01553                   break;
01554                } else {
01555                   ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
01556                }
01557             }
01558             ast_frfree(f);
01559          }
01560       } else
01561          ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
01562    } else
01563       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
01564    if (chan) {
01565       /* Final fixups */
01566       if (oh) {
01567          if (oh->context && *oh->context)
01568             strncpy(chan->context, oh->context, sizeof(chan->context) - 1);
01569          if (oh->exten && *oh->exten)
01570             strncpy(chan->exten, oh->exten, sizeof(chan->exten) - 1);
01571          chan->priority = oh->priority;
01572       }
01573       if (chan->_state == AST_STATE_UP) 
01574          state = AST_CONTROL_ANSWER;
01575    }
01576    if (outstate)
01577       *outstate = state;
01578    if (chan && res <= 0) {
01579       if (!chan->cdr) {
01580          chan->cdr = ast_cdr_alloc();
01581          if (chan->cdr)
01582             ast_cdr_init(chan->cdr, chan);
01583       }
01584       if (chan->cdr) {
01585          char tmp[256];
01586          sprintf(tmp, "%s/%s",type,(char *)data);
01587          ast_cdr_setapp(chan->cdr,"Dial",tmp);
01588          ast_cdr_update(chan);
01589          ast_cdr_start(chan->cdr);
01590          ast_cdr_end(chan->cdr);
01591          /* If the cause wasn't handled properly */
01592          if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
01593             ast_cdr_failed(chan->cdr);
01594       } else 
01595          ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
01596       ast_hangup(chan);
01597       chan = NULL;
01598    }
01599    return chan;
01600 }

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

Activate a given generator

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

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

int ast_active_channels void   ) 
 

Returns number of active/allocated channels

Definition at line 110 of file channel.c.

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

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

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

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

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

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

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

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

01711 {
01712    /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 
01713       If the remote end does not answer within the timeout, then do NOT hang up, but 
01714       return anyway.  */
01715    int res = -1;
01716    /* Stop if we're a zombie or need a soft hangup */
01717    ast_mutex_lock(&chan->lock);
01718    if (!chan->zombie && !ast_check_hangup(chan)) 
01719       if (chan->pvt->call)
01720          res = chan->pvt->call(chan, addr, timeout);
01721    ast_mutex_unlock(&chan->lock);
01722    return res;
01723 }

void ast_cancel_shutdown void   ) 
 

Cancels an existing shutdown and returns to normal operation

Definition at line 124 of file channel.c.

00125 {
00126    shutting_down = 0;
00127 }

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

02183 {
02184    /* Copy voice back and forth between the two channels.  Give the peer
02185       the ability to transfer calls with '#<extension' syntax. */
02186    struct ast_channel *cs[3];
02187    int to = -1;
02188    struct ast_frame *f;
02189    struct ast_channel *who = NULL;
02190    int res;
02191    int nativefailed=0;
02192 
02193    /* Stop if we're a zombie or need a soft hangup */
02194    if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) 
02195       return -1;
02196    if (c0->bridge) {
02197       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
02198          c0->name, c0->bridge->name);
02199       return -1;
02200    }
02201    if (c1->bridge) {
02202       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
02203          c1->name, c1->bridge->name);
02204       return -1;
02205    }
02206    
02207    /* Keep track of bridge */
02208    c0->bridge = c1;
02209    c1->bridge = c0;
02210    cs[0] = c0;
02211    cs[1] = c1;
02212    
02213    manager_event(EVENT_FLAG_CALL, "Link", 
02214          "Channel1: %s\r\n"
02215          "Channel2: %s\r\n",
02216          c0->name, c1->name);
02217 
02218    for (/* ever */;;) {
02219       /* Stop if we're a zombie or need a soft hangup */
02220       if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) {
02221          *fo = NULL;
02222          if (who) *rc = who;
02223          res = 0;
02224          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");
02225          break;
02226       }
02227       if (c0->pvt->bridge && 
02228          (c0->pvt->bridge == c1->pvt->bridge) && !nativefailed && !c0->monitor && !c1->monitor) {
02229             /* Looks like they share a bridge code */
02230          if (option_verbose > 2) 
02231             ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name);
02232          if (!(res = c0->pvt->bridge(c0, c1, flags, fo, rc))) {
02233             c0->bridge = NULL;
02234             c1->bridge = NULL;
02235             manager_event(EVENT_FLAG_CALL, "Unlink", 
02236                "Channel1: %s\r\n"
02237                "Channel2: %s\r\n",
02238                c0->name, c1->name);
02239             ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n",c0->name ,c1->name);
02240             return 0;
02241          }
02242          /* If they return non-zero then continue on normally.  Let "-2" mean don't worry about
02243             my not wanting to bridge */
02244          if ((res != -2) && (res != -3))
02245             ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name);
02246          if (res != -3) nativefailed++;
02247       }
02248    
02249          
02250       if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat)) &&
02251          !(c0->generator || c1->generator))  {
02252          if (ast_channel_make_compatible(c0, c1)) {
02253             ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
02254             manager_event(EVENT_FLAG_CALL, "Unlink", 
02255                "Channel1: %s\r\n"
02256                "Channel2: %s\r\n",
02257                c0->name, c1->name);
02258             return -1;
02259          }
02260       }
02261       who = ast_waitfor_n(cs, 2, &to);
02262       if (!who) {
02263          ast_log(LOG_DEBUG, "Nobody there, continuing...\n"); 
02264          continue;
02265       }
02266       f = ast_read(who);
02267       if (!f) {
02268          *fo = NULL;
02269          *rc = who;
02270          res = 0;
02271          ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
02272          break;
02273       }
02274 
02275       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
02276          *fo = f;
02277          *rc = who;
02278          res =  0;
02279          ast_log(LOG_DEBUG, "Got a FRAME_CONTROL frame on channel %s\n",who->name);
02280          break;
02281       }
02282       if ((f->frametype == AST_FRAME_VOICE) ||
02283          (f->frametype == AST_FRAME_TEXT) ||
02284          (f->frametype == AST_FRAME_VIDEO) || 
02285          (f->frametype == AST_FRAME_IMAGE) ||
02286          (f->frametype == AST_FRAME_DTMF)) {
02287          if ((f->frametype == AST_FRAME_DTMF) && 
02288             (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
02289             if ((who == c0)) {
02290                if  ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) {
02291                   *rc = c0;
02292                   *fo = f;
02293                   /* Take out of conference mode */
02294                   res = 0;
02295                   ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_0 on c0 (%s)\n",c0->name);
02296                   break;
02297                } else 
02298                   goto tackygoto;
02299             } else
02300             if ((who == c1)) {
02301                if (flags & AST_BRIDGE_DTMF_CHANNEL_1) {
02302                   *rc = c1;
02303                   *fo = f;
02304                   res =  0;
02305                   ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_1 on c1 (%s)\n",c1->name);
02306                   break;
02307                } else
02308                   goto tackygoto;
02309             }
02310          } else {
02311 #if 0
02312             ast_log(LOG_DEBUG, "Read from %s\n", who->name);
02313             if (who == last) 
02314                ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name);
02315             last = who;
02316 #endif
02317 tackygoto:
02318             /* Don't copy packets if there is a generator on either one, since they're
02319                not supposed to be listening anyway */
02320             if (who == c0) 
02321                ast_write(c1, f);
02322             else 
02323                ast_write(c0, f);
02324          }
02325          ast_frfree(f);
02326       } else
02327          ast_frfree(f);
02328       /* Swap who gets priority */
02329       cs[2] = cs[0];
02330       cs[0] = cs[1];
02331       cs[1] = cs[2];
02332    }
02333    c0->bridge = NULL;
02334    c1->bridge = NULL;
02335    manager_event(EVENT_FLAG_CALL, "Unlink", 
02336                "Channel1: %s\r\n"
02337                "Channel2: %s\r\n",
02338                c0->name, c1->name);
02339    ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n",c0->name,c1->name);
02340    return res;
02341 }

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

References ast_channel::deferdtmf.

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

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

01848 {
01849    int peerf;
01850    int chanf;
01851    int res;
01852    peerf = peer->nativeformats;
01853    chanf = chan->nativeformats;
01854    res = ast_translator_best_choice(&peerf, &chanf);
01855    if (res < 0) {
01856       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, chan->nativeformats, peer->name, peer->nativeformats);
01857       return -1;
01858    }
01859    /* Set read format on channel */
01860    res = ast_set_read_format(chan, peerf);
01861    if (res < 0) {
01862       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, chanf);
01863       return -1;
01864    }
01865    /* Set write format on peer channel */
01866    res = ast_set_write_format(peer, peerf);
01867    if (res < 0) {
01868       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, peerf);
01869       return -1;
01870    }
01871    /* Now we go the other way */
01872    peerf = peer->nativeformats;
01873    chanf = chan->nativeformats;
01874    res = ast_translator_best_choice(&chanf, &peerf);
01875    if (res < 0) {
01876       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, peer->nativeformats, chan->name, chan->nativeformats);
01877       return -1;
01878    }
01879    /* Set writeformat on channel */
01880    res = ast_set_write_format(chan, chanf);
01881    if (res < 0) {
01882       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, chanf);
01883       return -1;
01884    }
01885    /* Set read format on peer channel */
01886    res = ast_set_read_format(peer, chanf);
01887    if (res < 0) {
01888       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, peerf);
01889       return -1;
01890    }
01891    return 0;
01892 }

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

01895 {
01896    struct ast_frame null = { AST_FRAME_NULL, };
01897    ast_log(LOG_DEBUG, "Planning to masquerade %s into the structure of %s\n",
01898       clone->name, original->name);
01899    if (original->masq) {
01900       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
01901          original->masq->name, original->name);
01902       return -1;
01903    }
01904    if (clone->masqr) {
01905       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
01906          clone->name, clone->masqr->name);
01907       return -1;
01908    }
01909    original->masq = clone;
01910    clone->masqr = original;
01911    /* XXX can't really hold the lock here, but at the same time, it' s
01912       not really safe not to XXX */
01913    ast_queue_frame(original, &null, 0);
01914    ast_queue_frame(clone, &null, 0);
01915    ast_log(LOG_DEBUG, "Done planning to masquerade %s into the structure of %s\n", original->name, clone->name);
01916    return 0;
01917 }

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

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

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

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

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

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

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

01834 {
01835    if (chan->pvt->send_html)
01836       return chan->pvt->send_html(chan, subclass, data, datalen);
01837    return -1;
01838 }

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

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

01841 {
01842    if (chan->pvt->send_html)
01843       return chan->pvt->send_html(chan, AST_HTML_URL, url, strlen(url) + 1);
01844    return -1;
01845 }

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

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

02344 {
02345    int res;
02346    if (chan->pvt->setoption) {
02347       res = chan->pvt->setoption(chan, option, data, datalen);
02348       if (res < 0)
02349          return res;
02350    } else {
02351       errno = ENOSYS;
02352       return -1;
02353    }
02354    if (block) {
02355       /* XXX Implement blocking -- just wait for our option frame reply, discarding
02356          intermediate packets. XXX */
02357       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
02358       return -1;
02359    }
02360    return 0;
02361 }

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

References ast_channel::whentohangup.

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

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

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

01827 {
01828    if (chan->pvt->send_html)
01829       return 1;
01830    return 0;
01831 }

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

References ast_channel::deferdtmf.

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

void ast_channel_unregister char *  type  ) 
 

Unregister a channel class.

Definition at line 678 of file channel.c.

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

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

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

References ast_mutex_lock, ast_mutex_unlock, and channels.

Referenced by ast_parse_device_state().

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

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 69 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_rtp_bridge(), ast_sendtext(), ast_transfer(), ast_waitfordigit(), ast_waitfordigit_full(), and ast_write().

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

void ast_deactivate_generator struct ast_channel chan  ) 
 

Deactive an active generator

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

00734 {
00735    if (chan->generatordata) {
00736       chan->generator->release(chan, chan->generatordata);
00737       chan->generatordata = NULL;
00738       chan->generator = NULL;
00739       chan->writeinterrupt = 0;
00740    }
00741 }

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

01672 {
01673    char tech[AST_MAX_EXTENSION] = "";
01674    char *number;
01675    struct chanlist *chanls;
01676    int res = 0;
01677    
01678    strncpy(tech, device, sizeof(tech)-1);
01679    number = strchr(tech, '/');
01680    if (!number) {
01681        return AST_DEVICE_INVALID;
01682    }
01683    *number = 0;
01684    number++;
01685       
01686    if (ast_mutex_lock(&chlock)) {
01687       ast_log(LOG_WARNING, "Unable to lock channel list\n");
01688       return -1;
01689    }
01690    chanls = backends;
01691    while(chanls) {
01692       if (!strcasecmp(tech, chanls->type)) {
01693          ast_mutex_unlock(&chlock);
01694          if (!chanls->devicestate) 
01695             return ast_parse_device_state(device);
01696          else {
01697             res = chanls->devicestate(number);
01698             if (res == AST_DEVICE_UNKNOWN)
01699                return ast_parse_device_state(device);
01700             else
01701                return res;
01702          }
01703       }
01704       chanls = chanls->next;
01705    }
01706    ast_mutex_unlock(&chlock);
01707    return AST_DEVICE_INVALID;
01708 }

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 614 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_request_and_dial(), and ast_pbx_run().

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

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

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

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

01653 {
01654    char name[AST_CHANNEL_NAME] = "";
01655    char *cut;
01656    struct ast_channel *chan;
01657 
01658    chan = ast_channel_walk(NULL);
01659    while (chan) {
01660       strncpy(name, chan->name, sizeof(name)-1);
01661       cut = strchr(name,'-');
01662       if (cut)
01663               *cut = 0;
01664       if (!strcmp(name, device))
01665               return AST_DEVICE_INUSE;
01666       chan = ast_channel_walk(chan);
01667    }
01668    return AST_DEVICE_UNKNOWN;
01669 }

int ast_prod struct ast_channel chan  ) 
 

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

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

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 994 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_request_and_dial(), ast_app_getvoice(), ast_channel_bridge(), ast_recvchar(), 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().

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

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

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

Referenced by ast_app_getdata().

01746 {
01747    int pos=0;
01748    int to = ftimeout;
01749    char d;
01750    /* XXX Merge with full version? XXX */
01751    /* Stop if we're a zombie or need a soft hangup */
01752    if (c->zombie || ast_check_hangup(c)) 
01753       return -1;
01754    if (!len)
01755       return -1;
01756    do {
01757       if (c->stream) {
01758          d = ast_waitstream(c, AST_DIGIT_ANY);
01759          ast_stopstream(c);
01760          usleep(1000);
01761          if (!d)
01762             d = ast_waitfordigit(c, to);
01763       } else {
01764          d = ast_waitfordigit(c, to);
01765       }
01766       if (d < 0)
01767          return -1;
01768       if (d == 0) {
01769          s[pos]='\0';
01770          return 1;
01771       }
01772       if (!strchr(enders, d))
01773          s[pos++] = d;
01774       if (strchr(enders, d) || (pos >= len)) {
01775          s[pos]='\0';
01776          return 0;
01777       }
01778       to = timeout;
01779    } while(1);
01780    /* Never reached */
01781    return 0;
01782 }

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

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

Referenced by ast_app_getdata_full().

01785 {
01786    int pos=0;
01787    int to = ftimeout;
01788    char d;
01789    /* Stop if we're a zombie or need a soft hangup */
01790    if (c->zombie || ast_check_hangup(c)) 
01791       return -1;
01792    if (!len)
01793       return -1;
01794    do {
01795       if (c->stream) {
01796          d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
01797          ast_stopstream(c);
01798          usleep(1000);
01799          if (!d)
01800             d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
01801       } else {
01802          d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
01803       }
01804       if (d < 0)
01805          return -1;
01806       if (d == 0) {
01807          s[pos]='\0';
01808          return 1;
01809       }
01810       if (d == 1) {
01811          s[pos]='\0';
01812          return 2;
01813       }
01814       if (!strchr(enders, d))
01815          s[pos++] = d;
01816       if (strchr(enders, d) || (pos >= len)) {
01817          s[pos]='\0';
01818          return 0;
01819       }
01820       to = timeout;
01821    } while(1);
01822    /* Never reached */
01823    return 0;
01824 }

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

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

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

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

01608 {
01609    struct chanlist *chan;
01610    struct ast_channel *c = NULL;
01611    int capabilities;
01612    int fmt;
01613    int res;
01614    if (ast_mutex_lock(&chlock)) {
01615       ast_log(LOG_WARNING, "Unable to lock channel list\n");
01616       return NULL;
01617    }
01618    chan = backends;
01619    while(chan) {
01620       if (!strcasecmp(type, chan->type)) {
01621          capabilities = chan->capabilities;
01622          fmt = format;
01623          res = ast_translator_best_choice(&fmt, &capabilities);
01624          if (res < 0) {
01625             ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->capabilities, format);
01626             ast_mutex_unlock(&chlock);
01627             return NULL;
01628          }
01629          ast_mutex_unlock(&chlock);
01630          if (chan->requester)
01631             c = chan->requester(type, capabilities, data);
01632          if (c) {
01633             if (c->_state == AST_STATE_DOWN) {
01634                manager_event(EVENT_FLAG_CALL, "Newchannel",
01635                "Channel: %s\r\n"
01636                "State: %s\r\n"
01637                "Callerid: %s\r\n"
01638                "Uniqueid: %s\r\n",
01639                c->name, ast_state2str(c->_state), c->callerid ? c->callerid : "<unknown>", c->uniqueid);
01640             }
01641          }
01642          return c;
01643       }
01644       chan = chan->next;
01645    }
01646    if (!chan)
01647       ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
01648    ast_mutex_unlock(&chlock);
01649    return c;
01650 }

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

References __ast_request_and_dial(), and type.

01603 {
01604    return __ast_request_and_dial(type, format, data, timeout, outstate, callerid, NULL);
01605 }

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

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

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

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

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

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

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

01249 {
01250    int res = 0;
01251    /* Stop if we're a zombie or need a soft hangup */
01252    if (chan->zombie || ast_check_hangup(chan)) 
01253       return -1;
01254    CHECK_BLOCKING(chan);
01255    if (chan->pvt->send_text)
01256       res = chan->pvt->send_text(chan, text);
01257    chan->blocking = 0;
01258    return res;
01259 }

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

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

02132 {
02133    if (chan->callerid)
02134       free(chan->callerid);
02135    if (anitoo && chan->ani)
02136       free(chan->ani);
02137    if (callerid) {
02138       chan->callerid = strdup(callerid);
02139       if (anitoo)
02140          chan->ani = strdup(callerid);
02141    } else {
02142       chan->callerid = NULL;
02143       if (anitoo)
02144          chan->ani = NULL;
02145    }
02146    if (chan->cdr)
02147       ast_cdr_setcid(chan->cdr, chan);
02148    manager_event(EVENT_FLAG_CALL, "Newcallerid", 
02149             "Channel: %s\r\n"
02150             "Callerid: %s\r\n"
02151             "Uniqueid: %s\r\n",
02152             chan->name, chan->callerid ? 
02153             chan->callerid : "<Unknown>",
02154             chan->uniqueid);
02155 }

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

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

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

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

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

Definition at line 947 of file channel.c.

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

Referenced by ast_closestream().

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

int ast_shutting_down void   ) 
 

Returns non-zero if Asterisk is being shut down

Definition at line 129 of file channel.c.

00130 {
00131    return shutting_down;
00132 }

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

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

Referenced by ast_begin_shutdown().

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

int ast_softhangup_nolock struct ast_channel chan,
int  cause
 

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

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

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

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

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

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

02478 {
02479    struct ast_frame *f;
02480    int res;
02481    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
02482       return res;
02483 
02484    /* Give us some wiggle room */
02485    while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) {
02486       f = ast_read(chan);
02487       if (f)
02488          ast_frfree(f);
02489       else
02490          return -1;
02491    }
02492    return 0;
02493 }

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

Start a tone going

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

02458 {
02459    struct tonepair_def d = { 0, };
02460    d.freq1 = freq1;
02461    d.freq2 = freq2;
02462    d.duration = duration;
02463    if (vol < 1)
02464       d.vol = 8192;
02465    else
02466       d.vol = vol;
02467    if (ast_activate_generator(chan, &tonepair, &d))
02468       return -1;
02469    return 0;
02470 }

void ast_tonepair_stop struct ast_channel chan  ) 
 

Stop a tone from playing

Definition at line 2472 of file channel.c.

References ast_deactivate_generator().

02473 {
02474    ast_deactivate_generator(chan);
02475 }

int ast_transfer struct ast_channel chan,
char *  dest
 

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

01726 {
01727    /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 
01728       If the remote end does not answer within the timeout, then do NOT hang up, but 
01729       return anyway.  */
01730    int res = -1;
01731    /* Stop if we're a zombie or need a soft hangup */
01732    ast_mutex_lock(&chan->lock);
01733    if (!chan->zombie && !ast_check_hangup(chan)) {
01734       if (chan->pvt->transfer) {
01735          res = chan->pvt->transfer(chan, dest);
01736          if (!res)
01737             res = 1;
01738       } else
01739          res = 0;
01740    }
01741    ast_mutex_unlock(&chan->lock);
01742    return res;
01743 }

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

References ast_waitfor_n().

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

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

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

References ast_waitfor_nandfds().

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

00902 {
00903    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
00904 }

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

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

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

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

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

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

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

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

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

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

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

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

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

01322 {
01323    int res;
01324    if (!chan->pvt->write_video)
01325       return 0;
01326    res = ast_write(chan, fr);
01327    if (!res)
01328       res = 1;
01329    return res;
01330 }


Generated on Fri Feb 27 12:19:47 2004 for Asterisk by doxygen 1.3.5