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_generator
struct  ast_channel
 Main Channel structure associated with a channel. More...

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 /* if the call is a digital ISDN call */
#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) /* Soft hangup by device */
#define AST_SOFTHANGUP_ASYNCGOTO   (1 << 1) /* Soft hangup for async goto */
#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)
unsigned int ast_get_group (char *s)


Define Documentation

#define AST_ADSI_AVAILABLE   (1)
 

Definition at line 296 of file channel.h.

#define AST_ADSI_OFFHOOKONLY   (3)
 

Definition at line 298 of file channel.h.

#define AST_ADSI_UNAVAILABLE   (2)
 

Definition at line 297 of file channel.h.

#define AST_ADSI_UNKNOWN   (0)
 

Definition at line 295 of file channel.h.

#define AST_BRIDGE_DTMF_CHANNEL_0   (1 << 0)
 

Report DTMF on channel 0

Definition at line 643 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 645 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 651 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 647 of file channel.h.

#define AST_BRIDGE_REC_CHANNEL_1   (1 << 3)
 

Return all voice frames on channel 1

Definition at line 649 of file channel.h.

#define AST_CDR_CALLWAIT   (1 << 2)
 

Definition at line 292 of file channel.h.

#define AST_CDR_CONFERENCE   (1 << 3)
 

Definition at line 293 of file channel.h.

#define AST_CDR_FORWARD   (1 << 1)
 

Definition at line 291 of file channel.h.

#define AST_CDR_TRANSFER   (1 << 0)
 

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

#define AST_DEVICE_INUSE   2
 

Device is in use

Definition at line 338 of file channel.h.

Referenced by ast_parse_device_state().

#define AST_DEVICE_INVALID   4
 

Device is invalid

Definition at line 342 of file channel.h.

Referenced by ast_device_state().

#define AST_DEVICE_NOT_INUSE   1
 

Device is not used

Definition at line 336 of file channel.h.

#define AST_DEVICE_UNAVAILABLE   5
 

Device is unavailable

Definition at line 344 of file channel.h.

#define AST_DEVICE_UNKNOWN   0
 

Device is valid but channel didn't know state

Definition at line 334 of file channel.h.

Referenced by ast_device_state(), and ast_parse_device_state().

#define AST_FLAG_DIGITAL   1 /* if the call is a digital ISDN call */
 

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

#define AST_SOFTHANGUP_ASYNCGOTO   (1 << 1) /* Soft hangup for async goto */
 

Definition at line 302 of file channel.h.

Referenced by ast_pbx_run().

#define AST_SOFTHANGUP_DEV   (1 << 0) /* Soft hangup by device */
 

Definition at line 300 of file channel.h.

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

#define AST_SOFTHANGUP_EXPLICIT   (1 << 5)
 

Definition at line 307 of file channel.h.

#define AST_SOFTHANGUP_SHUTDOWN   (1 << 2)
 

Definition at line 304 of file channel.h.

Referenced by ast_begin_shutdown().

#define AST_SOFTHANGUP_TIMEOUT   (1 << 3)
 

Definition at line 305 of file channel.h.

Referenced by ast_check_hangup(), ast_pbx_run(), and ast_waitfor_nandfds().

#define AST_STATE_BUSY   7
 

Line is busy

Definition at line 325 of file channel.h.

Referenced by ast_state2str().

#define AST_STATE_DIALING   3
 

Digits (or equivalent) have been dialed

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

#define AST_STATE_DOWN   0
 

Channel is down and available

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

#define AST_STATE_OFFHOOK   2
 

Channel is off hook

Definition at line 315 of file channel.h.

Referenced by ast_state2str().

#define AST_STATE_RESERVED   1
 

Channel is down, but reserved

Definition at line 313 of file channel.h.

Referenced by ast_state2str().

#define AST_STATE_RING   4
 

Line is ringing

Definition at line 319 of file channel.h.

Referenced by ast_answer(), and ast_state2str().

#define AST_STATE_RINGING   5
 

Remote end is ringing

Definition at line 321 of file channel.h.

Referenced by ast_answer(), and ast_state2str().

#define AST_STATE_UP   6
 

Line is up

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

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

#define CRASH   do { } while(0)
 

Definition at line 836 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 272 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 1528 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, and outgoing_helper::variable.

Referenced by ast_request_and_dial().

01529 {
01530    int state = 0;
01531    struct ast_channel *chan;
01532    struct ast_frame *f;
01533    int res = 0;
01534    chan = ast_request(type, format, data);
01535    if (chan) {
01536       if (oh) {
01537          char *tmp, *var;
01538          /* JDG chanvar */
01539          tmp = oh->variable;
01540          /* FIXME replace this call with strsep  NOT*/
01541          while( (var = strtok_r(NULL, "|", &tmp)) ) {
01542             pbx_builtin_setvar( chan, var );
01543          } /* /JDG */
01544          if (oh->callerid && *oh->callerid)
01545             ast_set_callerid(chan, oh->callerid, 1);
01546          if (oh->account && *oh->account)
01547             ast_cdr_setaccount(chan, oh->account);
01548       }
01549       if (callerid && strlen(callerid))
01550          ast_set_callerid(chan, callerid, 1);
01551 
01552       if (!ast_call(chan, data, 0)) {
01553          while(timeout && (chan->_state != AST_STATE_UP)) {
01554             res = ast_waitfor(chan, timeout);
01555             if (res < 0) {
01556                /* Something not cool, or timed out */
01557                break;
01558             }
01559             /* If done, break out */
01560             if (!res)
01561                break;
01562             if (timeout > -1)
01563                timeout = res;
01564             f = ast_read(chan);
01565             if (!f) {
01566                state = AST_CONTROL_HANGUP;
01567                res = 0;
01568                break;
01569             }
01570             if (f->frametype == AST_FRAME_CONTROL) {
01571                if (f->subclass == AST_CONTROL_RINGING)
01572                   state = AST_CONTROL_RINGING;
01573                else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
01574                   state = f->subclass;
01575                   ast_frfree(f);
01576                   break;
01577                } else if (f->subclass == AST_CONTROL_ANSWER) {
01578                   state = f->subclass;
01579                   ast_frfree(f);
01580                   break;
01581                } else if (f->subclass == -1) {
01582                   /* Ignore -- just stopping indications */
01583                } else {
01584                   ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
01585                }
01586             }
01587             ast_frfree(f);
01588          }
01589       } else
01590          ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
01591    } else
01592       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
01593    if (chan) {
01594       /* Final fixups */
01595       if (oh) {
01596          if (oh->context && *oh->context)
01597             strncpy(chan->context, oh->context, sizeof(chan->context) - 1);
01598          if (oh->exten && *oh->exten)
01599             strncpy(chan->exten, oh->exten, sizeof(chan->exten) - 1);
01600          chan->priority = oh->priority;
01601       }
01602       if (chan->_state == AST_STATE_UP) 
01603          state = AST_CONTROL_ANSWER;
01604    }
01605    if (outstate)
01606       *outstate = state;
01607    if (chan && res <= 0) {
01608       if (!chan->cdr) {
01609          chan->cdr = ast_cdr_alloc();
01610          if (chan->cdr)
01611             ast_cdr_init(chan->cdr, chan);
01612       }
01613       if (chan->cdr) {
01614          char tmp[256];
01615          sprintf(tmp, "%s/%s",type,(char *)data);
01616          ast_cdr_setapp(chan->cdr,"Dial",tmp);
01617          ast_cdr_update(chan);
01618          ast_cdr_start(chan->cdr);
01619          ast_cdr_end(chan->cdr);
01620          /* If the cause wasn't handled properly */
01621          if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
01622             ast_cdr_failed(chan->cdr);
01623       } else 
01624          ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
01625       ast_hangup(chan);
01626       chan = NULL;
01627    }
01628    return chan;
01629 }

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

Activate a given generator

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

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

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, AST_PTHREADT_NULL, 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 == AST_PTHREADT_NULL) ? 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_PTHREADT_NULL, 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 != AST_PTHREADT_NULL) 
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 1739 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().

01740 {
01741    /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 
01742       If the remote end does not answer within the timeout, then do NOT hang up, but 
01743       return anyway.  */
01744    int res = -1;
01745    /* Stop if we're a zombie or need a soft hangup */
01746    ast_mutex_lock(&chan->lock);
01747    if (!chan->zombie && !ast_check_hangup(chan)) 
01748       if (chan->pvt->call)
01749          res = chan->pvt->call(chan, addr, timeout);
01750    ast_mutex_unlock(&chan->lock);
01751    return res;
01752 }

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

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

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

01877 {
01878    int peerf;
01879    int chanf;
01880    int res;
01881    peerf = peer->nativeformats;
01882    chanf = chan->nativeformats;
01883    res = ast_translator_best_choice(&peerf, &chanf);
01884    if (res < 0) {
01885       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, chan->nativeformats, peer->name, peer->nativeformats);
01886       return -1;
01887    }
01888    /* Set read format on channel */
01889    res = ast_set_read_format(chan, peerf);
01890    if (res < 0) {
01891       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, chanf);
01892       return -1;
01893    }
01894    /* Set write format on peer channel */
01895    res = ast_set_write_format(peer, peerf);
01896    if (res < 0) {
01897       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, peerf);
01898       return -1;
01899    }
01900    /* Now we go the other way */
01901    peerf = peer->nativeformats;
01902    chanf = chan->nativeformats;
01903    res = ast_translator_best_choice(&chanf, &peerf);
01904    if (res < 0) {
01905       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, peer->nativeformats, chan->name, chan->nativeformats);
01906       return -1;
01907    }
01908    /* Set writeformat on channel */
01909    res = ast_set_write_format(chan, chanf);
01910    if (res < 0) {
01911       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, chanf);
01912       return -1;
01913    }
01914    /* Set read format on peer channel */
01915    res = ast_set_read_format(peer, chanf);
01916    if (res < 0) {
01917       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, peerf);
01918       return -1;
01919    }
01920    return 0;
01921 }

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

01924 {
01925    struct ast_frame null = { AST_FRAME_NULL, };
01926    ast_log(LOG_DEBUG, "Planning to masquerade %s into the structure of %s\n",
01927       clone->name, original->name);
01928    if (original->masq) {
01929       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
01930          original->masq->name, original->name);
01931       return -1;
01932    }
01933    if (clone->masqr) {
01934       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
01935          clone->name, clone->masqr->name);
01936       return -1;
01937    }
01938    original->masq = clone;
01939    clone->masqr = original;
01940    /* XXX can't really hold the lock here, but at the same time, it' s
01941       not really safe not to XXX */
01942    ast_queue_frame(original, &null, 0);
01943    ast_queue_frame(clone, &null, 0);
01944    ast_log(LOG_DEBUG, "Done planning to masquerade %s into the structure of %s\n", original->name, clone->name);
01945    return 0;
01946 }

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

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, LOG_DEBUG, LOG_WARNING, malloc, ast_channel::next, option_debug, option_verbose, 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 1862 of file channel.c.

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

01863 {
01864    if (chan->pvt->send_html)
01865       return chan->pvt->send_html(chan, subclass, data, datalen);
01866    return -1;
01867 }

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

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

01870 {
01871    if (chan->pvt->send_html)
01872       return chan->pvt->send_html(chan, AST_HTML_URL, url, strlen(url) + 1);
01873    return -1;
01874 }

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

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

02375 {
02376    int res;
02377    if (chan->pvt->setoption) {
02378       res = chan->pvt->setoption(chan, option, data, datalen);
02379       if (res < 0)
02380          return res;
02381    } else {
02382       errno = ENOSYS;
02383       return -1;
02384    }
02385    if (block) {
02386       /* XXX Implement blocking -- just wait for our option frame reply, discarding
02387          intermediate packets. XXX */
02388       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
02389       return -1;
02390    }
02391    return 0;
02392 }

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

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

01856 {
01857    if (chan->pvt->send_html)
01858       return 1;
01859    return 0;
01860 }

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, 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       if (chan->generator && chan->generator->release) 
00737          chan->generator->release(chan, chan->generatordata);
00738       chan->generatordata = NULL;
00739       chan->generator = NULL;
00740       chan->writeinterrupt = 0;
00741    }
00742 }

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

01701 {
01702    char tech[AST_MAX_EXTENSION] = "";
01703    char *number;
01704    struct chanlist *chanls;
01705    int res = 0;
01706    
01707    strncpy(tech, device, sizeof(tech)-1);
01708    number = strchr(tech, '/');
01709    if (!number) {
01710        return AST_DEVICE_INVALID;
01711    }
01712    *number = 0;
01713    number++;
01714       
01715    if (ast_mutex_lock(&chlock)) {
01716       ast_log(LOG_WARNING, "Unable to lock channel list\n");
01717       return -1;
01718    }
01719    chanls = backends;
01720    while(chanls) {
01721       if (!strcasecmp(tech, chanls->type)) {
01722          ast_mutex_unlock(&chlock);
01723          if (!chanls->devicestate) 
01724             return ast_parse_device_state(device);
01725          else {
01726             res = chanls->devicestate(number);
01727             if (res == AST_DEVICE_UNKNOWN)
01728                return ast_parse_device_state(device);
01729             else
01730                return res;
01731          }
01732       }
01733       chanls = chanls->next;
01734    }
01735    ast_mutex_unlock(&chlock);
01736    return AST_DEVICE_INVALID;
01737 }

unsigned int ast_get_group char *  s  ) 
 

Definition at line 2526 of file channel.c.

References ast_log(), LOG_ERROR, LOG_WARNING, and s.

02527 {
02528    char *copy;
02529    char *piece;
02530    char *c=NULL;
02531    int start=0, finish=0,x;
02532    unsigned int group = 0;
02533    copy = ast_strdupa(s);
02534    if (!copy) {
02535       ast_log(LOG_ERROR, "Out of memory\n");
02536       return 0;
02537    }
02538    c = copy;
02539    
02540    while((piece = strsep(&c, ","))) {
02541       if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
02542          /* Range */
02543       } else if (sscanf(piece, "%d", &start)) {
02544          /* Just one */
02545          finish = start;
02546       } else {
02547          ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'.  Using '0'\n", s,piece);
02548          return 0;
02549       }
02550       for (x=start;x<=finish;x++) {
02551          if ((x > 31) || (x < 0)) {
02552             ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 31)\n", x);
02553          } else
02554             group |= (1 << x);
02555       }
02556    }
02557    return group;
02558 }

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       chan->zombie=1;
00634       ast_mutex_unlock(&chan->lock);
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 1201 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.

01202 {
01203    int res = -1;
01204    /* Stop if we're a zombie or need a soft hangup */
01205    if (chan->zombie || ast_check_hangup(chan)) 
01206       return -1;
01207    ast_mutex_lock(&chan->lock);
01208    if (chan->pvt->indicate)
01209       res = chan->pvt->indicate(chan, condition);
01210    ast_mutex_unlock(&chan->lock);
01211    if (!chan->pvt->indicate || res) {
01212       /*
01213        * Device does not support (that) indication, lets fake
01214        * it by doing our own tone generation. (PM2002)
01215        */
01216       if (condition >= 0) {
01217          const struct tone_zone_sound *ts = NULL;
01218          switch (condition) {
01219           case AST_CONTROL_RINGING:
01220             ts = ast_get_indication_tone(chan->zone, "ring");
01221             break;
01222           case AST_CONTROL_BUSY:
01223             ts = ast_get_indication_tone(chan->zone, "busy");
01224             break;
01225           case AST_CONTROL_CONGESTION:
01226             ts = ast_get_indication_tone(chan->zone, "congestion");
01227             break;
01228          }
01229          if (ts && ts->data[0]) {
01230             ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
01231             ast_playtones_start(chan,0,ts->data, 1);
01232             res = 0;
01233          } else if (condition == AST_CONTROL_PROGRESS) {
01234             /* ast_playtones_stop(chan); */
01235          } else {
01236             /* not handled */
01237             ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
01238             res = -1;
01239          }
01240       }
01241       else ast_playtones_stop(chan);
01242    }
01243    return res;
01244 }

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

01682 {
01683    char name[AST_CHANNEL_NAME] = "";
01684    char *cut;
01685    struct ast_channel *chan;
01686 
01687    chan = ast_channel_walk(NULL);
01688    while (chan) {
01689       strncpy(name, chan->name, sizeof(name)-1);
01690       cut = strchr(name,'-');
01691       if (cut)
01692               *cut = 0;
01693       if (!strcmp(name, device))
01694               return AST_DEVICE_INUSE;
01695       chan = ast_channel_walk(chan);
01696    }
01697    return AST_DEVICE_UNKNOWN;
01698 }

int ast_prod struct ast_channel chan  ) 
 

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

01334 {
01335    struct ast_frame a = { AST_FRAME_VOICE };
01336    char nothing[128];
01337    /* Send an empty audio frame to get things moving */
01338    if (chan->_state != AST_STATE_UP) {
01339       ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
01340       a.subclass = chan->pvt->rawwriteformat;
01341       a.data = nothing + AST_FRIENDLY_OFFSET;
01342       if (ast_write(chan, &a))
01343          ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
01344    }
01345    return 0;
01346 }

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

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

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

01775 {
01776    int pos=0;
01777    int to = ftimeout;
01778    char d;
01779    /* XXX Merge with full version? XXX */
01780    /* Stop if we're a zombie or need a soft hangup */
01781    if (c->zombie || ast_check_hangup(c)) 
01782       return -1;
01783    if (!len)
01784       return -1;
01785    do {
01786       if (c->stream) {
01787          d = ast_waitstream(c, AST_DIGIT_ANY);
01788          ast_stopstream(c);
01789          usleep(1000);
01790          if (!d)
01791             d = ast_waitfordigit(c, to);
01792       } else {
01793          d = ast_waitfordigit(c, to);
01794       }
01795       if (d < 0)
01796          return -1;
01797       if (d == 0) {
01798          s[pos]='\0';
01799          return 1;
01800       }
01801       if (!strchr(enders, d))
01802          s[pos++] = d;
01803       if (strchr(enders, d) || (pos >= len)) {
01804          s[pos]='\0';
01805          return 0;
01806       }
01807       to = timeout;
01808    } while(1);
01809    /* Never reached */
01810    return 0;
01811 }

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

01814 {
01815    int pos=0;
01816    int to = ftimeout;
01817    char d;
01818    /* Stop if we're a zombie or need a soft hangup */
01819    if (c->zombie || ast_check_hangup(c)) 
01820       return -1;
01821    if (!len)
01822       return -1;
01823    do {
01824       if (c->stream) {
01825          d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
01826          ast_stopstream(c);
01827          usleep(1000);
01828          if (!d)
01829             d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
01830       } else {
01831          d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
01832       }
01833       if (d < 0)
01834          return -1;
01835       if (d == 0) {
01836          s[pos]='\0';
01837          return 1;
01838       }
01839       if (d == 1) {
01840          s[pos]='\0';
01841          return 2;
01842       }
01843       if (!strchr(enders, d))
01844          s[pos++] = d;
01845       if (strchr(enders, d) || (pos >= len)) {
01846          s[pos]='\0';
01847          return 0;
01848       }
01849       to = timeout;
01850    } while(1);
01851    /* Never reached */
01852    return 0;
01853 }

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

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

01247 {
01248    int res,ourto,c;
01249    struct ast_frame *f;
01250    
01251    ourto = timeout;
01252    for(;;)
01253       {
01254       if (ast_check_hangup(chan)) return -1;
01255       res = ast_waitfor(chan,ourto);
01256       if (res <= 0) /* if timeout */
01257          {
01258          return 0;
01259          }
01260       ourto = res;
01261       f = ast_read(chan);
01262       if (f == NULL) return -1; /* if hangup */
01263       if ((f->frametype == AST_FRAME_CONTROL) &&
01264           (f->subclass == AST_CONTROL_HANGUP)) return -1; /* if hangup */
01265       if (f->frametype == AST_FRAME_TEXT)  /* if a text frame */
01266          {
01267          c = *((char *)f->data);  /* get the data */
01268          ast_frfree(f);
01269          return(c);
01270          }
01271       ast_frfree(f);
01272    }
01273 }

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 1636 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, and ast_channel::uniqueid.

Referenced by __ast_request_and_dial().

01637 {
01638    struct chanlist *chan;
01639    struct ast_channel *c = NULL;
01640    int capabilities;
01641    int fmt;
01642    int res;
01643    if (ast_mutex_lock(&chlock)) {
01644       ast_log(LOG_WARNING, "Unable to lock channel list\n");
01645       return NULL;
01646    }
01647    chan = backends;
01648    while(chan) {
01649       if (!strcasecmp(type, chan->type)) {
01650          capabilities = chan->capabilities;
01651          fmt = format;
01652          res = ast_translator_best_choice(&fmt, &capabilities);
01653          if (res < 0) {
01654             ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->capabilities, format);
01655             ast_mutex_unlock(&chlock);
01656             return NULL;
01657          }
01658          ast_mutex_unlock(&chlock);
01659          if (chan->requester)
01660             c = chan->requester(type, capabilities, data);
01661          if (c) {
01662             if (c->_state == AST_STATE_DOWN) {
01663                manager_event(EVENT_FLAG_CALL, "Newchannel",
01664                "Channel: %s\r\n"
01665                "State: %s\r\n"
01666                "Callerid: %s\r\n"
01667                "Uniqueid: %s\r\n",
01668                c->name, ast_state2str(c->_state), c->callerid ? c->callerid : "<unknown>", c->uniqueid);
01669             }
01670          }
01671          return c;
01672       }
01673       chan = chan->next;
01674    }
01675    if (!chan)
01676       ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
01677    ast_mutex_unlock(&chlock);
01678    return c;
01679 }

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

References __ast_request_and_dial().

01632 {
01633    return __ast_request_and_dial(type, format, data, timeout, outstate, callerid, NULL);
01634 }

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

01276 {
01277    int res = 0;
01278    /* Stop if we're a zombie or need a soft hangup */
01279    if (chan->zombie || ast_check_hangup(chan)) 
01280       return -1;
01281    CHECK_BLOCKING(chan);
01282    if (chan->pvt->send_text)
01283       res = chan->pvt->send_text(chan, text);
01284    chan->blocking = 0;
01285    return res;
01286 }

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

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

02163 {
02164    if (chan->callerid)
02165       free(chan->callerid);
02166    if (anitoo && chan->ani)
02167       free(chan->ani);
02168    if (callerid) {
02169       chan->callerid = strdup(callerid);
02170       if (anitoo)
02171          chan->ani = strdup(callerid);
02172    } else {
02173       chan->callerid = NULL;
02174       if (anitoo)
02175          chan->ani = NULL;
02176    }
02177    if (chan->cdr)
02178       ast_cdr_setcid(chan->cdr, chan);
02179    manager_event(EVENT_FLAG_CALL, "Newcallerid", 
02180             "Channel: %s\r\n"
02181             "Callerid: %s\r\n"
02182             "Uniqueid: %s\r\n",
02183             chan->name, chan->callerid ? 
02184             chan->callerid : "<Unknown>",
02185             chan->uniqueid);
02186 }

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

01498 {
01499    int fmt;
01500    int native;
01501    int res;
01502    
01503    native = chan->nativeformats;
01504    fmt = fmts;
01505    /* Find a translation path from the native read format to one of the user's read formats */
01506    res = ast_translator_best_choice(&fmt, &native);
01507    if (res < 0) {
01508       ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n",
01509          ast_getformatname(chan->nativeformats), ast_getformatname(fmts));
01510       return -1;
01511    }
01512    
01513    /* Now we have a good choice for both.  We'll write using our native format. */
01514    chan->pvt->rawreadformat = native;
01515    /* User perspective is fmt */
01516    chan->readformat = fmt;
01517    /* Free any read translation we have right now */
01518    if (chan->pvt->readtrans)
01519       ast_translator_free_path(chan->pvt->readtrans);
01520    /* Build a translation path from the raw read format to the user reading format */
01521    chan->pvt->readtrans = ast_translator_build_path(chan->readformat, chan->pvt->rawreadformat);
01522    if (option_debug)
01523       ast_log(LOG_DEBUG, "Set channel %s to read format %s\n", 
01524          chan->name, ast_getformatname(chan->readformat));
01525    return 0;
01526 }

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

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

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

Definition at line 974 of file channel.c.

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

Referenced by ast_closestream().

00975 {
00976    int res = -1;
00977 #ifdef ZAPTEL_OPTIMIZATIONS
00978    if (c->timingfd > -1) {
00979       if (!func) {
00980          samples = 0;
00981          data = 0;
00982       }
00983       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
00984       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
00985       c->timingfunc = func;
00986       c->timingdata = data;
00987    }
00988 #endif   
00989    return res;
00990 }

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

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

02509 {
02510    struct ast_frame *f;
02511    int res;
02512    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
02513       return res;
02514 
02515    /* Give us some wiggle room */
02516    while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) {
02517       f = ast_read(chan);
02518       if (f)
02519          ast_frfree(f);
02520       else
02521          return -1;
02522    }
02523    return 0;
02524 }

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

Start a tone going

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

02489 {
02490    struct tonepair_def d = { 0, };
02491    d.freq1 = freq1;
02492    d.freq2 = freq2;
02493    d.duration = duration;
02494    if (vol < 1)
02495       d.vol = 8192;
02496    else
02497       d.vol = vol;
02498    if (ast_activate_generator(chan, &tonepair, &d))
02499       return -1;
02500    return 0;
02501 }

void ast_tonepair_stop struct ast_channel chan  ) 
 

Stop a tone from playing

Definition at line 2503 of file channel.c.

References ast_deactivate_generator().

02504 {
02505    ast_deactivate_generator(chan);
02506 }

int ast_transfer struct ast_channel chan,
char *  dest
 

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

01755 {
01756    /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 
01757       If the remote end does not answer within the timeout, then do NOT hang up, but 
01758       return anyway.  */
01759    int res = -1;
01760    /* Stop if we're a zombie or need a soft hangup */
01761    ast_mutex_lock(&chan->lock);
01762    if (!chan->zombie && !ast_check_hangup(chan)) {
01763       if (chan->pvt->transfer) {
01764          res = chan->pvt->transfer(chan, dest);
01765          if (!res)
01766             res = 1;
01767       } else
01768          res = 0;
01769    }
01770    ast_mutex_unlock(&chan->lock);
01771    return res;
01772 }

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

00934 {
00935    struct ast_channel *chan;
00936    int oldms = ms;
00937    chan = ast_waitfor_n(&c, 1, &ms);
00938    if (ms < 0) {
00939       if (oldms < 0)
00940          return 0;
00941       else
00942          return -1;
00943    }
00944    return ms;
00945 }

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

References ast_waitfor_nandfds().

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

00929 {
00930    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
00931 }

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

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

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

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

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

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

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

00948 {
00949    /* XXX Should I be merged with waitfordigit_full XXX */
00950    struct ast_frame *f;
00951    char result = 0;
00952    /* Stop if we're a zombie or need a soft hangup */
00953    if (c->zombie || ast_check_hangup(c)) 
00954       return -1;
00955    /* Wait for a digit, no more than ms milliseconds total. */
00956    while(ms && !result) {
00957       ms = ast_waitfor(c, ms);
00958       if (ms < 0) /* Error */
00959          result = -1; 
00960       else if (ms > 0) {
00961          /* Read something */
00962          f = ast_read(c);
00963          if (f) {
00964             if (f->frametype == AST_FRAME_DTMF) 
00965                result = f->subclass;
00966             ast_frfree(f);
00967          } else
00968             result = -1;
00969       }
00970    }
00971    return result;
00972 }

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

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

00992 {
00993    struct ast_frame *f;
00994    char result = 0;
00995    struct ast_channel *rchan;
00996    int outfd;
00997    /* Stop if we're a zombie or need a soft hangup */
00998    if (c->zombie || ast_check_hangup(c)) 
00999       return -1;
01000    /* Wait for a digit, no more than ms milliseconds total. */
01001    while(ms && !result) {
01002       rchan = ast_waitfor_nandfds(&c, 1, &audio, (audio > -1) ? 1 : 0, NULL, &outfd, &ms);
01003       if ((!rchan) && (outfd < 0) && (ms)) /* Error */
01004          result = -1; 
01005       else if (outfd > -1) {
01006          result = 1;
01007       } else if (rchan) {
01008          /* Read something */
01009          f = ast_read(c);
01010          if (f) {
01011             if (f->frametype == AST_FRAME_DTMF) 
01012                result = f->subclass;
01013             ast_frfree(f);
01014          } else
01015             result = -1;
01016       }
01017    }
01018    return result;
01019 }

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

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

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

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

01349 {
01350    int res;
01351    if (!chan->pvt->write_video)
01352       return 0;
01353    res = ast_write(chan, fr);
01354    if (!res)
01355       res = 1;
01356    return res;
01357 }


Generated on Sun Apr 18 23:34:02 2004 for Asterisk by doxygen 1.3.6-20040222