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 <sys/poll.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_bridge_config
struct  ast_channel
 Main Channel structure associated with a channel. More...

struct  ast_generator
struct  outgoing_helper

Defines

#define AST_MAX_EXTENSION   80
 Max length of an extension. More...

#define AST_CHANNEL_NAME   80
#define AST_CHANNEL_MAX_STACK   32
#define MAX_LANGUAGE   20
#define AST_MAX_FDS   8
#define AST_FLAG_DIGITAL   1
#define LOAD_OH(oh)
#define AST_CDR_TRANSFER   (1 << 0)
#define AST_CDR_FORWARD   (1 << 1)
#define AST_CDR_CALLWAIT   (1 << 2)
#define AST_CDR_CONFERENCE   (1 << 3)
#define AST_ADSI_UNKNOWN   (0)
#define AST_ADSI_AVAILABLE   (1)
#define AST_ADSI_UNAVAILABLE   (2)
#define AST_ADSI_OFFHOOKONLY   (3)
#define AST_SOFTHANGUP_DEV   (1 << 0)
#define AST_SOFTHANGUP_ASYNCGOTO   (1 << 1)
#define AST_SOFTHANGUP_SHUTDOWN   (1 << 2)
#define AST_SOFTHANGUP_TIMEOUT   (1 << 3)
#define AST_SOFTHANGUP_APPUNLOAD   (1 << 4)
#define AST_SOFTHANGUP_EXPLICIT   (1 << 5)
#define AST_STATE_DOWN   0
#define AST_STATE_RESERVED   1
#define AST_STATE_OFFHOOK   2
#define AST_STATE_DIALING   3
#define AST_STATE_RING   4
#define AST_STATE_RINGING   5
#define AST_STATE_UP   6
#define AST_STATE_BUSY   7
#define AST_STATE_DIALING_OFFHOOK   8
#define AST_STATE_PRERING   9
#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. More...

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

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

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

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

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

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

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

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

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

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

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

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

int ast_safe_sleep (struct ast_channel *chan, int ms)
 Wait for a specied amount of time, looking for hangups. More...

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

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

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

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

ast_frameast_read (struct ast_channel *chan)
 Reads a frame. More...

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

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

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

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

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

int ast_senddigit (struct ast_channel *chan, char digit)
 Receives a text character from a channel. More...

int ast_recvchar (struct ast_channel *chan, int timeout)
ast_channelast_channel_walk_locked (struct ast_channel *prev)
 Browse channels in use. More...

ast_channelast_get_channel_by_name_locked (char *channame)
 Get channel by name (locks channel). More...

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

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

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

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

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

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

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

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

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

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

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

int ast_channel_defer_dtmf (struct ast_channel *chan)
 Defers DTMF. More...

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

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)
int ast_do_masquerade (struct ast_channel *chan)
unsigned int ast_get_group (char *s)


Define Documentation

#define AST_ADSI_AVAILABLE   (1)
 

Definition at line 311 of file channel.h.

#define AST_ADSI_OFFHOOKONLY   (3)
 

Definition at line 313 of file channel.h.

#define AST_ADSI_UNAVAILABLE   (2)
 

Definition at line 312 of file channel.h.

#define AST_ADSI_UNKNOWN   (0)
 

Definition at line 310 of file channel.h.

#define AST_BRIDGE_DTMF_CHANNEL_0   (1 << 0)
 

Report DTMF on channel 0

Definition at line 665 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 667 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 673 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 669 of file channel.h.

#define AST_BRIDGE_REC_CHANNEL_1   (1 << 3)
 

Return all voice frames on channel 1

Definition at line 671 of file channel.h.

#define AST_CDR_CALLWAIT   (1 << 2)
 

Definition at line 307 of file channel.h.

#define AST_CDR_CONFERENCE   (1 << 3)
 

Definition at line 308 of file channel.h.

#define AST_CDR_FORWARD   (1 << 1)
 

Definition at line 306 of file channel.h.

#define AST_CDR_TRANSFER   (1 << 0)
 

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

#define AST_DEVICE_INUSE   2
 

Device is in use

Definition at line 353 of file channel.h.

Referenced by ast_parse_device_state().

#define AST_DEVICE_INVALID   4
 

Device is invalid

Definition at line 357 of file channel.h.

Referenced by ast_device_state().

#define AST_DEVICE_NOT_INUSE   1
 

Device is not used

Definition at line 351 of file channel.h.

#define AST_DEVICE_UNAVAILABLE   5
 

Device is unavailable

Definition at line 359 of file channel.h.

#define AST_DEVICE_UNKNOWN   0
 

Device is valid but channel didn't know state

Definition at line 349 of file channel.h.

Referenced by ast_device_state(), and ast_parse_device_state().

#define AST_FLAG_DIGITAL   1
 

Definition at line 236 of file channel.h.

#define AST_MAX_EXTENSION   80
 

Max length of an extension.

Definition at line 31 of file channel.h.

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

#define AST_MAX_FDS   8
 

Definition at line 43 of file channel.h.

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

#define AST_SOFTHANGUP_APPUNLOAD   (1 << 4)
 

Definition at line 319 of file channel.h.

#define AST_SOFTHANGUP_ASYNCGOTO   (1 << 1)
 

Definition at line 316 of file channel.h.

Referenced by ast_async_goto(), and ast_pbx_run().

#define AST_SOFTHANGUP_DEV   (1 << 0)
 

Definition at line 315 of file channel.h.

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

#define AST_SOFTHANGUP_EXPLICIT   (1 << 5)
 

Definition at line 320 of file channel.h.

#define AST_SOFTHANGUP_SHUTDOWN   (1 << 2)
 

Definition at line 317 of file channel.h.

Referenced by ast_begin_shutdown().

#define AST_SOFTHANGUP_TIMEOUT   (1 << 3)
 

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

Referenced by ast_state2str().

#define AST_STATE_DIALING   3
 

Digits (or equivalent) have been dialed

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

#define AST_STATE_DOWN   0
 

Channel is down and available

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

#define AST_STATE_OFFHOOK   2
 

Channel is off hook

Definition at line 328 of file channel.h.

Referenced by ast_state2str().

#define AST_STATE_PRERING   9
 

Channel has detected an incoming call and is waiting for ring

Definition at line 342 of file channel.h.

#define AST_STATE_RESERVED   1
 

Channel is down, but reserved

Definition at line 326 of file channel.h.

Referenced by ast_state2str().

#define AST_STATE_RING   4
 

Line is ringing

Definition at line 332 of file channel.h.

Referenced by ast_answer(), and ast_state2str().

#define AST_STATE_RINGING   5
 

Remote end is ringing

Definition at line 334 of file channel.h.

Referenced by ast_answer(), and ast_state2str().

#define AST_STATE_UP   6
 

Line is up

Definition at line 336 of file channel.h.

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

#define CHECK_BLOCKING  
 

Definition at line 879 of file channel.h.

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

#define CRASH   do { } while(0)
 

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

Referenced by ast_pbx_outgoing_exten().

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

References ast_channel::_state, 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_frfree(), ast_hangup(), ast_log(), ast_read(), ast_request(), ast_set_callerid(), AST_STATE_UP, ast_waitfor(), ast_channel::callerid, ast_channel::cdr, ast_channel::context, ast_channel::exten, ast_frame::frametype, ast_channel::hangupcause, LOG_NOTICE, LOG_WARNING, pbx_builtin_setvar(), ast_channel::priority, and ast_frame::subclass.

Referenced by ast_pbx_outgoing_exten(), and ast_request_and_dial().

01747 {
01748    int state = 0;
01749    struct ast_channel *chan;
01750    struct ast_frame *f;
01751    int res = 0;
01752    char *variable;
01753    chan = ast_request(type, format, data);
01754    if (chan) {
01755       if (oh) {
01756          char *tmp, *var;
01757          /* JDG chanvar */
01758          if (oh->variable)
01759             variable = ast_strdupa(oh->variable);
01760          else
01761             variable = NULL;
01762          tmp = variable;
01763          /* FIXME replace this call with strsep  NOT*/
01764          while( (var = strtok_r(NULL, "|", &tmp)) ) {
01765             pbx_builtin_setvar( chan, var );
01766          } /* /JDG */
01767          if (oh->callerid && *oh->callerid)
01768             ast_set_callerid(chan, oh->callerid, 1);
01769          if (oh->account && *oh->account)
01770             ast_cdr_setaccount(chan, oh->account);
01771       }
01772       if (callerid && !ast_strlen_zero(callerid))
01773          ast_set_callerid(chan, callerid, 1);
01774 
01775       if (!ast_call(chan, data, 0)) {
01776          while(timeout && (chan->_state != AST_STATE_UP)) {
01777             res = ast_waitfor(chan, timeout);
01778             if (res < 0) {
01779                /* Something not cool, or timed out */
01780                break;
01781             }
01782             /* If done, break out */
01783             if (!res)
01784                break;
01785             if (timeout > -1)
01786                timeout = res;
01787             f = ast_read(chan);
01788             if (!f) {
01789                state = AST_CONTROL_HANGUP;
01790                res = 0;
01791                break;
01792             }
01793             if (f->frametype == AST_FRAME_CONTROL) {
01794                if (f->subclass == AST_CONTROL_RINGING)
01795                   state = AST_CONTROL_RINGING;
01796                else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
01797                   state = f->subclass;
01798                   ast_frfree(f);
01799                   break;
01800                } else if (f->subclass == AST_CONTROL_ANSWER) {
01801                   state = f->subclass;
01802                   ast_frfree(f);
01803                   break;
01804                } else if (f->subclass == AST_CONTROL_PROGRESS) {
01805                   /* Ignore */
01806                } else if (f->subclass == -1) {
01807                   /* Ignore -- just stopping indications */
01808                } else {
01809                   ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
01810                }
01811             }
01812             ast_frfree(f);
01813          }
01814       } else
01815          ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
01816    } else
01817       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
01818    if (chan) {
01819       /* Final fixups */
01820       if (oh) {
01821          if (oh->context && *oh->context)
01822             strncpy(chan->context, oh->context, sizeof(chan->context) - 1);
01823          if (oh->exten && *oh->exten)
01824             strncpy(chan->exten, oh->exten, sizeof(chan->exten) - 1);
01825          chan->priority = oh->priority;
01826       }
01827       if (chan->_state == AST_STATE_UP) 
01828          state = AST_CONTROL_ANSWER;
01829    }
01830    if (outstate)
01831       *outstate = state;
01832    if (chan && res <= 0) {
01833       if (!chan->cdr) {
01834          chan->cdr = ast_cdr_alloc();
01835          if (chan->cdr)
01836             ast_cdr_init(chan->cdr, chan);
01837       }
01838       if (chan->cdr) {
01839          char tmp[256];
01840          snprintf(tmp, 256, "%s/%s", type, (char *)data);
01841          ast_cdr_setapp(chan->cdr,"Dial",tmp);
01842          ast_cdr_update(chan);
01843          ast_cdr_start(chan->cdr);
01844          ast_cdr_end(chan->cdr);
01845          /* If the cause wasn't handled properly */
01846          if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
01847             ast_cdr_failed(chan->cdr);
01848       } else 
01849          ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
01850       ast_hangup(chan);
01851       chan = NULL;
01852    }
01853    return chan;
01854 }

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

Activate a given generator

Definition at line 849 of file channel.c.

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

Referenced by ast_linear_stream(), ast_playtones_start(), and ast_tonepair_start().

00850 {
00851    int res = 0;
00852    ast_mutex_lock(&chan->lock);
00853    if (chan->generatordata) {
00854       if (chan->generator && chan->generator->release)
00855          chan->generator->release(chan, chan->generatordata);
00856       chan->generatordata = NULL;
00857    }
00858    ast_prod(chan);
00859    if ((chan->generatordata = gen->alloc(chan, params))) {
00860       ast_settimeout(chan, 160, generator_force, chan);
00861       chan->generator = gen;
00862    } else {
00863       res = -1;
00864    }
00865    ast_mutex_unlock(&chan->lock);
00866    return res;
00867 }

int ast_active_channels void   
 

Returns number of active/allocated channels

Definition at line 120 of file channel.c.

References ast_mutex_lock, ast_mutex_unlock, and ast_channel::next.

00121 {
00122    struct ast_channel *c;
00123    int cnt = 0;
00124    ast_mutex_lock(&chlock);
00125    c = channels;
00126    while(c) {
00127       cnt++;
00128       c = c->next;
00129    }
00130    ast_mutex_unlock(&chlock);
00131    return cnt;
00132 }

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

Referenced by ast_control_streamfile().

00786 {
00787    int res = 0;
00788    ast_mutex_lock(&chan->lock);
00789    /* Stop if we're a zombie or need a soft hangup */
00790    if (chan->zombie || ast_check_hangup(chan)) {
00791       ast_mutex_unlock(&chan->lock);
00792       return -1;
00793    }
00794    switch(chan->_state) {
00795    case AST_STATE_RINGING:
00796    case AST_STATE_RING:
00797       if (chan->pvt->answer)
00798          res = chan->pvt->answer(chan);
00799       ast_setstate(chan, AST_STATE_UP);
00800       if (chan->cdr)
00801          ast_cdr_answer(chan->cdr);
00802       ast_mutex_unlock(&chan->lock);
00803       return res;
00804       break;
00805    case AST_STATE_UP:
00806       if (chan->cdr)
00807          ast_cdr_answer(chan->cdr);
00808       break;
00809    }
00810    ast_mutex_unlock(&chan->lock);
00811    return 0;
00812 }

int ast_autoservice_start struct ast_channel   chan
 

Automatically service a channel for us...

Definition at line 88 of file autoservice.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_pthread_create(), AST_PTHREADT_NULL, asent::chan, free, LOG_WARNING, malloc, and asent::next.

Referenced by ast_dtmf_stream(), ast_get_enum(), ast_get_srv(), and ast_get_txt().

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

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 124 of file autoservice.c.

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

Referenced by ast_dtmf_stream(), ast_get_enum(), ast_get_srv(), and ast_get_txt().

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

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

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

00106 {
00107    struct ast_channel *c;
00108    shutting_down = 1;
00109    if (hangup) {
00110       ast_mutex_lock(&chlock);
00111       c = channels;
00112       while(c) {
00113          ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
00114          c = c->next;
00115       }
00116       ast_mutex_unlock(&chlock);
00117    }
00118 }

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

01966 {
01967    /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 
01968       If the remote end does not answer within the timeout, then do NOT hang up, but 
01969       return anyway.  */
01970    int res = -1;
01971    /* Stop if we're a zombie or need a soft hangup */
01972    ast_mutex_lock(&chan->lock);
01973    if (!chan->zombie && !ast_check_hangup(chan)) 
01974       if (chan->pvt->call)
01975          res = chan->pvt->call(chan, addr, timeout);
01976    ast_mutex_unlock(&chan->lock);
01977    return res;
01978 }

void ast_cancel_shutdown void   
 

Cancels an existing shutdown and returns to normal operation

Definition at line 134 of file channel.c.

00135 {
00136    shutting_down = 0;
00137 }

int ast_channel_bridge struct ast_channel   c0,
struct ast_channel   c1,
struct ast_bridge_config   config,
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 2497 of file channel.c.

References ast_bridge_config::allowdisconnect_in, ast_bridge_config::allowdisconnect_out, ast_bridge_config::allowredirect_in, ast_bridge_config::allowredirect_out, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_IGNORE_SIGS, ast_channel_make_compatible(), ast_check_hangup(), ast_frfree(), ast_log(), ast_read(), ast_verbose(), ast_waitfor_n(), ast_write(), ast_channel_pvt::bridge, ast_channel::bridge, ast_bridge_config::end_sound, EVENT_FLAG_CALL, ast_bridge_config::firstpass, ast_frame::frametype, ast_channel::generator, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, ast_bridge_config::play_to_callee, ast_bridge_config::play_to_caller, ast_bridge_config::play_warning, ast_channel::pvt, ast_channel::readformat, ast_bridge_config::start_sound, ast_frame::subclass, ast_bridge_config::timelimit, ast_channel::uniqueid, VERBOSE_PREFIX_3, ast_bridge_config::warning_freq, ast_bridge_config::warning_sound, ast_channel::writeformat, and ast_channel::zombie.

02498 {
02499    /* Copy voice back and forth between the two channels.   Give the peer
02500       the ability to transfer calls with '#<extension' syntax. */
02501    int flags;
02502    struct ast_channel *cs[3];
02503    int to = -1;
02504    struct ast_frame *f;
02505    struct ast_channel *who = NULL;
02506    int res=0;
02507    int nativefailed=0;
02508    int firstpass;
02509    int o0nativeformats;
02510    int o1nativeformats;
02511    struct timeval start_time,precise_now;
02512    long elapsed_ms=0, time_left_ms=0;
02513    int playit=0, playitagain=1, first_time=1;
02514 
02515    flags = (config->allowdisconnect_out||config->allowredirect_out ? AST_BRIDGE_DTMF_CHANNEL_0 : 0) + (config->allowdisconnect_in||config->allowredirect_in ? AST_BRIDGE_DTMF_CHANNEL_1 : 0);
02516 
02517    firstpass = config->firstpass;
02518    config->firstpass = 0;
02519 
02520    /* timestamp */
02521    gettimeofday(&start_time,NULL);
02522    time_left_ms = config->timelimit;
02523 
02524    if (config->play_to_caller && config->start_sound && firstpass)
02525       bridge_playfile(c0,c1,config->start_sound,time_left_ms / 1000);
02526    if (config->play_to_callee && config->start_sound && firstpass)
02527       bridge_playfile(c1,c0,config->start_sound,time_left_ms / 1000);
02528 
02529    /* Stop if we're a zombie or need a soft hangup */
02530    if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) 
02531       return -1;
02532    if (c0->bridge) {
02533       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
02534          c0->name, c0->bridge->name);
02535       return -1;
02536    }
02537    if (c1->bridge) {
02538       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
02539          c1->name, c1->bridge->name);
02540       return -1;
02541    }
02542    
02543    /* Keep track of bridge */
02544    c0->bridge = c1;
02545    c1->bridge = c0;
02546    cs[0] = c0;
02547    cs[1] = c1;
02548    
02549    manager_event(EVENT_FLAG_CALL, "Link", 
02550          "Channel1: %s\r\n"
02551          "Channel2: %s\r\n"
02552          "Uniqueid1: %s\r\n"
02553          "Uniqueid2: %s\r\n",
02554          c0->name, c1->name, c0->uniqueid, c1->uniqueid);
02555    o1nativeformats = c1->nativeformats;
02556    o0nativeformats = c0->nativeformats;
02557    for (/* ever */;;) {
02558       /* timestamp */
02559       if (config->timelimit) {
02560          gettimeofday(&precise_now,NULL);
02561          elapsed_ms = tvdiff(&precise_now,&start_time);
02562          time_left_ms = config->timelimit - elapsed_ms;
02563 
02564          if (playitagain && (config->play_to_caller || config->play_to_callee) && (config->play_warning && time_left_ms <= config->play_warning)) { 
02565             /* narrowing down to the end */
02566             if (config->warning_freq == 0) {
02567                playit = 1;
02568                first_time=0;
02569                playitagain=0;
02570             } else if (first_time) {
02571                playit = 1;
02572                first_time=0;
02573             } else {
02574                if ((time_left_ms % config->warning_freq) <= 50) {
02575                   playit = 1;
02576                }
02577             }
02578          }
02579          if (time_left_ms <= 0) {
02580             if (config->play_to_caller && config->end_sound)
02581                bridge_playfile(c0,c1,config->end_sound,0);
02582             if (config->play_to_callee && config->end_sound)
02583                bridge_playfile(c1,c0,config->end_sound,0);
02584             *fo = NULL;
02585             if (who) *rc = who;
02586             res = 0;
02587             break;
02588          }
02589          if (time_left_ms >= 5000 && playit) {
02590             if (config->play_to_caller && config->warning_sound && config->play_warning)
02591                bridge_playfile(c0,c1,config->warning_sound,time_left_ms / 1000);
02592             if (config->play_to_callee && config->warning_sound && config->play_warning)
02593                bridge_playfile(c1,c0,config->warning_sound,time_left_ms / 1000);
02594             playit = 0;
02595          }
02596          
02597       }
02598       /* Stop if we're a zombie or need a soft hangup */
02599       if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) {
02600          *fo = NULL;
02601          if (who) *rc = who;
02602          res = 0;
02603          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");
02604          break;
02605       }
02606       if (c0->pvt->bridge && config->timelimit==0 &&
02607          (c0->pvt->bridge == c1->pvt->bridge) && !nativefailed && !c0->monitor && !c1->monitor) {
02608             /* Looks like they share a bridge code */
02609          if (option_verbose > 2) 
02610             ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name);
02611          if (!(res = c0->pvt->bridge(c0, c1, flags, fo, rc))) {
02612             c0->bridge = NULL;
02613             c1->bridge = NULL;
02614             manager_event(EVENT_FLAG_CALL, "Unlink", 
02615                "Channel1: %s\r\n"
02616                "Channel2: %s\r\n"
02617                "Uniqueid1: %s\r\n"
02618                "Uniqueid2: %s\r\n",
02619                c0->name, c1->name, c0->uniqueid, c1->uniqueid);
02620             ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n",c0->name ,c1->name);
02621             return 0;
02622          }
02623          /* If they return non-zero then continue on normally.  Let "-2" mean don't worry about
02624             my not wanting to bridge */
02625          if ((res != -2) && (res != -3))
02626             ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name);
02627          if (res != -3) nativefailed++;
02628       }
02629    
02630       if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) || (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
02631          !(c0->generator || c1->generator))  {
02632          if (ast_channel_make_compatible(c0, c1)) {
02633             ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
02634             manager_event(EVENT_FLAG_CALL, "Unlink", 
02635                "Channel1: %s\r\n"
02636                "Channel2: %s\r\n"
02637                "Uniqueid1: %s\r\n"
02638                "Uniqueid2: %s\r\n",
02639                c0->name, c1->name, c0->uniqueid, c1->uniqueid);
02640             return -1;
02641          }
02642          o0nativeformats = c0->nativeformats;
02643          o1nativeformats = c1->nativeformats;
02644       }
02645       who = ast_waitfor_n(cs, 2, &to);
02646       if (!who) {
02647          ast_log(LOG_DEBUG, "Nobody there, continuing...\n"); 
02648          continue;
02649       }
02650       f = ast_read(who);
02651       if (!f) {
02652          *fo = NULL;
02653          *rc = who;
02654          res = 0;
02655          ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
02656          break;
02657       }
02658 
02659       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
02660          *fo = f;
02661          *rc = who;
02662          res =  0;
02663          ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
02664          break;
02665       }
02666       if ((f->frametype == AST_FRAME_VOICE) ||
02667          (f->frametype == AST_FRAME_TEXT) ||
02668          (f->frametype == AST_FRAME_VIDEO) || 
02669          (f->frametype == AST_FRAME_IMAGE) ||
02670          (f->frametype == AST_FRAME_DTMF)) {
02671          if ((f->frametype == AST_FRAME_DTMF) && 
02672             (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
02673             if ((who == c0)) {
02674                if  ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) {
02675                   *rc = c0;
02676                   *fo = f;
02677                   /* Take out of conference mode */
02678                   res = 0;
02679                   ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_0 on c0 (%s)\n",c0->name);
02680                   break;
02681                } else 
02682                   goto tackygoto;
02683             } else
02684             if ((who == c1)) {
02685                if (flags & AST_BRIDGE_DTMF_CHANNEL_1) {
02686                   *rc = c1;
02687                   *fo = f;
02688                   res =  0;
02689                   ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_1 on c1 (%s)\n",c1->name);
02690                   break;
02691                } else
02692                   goto tackygoto;
02693             }
02694          } else {
02695 #if 0
02696             ast_log(LOG_DEBUG, "Read from %s\n", who->name);
02697             if (who == last) 
02698                ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name);
02699             last = who;
02700 #endif
02701 tackygoto:
02702             /* Don't copy packets if there is a generator on either one, since they're
02703                not supposed to be listening anyway */
02704             if (who == c0) 
02705                ast_write(c1, f);
02706             else 
02707                ast_write(c0, f);
02708          }
02709          ast_frfree(f);
02710       } else
02711          ast_frfree(f);
02712       /* Swap who gets priority */
02713       cs[2] = cs[0];
02714       cs[0] = cs[1];
02715       cs[1] = cs[2];
02716    }
02717    c0->bridge = NULL;
02718    c1->bridge = NULL;
02719    manager_event(EVENT_FLAG_CALL, "Unlink", 
02720                "Channel1: %s\r\n"
02721                "Channel2: %s\r\n"
02722                "Uniqueid1: %s\r\n"
02723                "Uniqueid2: %s\r\n",
02724                c0->name, c1->name, c0->uniqueid, c1->uniqueid);
02725    ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n",c0->name,c1->name);
02726    return res;
02727 }

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

References ast_channel::deferdtmf.

00442 {
00443    int pre = 0;
00444    if (chan) {
00445       pre = chan->deferdtmf;
00446       chan->deferdtmf = 1;
00447    }
00448    return pre;
00449 }

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

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

Referenced by ast_channel_bridge().

02103 {
02104    int peerf;
02105    int chanf;
02106    int res;
02107    ast_mutex_lock(&peer->lock);
02108    peerf = peer->nativeformats;
02109    ast_mutex_unlock(&peer->lock);
02110    ast_mutex_lock(&chan->lock);
02111    chanf = chan->nativeformats;
02112    ast_mutex_unlock(&chan->lock);
02113    res = ast_translator_best_choice(&peerf, &chanf);
02114    if (res < 0) {
02115       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, chan->nativeformats, peer->name, peer->nativeformats);
02116       return -1;
02117    }
02118    /* Set read format on channel */
02119    res = ast_set_read_format(chan, peerf);
02120    if (res < 0) {
02121       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, chanf);
02122       return -1;
02123    }
02124    /* Set write format on peer channel */
02125    res = ast_set_write_format(peer, peerf);
02126    if (res < 0) {
02127       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, peerf);
02128       return -1;
02129    }
02130    /* Now we go the other way */
02131    peerf = peer->nativeformats;
02132    chanf = chan->nativeformats;
02133    res = ast_translator_best_choice(&chanf, &peerf);
02134    if (res < 0) {
02135       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, peer->nativeformats, chan->name, chan->nativeformats);
02136       return -1;
02137    }
02138    /* Set writeformat on channel */
02139    res = ast_set_write_format(chan, chanf);
02140    if (res < 0) {
02141       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, chanf);
02142       return -1;
02143    }
02144    /* Set read format on peer channel */
02145    res = ast_set_read_format(peer, chanf);
02146    if (res < 0) {
02147       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, peerf);
02148       return -1;
02149    }
02150    return 0;
02151 }

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

References ast_log(), ast_mutex_lock, ast_mutex_trylock, ast_mutex_unlock, ast_queue_frame(), ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::masq, ast_channel::masqr, and ast_channel::name.

Referenced by ast_async_goto().

02154 {
02155    struct ast_frame null = { AST_FRAME_NULL, };
02156    int res = -1;
02157    ast_mutex_lock(&original->lock);
02158    while(ast_mutex_trylock(&clone->lock)) {
02159       ast_mutex_unlock(&original->lock);
02160       usleep(1);
02161       ast_mutex_lock(&original->lock);
02162    }
02163    ast_log(LOG_DEBUG, "Planning to masquerade %s into the structure of %s\n",
02164       clone->name, original->name);
02165    if (original->masq) {
02166       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
02167          original->masq->name, original->name);
02168    } else if (clone->masqr) {
02169       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
02170          clone->name, clone->masqr->name);
02171    } else {
02172       original->masq = clone;
02173       clone->masqr = original;
02174       ast_queue_frame(original, &null);
02175       ast_queue_frame(clone, &null);
02176       ast_log(LOG_DEBUG, "Done planning to masquerade %s into the structure of %s\n", original->name, clone->name);
02177       res = 0;
02178    }
02179    ast_mutex_unlock(&clone->lock);
02180    ast_mutex_unlock(&original->lock);
02181    return res;
02182 }

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

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

00158 {
00159    return ast_channel_register_ex(type, description, capabilities, requester, NULL);
00160 }

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

References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), backends, chanlist::capabilities, chanlist::description, description(), chanlist::devicestate, LOG_DEBUG, LOG_WARNING, malloc, chanlist::next, chanlist::requester, chanlist::type, type, and VERBOSE_PREFIX_2.

Referenced by ast_channel_register().

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

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

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

02089 {
02090    if (chan->pvt->send_html)
02091       return chan->pvt->send_html(chan, subclass, data, datalen);
02092    return -1;
02093 }

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

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

02096 {
02097    if (chan->pvt->send_html)
02098       return chan->pvt->send_html(chan, AST_HTML_URL, url, strlen(url) + 1);
02099    return -1;
02100 }

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

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

02730 {
02731    int res;
02732    if (chan->pvt->setoption) {
02733       res = chan->pvt->setoption(chan, option, data, datalen);
02734       if (res < 0)
02735          return res;
02736    } else {
02737       errno = ENOSYS;
02738       return -1;
02739    }
02740    if (block) {
02741       /* XXX Implement blocking -- just wait for our option frame reply, discarding
02742          intermediate packets. XXX */
02743       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
02744       return -1;
02745    }
02746    return 0;
02747 }

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

References ast_channel::whentohangup.

00145 {
00146    time_t   myt;
00147 
00148    time(&myt);
00149    if (offset)
00150       chan->whentohangup = myt + offset;
00151    else
00152       chan->whentohangup = 0;
00153    return;
00154 }

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

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

02082 {
02083    if (chan->pvt->send_html)
02084       return 1;
02085    return 0;
02086 }

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

References ast_channel::deferdtmf.

00452 {
00453    if (chan)
00454       chan->deferdtmf = 0;
00455 }

void ast_channel_unregister char *    type
 

Unregister a channel class.

Definition at line 756 of file channel.c.

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

00757 {
00758    struct chanlist *chan, *last=NULL;
00759    if (option_debug)
00760       ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", type);
00761    if (ast_mutex_lock(&chlock)) {
00762       ast_log(LOG_WARNING, "Unable to lock channel list\n");
00763       return;
00764    }
00765    if (option_verbose > 1)
00766       ast_verbose( VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", type);
00767 
00768    chan = backends;
00769    while(chan) {
00770       if (!strcasecmp(chan->type, type)) {
00771          if (last)
00772             last->next = chan->next;
00773          else
00774             backends = backends->next;
00775          free(chan);
00776          ast_mutex_unlock(&chlock);
00777          return;
00778       }
00779       last = chan;
00780       chan = chan->next;
00781    }
00782    ast_mutex_unlock(&chlock);
00783 }

struct ast_channel* ast_channel_walk_locked 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. If it returns a channel, that channel *has been locked*!

Definition at line 457 of file channel.c.

References ast_log(), ast_mutex_lock, ast_mutex_trylock, ast_mutex_unlock, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, and ast_channel::next.

Referenced by ast_async_goto_by_name(), ast_get_channel_by_name_locked(), and ast_parse_device_state().

00458 {
00459    /* Returns next channel (locked) */
00460    struct ast_channel *l, *ret;
00461    int retries = 0;  
00462 retry:
00463    ret=NULL;
00464    ast_mutex_lock(&chlock);
00465    l = channels;
00466    if (!prev) {
00467       if (l) {
00468          if (ast_mutex_trylock(&l->lock)) {
00469             if (retries < 10)
00470                ast_log(LOG_DEBUG, "Avoiding initial deadlock for '%s'\n", l->name);
00471             else
00472                ast_log(LOG_WARNING, "Avoided initial deadlock for '%s', %d retries!\n", l->name, retries);
00473             ast_mutex_unlock(&chlock);
00474             if (retries < 10) {
00475                usleep(1);
00476                retries++;
00477                goto retry;
00478             } else
00479                return NULL;
00480          }
00481       }
00482       ast_mutex_unlock(&chlock);
00483       return l;
00484    }
00485    while(l) {
00486       if (l == prev)
00487          ret = l->next;
00488       l = l->next;
00489    }
00490    if (ret) {
00491       if (ast_mutex_trylock(&ret->lock)) {
00492          if (retries < 10)
00493             ast_log(LOG_DEBUG, "Avoiding deadlock for '%s'\n", ret->name);
00494          else
00495             ast_log(LOG_WARNING, "Avoided deadlock for '%s', %d retries!\n", ret->name, retries);
00496          ast_mutex_unlock(&chlock);
00497          if (retries < 10) {
00498             usleep(1);
00499             retries++;
00500             goto retry;
00501          } else
00502             return NULL;
00503       }
00504    }
00505    ast_mutex_unlock(&chlock);
00506    return ret;
00507    
00508 }

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

00080 {
00081 time_t   myt;
00082 
00083      /* if soft hangup flag, return true */
00084    if (chan->_softhangup) return 1;
00085      /* if no private structure, return true */
00086    if (!chan->pvt->pvt) return 1;
00087      /* if no hangup scheduled, just return here */
00088    if (!chan->whentohangup) return 0;
00089    time(&myt); /* get current time */
00090      /* return, if not yet */
00091    if (chan->whentohangup > myt) return 0;
00092    chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
00093    return 1;
00094 }

void ast_deactivate_generator struct ast_channel   chan
 

Deactive an active generator

Definition at line 816 of file channel.c.

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

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

00817 {
00818    ast_mutex_lock(&chan->lock);
00819    if (chan->generatordata) {
00820       if (chan->generator && chan->generator->release) 
00821          chan->generator->release(chan, chan->generatordata);
00822       chan->generatordata = NULL;
00823       chan->generator = NULL;
00824       chan->writeinterrupt = 0;
00825       ast_settimeout(chan, 0, NULL, NULL);
00826    }
00827    ast_mutex_unlock(&chan->lock);
00828 }

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 1926 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, chanlist::devicestate, LOG_WARNING, chanlist::next, and chanlist::type.

01927 {
01928    char tech[AST_MAX_EXTENSION] = "";
01929    char *number;
01930    struct chanlist *chanls;
01931    int res = 0;
01932    
01933    strncpy(tech, device, sizeof(tech)-1);
01934    number = strchr(tech, '/');
01935    if (!number) {
01936        return AST_DEVICE_INVALID;
01937    }
01938    *number = 0;
01939    number++;
01940       
01941    if (ast_mutex_lock(&chlock)) {
01942       ast_log(LOG_WARNING, "Unable to lock channel list\n");
01943       return -1;
01944    }
01945    chanls = backends;
01946    while(chanls) {
01947       if (!strcasecmp(tech, chanls->type)) {
01948          ast_mutex_unlock(&chlock);
01949          if (!chanls->devicestate) 
01950             return ast_parse_device_state(device);
01951          else {
01952             res = chanls->devicestate(number);
01953             if (res == AST_DEVICE_UNKNOWN)
01954                return ast_parse_device_state(device);
01955             else
01956                return res;
01957          }
01958       }
01959       chanls = chanls->next;
01960    }
01961    ast_mutex_unlock(&chlock);
01962    return AST_DEVICE_INVALID;
01963 }

int ast_do_masquerade struct ast_channel   chan
 

Definition at line 2192 of file channel.c.

References ast_channel::_softhangup, ast_channel::_state, ast_channel::adsicpe, ast_channel_pvt::alertpipe, ast_channel_free(), ast_log(), AST_MAX_FDS, ast_mutex_lock, ast_mutex_unlock, ast_set_read_format(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_channel::blocker, ast_channel::blocking, ast_channel::callerid, ast_channel::dnid, EVENT_FLAG_CALL, ast_channel::exception, ast_channel::fdno, ast_channel::fds, ast_channel_pvt::fixup, ast_channel_pvt::hangup, ast_channel::lock, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::name, ast_channel::nativeformats, ast_frame::next, ast_channel::pvt, ast_channel::readformat, ast_channel_pvt::readq, ast_channel::timingfd, ast_channel::type, ast_channel::uniqueid, ast_channel::writeformat, and ast_channel::zombie.

Referenced by ast_async_goto(), ast_hangup(), ast_read(), ast_waitfor_nandfds(), and ast_write().

02193 {
02194    int x,i;
02195    int res=0;
02196    int origstate;
02197    char *tmp;
02198    struct ast_var_t *varptr;
02199    struct ast_frame *cur, *prev;
02200    struct ast_channel_pvt *p;
02201    struct ast_channel *clone = original->masq;
02202    int rformat = original->readformat;
02203    int wformat = original->writeformat;
02204    char newn[100];
02205    char orig[100];
02206    char masqn[100];
02207    char zombn[100];
02208    
02209 #if 1
02210    ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
02211       clone->name, clone->_state, original->name, original->_state);
02212 #endif
02213    /* XXX This is a seriously wacked out operation.  We're essentially putting the guts of
02214       the clone channel into the original channel.  Start by killing off the original
02215       channel's backend.   I'm not sure we're going to keep this function, because 
02216       while the features are nice, the cost is very high in terms of pure nastiness. XXX */
02217 
02218    /* We need the clone's lock, too */
02219    ast_mutex_lock(&clone->lock);
02220 
02221    ast_log(LOG_DEBUG, "Got clone lock on '%s' at %p\n", clone->name, &clone->lock);
02222 
02223    /* Having remembered the original read/write formats, we turn off any translation on either
02224       one */
02225    free_translation(clone);
02226    free_translation(original);
02227 
02228 
02229    /* Unlink the masquerade */
02230    original->masq = NULL;
02231    clone->masqr = NULL;
02232    
02233    /* Save the original name */
02234    strncpy(orig, original->name, sizeof(orig) - 1);
02235    /* Save the new name */
02236    strncpy(newn, clone->name, sizeof(newn) - 1);
02237    /* Create the masq name */
02238    snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
02239       
02240    /* Copy the name from the clone channel */
02241    strncpy(original->name, newn, sizeof(original->name)-1);
02242 
02243    /* Mangle the name of the clone channel */
02244    strncpy(clone->name, masqn, sizeof(clone->name) - 1);
02245    
02246    /* Notify any managers of the change, first the masq then the other */
02247    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid);
02248    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid);
02249 
02250    /* Swap the guts */  
02251    p = original->pvt;
02252    original->pvt = clone->pvt;
02253    clone->pvt = p;
02254 
02255    /* Save any pending frames on both sides.  Start by counting
02256     * how many we're going to need... */
02257    prev = NULL;
02258    cur = clone->pvt->readq;
02259    x = 0;
02260    while(cur) {
02261       x++;
02262       prev = cur;
02263       cur = cur->next;
02264    }
02265    /* If we had any, prepend them to the ones already in the queue, and 
02266     * load up the alertpipe */
02267    if (prev) {
02268       prev->next = original->pvt->readq;
02269       original->pvt->readq = clone->pvt->readq;
02270       clone->pvt->readq = NULL;
02271       if (original->pvt->alertpipe[1] > -1) {
02272          for (i=0;i<x;i++)
02273             write(original->pvt->alertpipe[1], &x, sizeof(x));
02274       }
02275    }
02276    clone->_softhangup = AST_SOFTHANGUP_DEV;
02277 
02278 
02279    /* And of course, so does our current state.  Note we need not
02280       call ast_setstate since the event manager doesn't really consider
02281       these separate.  We do this early so that the clone has the proper
02282       state of the original channel. */
02283    origstate = original->_state;
02284    original->_state = clone->_state;
02285    clone->_state = origstate;
02286 
02287    if (clone->pvt->fixup){
02288       res = clone->pvt->fixup(original, clone);
02289       if (res) 
02290          ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name);
02291    }
02292 
02293    /* Start by disconnecting the original's physical side */
02294    if (clone->pvt->hangup)
02295       res = clone->pvt->hangup(clone);
02296    if (res) {
02297       ast_log(LOG_WARNING, "Hangup failed!  Strange things may happen!\n");
02298       ast_mutex_unlock(&clone->lock);
02299       return -1;
02300    }
02301    
02302    snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
02303    /* Mangle the name of the clone channel */
02304    strncpy(clone->name, zombn, sizeof(clone->name) - 1);
02305    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid);
02306 
02307    /* Keep the same language.  */
02308    /* Update the type. */
02309    original->type = clone->type;
02310    /* Copy the FD's */
02311    for (x=0;x<AST_MAX_FDS;x++) {
02312       original->fds[x] = clone->fds[x];
02313    }
02314    /* Append variables from clone channel into original channel */
02315    /* XXX Is this always correct?  We have to in order to keep MACROS working XXX */
02316    varptr = original->varshead.first;
02317    if (varptr) {
02318       while(varptr->entries.next) {
02319          varptr = varptr->entries.next;
02320       }
02321       varptr->entries.next = clone->varshead.first;
02322    } else {
02323       original->varshead.first = clone->varshead.first;
02324    }
02325    clone->varshead.first = NULL;
02326    /* Presense of ADSI capable CPE follows clone */
02327    original->adsicpe = clone->adsicpe;
02328    /* Bridge remains the same */
02329    /* CDR fields remain the same */
02330    /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
02331    /* Application and data remain the same */
02332    /* Clone exception  becomes real one, as with fdno */
02333    original->exception = clone->exception;
02334    original->fdno = clone->fdno;
02335    /* Schedule context remains the same */
02336    /* Stream stuff stays the same */
02337    /* Keep the original state.  The fixup code will need to work with it most likely */
02338 
02339    /* dnid and callerid change to become the new, HOWEVER, we also link the original's
02340       fields back into the defunct 'clone' so that they will be freed when
02341       ast_frfree is eventually called */
02342    tmp = original->dnid;
02343    original->dnid = clone->dnid;
02344    clone->dnid = tmp;
02345    
02346    tmp = original->callerid;
02347    original->callerid = clone->callerid;
02348    clone->callerid = tmp;
02349    
02350    /* Restore original timing file descriptor */
02351    original->fds[AST_MAX_FDS - 2] = original->timingfd;
02352    
02353    /* Our native formats are different now */
02354    original->nativeformats = clone->nativeformats;
02355    
02356    /* Context, extension, priority, app data, jump table,  remain the same */
02357    /* pvt switches.  pbx stays the same, as does next */
02358    
02359    /* Set the write format */
02360    ast_set_write_format(original, wformat);
02361 
02362    /* Set the read format */
02363    ast_set_read_format(original, rformat);
02364 
02365    ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat);
02366 
02367    /* Okay.  Last thing is to let the channel driver know about all this mess, so he
02368       can fix up everything as best as possible */
02369    if (original->pvt->fixup) {
02370       res = original->pvt->fixup(clone, original);
02371       if (res) {
02372          ast_log(LOG_WARNING, "Driver for '%s' could not fixup channel %s\n",
02373             original->type, original->name);
02374          ast_mutex_unlock(&clone->lock);
02375          return -1;
02376       }
02377    } else
02378       ast_log(LOG_WARNING, "Driver '%s' does not have a fixup routine (for %s)!  Bad things may happen.\n",
02379          original->type, original->name);
02380    
02381    /* Now, at this point, the "clone" channel is totally F'd up.  We mark it as
02382       a zombie so nothing tries to touch it.  If it's already been marked as a
02383       zombie, then free it now (since it already is considered invalid). */
02384    if (clone->zombie) {
02385       ast_log(LOG_DEBUG, "Destroying clone '%s'\n", clone->name);
02386       ast_mutex_unlock(&clone->lock);
02387       ast_channel_free(clone);
02388       manager_event(EVENT_FLAG_CALL, "Hangup", "Channel: %s\r\n", zombn);
02389    } else {
02390       ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
02391       clone->zombie=1;
02392       ast_mutex_unlock(&clone->lock);
02393    }
02394    
02395    /* Signal any blocker */
02396    if (original->blocking)
02397       pthread_kill(original->blocker, SIGURG);
02398    ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n",
02399       original->name, original->_state);
02400    return 0;
02401 }

struct ast_channel* ast_get_channel_by_name_locked char *    channame
 

Get channel by name (locks channel).

Definition at line 510 of file channel.c.

References ast_channel_walk_locked(), ast_mutex_unlock, ast_channel::lock, and ast_channel::name.

00511 {
00512    struct ast_channel *chan;
00513    chan = ast_channel_walk_locked(NULL);
00514    while(chan) {
00515       if (!strcasecmp(chan->name, channame))
00516          return chan;
00517       ast_mutex_unlock(&chan->lock);
00518       chan = ast_channel_walk_locked(chan);
00519    }
00520    return NULL;
00521 }

unsigned int ast_get_group char *    s
 

Definition at line 2881 of file channel.c.

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

02882 {
02883    char *copy;
02884    char *piece;
02885    char *c=NULL;
02886    int start=0, finish=0,x;
02887    unsigned int group = 0;
02888    copy = ast_strdupa(s);
02889    if (!copy) {
02890       ast_log(LOG_ERROR, "Out of memory\n");
02891       return 0;
02892    }
02893    c = copy;
02894    
02895    while((piece = strsep(&c, ","))) {
02896       if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
02897          /* Range */
02898       } else if (sscanf(piece, "%d", &start)) {
02899          /* Just one */
02900          finish = start;
02901       } else {
02902          ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'.  Using '0'\n", s,piece);
02903          return 0;
02904       }
02905       for (x=start;x<=finish;x++) {
02906          if ((x > 31) || (x < 0)) {
02907             ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 31)\n", x);
02908          } else
02909             group |= (1 << x);
02910       }
02911    }
02912    return group;
02913 }

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

References ast_cdr_end(), ast_cdr_free(), ast_cdr_post(), ast_channel_free(), ast_closestream(), ast_do_masquerade(), ast_log(), ast_mutex_lock, ast_mutex_unlock, 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::hangupcause, ast_channel::lock, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::name, ast_channel::pvt, ast_generator::release, ast_channel::sched, sched_context_destroy(), ast_channel::stream, ast_channel::uniqueid, ast_channel::vstream, and ast_channel::zombie.

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

00690 {
00691    int res = 0;
00692    /* Don't actually hang up a channel that will masquerade as someone else, or
00693       if someone is going to masquerade as us */
00694    ast_mutex_lock(&chan->lock);
00695    if (chan->masq) {
00696       if (ast_do_masquerade(chan)) 
00697          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
00698    }
00699 
00700    if (chan->masq) {
00701       ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
00702       ast_mutex_unlock(&chan->lock);
00703       return 0;
00704    }
00705    /* If this channel is one which will be masqueraded into something, 
00706       mark it as a zombie already, so we know to free it later */
00707    if (chan->masqr) {
00708       chan->zombie=1;
00709       ast_mutex_unlock(&chan->lock);
00710       return 0;
00711    }
00712    free_translation(chan);
00713    if (chan->stream) 
00714       ast_closestream(chan->stream);
00715    if (chan->vstream)
00716       ast_closestream(chan->vstream);
00717    if (chan->sched)
00718       sched_context_destroy(chan->sched);
00719    /* Clear any tone stuff remaining */
00720    if (chan->generatordata)
00721       chan->generator->release(chan, chan->generatordata);
00722    chan->generatordata = NULL;
00723    chan->generator = NULL;
00724    if (chan->cdr) {
00725       /* End the CDR if it hasn't already */
00726       ast_cdr_end(chan->cdr);
00727       /* Post and Free the CDR */
00728       ast_cdr_post(chan->cdr);
00729       ast_cdr_free(chan->cdr);
00730    }
00731    if (chan->blocking) {
00732       ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
00733                "is blocked by thread %ld in procedure %s!  Expect a failure\n",
00734                (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
00735       CRASH;
00736    }
00737    if (!chan->zombie) {
00738       if (option_debug)
00739          ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
00740       if (chan->pvt->hangup)
00741          res = chan->pvt->hangup(chan);
00742    } else
00743       if (option_debug)
00744          ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name);
00745          
00746    ast_mutex_unlock(&chan->lock);
00747    manager_event(EVENT_FLAG_CALL, "Hangup", 
00748          "Channel: %s\r\n"
00749          "Uniqueid: %s\r\n"
00750          "Cause: %i\r\n",
00751          chan->name, chan->uniqueid, chan->hangupcause);
00752    ast_channel_free(chan);
00753    return res;
00754 }

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

References ast_check_hangup(), ast_get_indication_tone(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_playtones_start(), ast_playtones_stop(), tone_zone_sound::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.

01408 {
01409    int res = -1;
01410    /* Stop if we're a zombie or need a soft hangup */
01411    if (chan->zombie || ast_check_hangup(chan)) 
01412       return -1;
01413    ast_mutex_lock(&chan->lock);
01414    if (chan->pvt->indicate)
01415       res = chan->pvt->indicate(chan, condition);
01416    ast_mutex_unlock(&chan->lock);
01417    if (!chan->pvt->indicate || res) {
01418       /*
01419        * Device does not support (that) indication, lets fake
01420        * it by doing our own tone generation. (PM2002)
01421        */
01422       if (condition >= 0) {
01423          const struct tone_zone_sound *ts = NULL;
01424          switch (condition) {
01425           case AST_CONTROL_RINGING:
01426             ts = ast_get_indication_tone(chan->zone, "ring");
01427             break;
01428           case AST_CONTROL_BUSY:
01429             ts = ast_get_indication_tone(chan->zone, "busy");
01430             break;
01431           case AST_CONTROL_CONGESTION:
01432             ts = ast_get_indication_tone(chan->zone, "congestion");
01433             break;
01434          }
01435          if (ts && ts->data[0]) {
01436             ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
01437             ast_playtones_start(chan,0,ts->data, 1);
01438             res = 0;
01439          } else if (condition == AST_CONTROL_PROGRESS) {
01440             /* ast_playtones_stop(chan); */
01441          } else if (condition == AST_CONTROL_PROCEEDING) {
01442             /* Do nothing, really */
01443          } else {
01444             /* not handled */
01445             ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
01446             res = -1;
01447          }
01448       }
01449       else ast_playtones_stop(chan);
01450    }
01451    return res;
01452 }

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

References AST_CHANNEL_NAME, ast_channel_walk_locked(), AST_DEVICE_INUSE, AST_DEVICE_UNKNOWN, ast_mutex_unlock, ast_channel::lock, and ast_channel::name.

Referenced by ast_device_state().

01907 {
01908    char name[AST_CHANNEL_NAME] = "";
01909    char *cut;
01910    struct ast_channel *chan;
01911 
01912    chan = ast_channel_walk_locked(NULL);
01913    while (chan) {
01914       strncpy(name, chan->name, sizeof(name)-1);
01915       ast_mutex_unlock(&chan->lock);
01916       cut = strchr(name,'-');
01917       if (cut)
01918               *cut = 0;
01919       if (!strcmp(name, device))
01920               return AST_DEVICE_INUSE;
01921       chan = ast_channel_walk_locked(chan);
01922    }
01923    return AST_DEVICE_UNKNOWN;
01924 }

int ast_prod struct ast_channel   chan
 

Definition at line 1545 of file channel.c.

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

01546 {
01547    struct ast_frame a = { AST_FRAME_VOICE };
01548    char nothing[128];
01549    /* Send an empty audio frame to get things moving */
01550    if (chan->_state != AST_STATE_UP) {
01551       ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
01552       a.subclass = chan->pvt->rawwriteformat;
01553       a.data = nothing + AST_FRIENDLY_OFFSET;
01554       if (ast_write(chan, &a))
01555          ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
01556    }
01557    return 0;
01558 }

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

References ast_cdr_answer(), ast_cdr_end(), ast_check_hangup(), ast_deactivate_generator(), ast_do_masquerade(), ast_frame_dump(), ast_frfree(), ast_getformatname(), ast_log(), AST_MAX_FDS, ast_mutex_lock, ast_mutex_unlock, ast_seekstream(), ast_setstate(), ast_settimeout(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_translate(), ast_writestream(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, ast_generator::generate, ast_channel::generator, ast_channel::generatordata, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_frame::next, ast_frame::samples, SEEK_FORCECUR, ast_frame::subclass, and ast_channel::timingfunc.

Referenced by __ast_request_and_dial(), ast_app_getvoice(), ast_channel_bridge(), ast_play_and_prepend(), ast_play_and_record(), 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().

01190 {
01191    struct ast_frame *f = NULL;
01192    int blah;
01193 #ifdef ZAPTEL_OPTIMIZATIONS
01194    int (*func)(void *);
01195    void *data;
01196    int res;
01197 #endif
01198    static struct ast_frame null_frame = 
01199    {
01200       AST_FRAME_NULL,
01201    };
01202    
01203    ast_mutex_lock(&chan->lock);
01204    if (chan->masq) {
01205       if (ast_do_masquerade(chan)) {
01206          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01207          f = NULL;
01208       } else
01209          f =  &null_frame;
01210       ast_mutex_unlock(&chan->lock);
01211       return f;
01212    }
01213 
01214    /* Stop if we're a zombie or need a soft hangup */
01215    if (chan->zombie || ast_check_hangup(chan)) {
01216       if (chan->generator)
01217          ast_deactivate_generator(chan);
01218       ast_mutex_unlock(&chan->lock);
01219       return NULL;
01220    }
01221 
01222    if (!chan->deferdtmf && !ast_strlen_zero(chan->dtmfq)) {
01223       /* We have DTMF that has been deferred.  Return it now */
01224       chan->dtmff.frametype = AST_FRAME_DTMF;
01225       chan->dtmff.subclass = chan->dtmfq[0];
01226       /* Drop first digit */
01227       memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1);
01228       ast_mutex_unlock(&chan->lock);
01229       return &chan->dtmff;
01230    }
01231    
01232    /* Read and ignore anything on the alertpipe, but read only
01233       one sizeof(blah) per frame that we send from it */
01234    if (chan->pvt->alertpipe[0] > -1) {
01235       read(chan->pvt->alertpipe[0], &blah, sizeof(blah));
01236    }
01237 #ifdef ZAPTEL_OPTIMIZATIONS
01238    if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && chan->exception) {
01239       chan->exception = 0;
01240       blah = -1;
01241       /* IF we can't get event, assume it's an expired as-per the old interface */
01242       res = ioctl(chan->timingfd, ZT_GETEVENT, &blah);
01243       if (res) 
01244          blah = ZT_EVENT_TIMER_EXPIRED;
01245 
01246       if (blah == ZT_EVENT_TIMER_PING) {
01247 #if 0
01248          ast_log(LOG_NOTICE, "Oooh, there's a PING!\n");
01249 #endif         
01250          if (!chan->pvt->readq || !chan->pvt->readq->next) {
01251             /* Acknowledge PONG unless we need it again */
01252 #if 0
01253             ast_log(LOG_NOTICE, "Sending a PONG!\n");
01254 #endif            
01255             if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) {
01256                ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno));
01257             }
01258          }
01259       } else if (blah == ZT_EVENT_TIMER_EXPIRED) {
01260          ioctl(chan->timingfd, ZT_TIMERACK, &blah);
01261          func = chan->timingfunc;
01262          data = chan->timingdata;
01263          ast_mutex_unlock(&chan->lock);
01264          if (func) {
01265 #if 0
01266             ast_log(LOG_DEBUG, "Calling private function\n");
01267 #endif         
01268             func(data);
01269          } else {
01270             blah = 0;
01271             ast_mutex_lock(&chan->lock);
01272             ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
01273             chan->timingdata = NULL;
01274             ast_mutex_unlock(&chan->lock);
01275          }
01276          f =  &null_frame;
01277          return f;
01278       } else
01279          ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name);
01280    }
01281 #endif
01282    /* Check for pending read queue */
01283    if (chan->pvt->readq) {
01284       f = chan->pvt->readq;
01285       chan->pvt->readq = f->next;
01286       /* Interpret hangup and return NULL */
01287       if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
01288          ast_frfree(f);
01289          f = NULL;
01290       }
01291    } else {
01292       chan->blocker = pthread_self();
01293       if (chan->exception) {
01294          if (chan->pvt->exception) 
01295             f = chan->pvt->exception(chan);
01296          else {
01297             ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
01298             f = &null_frame;
01299          }
01300          /* Clear the exception flag */
01301          chan->exception = 0;
01302       } else
01303       if (chan->pvt->read)
01304          f = chan->pvt->read(chan);
01305       else
01306          ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
01307    }
01308 
01309 
01310    if (f && (f->frametype == AST_FRAME_VOICE)) {
01311       if (!(f->subclass & chan->nativeformats)) {
01312          /* This frame can't be from the current native formats -- drop it on the
01313             floor */
01314          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));
01315          ast_frfree(f);
01316          f = &null_frame;
01317       } else {
01318          if (chan->monitor && chan->monitor->read_stream ) {
01319 #ifndef MONITOR_CONSTANT_DELAY
01320             int jump = chan->outsmpl - chan->insmpl - 2 * f->samples;
01321             if (jump >= 0) {
01322                if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1)
01323                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
01324                chan->insmpl += jump + 2 * f->samples;
01325             } else
01326                chan->insmpl+= f->samples;
01327 #else
01328             int jump = chan->outsmpl - chan->insmpl;
01329             if (jump - MONITOR_DELAY >= 0) {
01330                if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
01331                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
01332                chan->insmpl += jump;
01333             } else
01334                chan->insmpl += f->samples;
01335 #endif
01336             if (ast_writestream(chan->monitor->read_stream, f) < 0)
01337                ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
01338          }
01339          if (chan->pvt->readtrans) {
01340             f = ast_translate(chan->pvt->readtrans, f, 1);
01341             if (!f)
01342                f = &null_frame;
01343          }
01344       }
01345    }
01346 
01347    /* Make sure we always return NULL in the future */
01348    if (!f) {
01349       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01350       if (chan->generator)
01351          ast_deactivate_generator(chan);
01352       /* End the CDR if appropriate */
01353       if (chan->cdr)
01354          ast_cdr_end(chan->cdr);
01355    } else if (chan->deferdtmf && f->frametype == AST_FRAME_DTMF) {
01356       if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
01357          chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
01358       else
01359          ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
01360       f = &null_frame;
01361    } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) {
01362       if (chan->_state == AST_STATE_UP) {
01363          ast_log(LOG_DEBUG, "Dropping duplicate answer!\n");
01364          f = &null_frame;
01365       }
01366       /* Answer the CDR */
01367       ast_setstate(chan, AST_STATE_UP);
01368       ast_cdr_answer(chan->cdr);
01369    } 
01370 
01371    /* Run any generator sitting on the line */
01372    if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) {
01373       /* Mask generator data temporarily and apply.  If there is a timing function, it
01374          will be calling the generator instead */
01375       void *tmp;
01376       int res;
01377       int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
01378       if (chan->timingfunc) {
01379          ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n");
01380          ast_settimeout(chan, 0, NULL, NULL);
01381       }
01382       tmp = chan->generatordata;
01383       chan->generatordata = NULL;
01384       generate = chan->generator->generate;
01385       res = generate(chan, tmp, f->datalen, f->samples);
01386       chan->generatordata = tmp;
01387       if (res) {
01388          ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
01389          ast_deactivate_generator(chan);
01390       }
01391    } else if (f && (f->frametype == AST_FRAME_CNG)) {
01392       if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
01393          ast_log(LOG_DEBUG, "Generator got CNG, switching to zap timed mode\n");
01394          ast_settimeout(chan, 160, generator_force, chan);
01395       }
01396    }
01397    if (chan->fin & 0x80000000)
01398       ast_frame_dump(chan->name, f, "<<");
01399    if ((chan->fin & 0x7fffffff) == 0x7fffffff)
01400       chan->fin &= 0x80000000;
01401    else
01402       chan->fin++;
01403    ast_mutex_unlock(&chan->lock);
01404    return f;
01405 }

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

02001 {
02002    int pos=0;
02003    int to = ftimeout;
02004    char d;
02005    /* XXX Merge with full version? XXX */
02006    /* Stop if we're a zombie or need a soft hangup */
02007    if (c->zombie || ast_check_hangup(c)) 
02008       return -1;
02009    if (!len)
02010       return -1;
02011    do {
02012       if (c->stream) {
02013          d = ast_waitstream(c, AST_DIGIT_ANY);
02014          ast_stopstream(c);
02015          usleep(1000);
02016          if (!d)
02017             d = ast_waitfordigit(c, to);
02018       } else {
02019          d = ast_waitfordigit(c, to);
02020       }
02021       if (d < 0)
02022          return -1;
02023       if (d == 0) {
02024          s[pos]='\0';
02025          return 1;
02026       }
02027       if (!strchr(enders, d))
02028          s[pos++] = d;
02029       if (strchr(enders, d) || (pos >= len)) {
02030          s[pos]='\0';
02031          return 0;
02032       }
02033       to = timeout;
02034    } while(1);
02035    /* Never reached */
02036    return 0;
02037 }

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

02040 {
02041    int pos=0;
02042    int to = ftimeout;
02043    char d;
02044    /* Stop if we're a zombie or need a soft hangup */
02045    if (c->zombie || ast_check_hangup(c)) 
02046       return -1;
02047    if (!len)
02048       return -1;
02049    do {
02050       if (c->stream) {
02051          d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
02052          ast_stopstream(c);
02053          usleep(1000);
02054          if (!d)
02055             d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
02056       } else {
02057          d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
02058       }
02059       if (d < 0)
02060          return -1;
02061       if (d == 0) {
02062          s[pos]='\0';
02063          return 1;
02064       }
02065       if (d == 1) {
02066          s[pos]='\0';
02067          return 2;
02068       }
02069       if (!strchr(enders, d))
02070          s[pos++] = d;
02071       if (strchr(enders, d) || (pos >= len)) {
02072          s[pos]='\0';
02073          return 0;
02074       }
02075       to = timeout;
02076    } while(1);
02077    /* Never reached */
02078    return 0;
02079 }

int ast_recvchar struct ast_channel   chan,
int    timeout
 

Definition at line 1454 of file channel.c.

References ast_check_hangup(), ast_frfree(), ast_read(), ast_waitfor(), ast_frame::data, ast_frame::frametype, ast_frame::subclass, and timeout.

01455 {
01456    int res,ourto,c;
01457    struct ast_frame *f;
01458    
01459    ourto = timeout;
01460    for(;;)
01461       {
01462       if (ast_check_hangup(chan)) return -1;
01463       res = ast_waitfor(chan,ourto);
01464       if (res <= 0) /* if timeout */
01465          {
01466          return 0;
01467          }
01468       ourto = res;
01469       f = ast_read(chan);
01470       if (f == NULL) return -1; /* if hangup */
01471       if ((f->frametype == AST_FRAME_CONTROL) &&
01472           (f->subclass == AST_CONTROL_HANGUP)) return -1; /* if hangup */
01473       if (f->frametype == AST_FRAME_TEXT)  /* if a text frame */
01474          {
01475          c = *((char *)f->data);  /* get the data */
01476          ast_frfree(f);
01477          return(c);
01478          }
01479       ast_frfree(f);
01480    }
01481 }

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 1861 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, chanlist::capabilities, EVENT_FLAG_CALL, LOG_WARNING, manager_event(), ast_channel::name, chanlist::next, chanlist::requester, chanlist::type, and ast_channel::uniqueid.

Referenced by __ast_request_and_dial().

01862 {
01863    struct chanlist *chan;
01864    struct ast_channel *c = NULL;
01865    int capabilities;
01866    int fmt;
01867    int res;
01868    if (ast_mutex_lock(&chlock)) {
01869       ast_log(LOG_WARNING, "Unable to lock channel list\n");
01870       return NULL;
01871    }
01872    chan = backends;
01873    while(chan) {
01874       if (!strcasecmp(type, chan->type)) {
01875          capabilities = chan->capabilities;
01876          fmt = format;
01877          res = ast_translator_best_choice(&fmt, &capabilities);
01878          if (res < 0) {
01879             ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->capabilities, format);
01880             ast_mutex_unlock(&chlock);
01881             return NULL;
01882          }
01883          ast_mutex_unlock(&chlock);
01884          if (chan->requester)
01885             c = chan->requester(type, capabilities, data);
01886          if (c) {
01887             if (c->_state == AST_STATE_DOWN) {
01888                manager_event(EVENT_FLAG_CALL, "Newchannel",
01889                "Channel: %s\r\n"
01890                "State: %s\r\n"
01891                "Callerid: %s\r\n"
01892                "Uniqueid: %s\r\n",
01893                c->name, ast_state2str(c->_state), c->callerid ? c->callerid : "<unknown>", c->uniqueid);
01894             }
01895          }
01896          return c;
01897       }
01898       chan = chan->next;
01899    }
01900    if (!chan)
01901       ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
01902    ast_mutex_unlock(&chlock);
01903    return c;
01904 }

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

References __ast_request_and_dial().

Referenced by ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().

01857 {
01858    return __ast_request_and_dial(type, format, data, timeout, outstate, callerid, NULL);
01859 }

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

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

Referenced by ast_dtmf_stream().

00545 {
00546    struct ast_frame *f;
00547    while(ms > 0) {
00548       ms = ast_waitfor(chan, ms);
00549       if (ms <0)
00550          return -1;
00551       if (ms > 0) {
00552          f = ast_read(chan);
00553          if (!f)
00554             return -1;
00555          ast_frfree(f);
00556       }
00557    }
00558    return 0;
00559 }

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

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

00525 {
00526    struct ast_frame *f;
00527 
00528    while(ms > 0) {
00529       if( cond && ((*cond)(data) == 0 ) )
00530          return 0;
00531       ms = ast_waitfor(chan, ms);
00532       if (ms <0)
00533          return -1;
00534       if (ms > 0) {
00535          f = ast_read(chan);
00536          if (!f)
00537             return -1;
00538          ast_frfree(f);
00539       }
00540    }
00541    return 0;
00542 }

int ast_senddigit struct ast_channel   chan,
char    digit
 

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

01541 {
01542    return do_senddigit(chan, digit);
01543 }

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

01484 {
01485    int res = 0;
01486    /* Stop if we're a zombie or need a soft hangup */
01487    if (chan->zombie || ast_check_hangup(chan)) 
01488       return -1;
01489    CHECK_BLOCKING(chan);
01490    if (chan->pvt->send_text)
01491       res = chan->pvt->send_text(chan, text);
01492    chan->blocking = 0;
01493    return res;
01494 }

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

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

02404 {
02405    if (chan->callerid)
02406       free(chan->callerid);
02407    if (anitoo && chan->ani)
02408       free(chan->ani);
02409    if (callerid) {
02410       chan->callerid = strdup(callerid);
02411       if (anitoo)
02412          chan->ani = strdup(callerid);
02413    } else {
02414       chan->callerid = NULL;
02415       if (anitoo)
02416          chan->ani = NULL;
02417    }
02418    if (chan->cdr)
02419       ast_cdr_setcid(chan->cdr, chan);
02420    manager_event(EVENT_FLAG_CALL, "Newcallerid", 
02421             "Channel: %s\r\n"
02422             "Callerid: %s\r\n"
02423             "Uniqueid: %s\r\n",
02424             chan->name, chan->callerid ? 
02425             chan->callerid : "<Unknown>",
02426             chan->uniqueid);
02427 }

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

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

Referenced by ast_app_getvoice(), ast_channel_make_compatible(), ast_do_masquerade(), ast_play_and_prepend(), and ast_play_and_record().

01713 {
01714    int fmt;
01715    int native;
01716    int res;
01717    
01718    ast_mutex_lock(&chan->lock);
01719    native = chan->nativeformats;
01720    fmt = fmts;
01721    /* Find a translation path from the native read format to one of the user's read formats */
01722    res = ast_translator_best_choice(&fmt, &native);
01723    if (res < 0) {
01724       ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n",
01725          ast_getformatname(chan->nativeformats), ast_getformatname(fmts));
01726       ast_mutex_unlock(&chan->lock);
01727       return -1;
01728    }
01729    
01730    /* Now we have a good choice for both.  We'll write using our native format. */
01731    chan->pvt->rawreadformat = native;
01732    /* User perspective is fmt */
01733    chan->readformat = fmt;
01734    /* Free any read translation we have right now */
01735    if (chan->pvt->readtrans)
01736       ast_translator_free_path(chan->pvt->readtrans);
01737    /* Build a translation path from the raw read format to the user reading format */
01738    chan->pvt->readtrans = ast_translator_build_path(chan->readformat, chan->pvt->rawreadformat);
01739    if (option_debug)
01740       ast_log(LOG_DEBUG, "Set channel %s to read format %s\n", 
01741          chan->name, ast_getformatname(chan->readformat));
01742    ast_mutex_unlock(&chan->lock);
01743    return 0;
01744 }

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

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

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

01680 {
01681    int fmt;
01682    int native;
01683    int res;
01684    
01685    ast_mutex_lock(&chan->lock);
01686    native = chan->nativeformats;
01687    fmt = fmts;
01688    
01689    res = ast_translator_best_choice(&native, &fmt);
01690    if (res < 0) {
01691       ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n",
01692          ast_getformatname(fmts), ast_getformatname(chan->nativeformats));
01693       ast_mutex_unlock(&chan->lock);
01694       return -1;
01695    }
01696    
01697    /* Now we have a good choice for both.  We'll write using our native format. */
01698    chan->pvt->rawwriteformat = native;
01699    /* User perspective is fmt */
01700    chan->writeformat = fmt;
01701    /* Free any write translation we have right now */
01702    if (chan->pvt->writetrans)
01703       ast_translator_free_path(chan->pvt->writetrans);
01704    /* Build a translation path from the user write format to the raw writing format */
01705    chan->pvt->writetrans = ast_translator_build_path(chan->pvt->rawwriteformat, chan->writeformat);
01706    if (option_debug)
01707       ast_log(LOG_DEBUG, "Set channel %s to write format %s\n", chan->name, ast_getformatname(chan->writeformat));
01708    ast_mutex_unlock(&chan->lock);
01709    return 0;
01710 }

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

Definition at line 1119 of file channel.c.

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

Referenced by ast_activate_generator(), ast_closestream(), ast_deactivate_generator(), and ast_read().

01120 {
01121    int res = -1;
01122 #ifdef ZAPTEL_OPTIMIZATIONS
01123    if (c->timingfd > -1) {
01124       if (!func) {
01125          samples = 0;
01126          data = 0;
01127       }
01128       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01129       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01130       c->timingfunc = func;
01131       c->timingdata = data;
01132    }
01133 #endif   
01134    return res;
01135 }

int ast_shutting_down void   
 

Returns non-zero if Asterisk is being shut down

Definition at line 139 of file channel.c.

00140 {
00141    return shutting_down;
00142 }

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

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

Referenced by ast_begin_shutdown().

00669 {
00670    int res;
00671    ast_mutex_lock(&chan->lock);
00672    res = ast_softhangup_nolock(chan, cause);
00673    ast_mutex_unlock(&chan->lock);
00674    return res;
00675 }

int ast_softhangup_nolock struct ast_channel   chan,
int    cause
 

Definition at line 653 of file channel.c.

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

Referenced by ast_async_goto(), and ast_softhangup().

00654 {
00655    int res = 0;
00656    struct ast_frame f = { AST_FRAME_NULL };
00657    if (option_debug)
00658       ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
00659    /* Inform channel driver that we need to be hung up, if it cares */
00660    chan->_softhangup |= cause;
00661    ast_queue_frame(chan, &f);
00662    /* Interrupt any poll call or such */
00663    if (chan->blocking)
00664       pthread_kill(chan->blocker, SIGURG);
00665    return res;
00666 }

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

00206 {
00207    /* XXX Not reentrant XXX */
00208    static char localtmp[256];
00209    switch(state) {
00210    case AST_STATE_DOWN:
00211       return "Down";
00212    case AST_STATE_RESERVED:
00213       return "Rsrvd";
00214    case AST_STATE_OFFHOOK:
00215       return "OffHook";
00216    case AST_STATE_DIALING:
00217       return "Dialing";
00218    case AST_STATE_RING:
00219       return "Ring";
00220    case AST_STATE_RINGING:
00221       return "Ringing";
00222    case AST_STATE_UP:
00223       return "Up";
00224    case AST_STATE_BUSY:
00225       return "Busy";
00226    default:
00227       snprintf(localtmp, sizeof(localtmp), "Unknown (%d)\n", state);
00228       return localtmp;
00229    }
00230 }

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

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

02864 {
02865    struct ast_frame *f;
02866    int res;
02867    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
02868       return res;
02869 
02870    /* Give us some wiggle room */
02871    while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) {
02872       f = ast_read(chan);
02873       if (f)
02874          ast_frfree(f);
02875       else
02876          return -1;
02877    }
02878    return 0;
02879 }

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

Start a tone going

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

02844 {
02845    struct tonepair_def d = { 0, };
02846    d.freq1 = freq1;
02847    d.freq2 = freq2;
02848    d.duration = duration;
02849    if (vol < 1)
02850       d.vol = 8192;
02851    else
02852       d.vol = vol;
02853    if (ast_activate_generator(chan, &tonepair, &d))
02854       return -1;
02855    return 0;
02856 }

void ast_tonepair_stop struct ast_channel   chan
 

Stop a tone from playing

Definition at line 2858 of file channel.c.

References ast_deactivate_generator().

02859 {
02860    ast_deactivate_generator(chan);
02861 }

int ast_transfer struct ast_channel   chan,
char *    dest
 

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

01981 {
01982    /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 
01983       If the remote end does not answer within the timeout, then do NOT hang up, but 
01984       return anyway.  */
01985    int res = -1;
01986    /* Stop if we're a zombie or need a soft hangup */
01987    ast_mutex_lock(&chan->lock);
01988    if (!chan->zombie && !ast_check_hangup(chan)) {
01989       if (chan->pvt->transfer) {
01990          res = chan->pvt->transfer(chan, dest);
01991          if (!res)
01992             res = 1;
01993       } else
01994          res = 0;
01995    }
01996    ast_mutex_unlock(&chan->lock);
01997    return res;
01998 }

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

References ast_waitfor_n().

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

01079 {
01080    struct ast_channel *chan;
01081    int oldms = ms;
01082    chan = ast_waitfor_n(&c, 1, &ms);
01083    if (ms < 0) {
01084       if (oldms < 0)
01085          return 0;
01086       else
01087          return -1;
01088    }
01089    return ms;
01090 }

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

References ast_waitfor_nandfds().

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

01074 {
01075    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
01076 }

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

References ast_log(), pollfd::events, pollfd::fd, LOG_WARNING, poll(), POLLIN, and POLLPRI.

00870 {
00871    /* Wait for x amount of time on a file descriptor to have input.  */
00872    struct timeval start, now;
00873    int res;
00874    int x, y;
00875    int winner = -1;
00876    int spoint;
00877    struct pollfd *pfds;
00878    
00879    pfds = alloca(sizeof(struct pollfd) * n);
00880    if (!pfds) {
00881       ast_log(LOG_WARNING, "alloca failed!  bad things will happen.\n");
00882       return -1;
00883    }
00884    if (*ms > 0)
00885       gettimeofday(&start, NULL);
00886    y = 0;
00887    for (x=0;x<n;x++) {
00888       if (fds[x] > -1) {
00889          pfds[y].fd = fds[x];
00890          pfds[y].events = POLLIN | POLLPRI;
00891          y++;
00892       }
00893    }
00894    res = poll(pfds, y, *ms);
00895    if (res < 0) {
00896       /* Simulate a timeout if we were interrupted */
00897       if (errno != EINTR)
00898          *ms = -1;
00899       else
00900          *ms = 0;
00901       return -1;
00902    }
00903    spoint = 0;
00904    for (x=0;x<n;x++) {
00905       if (fds[x] > -1) {
00906          if ((res = ast_fdisset(pfds, fds[x], y, &spoint))) {
00907             winner = fds[x];
00908             if (exception) {
00909                if (res & POLLPRI)
00910                   *exception = -1;
00911                else
00912                   *exception = 0;
00913             }
00914          }
00915       }
00916    }
00917    if (*ms > 0) {
00918       long passed;
00919       gettimeofday(&now, NULL);
00920       passed = (now.tv_sec - start.tv_sec) * 1000;
00921       passed += (now.tv_usec - start.tv_usec) / 1000;
00922       if (passed <= *ms)
00923          *ms -= passed;
00924       else
00925          *ms = 0;
00926    }
00927    return winner;
00928 }

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

References ast_channel::_softhangup, ast_do_masquerade(), ast_log(), AST_MAX_FDS, ast_mutex_lock, ast_mutex_unlock, AST_SOFTHANGUP_TIMEOUT, ast_channel::blocking, CHECK_BLOCKING, pollfd::events, ast_channel::exception, pollfd::fd, ast_channel::fdno, ast_channel::fds, ast_channel::lock, LOG_WARNING, ast_channel::masq, poll(), POLLIN, POLLPRI, and ast_channel::whentohangup.

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

00932 {
00933    /* Wait for x amount of time on a file descriptor to have input.  */
00934    struct timeval start, end;
00935    struct pollfd *pfds;
00936    int res;
00937    long rms;
00938    int x, y, max;
00939    int spoint;
00940    time_t now = 0;
00941    long whentohangup = 0, havewhen = 0, diff;
00942    struct ast_channel *winner = NULL;
00943 
00944    pfds = alloca(sizeof(struct pollfd) * (n * AST_MAX_FDS + nfds));
00945    if (!pfds) {
00946       ast_log(LOG_WARNING, "alloca failed!  bad things will happen.\n");
00947       *outfd = -1;
00948       return NULL;
00949    }
00950 
00951    if (outfd)
00952       *outfd = -99999;
00953    if (exception)
00954       *exception = 0;
00955    
00956    /* Perform any pending masquerades */
00957    for (x=0;x<n;x++) {
00958       ast_mutex_lock(&c[x]->lock);
00959       if (c[x]->whentohangup) {
00960          if (!havewhen)
00961             time(&now);
00962          diff = c[x]->whentohangup - now;
00963          if (!havewhen || (diff < whentohangup)) {
00964             havewhen++;
00965             whentohangup = diff;
00966          }
00967       }
00968       if (c[x]->masq) {
00969          if (ast_do_masquerade(c[x])) {
00970             ast_log(LOG_WARNING, "Masquerade failed\n");
00971             *ms = -1;
00972             ast_mutex_unlock(&c[x]->lock);
00973             return NULL;
00974          }
00975       }
00976       ast_mutex_unlock(&c[x]->lock);
00977    }
00978 
00979    rms = *ms;
00980    
00981    if (havewhen) {
00982       if ((*ms < 0) || (whentohangup * 1000 < *ms)) {
00983          rms =  whentohangup * 1000;
00984       }
00985    }
00986    max = 0;
00987    for (x=0;x<n;x++) {
00988       for (y=0;y<AST_MAX_FDS;y++) {
00989          if (c[x]->fds[y] > -1) {
00990             pfds[max].fd = c[x]->fds[y];
00991             pfds[max].events = POLLIN | POLLPRI;
00992             max++;
00993          }
00994       }
00995       CHECK_BLOCKING(c[x]);
00996    }
00997    for (x=0;x<nfds; x++) {
00998       if (fds[x] > -1) {
00999          pfds[max].fd = fds[x];
01000          pfds[max].events = POLLIN | POLLPRI;
01001          max++;
01002       }
01003    }
01004    if (*ms > 0) 
01005       gettimeofday(&start, NULL);
01006    res = poll(pfds, max, rms);
01007    if (res < 0) {
01008       for (x=0;x<n;x++) 
01009          c[x]->blocking = 0;
01010       /* Simulate a timeout if we were interrupted */
01011       if (errno != EINTR)
01012          *ms = -1;
01013       else {
01014          /* Just an interrupt */
01015 #if 0
01016          *ms = 0;
01017 #endif         
01018       }
01019       return NULL;
01020    }
01021 
01022    if (havewhen)
01023       time(&now);
01024    spoint = 0;
01025    for (x=0;x<n;x++) {
01026       c[x]->blocking = 0;
01027       if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) {
01028          c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
01029          if (!winner)
01030             winner = c[x];
01031       }
01032       for (y=0;y<AST_MAX_FDS;y++) {
01033          if (c[x]->fds[y] > -1) {
01034             if ((res = ast_fdisset(pfds, c[x]->fds[y], max, &spoint))) {
01035                if (res & POLLPRI)
01036                   c[x]->exception = -1;
01037                else
01038                   c[x]->exception = 0;
01039                c[x]->fdno = y;
01040                winner = c[x];
01041             }
01042          }
01043       }
01044    }
01045    for (x=0;x<nfds;x++) {
01046       if (fds[x] > -1) {
01047          if ((res = ast_fdisset(pfds, fds[x], max, &spoint))) {
01048             if (outfd)
01049                *outfd = fds[x];
01050             if (exception) {  
01051                if (res & POLLPRI) 
01052                   *exception = -1;
01053                else
01054                   *exception = 0;
01055             }
01056             winner = NULL;
01057          }
01058       }  
01059    }
01060    if (*ms > 0) {
01061       long diff;
01062       gettimeofday(&end, NULL);
01063       diff = (end.tv_sec - start.tv_sec) * 1000;
01064       diff += (end.tv_usec - start.tv_usec) / 1000;
01065       if (diff < *ms)
01066          *ms -= diff;
01067       else
01068          *ms = 0;
01069    }
01070    return winner;
01071 }

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

References ast_check_hangup(), ast_frfree(), ast_read(), ast_waitfor(), ast_frame::frametype, ast_frame::subclass, and ast_channel::zombie.

Referenced by ast_control_streamfile(), ast_pbx_run(), and ast_readstring().

01093 {
01094    /* XXX Should I be merged with waitfordigit_full XXX */
01095    struct ast_frame *f;
01096    char result = 0;
01097    /* Stop if we're a zombie or need a soft hangup */
01098    if (c->zombie || ast_check_hangup(c)) 
01099       return -1;
01100    /* Wait for a digit, no more than ms milliseconds total. */
01101    while(ms && !result) {
01102       ms = ast_waitfor(c, ms);
01103       if (ms < 0) /* Error */
01104          result = -1; 
01105       else if (ms > 0) {
01106          /* Read something */
01107          f = ast_read(c);
01108          if (f) {
01109             if (f->frametype == AST_FRAME_DTMF) 
01110                result = f->subclass;
01111             ast_frfree(f);
01112          } else
01113             result = -1;
01114       }
01115    }
01116    return result;
01117 }

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

Definition at line 1136 of file channel.c.

References ast_check_hangup(), ast_frfree(), ast_log(), ast_read(), ast_waitfor_nandfds(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, ast_frame::subclass, and ast_channel::zombie.

Referenced by ast_readstring_full().

01137 {
01138    struct ast_frame *f;
01139    struct ast_channel *rchan;
01140    int outfd;
01141    int res;
01142    /* Stop if we're a zombie or need a soft hangup */
01143    if (c->zombie || ast_check_hangup(c)) 
01144       return -1;
01145    /* Wait for a digit, no more than ms milliseconds total. */
01146    while(ms) {
01147       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01148       if ((!rchan) && (outfd < 0) && (ms)) { 
01149          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01150          return -1;
01151       } else if (outfd > -1) {
01152          /* The FD we were watching has something waiting */
01153          return 1;
01154       } else if (rchan) {
01155          f = ast_read(c);
01156          if(!f) {
01157             return -1;
01158          }
01159 
01160          switch(f->frametype) {
01161          case AST_FRAME_DTMF:
01162             res = f->subclass;
01163             ast_frfree(f);
01164             return res;
01165          case AST_FRAME_CONTROL:
01166             switch(f->subclass) {
01167             case AST_CONTROL_HANGUP:
01168                ast_frfree(f);
01169                return -1;
01170             case AST_CONTROL_RINGING:
01171             case AST_CONTROL_ANSWER:
01172                /* Unimportant */
01173                break;
01174             default:
01175                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01176             }
01177          case AST_FRAME_VOICE:
01178             /* Write audio if appropriate */
01179             if (audiofd > -1)
01180                write(audiofd, f->data, f->datalen);
01181          }
01182          /* Ignore */
01183          ast_frfree(f);
01184       }
01185    }
01186    return 0; // Time is up
01187 }

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

References ast_channel::_softhangup, ast_check_hangup(), ast_deactivate_generator(), ast_do_masquerade(), ast_frame_dump(), 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, ast_frame::samples, 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_dtmf_stream(), ast_prod(), ast_rtp_bridge(), and ast_write_video().

01572 {
01573    int res = -1;
01574    struct ast_frame *f = NULL;
01575    /* Stop if we're a zombie or need a soft hangup */
01576    ast_mutex_lock(&chan->lock);
01577    if (chan->zombie || ast_check_hangup(chan))  {
01578       ast_mutex_unlock(&chan->lock);
01579       return -1;
01580    }
01581    /* Handle any pending masquerades */
01582    if (chan->masq) {
01583       if (ast_do_masquerade(chan)) {
01584          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01585          ast_mutex_unlock(&chan->lock);
01586          return -1;
01587       }
01588    }
01589    if (chan->masqr) {
01590       ast_mutex_unlock(&chan->lock);
01591       return 0;
01592    }
01593    if (chan->generatordata) {
01594       if (chan->writeinterrupt)
01595          ast_deactivate_generator(chan);
01596       else {
01597          ast_mutex_unlock(&chan->lock);
01598          return 0;
01599       }
01600    }
01601    if (chan->fout & 0x80000000)
01602       ast_frame_dump(chan->name, fr, ">>");
01603    CHECK_BLOCKING(chan);
01604    switch(fr->frametype) {
01605    case AST_FRAME_CONTROL:
01606       /* XXX Interpret control frames XXX */
01607       ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n");
01608       break;
01609    case AST_FRAME_DTMF:
01610       chan->blocking = 0;
01611       ast_mutex_unlock(&chan->lock);
01612       res = do_senddigit(chan,fr->subclass);
01613       ast_mutex_lock(&chan->lock);
01614       CHECK_BLOCKING(chan);
01615       break;
01616    case AST_FRAME_TEXT:
01617       if (chan->pvt->send_text)
01618          res = chan->pvt->send_text(chan, (char *) fr->data);
01619       break;
01620    case AST_FRAME_VIDEO:
01621       /* XXX Handle translation of video codecs one day XXX */
01622       if (chan->pvt->write_video)
01623          res = chan->pvt->write_video(chan, fr);
01624       else
01625          res = 0;
01626       break;
01627    default:
01628       if (chan->pvt->write) {
01629          if (chan->pvt->writetrans) {
01630             f = ast_translate(chan->pvt->writetrans, fr, 0);
01631          } else
01632             f = fr;
01633          if (f) {
01634             res = chan->pvt->write(chan, f);
01635             if( chan->monitor &&
01636                   chan->monitor->write_stream &&
01637                   f && ( f->frametype == AST_FRAME_VOICE ) ) {
01638 #ifndef MONITOR_CONSTANT_DELAY
01639                int jump = chan->insmpl - chan->outsmpl - 2 * f->samples;
01640                if (jump >= 0) {
01641                   if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1)
01642                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
01643                   chan->outsmpl += jump + 2 * f->samples;
01644                } else
01645                   chan->outsmpl += f->samples;
01646 #else
01647                int jump = chan->insmpl - chan->outsmpl;
01648                if (jump - MONITOR_DELAY >= 0) {
01649                   if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
01650                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
01651                   chan->outsmpl += jump;
01652                } else
01653                   chan->outsmpl += f->samples;
01654 #endif
01655             if (ast_writestream(chan->monitor->write_stream, f) < 0)
01656                   ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
01657             }
01658          } else
01659             res = 0;
01660       }
01661    }
01662    if (f && (f != fr))
01663       ast_frfree(f);
01664    chan->blocking = 0;
01665    /* Consider a write failure to force a soft hangup */
01666    if (res < 0)
01667       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01668    else {
01669       if ((chan->fout & 0x7fffffff) == 0x7fffffff)
01670          chan->fout &= 0x80000000;
01671       else
01672          chan->fout++;
01673       chan->fout++;
01674    }
01675    ast_mutex_unlock(&chan->lock);
01676    return res;
01677 }

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

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

01561 {
01562    int res;
01563    if (!chan->pvt->write_video)
01564       return 0;
01565    res = ast_write(chan, fr);
01566    if (!res)
01567       res = 1;
01568    return res;
01569 }


Generated on Thu Oct 28 11:33:01 2004 for Asterisk by doxygen1.2.15