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

channel.h File Reference

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

Go to the source code of this file.

Data Structures

struct  ast_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
#define LOAD_OH(oh)
#define AST_CDR_TRANSFER   (1 << 0)
#define AST_CDR_FORWARD   (1 << 1)
#define AST_CDR_CALLWAIT   (1 << 2)
#define AST_CDR_CONFERENCE   (1 << 3)
#define AST_ADSI_UNKNOWN   (0)
#define AST_ADSI_AVAILABLE   (1)
#define AST_ADSI_UNAVAILABLE   (2)
#define AST_ADSI_OFFHOOKONLY   (3)
#define AST_SOFTHANGUP_DEV   (1 << 0)
#define AST_SOFTHANGUP_ASYNCGOTO   (1 << 1)
#define AST_SOFTHANGUP_SHUTDOWN   (1 << 2)
#define AST_SOFTHANGUP_TIMEOUT   (1 << 3)
#define AST_SOFTHANGUP_APPUNLOAD   (1 << 4)
#define AST_SOFTHANGUP_EXPLICIT   (1 << 5)
#define AST_STATE_DOWN   0
#define AST_STATE_RESERVED   1
#define AST_STATE_OFFHOOK   2
#define AST_STATE_DIALING   3
#define AST_STATE_RING   4
#define AST_STATE_RINGING   5
#define AST_STATE_UP   6
#define AST_STATE_BUSY   7
#define AST_STATE_DIALING_OFFHOOK   8
#define AST_STATE_PRERING   9
#define AST_STATE_MUTE   (1 << 16)
#define AST_DEVICE_UNKNOWN   0
#define AST_DEVICE_NOT_INUSE   1
#define AST_DEVICE_INUSE   2
#define AST_DEVICE_BUSY   3
#define AST_DEVICE_INVALID   4
#define AST_DEVICE_UNAVAILABLE   5
#define AST_BRIDGE_DTMF_CHANNEL_0   (1 << 0)
#define AST_BRIDGE_DTMF_CHANNEL_1   (1 << 1)
#define AST_BRIDGE_REC_CHANNEL_0   (1 << 2)
#define AST_BRIDGE_REC_CHANNEL_1   (1 << 3)
#define AST_BRIDGE_IGNORE_SIGS   (1 << 4)
#define CRASH   do { } while(0)
#define CHECK_BLOCKING(c)

Functions

ast_channelast_request (char *type, int format, void *data)
 Requests a channel.
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 311 of file channel.h.

#define AST_ADSI_OFFHOOKONLY   (3)
 

Definition at line 313 of file channel.h.

#define AST_ADSI_UNAVAILABLE   (2)
 

Definition at line 312 of file channel.h.

#define AST_ADSI_UNKNOWN   (0)
 

Definition at line 310 of file channel.h.

#define AST_BRIDGE_DTMF_CHANNEL_0   (1 << 0)
 

Report DTMF on channel 0 Definition at line 665 of file channel.h.

Referenced by ast_channel_bridge(), and ast_rtp_bridge().

#define AST_BRIDGE_DTMF_CHANNEL_1   (1 << 1)
 

Report DTMF on channel 1 Definition at line 667 of file channel.h.

Referenced by ast_channel_bridge(), and ast_rtp_bridge().

#define AST_BRIDGE_IGNORE_SIGS   (1 << 4)
 

Ignore all signal frames except NULL Definition at line 673 of file channel.h.

Referenced by ast_channel_bridge().

#define AST_BRIDGE_REC_CHANNEL_0   (1 << 2)
 

Return all voice frames on channel 0 Definition at line 669 of file channel.h.

#define AST_BRIDGE_REC_CHANNEL_1   (1 << 3)
 

Return all voice frames on channel 1 Definition at line 671 of file channel.h.

#define AST_CDR_CALLWAIT   (1 << 2)
 

Definition at line 307 of file channel.h.

#define AST_CDR_CONFERENCE   (1 << 3)
 

Definition at line 308 of file channel.h.

#define AST_CDR_FORWARD   (1 << 1)
 

Definition at line 306 of file channel.h.

#define AST_CDR_TRANSFER   (1 << 0)
 

Definition at line 305 of file channel.h.

#define AST_CHANNEL_MAX_STACK   32
 

Definition at line 38 of file channel.h.

Referenced by pbx_exec().

#define AST_CHANNEL_NAME   80
 

Definition at line 37 of file channel.h.

Referenced by ast_channel_free(), and ast_parse_device_state().

#define AST_DEVICE_BUSY   3
 

Device is busy Definition at line 355 of file channel.h.

#define AST_DEVICE_INUSE   2
 

Device is in use Definition at line 353 of file channel.h.

Referenced by ast_parse_device_state().

#define AST_DEVICE_INVALID   4
 

Device is invalid Definition at line 357 of file channel.h.

Referenced by ast_device_state().

#define AST_DEVICE_NOT_INUSE   1
 

Device is not used Definition at line 351 of file channel.h.

#define AST_DEVICE_UNAVAILABLE   5
 

Device is unavailable Definition at line 359 of file channel.h.

#define AST_DEVICE_UNKNOWN   0
 

Device is valid but channel didn't know state Definition at line 349 of file channel.h.

Referenced by ast_device_state(), and ast_parse_device_state().

#define AST_FLAG_DIGITAL   1
 

Definition at line 236 of file channel.h.

#define AST_MAX_EXTENSION   80
 

Max length of an extension.

Definition at line 31 of file channel.h.

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

#define AST_MAX_FDS   8
 

Definition at line 43 of file channel.h.

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

#define AST_SOFTHANGUP_APPUNLOAD   (1 << 4)
 

Definition at line 319 of file channel.h.

#define AST_SOFTHANGUP_ASYNCGOTO   (1 << 1)
 

Definition at line 316 of file channel.h.

Referenced by ast_async_goto(), and ast_pbx_run().

#define AST_SOFTHANGUP_DEV   (1 << 0)
 

Definition at line 315 of file channel.h.

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

#define AST_SOFTHANGUP_EXPLICIT   (1 << 5)
 

Definition at line 320 of file channel.h.

#define AST_SOFTHANGUP_SHUTDOWN   (1 << 2)
 

Definition at line 317 of file channel.h.

Referenced by ast_begin_shutdown().

#define AST_SOFTHANGUP_TIMEOUT   (1 << 3)
 

Definition at line 318 of file channel.h.

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

#define AST_STATE_BUSY   7
 

Line is busy Definition at line 338 of file channel.h.

Referenced by ast_state2str().

#define AST_STATE_DIALING   3
 

Digits (or equivalent) have been dialed Definition at line 330 of file channel.h.

Referenced by ast_state2str().

#define AST_STATE_DIALING_OFFHOOK   8
 

Digits (or equivalent) have been dialed while offhook Definition at line 340 of file channel.h.

#define AST_STATE_DOWN   0
 

Channel is down and available Definition at line 324 of file channel.h.

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

#define AST_STATE_MUTE   (1 << 16)
 

Do not transmit voice data Definition at line 346 of file channel.h.

#define AST_STATE_OFFHOOK   2
 

Channel is off hook Definition at line 328 of file channel.h.

Referenced by ast_state2str().

#define AST_STATE_PRERING   9
 

Channel has detected an incoming call and is waiting for ring Definition at line 342 of file channel.h.

#define AST_STATE_RESERVED   1
 

Channel is down, but reserved Definition at line 326 of file channel.h.

Referenced by ast_state2str().

#define AST_STATE_RING   4
 

Line is ringing Definition at line 332 of file channel.h.

Referenced by ast_answer(), and ast_state2str().

#define AST_STATE_RINGING   5
 

Remote end is ringing Definition at line 334 of file channel.h.

Referenced by ast_answer(), and ast_state2str().

#define AST_STATE_UP   6
 

Line is up Definition at line 336 of file channel.h.

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

#define CHECK_BLOCKING  ) 
 

Definition at line 879 of file channel.h.

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

#define CRASH   do { } while(0)
 

Definition at line 876 of file channel.h.

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

#define LOAD_OH oh   ) 
 

Definition at line 287 of file channel.h.

Referenced by ast_pbx_outgoing_exten().

#define MAX_LANGUAGE   20
 

Definition at line 40 of file channel.h.

Referenced by ast_fileexists(), and ast_openvstream().


Function Documentation

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

Definition at line 1746 of file channel.c.

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

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

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

Activate a given generator Definition at line 849 of file channel.c.

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

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

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

int ast_active_channels void   ) 
 

Returns number of active/allocated channels Definition at line 120 of file channel.c.

References ast_mutex_lock, ast_mutex_unlock, 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 785 of file channel.c.

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

Referenced by ast_control_streamfile().

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

int ast_autoservice_start struct ast_channel chan  ) 
 

Automatically service a channel for us... Definition at line 88 of file autoservice.c.

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

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

int ast_autoservice_stop struct ast_channel chan  ) 
 

Stop servicing a channel for us... Returns -1 on error or if channel has been hungup Definition at line 124 of file autoservice.c.

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

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

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

void ast_begin_shutdown int  hangup  ) 
 

Initiate system shutdown -- prevents new channels from being allocated. If "hangup" is non-zero, all existing channels will receive soft hangups Definition at line 105 of file channel.c.

References ast_mutex_lock, ast_mutex_unlock, ast_softhangup(), AST_SOFTHANGUP_SHUTDOWN, and 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 1965 of file channel.c.

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

Referenced by __ast_request_and_dial().

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

void ast_cancel_shutdown void   ) 
 

Cancels an existing shutdown and returns to normal operation Definition at line 134 of file channel.c.

00135 { 00136 shutting_down = 0; 00137 }

int ast_channel_bridge struct ast_channel c0,
struct ast_channel c1,
struct ast_bridge_config config,
struct ast_frame **  fo,
struct ast_channel **  rc
 

Bridge two channels together.

Parameters:
c0 first channel to bridge
c1 second channel to bridge
flags for the channels
fo destination frame(?)
rc destination channel(?) Bridge two channels (c0 and c1) together. If an important frame occurs, we return that frame in rf (remember, it could be NULL) and which channel (0 or 1) in rc
Definition at line 2497 of file channel.c.

References ast_bridge_config::allowdisconnect_in, ast_bridge_config::allowdisconnect_out, ast_bridge_config::allowredirect_in, ast_bridge_config::allowredirect_out, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_IGNORE_SIGS, ast_channel_make_compatible(), ast_check_hangup(), AST_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, ast_bridge_config::firstpass, 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.

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

int ast_channel_defer_dtmf struct ast_channel chan  ) 
 

Defers DTMF.

Defer DTMF so that you only read things like hangups and audio. Returns non-zero if channel was already DTMF-deferred or 0 if channel is just now being DTMF-deferred Definition at line 441 of file channel.c.

References ast_channel::deferdtmf.

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

int ast_channel_make_compatible struct ast_channel c0,
struct ast_channel c1
 

Makes two channel formats compatible.

Parameters:
c0 first channel to make compatible
c1 other channel to make compatible Set two channels to compatible formats -- call before ast_channel_bridge in general . Returns 0 on success and -1 if it could not be done
Definition at line 2102 of file channel.c.

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

Referenced by ast_channel_bridge().

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

int ast_channel_masquerade struct ast_channel original,
struct ast_channel clone
 

Weird function made for call transfers.

Parameters:
original channel to make a copy of
clone copy of the original channel This is a very strange and freaky function used primarily for transfer. Suppose that "original" and "clone" are two channels in random situations. This function takes the guts out of "clone" and puts them into the "original" channel, then alerts the channel driver of the change, asking it to fixup any private information (like the p->owner pointer) that is affected by the change. The physical layer of the original channel is hung up.
Definition at line 2153 of file channel.c.

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

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

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

Checks the value of an option.

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

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

Registers a channel.

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

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

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

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

Definition at line 162 of file channel.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), backends, 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 2088 of file channel.c.

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

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

int ast_channel_sendurl struct ast_channel channel,
char *  url
 

Sends a URL on a given link.

Send URL on link. Returns 0 on success or -1 on failure Definition at line 2095 of file channel.c.

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

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

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

Sets an option on a channel.

Parameters:
channel channel to set options on
option option to change
data data specific to option
datalen length of the data
block blocking or not Set an option on a channel (see frame.h), optionally blocking awaiting the reply Returns 0 on success and -1 on failure
Definition at line 2729 of file channel.c.

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

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

void ast_channel_setwhentohangup struct ast_channel chan,
time_t  offset
 

Set when to hang a channel up.

Parameters:
chan channel on which to check for hang up
offset offset in seconds from current time of when to hang up This function sets the absolute time out on a channel (when to hang up).
Definition at line 144 of file channel.c.

References ast_channel::whentohangup.

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

int ast_channel_supports_html struct ast_channel channel  ) 
 

Checks for HTML support on a channel.

Returns 0 if channel does not support HTML or non-zero if it does Definition at line 2081 of file channel.c.

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

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

void ast_channel_undefer_dtmf struct ast_channel chan  ) 
 

Undeos a defer.

Undo defer. ast_read will return any dtmf characters that were queued Definition at line 451 of file channel.c.

References ast_channel::deferdtmf.

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

void ast_channel_unregister char *  type  ) 
 

Unregister a channel class.

Definition at line 756 of file channel.c.

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

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

struct ast_channel* ast_channel_walk_locked struct ast_channel prev  ) 
 

Browse channels in use.

Parameters:
prev where you want to start in the channel list Browse the channels currently in use Returns the next channel in the list, NULL on end. If it returns a channel, that channel *has been locked*!
Definition at line 457 of file channel.c.

References ast_log(), ast_mutex_lock, ast_mutex_trylock, ast_mutex_unlock, channels, LOG_DEBUG, and LOG_WARNING.

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

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

int ast_check_hangup struct ast_channel chan  ) 
 

Check to see if a channel is needing hang up.

Parameters:
chan channel on which to check for hang up This function determines if the channel is being requested to be hung up. Returns 0 if not, or 1 if hang up is requested (including time-out).
Definition at line 79 of file channel.c.

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

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

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

void ast_deactivate_generator struct ast_channel chan  ) 
 

Deactive an active generator Definition at line 816 of file channel.c.

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

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

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

int ast_device_state char *  device  ) 
 

Asks a channel for device state.

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

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

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

int ast_do_masquerade struct ast_channel chan  ) 
 

Definition at line 2192 of file channel.c.

References ast_channel::_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, ast_channel::uniqueid, and ast_channel::writeformat.

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

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

struct ast_channel* ast_get_channel_by_name_locked char *  channame  ) 
 

Get channel by name (locks channel).

Definition at line 510 of file channel.c.

References ast_channel_walk_locked(), and ast_mutex_unlock.

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

unsigned int ast_get_group char *  s  ) 
 

Definition at line 2881 of file channel.c.

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

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

int ast_hangup struct ast_channel chan  ) 
 

Hang up a channel.

Parameters:
chan channel to hang up This function performs a hard hangup on a channel. Unlike the soft-hangup, this function performs all stream stopping, etc, on the channel that needs to end. chan is no longer valid after this call. Returns 0 on success, -1 on failure.
Definition at line 689 of file channel.c.

References ast_cdr_end(), ast_cdr_free(), ast_cdr_post(), ast_channel_free(), ast_closestream(), ast_do_masquerade(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_channel::blocker, ast_channel::blocking, ast_channel::blockproc, ast_channel::cdr, CRASH, EVENT_FLAG_CALL, ast_channel::generator, ast_channel::generatordata, ast_channel_pvt::hangup, ast_channel::hangupcause, ast_channel::lock, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::name, 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().

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

int ast_indicate struct ast_channel chan,
int  condition
 

Indicates condition of channel.

Parameters:
chan channel to change the indication
condition which condition to indicate on the channel Indicate a condition such as AST_CONTROL_BUSY, AST_CONTROL_RINGING, or AST_CONTROL_CONGESTION on a channel Returns 0 on success, -1 on failure
Definition at line 1407 of file channel.c.

References ast_check_hangup(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROCEEDING, 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.

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

int ast_parse_device_state char *  device  ) 
 

Search the Channels by Name.

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

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

Referenced by ast_device_state().

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

int ast_prod struct ast_channel chan  ) 
 

Definition at line 1545 of file channel.c.

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

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

struct ast_frame* ast_read struct ast_channel chan  ) 
 

Reads a frame.

Parameters:
chan channel to read a frame from Read a frame. Returns a frame, or NULL on error. If it returns NULL, you best just stop reading frames and assume the channel has been disconnected.
Definition at line 1189 of file channel.c.

References ast_channel::_softhangup, ast_channel::_state, 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_CNG, 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_settimeout(), 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_play_and_prepend(), ast_play_and_record(), ast_recvchar(), ast_rtp_bridge(), ast_safe_sleep(), ast_safe_sleep_conditional(), ast_tonepair(), ast_waitfordigit(), ast_waitfordigit_full(), ast_waitstream(), ast_waitstream_fr(), and ast_waitstream_full().

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

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

Reads multiple digits.

Parameters:
c channel to read from
s string to read in to. Must be at least the size of your length
len how many digits to read (maximum)
timeout how long to timeout between digits
rtimeout timeout to wait on the first digit
enders digits to end the string Read in a digit string "s", max length "len", maximum timeout between digits "timeout" (-1 for none), terminated by anything in "enders". Give them rtimeout for the first digit. Returns 0 on normal return, or 1 on a timeout. In the case of a timeout, any digits that were read before the timeout will still be available in s. RETURNS 2 in full version when ctrlfd is available, NOT 1
Definition at line 2000 of file channel.c.

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

Referenced by ast_app_getdata().

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

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

Definition at line 2039 of file channel.c.

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

Referenced by ast_app_getdata_full().

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

int ast_recvchar struct ast_channel chan,
int  timeout
 

Definition at line 1454 of file channel.c.

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

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

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

Requests a channel.

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

References ast_channel::_state, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_state2str(), AST_STATE_DOWN, ast_translator_best_choice(), backends, ast_channel::callerid, 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().

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

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

Parameters:
type type of channel to request
format requested channel format
data data to pass to the channel requester
timeout maximum amount of time to wait for an answer
why unsuccessful (if unsuceessful) Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it Returns an ast_channel on success or no answer, NULL on failure. Check the value of chan->_state to know if the call was answered or not.
Definition at line 1856 of file channel.c.

References __ast_request_and_dial(), and type.

Referenced by ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().

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

int ast_safe_sleep struct ast_channel chan,
int  ms
 

Wait for a specied amount of time, looking for hangups.

Parameters:
chan channel to wait for
ms length of time in milliseconds to sleep Waits for a specified amount of time, servicing the channel as required. returns -1 on hangup, otherwise 0.
Definition at line 544 of file channel.c.

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

Referenced by ast_dtmf_stream().

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

int ast_safe_sleep_conditional struct ast_channel chan,
int  ms,
int(*  cond)(void *),
void *  data
 

Wait for a specied amount of time, looking for hangups and a condition argument.

Parameters:
chan channel to wait for
ms length of time in milliseconds to sleep
cond a function pointer for testing continue condition
data argument to be passed to the condition test function Waits for a specified amount of time, servicing the channel as required. If cond returns 0, this function returns. returns -1 on hangup, otherwise 0.
Definition at line 523 of file channel.c.

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

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

int ast_senddigit struct ast_channel chan,
char  digit
 

Receives a text character from a channel.

Parameters:
chan channel to act upon
timeout timeout in milliseconds (0 for infinite wait) Read a char of text from a channel Returns 0 on success, -1 on failure
Definition at line 1540 of file channel.c.
01541 { 01542 return do_senddigit(chan, digit); 01543 }

int ast_sendtext struct ast_channel chan,
char *  text
 

Sends text to a channel.

Parameters:
chan channel to act upon
text string of text to send on the channel Write text to a display on a channel Returns 0 on success, -1 on failure
Definition at line 1483 of file channel.c.

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

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

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

Definition at line 2403 of file channel.c.

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

Referenced by __ast_request_and_dial().

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

int ast_set_read_format struct ast_channel chan,
int  format
 

Sets read format on channel chan.

Parameters:
chan channel to change
format format to change to Set read format for channel to whichever component of "format" is best. Returns 0 on success, -1 on failure
Definition at line 1712 of file channel.c.

References ast_getformatname(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_translator_best_choice(), ast_translator_build_path(), ast_translator_free_path(), ast_channel::lock, LOG_DEBUG, LOG_NOTICE, ast_channel::name, ast_channel::nativeformats, 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(), ast_do_masquerade(), ast_play_and_prepend(), and ast_play_and_record().

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

int ast_set_write_format struct ast_channel chan,
int  format
 

Sets write format on channel chan.

Parameters:
chan channel to change
format new format for writing Set write format for channel to whichever compoent of "format" is best. Returns 0 on success, -1 on failure
Definition at line 1679 of file channel.c.

References ast_getformatname(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_translator_best_choice(), ast_translator_build_path(), ast_translator_free_path(), ast_channel::lock, LOG_DEBUG, LOG_NOTICE, ast_channel::name, ast_channel::nativeformats, 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().

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

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

Definition at line 1119 of file channel.c.

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

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

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

int ast_shutting_down void   ) 
 

Returns non-zero if Asterisk is being shut down Definition at line 139 of file channel.c.

00140 { 00141 return shutting_down; 00142 }

int ast_softhangup struct ast_channel chan,
int  cause
 

Softly hangup up a channel.

Parameters:
chan channel to be soft-hung-up Call the protocol layer, but don't destroy the channel structure (use this if you are trying to safely hangup a channel managed by another thread. Returns 0 regardless
Definition at line 668 of file channel.c.

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

Referenced by ast_begin_shutdown().

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

int ast_softhangup_nolock struct ast_channel chan,
int  cause
 

Definition at line 653 of file channel.c.

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

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

char* ast_state2str int  state  ) 
 

Gives the string form of a given state.

Parameters:
state state to get the name of Give a name to a state Pretty self explanatory. Returns the text form of the binary state given
Definition at line 205 of file channel.c.

References AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_OFFHOOK, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, and AST_STATE_UP.

Referenced by ast_request(), and ast_setstate().

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

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

Play a tone pair for a given amount of time Definition at line 2863 of file channel.c.

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

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

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

Start a tone going Definition at line 2843 of file channel.c.

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

Referenced by ast_tonepair().

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

void ast_tonepair_stop struct ast_channel chan  ) 
 

Stop a tone from playing Definition at line 2858 of file channel.c.

References ast_deactivate_generator().

02859 { 02860 ast_deactivate_generator(chan); 02861 }

int ast_transfer struct ast_channel chan,
char *  dest
 

Definition at line 1980 of file channel.c.

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

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

int ast_waitfor struct ast_channel chan,
int  ms
 

Wait for input on a channel.

Parameters:
chan channel to wait on
ms length of time to wait on the channel Wait for input on a channel for a given # of milliseconds (<0 for indefinite). Returns < 0 on failure, 0 if nothing ever arrived, and the # of ms remaining otherwise
Definition at line 1078 of file channel.c.

References ast_waitfor_n().

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

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

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

Waits for input on a group of channels.

Wait for input on an array of channels for a given # of milliseconds. Return channel with activity, or NULL if none has activity. time "ms" is modified in-place, if applicable Definition at line 1073 of file channel.c.

References ast_waitfor_nandfds().

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

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

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

Waits for input on an fd.

This version works on fd's only. Be careful with it. Definition at line 869 of file channel.c.

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

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

struct ast_channel* ast_waitfor_nandfds struct ast_channel **  chan,
int  n,
int *  fds,
int  nfds,
int *  exception,
int *  outfd,
int *  ms
 

Waits for activity on a group of channels.

Parameters:
chan an array of pointers to channels
n number of channels that are to be waited upon
fds an array of fds to wait upon
nfds the number of fds to wait upon
exception exception flag
outfd fd that had activity on it
ms how long the wait was Big momma function here. Wait for activity on any of the n channels, or any of the nfds file descriptors. Returns the channel with activity, or NULL on error or if an FD came first. If the FD came first, it will be returned in outfd, otherwise, outfd will be -1
Definition at line 930 of file channel.c.

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

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

char ast_waitfordigit struct ast_channel c,
int  ms
 

Waits for a digit.

Parameters:
c channel to wait for a digit on
ms how many milliseconds to wait Wait for a digit. Returns <0 on error, 0 on no entry, and the digit on success.
Definition at line 1092 of file channel.c.

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

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

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

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

Definition at line 1136 of file channel.c.

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

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

int ast_write struct ast_channel chan,
struct ast_frame frame
 

Write a frame to a channel.

Parameters:
chan destination channel of the frame
frame frame that will be written This function writes the given frame to the indicated channel. It returns 0 on success, -1 on failure.
Definition at line 1571 of file channel.c.

References ast_channel::_softhangup, ast_check_hangup(), ast_deactivate_generator(), ast_do_masquerade(), AST_FRAME_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().

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

int ast_write_video struct ast_channel chan,
struct ast_frame frame
 

Write video frame to a channel.

Parameters:
chan destination channel of the frame
frame frame that will be written This function writes the given frame to the indicated channel. It returns 1 on success, 0 if not implemented, and -1 on failure.
Definition at line 1560 of file channel.c.

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

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


Generated on Fri Sep 24 21:03:50 2004 for Asterisk by doxygen 1.3.8