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

channel.h File Reference

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

Include dependency graph for channel.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Data Structures

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

struct  ast_bridge_config
struct  outgoing_helper

Defines

#define AST_MAX_EXTENSION   80
 Max length of an extension.

#define AST_CHANNEL_NAME   80
#define AST_CHANNEL_MAX_STACK   32
#define MAX_LANGUAGE   20
#define AST_MAX_FDS   8
#define AST_FLAG_DIGITAL   1 /* if the call is a digital ISDN call */
#define LOAD_OH(oh)
#define AST_CDR_TRANSFER   (1 << 0)
#define AST_CDR_FORWARD   (1 << 1)
#define AST_CDR_CALLWAIT   (1 << 2)
#define AST_CDR_CONFERENCE   (1 << 3)
#define AST_ADSI_UNKNOWN   (0)
#define AST_ADSI_AVAILABLE   (1)
#define AST_ADSI_UNAVAILABLE   (2)
#define AST_ADSI_OFFHOOKONLY   (3)
#define AST_SOFTHANGUP_DEV   (1 << 0) /* Soft hangup by device */
#define AST_SOFTHANGUP_ASYNCGOTO   (1 << 1) /* Soft hangup for async goto */
#define AST_SOFTHANGUP_SHUTDOWN   (1 << 2)
#define AST_SOFTHANGUP_TIMEOUT   (1 << 3)
#define AST_SOFTHANGUP_APPUNLOAD   (1 << 4)
#define AST_SOFTHANGUP_EXPLICIT   (1 << 5)
#define AST_STATE_DOWN   0
#define AST_STATE_RESERVED   1
#define AST_STATE_OFFHOOK   2
#define AST_STATE_DIALING   3
#define AST_STATE_RING   4
#define AST_STATE_RINGING   5
#define AST_STATE_UP   6
#define AST_STATE_BUSY   7
#define AST_STATE_DIALING_OFFHOOK   8
#define AST_STATE_MUTE   (1 << 16)
#define AST_DEVICE_UNKNOWN   0
#define AST_DEVICE_NOT_INUSE   1
#define AST_DEVICE_INUSE   2
#define AST_DEVICE_BUSY   3
#define AST_DEVICE_INVALID   4
#define AST_DEVICE_UNAVAILABLE   5
#define AST_BRIDGE_DTMF_CHANNEL_0   (1 << 0)
#define AST_BRIDGE_DTMF_CHANNEL_1   (1 << 1)
#define AST_BRIDGE_REC_CHANNEL_0   (1 << 2)
#define AST_BRIDGE_REC_CHANNEL_1   (1 << 3)
#define AST_BRIDGE_IGNORE_SIGS   (1 << 4)
#define CRASH   do { } while(0)
#define CHECK_BLOCKING(c)

Functions

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

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

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

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

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

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

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

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

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

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

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

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

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

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

int ast_safe_sleep_conditional (struct ast_channel *chan, int ms, int(*cond)(void *), void *data)
 Wait for a specied amount of time, looking for hangups and a condition argument.

ast_channelast_waitfor_nandfds (struct ast_channel **chan, int n, int *fds, int nfds, int *exception, int *outfd, int *ms)
 Waits for activity on a group of channels.

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

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

ast_frameast_read (struct ast_channel *chan)
 Reads a frame.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

int ast_channel_defer_dtmf (struct ast_channel *chan)
 Defers DTMF.

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

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

#define AST_ADSI_OFFHOOKONLY   (3)
 

Definition at line 312 of file channel.h.

#define AST_ADSI_UNAVAILABLE   (2)
 

Definition at line 311 of file channel.h.

#define AST_ADSI_UNKNOWN   (0)
 

Definition at line 309 of file channel.h.

#define AST_BRIDGE_DTMF_CHANNEL_0   (1 << 0)
 

Report DTMF on channel 0

Definition at line 662 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 664 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 670 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 666 of file channel.h.

#define AST_BRIDGE_REC_CHANNEL_1   (1 << 3)
 

Return all voice frames on channel 1

Definition at line 668 of file channel.h.

#define AST_CDR_CALLWAIT   (1 << 2)
 

Definition at line 306 of file channel.h.

#define AST_CDR_CONFERENCE   (1 << 3)
 

Definition at line 307 of file channel.h.

#define AST_CDR_FORWARD   (1 << 1)
 

Definition at line 305 of file channel.h.

#define AST_CDR_TRANSFER   (1 << 0)
 

Definition at line 304 of file channel.h.

#define AST_CHANNEL_MAX_STACK   32
 

Definition at line 39 of file channel.h.

Referenced by pbx_exec().

#define AST_CHANNEL_NAME   80
 

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

#define AST_DEVICE_INUSE   2
 

Device is in use

Definition at line 350 of file channel.h.

Referenced by ast_parse_device_state().

#define AST_DEVICE_INVALID   4
 

Device is invalid

Definition at line 354 of file channel.h.

Referenced by ast_device_state().

#define AST_DEVICE_NOT_INUSE   1
 

Device is not used

Definition at line 348 of file channel.h.

#define AST_DEVICE_UNAVAILABLE   5
 

Device is unavailable

Definition at line 356 of file channel.h.

#define AST_DEVICE_UNKNOWN   0
 

Device is valid but channel didn't know state

Definition at line 346 of file channel.h.

Referenced by ast_device_state(), and ast_parse_device_state().

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

Definition at line 237 of file channel.h.

#define AST_MAX_EXTENSION   80
 

Max length of an extension.

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

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

Definition at line 315 of file channel.h.

Referenced by ast_async_goto(), and ast_pbx_run().

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

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

#define AST_SOFTHANGUP_SHUTDOWN   (1 << 2)
 

Definition at line 316 of file channel.h.

Referenced by ast_begin_shutdown().

#define AST_SOFTHANGUP_TIMEOUT   (1 << 3)
 

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

Referenced by ast_state2str().

#define AST_STATE_DIALING   3
 

Digits (or equivalent) have been dialed

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

#define AST_STATE_DOWN   0
 

Channel is down and available

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

#define AST_STATE_OFFHOOK   2
 

Channel is off hook

Definition at line 327 of file channel.h.

Referenced by ast_state2str().

#define AST_STATE_RESERVED   1
 

Channel is down, but reserved

Definition at line 325 of file channel.h.

Referenced by ast_state2str().

#define AST_STATE_RING   4
 

Line is ringing

Definition at line 331 of file channel.h.

Referenced by ast_answer(), and ast_state2str().

#define AST_STATE_RINGING   5
 

Remote end is ringing

Definition at line 333 of file channel.h.

Referenced by ast_answer(), and ast_state2str().

#define AST_STATE_UP   6
 

Line is up

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

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

#define CRASH   do { } while(0)
 

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

Referenced by ast_pbx_outgoing_exten().

#define MAX_LANGUAGE   20
 

Definition at line 41 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 1671 of file channel.c.

References ast_channel::_state, outgoing_helper::account, ast_call(), ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_setapp(), ast_cdr_start(), ast_cdr_update(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_FRAME_CONTROL, ast_frfree(), ast_hangup(), ast_log(), ast_read(), ast_request(), ast_set_callerid(), AST_STATE_UP, ast_waitfor(), outgoing_helper::callerid, ast_channel::cdr, ast_channel::context, outgoing_helper::context, ast_channel::exten, outgoing_helper::exten, ast_channel::hangupcause, LOG_NOTICE, LOG_WARNING, pbx_builtin_setvar(), outgoing_helper::priority, ast_channel::priority, type, and outgoing_helper::variable.

Referenced by ast_pbx_outgoing_exten(), and ast_request_and_dial().

01672 { 01673 int state = 0; 01674 struct ast_channel *chan; 01675 struct ast_frame *f; 01676 int res = 0; 01677 char *variable; 01678 chan = ast_request(type, format, data); 01679 if (chan) { 01680 if (oh) { 01681 char *tmp, *var; 01682 /* JDG chanvar */ 01683 if (oh->variable) 01684 variable = ast_strdupa(oh->variable); 01685 else 01686 variable = NULL; 01687 tmp = variable; 01688 /* FIXME replace this call with strsep NOT*/ 01689 while( (var = strtok_r(NULL, "|", &tmp)) ) { 01690 pbx_builtin_setvar( chan, var ); 01691 } /* /JDG */ 01692 if (oh->callerid && *oh->callerid) 01693 ast_set_callerid(chan, oh->callerid, 1); 01694 if (oh->account && *oh->account) 01695 ast_cdr_setaccount(chan, oh->account); 01696 } 01697 if (callerid && !ast_strlen_zero(callerid)) 01698 ast_set_callerid(chan, callerid, 1); 01699 01700 if (!ast_call(chan, data, 0)) { 01701 while(timeout && (chan->_state != AST_STATE_UP)) { 01702 res = ast_waitfor(chan, timeout); 01703 if (res < 0) { 01704 /* Something not cool, or timed out */ 01705 break; 01706 } 01707 /* If done, break out */ 01708 if (!res) 01709 break; 01710 if (timeout > -1) 01711 timeout = res; 01712 f = ast_read(chan); 01713 if (!f) { 01714 state = AST_CONTROL_HANGUP; 01715 res = 0; 01716 break; 01717 } 01718 if (f->frametype == AST_FRAME_CONTROL) { 01719 if (f->subclass == AST_CONTROL_RINGING) 01720 state = AST_CONTROL_RINGING; 01721 else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) { 01722 state = f->subclass; 01723 ast_frfree(f); 01724 break; 01725 } else if (f->subclass == AST_CONTROL_ANSWER) { 01726 state = f->subclass; 01727 ast_frfree(f); 01728 break; 01729 } else if (f->subclass == AST_CONTROL_PROGRESS) { 01730 /* Ignore */ 01731 } else if (f->subclass == -1) { 01732 /* Ignore -- just stopping indications */ 01733 } else { 01734 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass); 01735 } 01736 } 01737 ast_frfree(f); 01738 } 01739 } else 01740 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 01741 } else 01742 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 01743 if (chan) { 01744 /* Final fixups */ 01745 if (oh) { 01746 if (oh->context && *oh->context) 01747 strncpy(chan->context, oh->context, sizeof(chan->context) - 1); 01748 if (oh->exten && *oh->exten) 01749 strncpy(chan->exten, oh->exten, sizeof(chan->exten) - 1); 01750 chan->priority = oh->priority; 01751 } 01752 if (chan->_state == AST_STATE_UP) 01753 state = AST_CONTROL_ANSWER; 01754 } 01755 if (outstate) 01756 *outstate = state; 01757 if (chan && res <= 0) { 01758 if (!chan->cdr) { 01759 chan->cdr = ast_cdr_alloc(); 01760 if (chan->cdr) 01761 ast_cdr_init(chan->cdr, chan); 01762 } 01763 if (chan->cdr) { 01764 char tmp[256]; 01765 sprintf(tmp, "%s/%s",type,(char *)data); 01766 ast_cdr_setapp(chan->cdr,"Dial",tmp); 01767 ast_cdr_update(chan); 01768 ast_cdr_start(chan->cdr); 01769 ast_cdr_end(chan->cdr); 01770 /* If the cause wasn't handled properly */ 01771 if (ast_cdr_disposition(chan->cdr,chan->hangupcause)) 01772 ast_cdr_failed(chan->cdr); 01773 } else 01774 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 01775 ast_hangup(chan); 01776 chan = NULL; 01777 } 01778 return chan; 01779 }

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

Activate a given generator

Definition at line 791 of file channel.c.

References ast_generator::alloc, ast_mutex_lock, ast_mutex_unlock, ast_prod(), 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().

00792 { 00793 int res = 0; 00794 ast_mutex_lock(&chan->lock); 00795 if (chan->generatordata) { 00796 if (chan->generator && chan->generator->release) 00797 chan->generator->release(chan, chan->generatordata); 00798 chan->generatordata = NULL; 00799 } 00800 ast_prod(chan); 00801 if ((chan->generatordata = gen->alloc(chan, params))) { 00802 chan->generator = gen; 00803 } else { 00804 res = -1; 00805 } 00806 ast_mutex_unlock(&chan->lock); 00807 return res; 00808 }

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

00751 { 00752 int res = 0; 00753 /* Stop if we're a zombie or need a soft hangup */ 00754 if (chan->zombie || ast_check_hangup(chan)) 00755 return -1; 00756 switch(chan->_state) { 00757 case AST_STATE_RINGING: 00758 case AST_STATE_RING: 00759 ast_mutex_lock(&chan->lock); 00760 if (chan->pvt->answer) 00761 res = chan->pvt->answer(chan); 00762 ast_mutex_unlock(&chan->lock); 00763 ast_setstate(chan, AST_STATE_UP); 00764 if (chan->cdr) 00765 ast_cdr_answer(chan->cdr); 00766 return res; 00767 break; 00768 case AST_STATE_UP: 00769 if (chan->cdr) 00770 ast_cdr_answer(chan->cdr); 00771 break; 00772 } 00773 return 0; 00774 }

int ast_autoservice_start struct ast_channel chan  ) 
 

Automatically service a channel for us...

Definition at line 87 of file autoservice.c.

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

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

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

int ast_autoservice_stop struct ast_channel chan  ) 
 

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

Definition at line 123 of file autoservice.c.

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

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

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

void ast_begin_shutdown int  hangup  ) 
 

Initiate system shutdown -- prevents new channels from being allocated. If "hangup" is non-zero, all existing channels will receive soft hangups

Definition at line 105 of file channel.c.

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

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

01891 { 01892 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 01893 If the remote end does not answer within the timeout, then do NOT hang up, but 01894 return anyway. */ 01895 int res = -1; 01896 /* Stop if we're a zombie or need a soft hangup */ 01897 ast_mutex_lock(&chan->lock); 01898 if (!chan->zombie && !ast_check_hangup(chan)) 01899 if (chan->pvt->call) 01900 res = chan->pvt->call(chan, addr, timeout); 01901 ast_mutex_unlock(&chan->lock); 01902 return res; 01903 }

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

References ast_bridge_config::allowdisconnect, 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_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_read(), ast_verbose(), ast_waitfor_n(), ast_write(), ast_channel::bridge, ast_bridge_config::end_sound, EVENT_FLAG_CALL, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::name, option_verbose, ast_bridge_config::play_to_callee, ast_bridge_config::play_to_caller, ast_bridge_config::play_warning, ast_bridge_config::start_sound, ast_bridge_config::timelimit, VERBOSE_PREFIX_3, ast_bridge_config::warning_freq, ast_bridge_config::warning_sound, and ast_channel::zombie.

02419 { 02420 /* Copy voice back and forth between the two channels. Give the peer 02421 the ability to transfer calls with '#<extension' syntax. */ 02422 int flags; 02423 struct ast_channel *cs[3]; 02424 int to = -1; 02425 struct ast_frame *f; 02426 struct ast_channel *who = NULL; 02427 int res=0; 02428 int nativefailed=0; 02429 struct timeval start_time,precise_now; 02430 long elapsed_ms=0, time_left_ms=0; 02431 int playit=0, playitagain=1, first_time=1; 02432 02433 flags = (config->allowdisconnect||config->allowredirect_out ? AST_BRIDGE_DTMF_CHANNEL_0 : 0) + (config->allowredirect_in ? AST_BRIDGE_DTMF_CHANNEL_1 : 0); 02434 02435 /* timestamp */ 02436 gettimeofday(&start_time,NULL); 02437 time_left_ms = config->timelimit; 02438 02439 if (config->play_to_caller && config->start_sound) 02440 bridge_playfile(c0,c1,config->start_sound,time_left_ms / 1000); 02441 if (config->play_to_callee && config->start_sound) 02442 bridge_playfile(c1,c0,config->start_sound,time_left_ms / 1000); 02443 02444 /* Stop if we're a zombie or need a soft hangup */ 02445 if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) 02446 return -1; 02447 if (c0->bridge) { 02448 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 02449 c0->name, c0->bridge->name); 02450 return -1; 02451 } 02452 if (c1->bridge) { 02453 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 02454 c1->name, c1->bridge->name); 02455 return -1; 02456 } 02457 02458 /* Keep track of bridge */ 02459 c0->bridge = c1; 02460 c1->bridge = c0; 02461 cs[0] = c0; 02462 cs[1] = c1; 02463 02464 manager_event(EVENT_FLAG_CALL, "Link", 02465 "Channel1: %s\r\n" 02466 "Channel2: %s\r\n" 02467 "Uniqueid1: %s\r\n" 02468 "Uniqueid2: %s\r\n", 02469 c0->name, c1->name, c0->uniqueid, c1->uniqueid); 02470 02471 for (/* ever */;;) { 02472 /* timestamp */ 02473 if (config->timelimit) { 02474 gettimeofday(&precise_now,NULL); 02475 elapsed_ms = tvdiff(&precise_now,&start_time); 02476 time_left_ms = config->timelimit - elapsed_ms; 02477 02478 if (playitagain && (config->play_to_caller || config->play_to_callee) && (config->play_warning && time_left_ms <= config->play_warning)) { 02479 /* narrowing down to the end */ 02480 if (config->warning_freq == 0) { 02481 playit = 1; 02482 first_time=0; 02483 playitagain=0; 02484 } else if (first_time) { 02485 playit = 1; 02486 first_time=0; 02487 } else { 02488 if ((time_left_ms % config->warning_freq) <= 50) { 02489 playit = 1; 02490 } 02491 } 02492 } 02493 if (time_left_ms <= 0) { 02494 if (config->play_to_caller && config->end_sound) 02495 bridge_playfile(c0,c1,config->end_sound,0); 02496 if (config->play_to_callee && config->end_sound) 02497 bridge_playfile(c1,c0,config->end_sound,0); 02498 *fo = NULL; 02499 if (who) *rc = who; 02500 res = 0; 02501 break; 02502 } 02503 if (time_left_ms >= 5000 && playit) { 02504 if (config->play_to_caller && config->warning_sound && config->play_warning) 02505 bridge_playfile(c0,c1,config->warning_sound,time_left_ms / 1000); 02506 if (config->play_to_callee && config->warning_sound && config->play_warning) 02507 bridge_playfile(c1,c0,config->warning_sound,time_left_ms / 1000); 02508 playit = 0; 02509 } 02510 02511 } 02512 /* Stop if we're a zombie or need a soft hangup */ 02513 if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) { 02514 *fo = NULL; 02515 if (who) *rc = who; 02516 res = 0; 02517 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"); 02518 break; 02519 } 02520 if (c0->pvt->bridge && config->timelimit==0 && 02521 (c0->pvt->bridge == c1->pvt->bridge) && !nativefailed && !c0->monitor && !c1->monitor) { 02522 /* Looks like they share a bridge code */ 02523 if (option_verbose > 2) 02524 ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name); 02525 if (!(res = c0->pvt->bridge(c0, c1, flags, fo, rc))) { 02526 c0->bridge = NULL; 02527 c1->bridge = NULL; 02528 manager_event(EVENT_FLAG_CALL, "Unlink", 02529 "Channel1: %s\r\n" 02530 "Channel2: %s\r\n" 02531 "Uniqueid1: %s\r\n" 02532 "Uniqueid2: %s\r\n", 02533 c0->name, c1->name, c0->uniqueid, c1->uniqueid); 02534 ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n",c0->name ,c1->name); 02535 return 0; 02536 } 02537 /* If they return non-zero then continue on normally. Let "-2" mean don't worry about 02538 my not wanting to bridge */ 02539 if ((res != -2) && (res != -3)) 02540 ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name); 02541 if (res != -3) nativefailed++; 02542 } 02543 02544 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat)) && 02545 !(c0->generator || c1->generator)) { 02546 if (ast_channel_make_compatible(c0, c1)) { 02547 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 02548 manager_event(EVENT_FLAG_CALL, "Unlink", 02549 "Channel1: %s\r\n" 02550 "Channel2: %s\r\n" 02551 "Uniqueid1: %s\r\n" 02552 "Uniqueid2: %s\r\n", 02553 c0->name, c1->name, c0->uniqueid, c1->uniqueid); 02554 return -1; 02555 } 02556 } 02557 who = ast_waitfor_n(cs, 2, &to); 02558 if (!who) { 02559 ast_log(LOG_DEBUG, "Nobody there, continuing...\n"); 02560 continue; 02561 } 02562 f = ast_read(who); 02563 if (!f) { 02564 *fo = NULL; 02565 *rc = who; 02566 res = 0; 02567 ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name); 02568 break; 02569 } 02570 02571 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 02572 *fo = f; 02573 *rc = who; 02574 res = 0; 02575 ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name); 02576 break; 02577 } 02578 if ((f->frametype == AST_FRAME_VOICE) || 02579 (f->frametype == AST_FRAME_TEXT) || 02580 (f->frametype == AST_FRAME_VIDEO) || 02581 (f->frametype == AST_FRAME_IMAGE) || 02582 (f->frametype == AST_FRAME_DTMF)) { 02583 if ((f->frametype == AST_FRAME_DTMF) && 02584 (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 02585 if ((who == c0)) { 02586 if ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) { 02587 *rc = c0; 02588 *fo = f; 02589 /* Take out of conference mode */ 02590 res = 0; 02591 ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_0 on c0 (%s)\n",c0->name); 02592 break; 02593 } else 02594 goto tackygoto; 02595 } else 02596 if ((who == c1)) { 02597 if (flags & AST_BRIDGE_DTMF_CHANNEL_1) { 02598 *rc = c1; 02599 *fo = f; 02600 res = 0; 02601 ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_1 on c1 (%s)\n",c1->name); 02602 break; 02603 } else 02604 goto tackygoto; 02605 } 02606 } else { 02607 #if 0 02608 ast_log(LOG_DEBUG, "Read from %s\n", who->name); 02609 if (who == last) 02610 ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name); 02611 last = who; 02612 #endif 02613 tackygoto: 02614 /* Don't copy packets if there is a generator on either one, since they're 02615 not supposed to be listening anyway */ 02616 if (who == c0) 02617 ast_write(c1, f); 02618 else 02619 ast_write(c0, f); 02620 } 02621 ast_frfree(f); 02622 } else 02623 ast_frfree(f); 02624 /* Swap who gets priority */ 02625 cs[2] = cs[0]; 02626 cs[0] = cs[1]; 02627 cs[1] = cs[2]; 02628 } 02629 c0->bridge = NULL; 02630 c1->bridge = NULL; 02631 manager_event(EVENT_FLAG_CALL, "Unlink", 02632 "Channel1: %s\r\n" 02633 "Channel2: %s\r\n" 02634 "Uniqueid1: %s\r\n" 02635 "Uniqueid2: %s\r\n", 02636 c0->name, c1->name, c0->uniqueid, c1->uniqueid); 02637 ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n",c0->name,c1->name); 02638 return res; 02639 }

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

References ast_channel::deferdtmf.

00436 { 00437 int pre = 0; 00438 if (chan) { 00439 pre = chan->deferdtmf; 00440 chan->deferdtmf = 1; 00441 } 00442 return pre; 00443 }

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

02028 { 02029 int peerf; 02030 int chanf; 02031 int res; 02032 ast_mutex_lock(&peer->lock); 02033 peerf = peer->nativeformats; 02034 ast_mutex_unlock(&peer->lock); 02035 ast_mutex_lock(&chan->lock); 02036 chanf = chan->nativeformats; 02037 ast_mutex_unlock(&chan->lock); 02038 res = ast_translator_best_choice(&peerf, &chanf); 02039 if (res < 0) { 02040 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, chan->nativeformats, peer->name, peer->nativeformats); 02041 return -1; 02042 } 02043 /* Set read format on channel */ 02044 res = ast_set_read_format(chan, peerf); 02045 if (res < 0) { 02046 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, chanf); 02047 return -1; 02048 } 02049 /* Set write format on peer channel */ 02050 res = ast_set_write_format(peer, peerf); 02051 if (res < 0) { 02052 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, peerf); 02053 return -1; 02054 } 02055 /* Now we go the other way */ 02056 peerf = peer->nativeformats; 02057 chanf = chan->nativeformats; 02058 res = ast_translator_best_choice(&chanf, &peerf); 02059 if (res < 0) { 02060 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, peer->nativeformats, chan->name, chan->nativeformats); 02061 return -1; 02062 } 02063 /* Set writeformat on channel */ 02064 res = ast_set_write_format(chan, chanf); 02065 if (res < 0) { 02066 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, chanf); 02067 return -1; 02068 } 02069 /* Set read format on peer channel */ 02070 res = ast_set_read_format(peer, chanf); 02071 if (res < 0) { 02072 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, peerf); 02073 return -1; 02074 } 02075 return 0; 02076 }

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

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

02079 { 02080 struct ast_frame null = { AST_FRAME_NULL, }; 02081 int res = -1; 02082 ast_mutex_lock(&original->lock); 02083 while(ast_mutex_trylock(&clone->lock)) { 02084 ast_mutex_unlock(&original->lock); 02085 usleep(1); 02086 ast_mutex_lock(&original->lock); 02087 } 02088 ast_log(LOG_DEBUG, "Planning to masquerade %s into the structure of %s\n", 02089 clone->name, original->name); 02090 if (original->masq) { 02091 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 02092 original->masq->name, original->name); 02093 } else if (clone->masqr) { 02094 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 02095 clone->name, clone->masqr->name); 02096 } else { 02097 original->masq = clone; 02098 clone->masqr = original; 02099 ast_queue_frame(original, &null); 02100 ast_queue_frame(clone, &null); 02101 ast_log(LOG_DEBUG, "Done planning to masquerade %s into the structure of %s\n", original->name, clone->name); 02102 res = 0; 02103 } 02104 ast_mutex_unlock(&clone->lock); 02105 ast_mutex_unlock(&original->lock); 02106 return res; 02107 }

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

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

02014 { 02015 if (chan->pvt->send_html) 02016 return chan->pvt->send_html(chan, subclass, data, datalen); 02017 return -1; 02018 }

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

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

02021 { 02022 if (chan->pvt->send_html) 02023 return chan->pvt->send_html(chan, AST_HTML_URL, url, strlen(url) + 1); 02024 return -1; 02025 }

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

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

02642 { 02643 int res; 02644 if (chan->pvt->setoption) { 02645 res = chan->pvt->setoption(chan, option, data, datalen); 02646 if (res < 0) 02647 return res; 02648 } else { 02649 errno = ENOSYS; 02650 return -1; 02651 } 02652 if (block) { 02653 /* XXX Implement blocking -- just wait for our option frame reply, discarding 02654 intermediate packets. XXX */ 02655 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 02656 return -1; 02657 } 02658 return 0; 02659 }

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

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

02007 { 02008 if (chan->pvt->send_html) 02009 return 1; 02010 return 0; 02011 }

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

References ast_channel::deferdtmf.

00446 { 00447 if (chan) 00448 chan->deferdtmf = 0; 00449 }

void ast_channel_unregister char *  type  ) 
 

Unregister a channel class.

Definition at line 721 of file channel.c.

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

00722 { 00723 struct chanlist *chan, *last=NULL; 00724 if (option_debug) 00725 ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", type); 00726 if (ast_mutex_lock(&chlock)) { 00727 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 00728 return; 00729 } 00730 if (option_verbose > 1) 00731 ast_verbose( VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", type); 00732 00733 chan = backends; 00734 while(chan) { 00735 if (!strcasecmp(chan->type, type)) { 00736 if (last) 00737 last->next = chan->next; 00738 else 00739 backends = backends->next; 00740 free(chan); 00741 ast_mutex_unlock(&chlock); 00742 return; 00743 } 00744 last = chan; 00745 chan = chan->next; 00746 } 00747 ast_mutex_unlock(&chlock); 00748 }

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

References ast_mutex_lock, ast_mutex_unlock, and channels.

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

00452 { 00453 /* Returns next channel (locked) */ 00454 struct ast_channel *l, *ret=NULL; 00455 ast_mutex_lock(&chlock); 00456 l = channels; 00457 if (!prev) { 00458 if (l) 00459 ast_mutex_lock(&l->lock); 00460 ast_mutex_unlock(&chlock); 00461 return l; 00462 } 00463 while(l) { 00464 if (l == prev) 00465 ret = l->next; 00466 l = l->next; 00467 } 00468 if (ret) 00469 ast_mutex_lock(&ret->lock); 00470 ast_mutex_unlock(&chlock); 00471 return ret; 00472 00473 }

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

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

00779 { 00780 ast_mutex_lock(&chan->lock); 00781 if (chan->generatordata) { 00782 if (chan->generator && chan->generator->release) 00783 chan->generator->release(chan, chan->generatordata); 00784 chan->generatordata = NULL; 00785 chan->generator = NULL; 00786 chan->writeinterrupt = 0; 00787 } 00788 ast_mutex_unlock(&chan->lock); 00789 }

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

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

01852 { 01853 char tech[AST_MAX_EXTENSION] = ""; 01854 char *number; 01855 struct chanlist *chanls; 01856 int res = 0; 01857 01858 strncpy(tech, device, sizeof(tech)-1); 01859 number = strchr(tech, '/'); 01860 if (!number) { 01861 return AST_DEVICE_INVALID; 01862 } 01863 *number = 0; 01864 number++; 01865 01866 if (ast_mutex_lock(&chlock)) { 01867 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 01868 return -1; 01869 } 01870 chanls = backends; 01871 while(chanls) { 01872 if (!strcasecmp(tech, chanls->type)) { 01873 ast_mutex_unlock(&chlock); 01874 if (!chanls->devicestate) 01875 return ast_parse_device_state(device); 01876 else { 01877 res = chanls->devicestate(number); 01878 if (res == AST_DEVICE_UNKNOWN) 01879 return ast_parse_device_state(device); 01880 else 01881 return res; 01882 } 01883 } 01884 chanls = chanls->next; 01885 } 01886 ast_mutex_unlock(&chlock); 01887 return AST_DEVICE_INVALID; 01888 }

int ast_do_masquerade struct ast_channel chan  ) 
 

Definition at line 2117 of file channel.c.

References 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, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::name, ast_channel::nativeformats, ast_channel::next, ast_channel_pvt::pvt, ast_channel::pvt, ast_channel::readformat, ast_channel_pvt::readq, ast_channel::timingfd, ast_channel::type, and ast_channel::writeformat.

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

02118 { 02119 int x,i; 02120 int res=0; 02121 char *tmp; 02122 struct ast_var_t *varptr; 02123 struct ast_frame *cur, *prev; 02124 struct ast_channel_pvt *p; 02125 struct ast_channel *clone = original->masq; 02126 int rformat = original->readformat; 02127 int wformat = original->writeformat; 02128 char newn[100]; 02129 char orig[100]; 02130 char masqn[100]; 02131 char zombn[100]; 02132 02133 #if 1 02134 ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", 02135 clone->name, clone->_state, original->name, original->_state); 02136 #endif 02137 /* XXX This is a seriously wacked out operation. We're essentially putting the guts of 02138 the clone channel into the original channel. Start by killing off the original 02139 channel's backend. I'm not sure we're going to keep this function, because 02140 while the features are nice, the cost is very high in terms of pure nastiness. XXX */ 02141 02142 /* We need the clone's lock, too */ 02143 ast_mutex_lock(&clone->lock); 02144 02145 ast_log(LOG_DEBUG, "Got clone lock on '%s' at %p\n", clone->name, &clone->lock); 02146 02147 /* Having remembered the original read/write formats, we turn off any translation on either 02148 one */ 02149 free_translation(clone); 02150 free_translation(original); 02151 02152 02153 /* Unlink the masquerade */ 02154 original->masq = NULL; 02155 clone->masqr = NULL; 02156 02157 /* Save the original name */ 02158 strncpy(orig, original->name, sizeof(orig) - 1); 02159 /* Save the new name */ 02160 strncpy(newn, clone->name, sizeof(newn) - 1); 02161 /* Create the masq name */ 02162 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn); 02163 02164 /* Copy the name from the clone channel */ 02165 strncpy(original->name, newn, sizeof(original->name)-1); 02166 02167 /* Mangle the name of the clone channel */ 02168 strncpy(clone->name, masqn, sizeof(clone->name) - 1); 02169 02170 /* Notify any managers of the change, first the masq then the other */ 02171 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\n", newn, masqn); 02172 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\n", orig, newn); 02173 02174 /* Swap the guts */ 02175 p = original->pvt; 02176 original->pvt = clone->pvt; 02177 clone->pvt = p; 02178 02179 /* Save any pending frames on both sides. Start by counting 02180 * how many we're going to need... */ 02181 prev = NULL; 02182 cur = clone->pvt->readq; 02183 x = 0; 02184 while(cur) { 02185 x++; 02186 prev = cur; 02187 cur = cur->next; 02188 } 02189 /* If we had any, prepend them to the ones already in the queue, and 02190 * load up the alertpipe */ 02191 if (prev) { 02192 prev->next = original->pvt->readq; 02193 original->pvt->readq = clone->pvt->readq; 02194 clone->pvt->readq = NULL; 02195 if (original->pvt->alertpipe[1] > -1) { 02196 for (i=0;i<x;i++) 02197 write(original->pvt->alertpipe[1], &x, sizeof(x)); 02198 } 02199 } 02200 clone->_softhangup = AST_SOFTHANGUP_DEV; 02201 02202 02203 if (clone->pvt->fixup){ 02204 res = clone->pvt->fixup(original, clone); 02205 if (res) 02206 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name); 02207 } 02208 02209 /* Start by disconnecting the original's physical side */ 02210 if (clone->pvt->hangup) 02211 res = clone->pvt->hangup(clone); 02212 if (res) { 02213 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n"); 02214 ast_mutex_unlock(&clone->lock); 02215 return -1; 02216 } 02217 02218 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); 02219 /* Mangle the name of the clone channel */ 02220 strncpy(clone->name, zombn, sizeof(clone->name) - 1); 02221 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\n", masqn, zombn); 02222 02223 /* Keep the same language. */ 02224 /* Update the type. */ 02225 original->type = clone->type; 02226 /* Copy the FD's */ 02227 for (x=0;x<AST_MAX_FDS;x++) { 02228 original->fds[x] = clone->fds[x]; 02229 } 02230 /* Append variables from clone channel into original channel */ 02231 /* XXX Is this always correct? We have to in order to keep MACROS working XXX */ 02232 varptr = original->varshead.first; 02233 if (varptr) { 02234 while(varptr->entries.next) { 02235 varptr = varptr->entries.next; 02236 } 02237 varptr->entries.next = clone->varshead.first; 02238 } else { 02239 original->varshead.first = clone->varshead.first; 02240 } 02241 clone->varshead.first = NULL; 02242 /* Presense of ADSI capable CPE follows clone */ 02243 original->adsicpe = clone->adsicpe; 02244 /* Bridge remains the same */ 02245 /* CDR fields remain the same */ 02246 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 02247 /* Application and data remain the same */ 02248 /* Clone exception becomes real one, as with fdno */ 02249 original->exception = clone->exception; 02250 original->fdno = clone->fdno; 02251 /* Schedule context remains the same */ 02252 /* Stream stuff stays the same */ 02253 /* Keep the original state. The fixup code will need to work with it most likely */ 02254 02255 /* dnid and callerid change to become the new, HOWEVER, we also link the original's 02256 fields back into the defunct 'clone' so that they will be freed when 02257 ast_frfree is eventually called */ 02258 tmp = original->dnid; 02259 original->dnid = clone->dnid; 02260 clone->dnid = tmp; 02261 02262 tmp = original->callerid; 02263 original->callerid = clone->callerid; 02264 clone->callerid = tmp; 02265 02266 /* Restore original timing file descriptor */ 02267 original->fds[AST_MAX_FDS - 2] = original->timingfd; 02268 02269 /* Our native formats are different now */ 02270 original->nativeformats = clone->nativeformats; 02271 02272 /* And of course, so does our current state. Note we need not 02273 call ast_setstate since the event manager doesn't really consider 02274 these separate */ 02275 original->_state = clone->_state; 02276 02277 /* Context, extension, priority, app data, jump table, remain the same */ 02278 /* pvt switches. pbx stays the same, as does next */ 02279 02280 /* Set the write format */ 02281 ast_set_write_format(original, wformat); 02282 02283 /* Set the read format */ 02284 ast_set_read_format(original, rformat); 02285 02286 ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat); 02287 02288 /* Okay. Last thing is to let the channel driver know about all this mess, so he 02289 can fix up everything as best as possible */ 02290 if (original->pvt->fixup) { 02291 res = original->pvt->fixup(clone, original); 02292 if (res) { 02293 ast_log(LOG_WARNING, "Driver for '%s' could not fixup channel %s\n", 02294 original->type, original->name); 02295 ast_mutex_unlock(&clone->lock); 02296 return -1; 02297 } 02298 } else 02299 ast_log(LOG_WARNING, "Driver '%s' does not have a fixup routine (for %s)! Bad things may happen.\n", 02300 original->type, original->name); 02301 02302 /* Now, at this point, the "clone" channel is totally F'd up. We mark it as 02303 a zombie so nothing tries to touch it. If it's already been marked as a 02304 zombie, then free it now (since it already is considered invalid). */ 02305 if (clone->zombie) { 02306 ast_log(LOG_DEBUG, "Destroying clone '%s'\n", clone->name); 02307 ast_mutex_unlock(&clone->lock); 02308 ast_channel_free(clone); 02309 manager_event(EVENT_FLAG_CALL, "Hangup", "Channel: %s\r\n", zombn); 02310 } else { 02311 ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name); 02312 clone->zombie=1; 02313 ast_mutex_unlock(&clone->lock); 02314 } 02315 02316 /* Signal any blocker */ 02317 if (original->blocking) 02318 pthread_kill(original->blocker, SIGURG); 02319 ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n", 02320 original->name, original->_state); 02321 return 0; 02322 }

struct ast_channel* ast_get_channel_by_name_locked char *  channame  ) 
 

Get channel by name (locks channel).

Definition at line 475 of file channel.c.

References ast_channel_walk_locked(), and ast_mutex_unlock.

00476 { 00477 struct ast_channel *chan; 00478 chan = ast_channel_walk_locked(NULL); 00479 while(chan) { 00480 if (!strcasecmp(chan->name, channame)) 00481 return chan; 00482 ast_mutex_unlock(&chan->lock); 00483 chan = ast_channel_walk_locked(chan); 00484 } 00485 return NULL; 00486 }

unsigned int ast_get_group char *  s  ) 
 

Definition at line 2793 of file channel.c.

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

02794 { 02795 char *copy; 02796 char *piece; 02797 char *c=NULL; 02798 int start=0, finish=0,x; 02799 unsigned int group = 0; 02800 copy = ast_strdupa(s); 02801 if (!copy) { 02802 ast_log(LOG_ERROR, "Out of memory\n"); 02803 return 0; 02804 } 02805 c = copy; 02806 02807 while((piece = strsep(&c, ","))) { 02808 if (sscanf(piece, "%d-%d", &start, &finish) == 2) { 02809 /* Range */ 02810 } else if (sscanf(piece, "%d", &start)) { 02811 /* Just one */ 02812 finish = start; 02813 } else { 02814 ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'. Using '0'\n", s,piece); 02815 return 0; 02816 } 02817 for (x=start;x<=finish;x++) { 02818 if ((x > 31) || (x < 0)) { 02819 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 31)\n", x); 02820 } else 02821 group |= (1 << x); 02822 } 02823 } 02824 return group; 02825 }

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

00655 { 00656 int res = 0; 00657 /* Don't actually hang up a channel that will masquerade as someone else, or 00658 if someone is going to masquerade as us */ 00659 ast_mutex_lock(&chan->lock); 00660 if (chan->masq) { 00661 if (ast_do_masquerade(chan)) 00662 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 00663 } 00664 00665 if (chan->masq) { 00666 ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name); 00667 ast_mutex_unlock(&chan->lock); 00668 return 0; 00669 } 00670 /* If this channel is one which will be masqueraded into something, 00671 mark it as a zombie already, so we know to free it later */ 00672 if (chan->masqr) { 00673 chan->zombie=1; 00674 ast_mutex_unlock(&chan->lock); 00675 return 0; 00676 } 00677 free_translation(chan); 00678 if (chan->stream) 00679 ast_closestream(chan->stream); 00680 if (chan->vstream) 00681 ast_closestream(chan->vstream); 00682 if (chan->sched) 00683 sched_context_destroy(chan->sched); 00684 /* Clear any tone stuff remaining */ 00685 if (chan->generatordata) 00686 chan->generator->release(chan, chan->generatordata); 00687 chan->generatordata = NULL; 00688 chan->generator = NULL; 00689 if (chan->cdr) { 00690 /* End the CDR if it hasn't already */ 00691 ast_cdr_end(chan->cdr); 00692 /* Post and Free the CDR */ 00693 ast_cdr_post(chan->cdr); 00694 ast_cdr_free(chan->cdr); 00695 } 00696 if (chan->blocking) { 00697 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 00698 "is blocked by thread %ld in procedure %s! Expect a failure\n", 00699 (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 00700 CRASH; 00701 } 00702 if (!chan->zombie) { 00703 if (option_debug) 00704 ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name); 00705 if (chan->pvt->hangup) 00706 res = chan->pvt->hangup(chan); 00707 } else 00708 if (option_debug) 00709 ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name); 00710 00711 ast_mutex_unlock(&chan->lock); 00712 manager_event(EVENT_FLAG_CALL, "Hangup", 00713 "Channel: %s\r\n" 00714 "Uniqueid: %s\r\n" 00715 "Cause: %i\r\n", 00716 chan->name, chan->uniqueid, chan->hangupcause); 00717 ast_channel_free(chan); 00718 return res; 00719 }

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

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

01335 { 01336 int res = -1; 01337 /* Stop if we're a zombie or need a soft hangup */ 01338 if (chan->zombie || ast_check_hangup(chan)) 01339 return -1; 01340 ast_mutex_lock(&chan->lock); 01341 if (chan->pvt->indicate) 01342 res = chan->pvt->indicate(chan, condition); 01343 ast_mutex_unlock(&chan->lock); 01344 if (!chan->pvt->indicate || res) { 01345 /* 01346 * Device does not support (that) indication, lets fake 01347 * it by doing our own tone generation. (PM2002) 01348 */ 01349 if (condition >= 0) { 01350 const struct tone_zone_sound *ts = NULL; 01351 switch (condition) { 01352 case AST_CONTROL_RINGING: 01353 ts = ast_get_indication_tone(chan->zone, "ring"); 01354 break; 01355 case AST_CONTROL_BUSY: 01356 ts = ast_get_indication_tone(chan->zone, "busy"); 01357 break; 01358 case AST_CONTROL_CONGESTION: 01359 ts = ast_get_indication_tone(chan->zone, "congestion"); 01360 break; 01361 } 01362 if (ts && ts->data[0]) { 01363 ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition); 01364 ast_playtones_start(chan,0,ts->data, 1); 01365 res = 0; 01366 } else if (condition == AST_CONTROL_PROGRESS) { 01367 /* ast_playtones_stop(chan); */ 01368 } else { 01369 /* not handled */ 01370 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); 01371 res = -1; 01372 } 01373 } 01374 else ast_playtones_stop(chan); 01375 } 01376 return res; 01377 }

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

01832 { 01833 char name[AST_CHANNEL_NAME] = ""; 01834 char *cut; 01835 struct ast_channel *chan; 01836 01837 chan = ast_channel_walk_locked(NULL); 01838 while (chan) { 01839 strncpy(name, chan->name, sizeof(name)-1); 01840 ast_mutex_unlock(&chan->lock); 01841 cut = strchr(name,'-'); 01842 if (cut) 01843 *cut = 0; 01844 if (!strcmp(name, device)) 01845 return AST_DEVICE_INUSE; 01846 chan = ast_channel_walk_locked(chan); 01847 } 01848 return AST_DEVICE_UNKNOWN; 01849 }

int ast_prod struct ast_channel chan  ) 
 

Definition at line 1470 of file channel.c.

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

Referenced by ast_activate_generator().

01471 { 01472 struct ast_frame a = { AST_FRAME_VOICE }; 01473 char nothing[128]; 01474 /* Send an empty audio frame to get things moving */ 01475 if (chan->_state != AST_STATE_UP) { 01476 ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name); 01477 a.subclass = chan->pvt->rawwriteformat; 01478 a.data = nothing + AST_FRIENDLY_OFFSET; 01479 if (ast_write(chan, &a)) 01480 ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name); 01481 } 01482 return 0; 01483 }

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

References ast_channel::_softhangup, ast_channel_pvt::alertpipe, ast_cdr_answer(), ast_cdr_end(), ast_check_hangup(), AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, ast_deactivate_generator(), ast_do_masquerade(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frame_dump(), AST_FRAME_NULL, AST_FRAME_VOICE, ast_frfree(), ast_getformatname(), ast_log(), AST_MAX_FDS, ast_mutex_lock, ast_mutex_unlock, ast_seekstream(), ast_setstate(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_translate(), ast_writestream(), ast_channel::blocker, ast_channel::cdr, ast_channel::deferdtmf, ast_channel::dtmff, ast_channel::dtmfq, ast_channel_pvt::exception, ast_channel::exception, ast_channel::fdno, ast_channel::fin, ast_frame::frametype, ast_generator::generate, ast_channel::generator, ast_channel::generatordata, ast_channel::insmpl, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::masq, ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, ast_frame::next, ast_channel::outsmpl, ast_channel::pvt, ast_channel_pvt::read, ast_channel_monitor::read_stream, ast_channel_pvt::readq, ast_channel_pvt::readtrans, SEEK_FORCECUR, ast_frame::subclass, ast_channel::timingdata, ast_channel::timingfd, ast_channel::timingfunc, and ast_channel::zombie.

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

01131 { 01132 struct ast_frame *f = NULL; 01133 int blah; 01134 #ifdef ZAPTEL_OPTIMIZATIONS 01135 int (*func)(void *); 01136 void *data; 01137 int res; 01138 #endif 01139 static struct ast_frame null_frame = 01140 { 01141 AST_FRAME_NULL, 01142 }; 01143 01144 ast_mutex_lock(&chan->lock); 01145 if (chan->masq) { 01146 if (ast_do_masquerade(chan)) { 01147 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01148 f = NULL; 01149 } else 01150 f = &null_frame; 01151 ast_mutex_unlock(&chan->lock); 01152 return f; 01153 } 01154 01155 /* Stop if we're a zombie or need a soft hangup */ 01156 if (chan->zombie || ast_check_hangup(chan)) { 01157 if (chan->generator) 01158 ast_deactivate_generator(chan); 01159 ast_mutex_unlock(&chan->lock); 01160 return NULL; 01161 } 01162 01163 if (!chan->deferdtmf && !ast_strlen_zero(chan->dtmfq)) { 01164 /* We have DTMF that has been deferred. Return it now */ 01165 chan->dtmff.frametype = AST_FRAME_DTMF; 01166 chan->dtmff.subclass = chan->dtmfq[0]; 01167 /* Drop first digit */ 01168 memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1); 01169 ast_mutex_unlock(&chan->lock); 01170 return &chan->dtmff; 01171 } 01172 01173 /* Read and ignore anything on the alertpipe, but read only 01174 one sizeof(blah) per frame that we send from it */ 01175 if (chan->pvt->alertpipe[0] > -1) { 01176 read(chan->pvt->alertpipe[0], &blah, sizeof(blah)); 01177 } 01178 #ifdef ZAPTEL_OPTIMIZATIONS 01179 if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && chan->exception) { 01180 chan->exception = 0; 01181 blah = -1; 01182 /* IF we can't get event, assume it's an expired as-per the old interface */ 01183 res = ioctl(chan->timingfd, ZT_GETEVENT, &blah); 01184 if (res) 01185 blah = ZT_EVENT_TIMER_EXPIRED; 01186 01187 if (blah == ZT_EVENT_TIMER_PING) { 01188 #if 0 01189 ast_log(LOG_NOTICE, "Oooh, there's a PING!\n"); 01190 #endif 01191 if (!chan->pvt->readq || !chan->pvt->readq->next) { 01192 /* Acknowledge PONG unless we need it again */ 01193 #if 0 01194 ast_log(LOG_NOTICE, "Sending a PONG!\n"); 01195 #endif 01196 if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) { 01197 ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno)); 01198 } 01199 } 01200 } else if (blah == ZT_EVENT_TIMER_EXPIRED) { 01201 ioctl(chan->timingfd, ZT_TIMERACK, &blah); 01202 func = chan->timingfunc; 01203 data = chan->timingdata; 01204 ast_mutex_unlock(&chan->lock); 01205 if (func) { 01206 #if 0 01207 ast_log(LOG_DEBUG, "Calling private function\n"); 01208 #endif 01209 func(data); 01210 } else { 01211 blah = 0; 01212 ast_mutex_lock(&chan->lock); 01213 ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah); 01214 chan->timingdata = NULL; 01215 ast_mutex_unlock(&chan->lock); 01216 } 01217 f = &null_frame; 01218 return f; 01219 } else 01220 ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name); 01221 } 01222 #endif 01223 /* Check for pending read queue */ 01224 if (chan->pvt->readq) { 01225 f = chan->pvt->readq; 01226 chan->pvt->readq = f->next; 01227 /* Interpret hangup and return NULL */ 01228 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) { 01229 ast_frfree(f); 01230 f = NULL; 01231 } 01232 } else { 01233 chan->blocker = pthread_self(); 01234 if (chan->exception) { 01235 if (chan->pvt->exception) 01236 f = chan->pvt->exception(chan); 01237 else { 01238 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name); 01239 f = &null_frame; 01240 } 01241 /* Clear the exception flag */ 01242 chan->exception = 0; 01243 } else 01244 if (chan->pvt->read) 01245 f = chan->pvt->read(chan); 01246 else 01247 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name); 01248 } 01249 01250 01251 if (f && (f->frametype == AST_FRAME_VOICE)) { 01252 if (!(f->subclass & chan->nativeformats)) { 01253 /* This frame can't be from the current native formats -- drop it on the 01254 floor */ 01255 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)); 01256 ast_frfree(f); 01257 f = &null_frame; 01258 } else { 01259 if (chan->monitor && chan->monitor->read_stream ) { 01260 #ifndef MONITOR_CONSTANT_DELAY 01261 int jump = chan->outsmpl - chan->insmpl - 2 * f->samples; 01262 if (jump >= 0) { 01263 if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1) 01264 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01265 chan->insmpl += jump + 2 * f->samples; 01266 } else 01267 chan->insmpl+= f->samples; 01268 #else 01269 int jump = chan->outsmpl - chan->insmpl; 01270 if (jump - MONITOR_DELAY >= 0) { 01271 if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1) 01272 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n"); 01273 chan->insmpl += jump; 01274 } else 01275 chan->insmpl += f->samples; 01276 #endif 01277 if (ast_writestream(chan->monitor->read_stream, f) < 0) 01278 ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n"); 01279 } 01280 if (chan->pvt->readtrans) { 01281 f = ast_translate(chan->pvt->readtrans, f, 1); 01282 if (!f) 01283 f = &null_frame; 01284 } 01285 } 01286 } 01287 01288 /* Make sure we always return NULL in the future */ 01289 if (!f) { 01290 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01291 if (chan->generator) 01292 ast_deactivate_generator(chan); 01293 /* End the CDR if appropriate */ 01294 if (chan->cdr) 01295 ast_cdr_end(chan->cdr); 01296 } else if (chan->deferdtmf && f->frametype == AST_FRAME_DTMF) { 01297 if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) 01298 chan->dtmfq[strlen(chan->dtmfq)] = f->subclass; 01299 else 01300 ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name); 01301 f = &null_frame; 01302 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) { 01303 /* Answer the CDR */ 01304 ast_setstate(chan, AST_STATE_UP); 01305 ast_cdr_answer(chan->cdr); 01306 } 01307 01308 /* Run any generator sitting on the line */ 01309 if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) { 01310 /* Mask generator data temporarily */ 01311 void *tmp; 01312 int res; 01313 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 01314 tmp = chan->generatordata; 01315 chan->generatordata = NULL; 01316 generate = chan->generator->generate; 01317 res = generate(chan, tmp, f->datalen, f->samples); 01318 chan->generatordata = tmp; 01319 if (res) { 01320 ast_log(LOG_DEBUG, "Auto-deactivating generator\n"); 01321 ast_deactivate_generator(chan); 01322 } 01323 } 01324 if (chan->fin & 0x80000000) 01325 ast_frame_dump(chan->name, f, "<<"); 01326 if ((chan->fin & 0x7fffffff) == 0x7fffffff) 01327 chan->fin &= 0x80000000; 01328 else 01329 chan->fin++; 01330 ast_mutex_unlock(&chan->lock); 01331 return f; 01332 }

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

01926 { 01927 int pos=0; 01928 int to = ftimeout; 01929 char d; 01930 /* XXX Merge with full version? XXX */ 01931 /* Stop if we're a zombie or need a soft hangup */ 01932 if (c->zombie || ast_check_hangup(c)) 01933 return -1; 01934 if (!len) 01935 return -1; 01936 do { 01937 if (c->stream) { 01938 d = ast_waitstream(c, AST_DIGIT_ANY); 01939 ast_stopstream(c); 01940 usleep(1000); 01941 if (!d) 01942 d = ast_waitfordigit(c, to); 01943 } else { 01944 d = ast_waitfordigit(c, to); 01945 } 01946 if (d < 0) 01947 return -1; 01948 if (d == 0) { 01949 s[pos]='\0'; 01950 return 1; 01951 } 01952 if (!strchr(enders, d)) 01953 s[pos++] = d; 01954 if (strchr(enders, d) || (pos >= len)) { 01955 s[pos]='\0'; 01956 return 0; 01957 } 01958 to = timeout; 01959 } while(1); 01960 /* Never reached */ 01961 return 0; 01962 }

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

01965 { 01966 int pos=0; 01967 int to = ftimeout; 01968 char d; 01969 /* Stop if we're a zombie or need a soft hangup */ 01970 if (c->zombie || ast_check_hangup(c)) 01971 return -1; 01972 if (!len) 01973 return -1; 01974 do { 01975 if (c->stream) { 01976 d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd); 01977 ast_stopstream(c); 01978 usleep(1000); 01979 if (!d) 01980 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 01981 } else { 01982 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd); 01983 } 01984 if (d < 0) 01985 return -1; 01986 if (d == 0) { 01987 s[pos]='\0'; 01988 return 1; 01989 } 01990 if (d == 1) { 01991 s[pos]='\0'; 01992 return 2; 01993 } 01994 if (!strchr(enders, d)) 01995 s[pos++] = d; 01996 if (strchr(enders, d) || (pos >= len)) { 01997 s[pos]='\0'; 01998 return 0; 01999 } 02000 to = timeout; 02001 } while(1); 02002 /* Never reached */ 02003 return 0; 02004 }

int ast_recvchar struct ast_channel chan,
int  timeout
 

Definition at line 1379 of file channel.c.

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

01380 { 01381 int res,ourto,c; 01382 struct ast_frame *f; 01383 01384 ourto = timeout; 01385 for(;;) 01386 { 01387 if (ast_check_hangup(chan)) return -1; 01388 res = ast_waitfor(chan,ourto); 01389 if (res <= 0) /* if timeout */ 01390 { 01391 return 0; 01392 } 01393 ourto = res; 01394 f = ast_read(chan); 01395 if (f == NULL) return -1; /* if hangup */ 01396 if ((f->frametype == AST_FRAME_CONTROL) && 01397 (f->subclass == AST_CONTROL_HANGUP)) return -1; /* if hangup */ 01398 if (f->frametype == AST_FRAME_TEXT) /* if a text frame */ 01399 { 01400 c = *((char *)f->data); /* get the data */ 01401 ast_frfree(f); 01402 return(c); 01403 } 01404 ast_frfree(f); 01405 } 01406 }

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

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

Referenced by __ast_request_and_dial().

01787 { 01788 struct chanlist *chan; 01789 struct ast_channel *c = NULL; 01790 int capabilities; 01791 int fmt; 01792 int res; 01793 if (ast_mutex_lock(&chlock)) { 01794 ast_log(LOG_WARNING, "Unable to lock channel list\n"); 01795 return NULL; 01796 } 01797 chan = backends; 01798 while(chan) { 01799 if (!strcasecmp(type, chan->type)) { 01800 capabilities = chan->capabilities; 01801 fmt = format; 01802 res = ast_translator_best_choice(&fmt, &capabilities); 01803 if (res < 0) { 01804 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->capabilities, format); 01805 ast_mutex_unlock(&chlock); 01806 return NULL; 01807 } 01808 ast_mutex_unlock(&chlock); 01809 if (chan->requester) 01810 c = chan->requester(type, capabilities, data); 01811 if (c) { 01812 if (c->_state == AST_STATE_DOWN) { 01813 manager_event(EVENT_FLAG_CALL, "Newchannel", 01814 "Channel: %s\r\n" 01815 "State: %s\r\n" 01816 "Callerid: %s\r\n" 01817 "Uniqueid: %s\r\n", 01818 c->name, ast_state2str(c->_state), c->callerid ? c->callerid : "<unknown>", c->uniqueid); 01819 } 01820 } 01821 return c; 01822 } 01823 chan = chan->next; 01824 } 01825 if (!chan) 01826 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type); 01827 ast_mutex_unlock(&chlock); 01828 return c; 01829 }

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

References __ast_request_and_dial(), and type.

Referenced by ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().

01782 { 01783 return __ast_request_and_dial(type, format, data, timeout, outstate, callerid, NULL); 01784 }

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

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

Referenced by ast_dtmf_stream().

00510 { 00511 struct ast_frame *f; 00512 while(ms > 0) { 00513 ms = ast_waitfor(chan, ms); 00514 if (ms <0) 00515 return -1; 00516 if (ms > 0) { 00517 f = ast_read(chan); 00518 if (!f) 00519 return -1; 00520 ast_frfree(f); 00521 } 00522 } 00523 return 0; 00524 }

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

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

00490 { 00491 struct ast_frame *f; 00492 00493 while(ms > 0) { 00494 if( cond && ((*cond)(data) == 0 ) ) 00495 return 0; 00496 ms = ast_waitfor(chan, ms); 00497 if (ms <0) 00498 return -1; 00499 if (ms > 0) { 00500 f = ast_read(chan); 00501 if (!f) 00502 return -1; 00503 ast_frfree(f); 00504 } 00505 } 00506 return 0; 00507 }

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

01466 { 01467 return do_senddigit(chan, digit); 01468 }

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

01409 { 01410 int res = 0; 01411 /* Stop if we're a zombie or need a soft hangup */ 01412 if (chan->zombie || ast_check_hangup(chan)) 01413 return -1; 01414 CHECK_BLOCKING(chan); 01415 if (chan->pvt->send_text) 01416 res = chan->pvt->send_text(chan, text); 01417 chan->blocking = 0; 01418 return res; 01419 }

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

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

02325 { 02326 if (chan->callerid) 02327 free(chan->callerid); 02328 if (anitoo && chan->ani) 02329 free(chan->ani); 02330 if (callerid) { 02331 chan->callerid = strdup(callerid); 02332 if (anitoo) 02333 chan->ani = strdup(callerid); 02334 } else { 02335 chan->callerid = NULL; 02336 if (anitoo) 02337 chan->ani = NULL; 02338 } 02339 if (chan->cdr) 02340 ast_cdr_setcid(chan->cdr, chan); 02341 manager_event(EVENT_FLAG_CALL, "Newcallerid", 02342 "Channel: %s\r\n" 02343 "Callerid: %s\r\n" 02344 "Uniqueid: %s\r\n", 02345 chan->name, chan->callerid ? 02346 chan->callerid : "<Unknown>", 02347 chan->uniqueid); 02348 }

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 1637 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, option_debug, ast_channel::pvt, ast_channel_pvt::rawreadformat, ast_channel::readformat, and ast_channel_pvt::readtrans.

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

01638 { 01639 int fmt; 01640 int native; 01641 int res; 01642 01643 ast_mutex_lock(&chan->lock); 01644 native = chan->nativeformats; 01645 fmt = fmts; 01646 /* Find a translation path from the native read format to one of the user's read formats */ 01647 res = ast_translator_best_choice(&fmt, &native); 01648 if (res < 0) { 01649 ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n", 01650 ast_getformatname(chan->nativeformats), ast_getformatname(fmts)); 01651 ast_mutex_unlock(&chan->lock); 01652 return -1; 01653 } 01654 01655 /* Now we have a good choice for both. We'll write using our native format. */ 01656 chan->pvt->rawreadformat = native; 01657 /* User perspective is fmt */ 01658 chan->readformat = fmt; 01659 /* Free any read translation we have right now */ 01660 if (chan->pvt->readtrans) 01661 ast_translator_free_path(chan->pvt->readtrans); 01662 /* Build a translation path from the raw read format to the user reading format */ 01663 chan->pvt->readtrans = ast_translator_build_path(chan->readformat, chan->pvt->rawreadformat); 01664 if (option_debug) 01665 ast_log(LOG_DEBUG, "Set channel %s to read format %s\n", 01666 chan->name, ast_getformatname(chan->readformat)); 01667 ast_mutex_unlock(&chan->lock); 01668 return 0; 01669 }

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

01605 { 01606 int fmt; 01607 int native; 01608 int res; 01609 01610 ast_mutex_lock(&chan->lock); 01611 native = chan->nativeformats; 01612 fmt = fmts; 01613 01614 res = ast_translator_best_choice(&native, &fmt); 01615 if (res < 0) { 01616 ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n", 01617 ast_getformatname(fmts), ast_getformatname(chan->nativeformats)); 01618 ast_mutex_unlock(&chan->lock); 01619 return -1; 01620 } 01621 01622 /* Now we have a good choice for both. We'll write using our native format. */ 01623 chan->pvt->rawwriteformat = native; 01624 /* User perspective is fmt */ 01625 chan->writeformat = fmt; 01626 /* Free any write translation we have right now */ 01627 if (chan->pvt->writetrans) 01628 ast_translator_free_path(chan->pvt->writetrans); 01629 /* Build a translation path from the user write format to the raw writing format */ 01630 chan->pvt->writetrans = ast_translator_build_path(chan->pvt->rawwriteformat, chan->writeformat); 01631 if (option_debug) 01632 ast_log(LOG_DEBUG, "Set channel %s to write format %s\n", chan->name, ast_getformatname(chan->writeformat)); 01633 ast_mutex_unlock(&chan->lock); 01634 return 0; 01635 }

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

Definition at line 1060 of file channel.c.

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

Referenced by ast_closestream().

01061 { 01062 int res = -1; 01063 #ifdef ZAPTEL_OPTIMIZATIONS 01064 if (c->timingfd > -1) { 01065 if (!func) { 01066 samples = 0; 01067 data = 0; 01068 } 01069 ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples); 01070 res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples); 01071 c->timingfunc = func; 01072 c->timingdata = data; 01073 } 01074 #endif 01075 return res; 01076 }

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

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

Referenced by ast_begin_shutdown().

00634 { 00635 int res; 00636 ast_mutex_lock(&chan->lock); 00637 res = ast_softhangup_nolock(chan, cause); 00638 ast_mutex_unlock(&chan->lock); 00639 return res; 00640 }

int ast_softhangup_nolock struct ast_channel chan,
int  cause
 

Definition at line 618 of file channel.c.

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

Referenced by ast_async_goto(), and ast_softhangup().

00619 { 00620 int res = 0; 00621 struct ast_frame f = { AST_FRAME_NULL }; 00622 if (option_debug) 00623 ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name); 00624 /* Inform channel driver that we need to be hung up, if it cares */ 00625 chan->_softhangup |= cause; 00626 ast_queue_frame(chan, &f); 00627 /* Interrupt any poll call or such */ 00628 if (chan->blocking) 00629 pthread_kill(chan->blocker, SIGURG); 00630 return res; 00631 }

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

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

02776 { 02777 struct ast_frame *f; 02778 int res; 02779 if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol))) 02780 return res; 02781 02782 /* Give us some wiggle room */ 02783 while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) { 02784 f = ast_read(chan); 02785 if (f) 02786 ast_frfree(f); 02787 else 02788 return -1; 02789 } 02790 return 0; 02791 }

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

Start a tone going

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

02756 { 02757 struct tonepair_def d = { 0, }; 02758 d.freq1 = freq1; 02759 d.freq2 = freq2; 02760 d.duration = duration; 02761 if (vol < 1) 02762 d.vol = 8192; 02763 else 02764 d.vol = vol; 02765 if (ast_activate_generator(chan, &tonepair, &d)) 02766 return -1; 02767 return 0; 02768 }

void ast_tonepair_stop struct ast_channel chan  ) 
 

Stop a tone from playing

Definition at line 2770 of file channel.c.

References ast_deactivate_generator().

02771 { 02772 ast_deactivate_generator(chan); 02773 }

int ast_transfer struct ast_channel chan,
char *  dest
 

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

01906 { 01907 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 01908 If the remote end does not answer within the timeout, then do NOT hang up, but 01909 return anyway. */ 01910 int res = -1; 01911 /* Stop if we're a zombie or need a soft hangup */ 01912 ast_mutex_lock(&chan->lock); 01913 if (!chan->zombie && !ast_check_hangup(chan)) { 01914 if (chan->pvt->transfer) { 01915 res = chan->pvt->transfer(chan, dest); 01916 if (!res) 01917 res = 1; 01918 } else 01919 res = 0; 01920 } 01921 ast_mutex_unlock(&chan->lock); 01922 return res; 01923 }

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

References ast_waitfor_n().

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

01020 { 01021 struct ast_channel *chan; 01022 int oldms = ms; 01023 chan = ast_waitfor_n(&c, 1, &ms); 01024 if (ms < 0) { 01025 if (oldms < 0) 01026 return 0; 01027 else 01028 return -1; 01029 } 01030 return ms; 01031 }

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

References ast_waitfor_nandfds().

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

01015 { 01016 return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms); 01017 }

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

References ast_log(), LOG_WARNING, poll(), POLLIN, and POLLPRI.

00811 { 00812 /* Wait for x amount of time on a file descriptor to have input. */ 00813 struct timeval start, now; 00814 int res; 00815 int x, y; 00816 int winner = -1; 00817 int spoint; 00818 struct pollfd *pfds; 00819 00820 pfds = alloca(sizeof(struct pollfd) * n); 00821 if (!pfds) { 00822 ast_log(LOG_WARNING, "alloca failed! bad things will happen.\n"); 00823 return -1; 00824 } 00825 if (*ms > 0) 00826 gettimeofday(&start, NULL); 00827 y = 0; 00828 for (x=0;x<n;x++) { 00829 if (fds[x] > -1) { 00830 pfds[y].fd = fds[x]; 00831 pfds[y].events = POLLIN | POLLPRI; 00832 y++; 00833 } 00834 } 00835 res = poll(pfds, y, *ms); 00836 if (res < 0) { 00837 /* Simulate a timeout if we were interrupted */ 00838 if (errno != EINTR) 00839 *ms = -1; 00840 else 00841 *ms = 0; 00842 return -1; 00843 } 00844 spoint = 0; 00845 for (x=0;x<n;x++) { 00846 if (fds[x] > -1) { 00847 if ((res = ast_fdisset(pfds, fds[x], y, &spoint))) { 00848 winner = fds[x]; 00849 if (exception) { 00850 if (res & POLLPRI) 00851 *exception = -1; 00852 else 00853 *exception = 0; 00854 } 00855 } 00856 } 00857 } 00858 if (*ms > 0) { 00859 long passed; 00860 gettimeofday(&now, NULL); 00861 passed = (now.tv_sec - start.tv_sec) * 1000; 00862 passed += (now.tv_usec - start.tv_usec) / 1000; 00863 if (passed <= *ms) 00864 *ms -= passed; 00865 else 00866 *ms = 0; 00867 } 00868 return winner; 00869 }

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

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

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

00873 { 00874 /* Wait for x amount of time on a file descriptor to have input. */ 00875 struct timeval start, end; 00876 struct pollfd *pfds; 00877 int res; 00878 long rms; 00879 int x, y, max; 00880 int spoint; 00881 time_t now = 0; 00882 long whentohangup = 0, havewhen = 0, diff; 00883 struct ast_channel *winner = NULL; 00884 00885 pfds = alloca(sizeof(struct pollfd) * (n * AST_MAX_FDS + nfds)); 00886 if (!pfds) { 00887 ast_log(LOG_WARNING, "alloca failed! bad things will happen.\n"); 00888 *outfd = -1; 00889 return NULL; 00890 } 00891 00892 if (outfd) 00893 *outfd = -99999; 00894 if (exception) 00895 *exception = 0; 00896 00897 /* Perform any pending masquerades */ 00898 for (x=0;x<n;x++) { 00899 ast_mutex_lock(&c[x]->lock); 00900 if (c[x]->whentohangup) { 00901 if (!havewhen) 00902 time(&now); 00903 diff = c[x]->whentohangup - now; 00904 if (!havewhen || (diff < whentohangup)) { 00905 havewhen++; 00906 whentohangup = diff; 00907 } 00908 } 00909 if (c[x]->masq) { 00910 if (ast_do_masquerade(c[x])) { 00911 ast_log(LOG_WARNING, "Masquerade failed\n"); 00912 *ms = -1; 00913 ast_mutex_unlock(&c[x]->lock); 00914 return NULL; 00915 } 00916 } 00917 ast_mutex_unlock(&c[x]->lock); 00918 } 00919 00920 rms = *ms; 00921 00922 if (havewhen) { 00923 if ((*ms < 0) || (whentohangup * 1000 < *ms)) { 00924 rms = whentohangup * 1000; 00925 } 00926 } 00927 max = 0; 00928 for (x=0;x<n;x++) { 00929 for (y=0;y<AST_MAX_FDS;y++) { 00930 if (c[x]->fds[y] > -1) { 00931 pfds[max].fd = c[x]->fds[y]; 00932 pfds[max].events = POLLIN | POLLPRI; 00933 max++; 00934 } 00935 } 00936 CHECK_BLOCKING(c[x]); 00937 } 00938 for (x=0;x<nfds; x++) { 00939 if (fds[x] > -1) { 00940 pfds[max].fd = fds[x]; 00941 pfds[max].events = POLLIN | POLLPRI; 00942 max++; 00943 } 00944 } 00945 if (*ms > 0) 00946 gettimeofday(&start, NULL); 00947 res = poll(pfds, max, rms); 00948 if (res < 0) { 00949 for (x=0;x<n;x++) 00950 c[x]->blocking = 0; 00951 /* Simulate a timeout if we were interrupted */ 00952 if (errno != EINTR) 00953 *ms = -1; 00954 else { 00955 /* Just an interrupt */ 00956 #if 0 00957 *ms = 0; 00958 #endif 00959 } 00960 return NULL; 00961 } 00962 00963 if (havewhen) 00964 time(&now); 00965 spoint = 0; 00966 for (x=0;x<n;x++) { 00967 c[x]->blocking = 0; 00968 if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) { 00969 c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT; 00970 if (!winner) 00971 winner = c[x]; 00972 } 00973 for (y=0;y<AST_MAX_FDS;y++) { 00974 if (c[x]->fds[y] > -1) { 00975 if ((res = ast_fdisset(pfds, c[x]->fds[y], max, &spoint))) { 00976 if (res & POLLPRI) 00977 c[x]->exception = -1; 00978 else 00979 c[x]->exception = 0; 00980 c[x]->fdno = y; 00981 winner = c[x]; 00982 } 00983 } 00984 } 00985 } 00986 for (x=0;x<nfds;x++) { 00987 if (fds[x] > -1) { 00988 if ((res = ast_fdisset(pfds, fds[x], max, &spoint))) { 00989 if (outfd) 00990 *outfd = fds[x]; 00991 if (exception) { 00992 if (res & POLLPRI) 00993 *exception = -1; 00994 else 00995 *exception = 0; 00996 } 00997 winner = NULL; 00998 } 00999 } 01000 } 01001 if (*ms > 0) { 01002 long diff; 01003 gettimeofday(&end, NULL); 01004 diff = (end.tv_sec - start.tv_sec) * 1000; 01005 diff += (end.tv_usec - start.tv_usec) / 1000; 01006 if (diff < *ms) 01007 *ms -= diff; 01008 else 01009 *ms = 0; 01010 } 01011 return winner; 01012 }

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

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

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

01034 { 01035 /* XXX Should I be merged with waitfordigit_full XXX */ 01036 struct ast_frame *f; 01037 char result = 0; 01038 /* Stop if we're a zombie or need a soft hangup */ 01039 if (c->zombie || ast_check_hangup(c)) 01040 return -1; 01041 /* Wait for a digit, no more than ms milliseconds total. */ 01042 while(ms && !result) { 01043 ms = ast_waitfor(c, ms); 01044 if (ms < 0) /* Error */ 01045 result = -1; 01046 else if (ms > 0) { 01047 /* Read something */ 01048 f = ast_read(c); 01049 if (f) { 01050 if (f->frametype == AST_FRAME_DTMF) 01051 result = f->subclass; 01052 ast_frfree(f); 01053 } else 01054 result = -1; 01055 } 01056 } 01057 return result; 01058 }

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

Definition at line 1077 of file channel.c.

References ast_check_hangup(), AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_read(), ast_waitfor_nandfds(), LOG_WARNING, and ast_channel::zombie.

Referenced by ast_readstring_full().

01078 { 01079 struct ast_frame *f; 01080 struct ast_channel *rchan; 01081 int outfd; 01082 int res; 01083 /* Stop if we're a zombie or need a soft hangup */ 01084 if (c->zombie || ast_check_hangup(c)) 01085 return -1; 01086 /* Wait for a digit, no more than ms milliseconds total. */ 01087 while(ms) { 01088 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01089 if ((!rchan) && (outfd < 0) && (ms)) { 01090 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01091 return -1; 01092 } else if (outfd > -1) { 01093 /* The FD we were watching has something waiting */ 01094 return 1; 01095 } else if (rchan) { 01096 f = ast_read(c); 01097 if(!f) { 01098 return -1; 01099 } 01100 01101 switch(f->frametype) { 01102 case AST_FRAME_DTMF: 01103 res = f->subclass; 01104 ast_frfree(f); 01105 return res; 01106 case AST_FRAME_CONTROL: 01107 switch(f->subclass) { 01108 case AST_CONTROL_HANGUP: 01109 ast_frfree(f); 01110 return -1; 01111 case AST_CONTROL_RINGING: 01112 case AST_CONTROL_ANSWER: 01113 /* Unimportant */ 01114 break; 01115 default: 01116 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass); 01117 } 01118 case AST_FRAME_VOICE: 01119 /* Write audio if appropriate */ 01120 if (audiofd > -1) 01121 write(audiofd, f->data, f->datalen); 01122 } 01123 /* Ignore */ 01124 ast_frfree(f); 01125 } 01126 } 01127 return 0; // Time is up 01128 }

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

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

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

01497 { 01498 int res = -1; 01499 struct ast_frame *f = NULL; 01500 /* Stop if we're a zombie or need a soft hangup */ 01501 ast_mutex_lock(&chan->lock); 01502 if (chan->zombie || ast_check_hangup(chan)) { 01503 ast_mutex_unlock(&chan->lock); 01504 return -1; 01505 } 01506 /* Handle any pending masquerades */ 01507 if (chan->masq) { 01508 if (ast_do_masquerade(chan)) { 01509 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01510 ast_mutex_unlock(&chan->lock); 01511 return -1; 01512 } 01513 } 01514 if (chan->masqr) { 01515 ast_mutex_unlock(&chan->lock); 01516 return 0; 01517 } 01518 if (chan->generatordata) { 01519 if (chan->writeinterrupt) 01520 ast_deactivate_generator(chan); 01521 else { 01522 ast_mutex_unlock(&chan->lock); 01523 return 0; 01524 } 01525 } 01526 if (chan->fout & 0x80000000) 01527 ast_frame_dump(chan->name, fr, ">>"); 01528 CHECK_BLOCKING(chan); 01529 switch(fr->frametype) { 01530 case AST_FRAME_CONTROL: 01531 /* XXX Interpret control frames XXX */ 01532 ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n"); 01533 break; 01534 case AST_FRAME_DTMF: 01535 chan->blocking = 0; 01536 ast_mutex_unlock(&chan->lock); 01537 res = do_senddigit(chan,fr->subclass); 01538 ast_mutex_lock(&chan->lock); 01539 CHECK_BLOCKING(chan); 01540 break; 01541 case AST_FRAME_TEXT: 01542 if (chan->pvt->send_text) 01543 res = chan->pvt->send_text(chan, (char *) fr->data); 01544 break; 01545 case AST_FRAME_VIDEO: 01546 /* XXX Handle translation of video codecs one day XXX */ 01547 if (chan->pvt->write_video) 01548 res = chan->pvt->write_video(chan, fr); 01549 else 01550 res = 0; 01551 break; 01552 default: 01553 if (chan->pvt->write) { 01554 if (chan->pvt->writetrans) { 01555 f = ast_translate(chan->pvt->writetrans, fr, 0); 01556 } else 01557 f = fr; 01558 if (f) { 01559 res = chan->pvt->write(chan, f); 01560 if( chan->monitor && 01561 chan->monitor->write_stream && 01562 f && ( f->frametype == AST_FRAME_VOICE ) ) { 01563 #ifndef MONITOR_CONSTANT_DELAY 01564 int jump = chan->insmpl - chan->outsmpl - 2 * f->samples; 01565 if (jump >= 0) { 01566 if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1) 01567 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 01568 chan->outsmpl += jump + 2 * f->samples; 01569 } else 01570 chan->outsmpl += f->samples; 01571 #else 01572 int jump = chan->insmpl - chan->outsmpl; 01573 if (jump - MONITOR_DELAY >= 0) { 01574 if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1) 01575 ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n"); 01576 chan->outsmpl += jump; 01577 } else 01578 chan->outsmpl += f->samples; 01579 #endif 01580 if (ast_writestream(chan->monitor->write_stream, f) < 0) 01581 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n"); 01582 } 01583 } else 01584 res = 0; 01585 } 01586 } 01587 if (f && (f != fr)) 01588 ast_frfree(f); 01589 chan->blocking = 0; 01590 /* Consider a write failure to force a soft hangup */ 01591 if (res < 0) 01592 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01593 else { 01594 if ((chan->fout & 0x7fffffff) == 0x7fffffff) 01595 chan->fout &= 0x80000000; 01596 else 01597 chan->fout++; 01598 chan->fout++; 01599 } 01600 ast_mutex_unlock(&chan->lock); 01601 return res; 01602 }

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

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

01486 { 01487 int res; 01488 if (!chan->pvt->write_video) 01489 return 0; 01490 res = ast_write(chan, fr); 01491 if (!res) 01492 res = 1; 01493 return res; 01494 }


Generated on Sat Jun 12 16:41:09 2004 for Asterisk by doxygen 1.3.7