Index: channel.c =================================================================== RCS file: /usr/cvsroot/asterisk/channel.c,v retrieving revision 1.193 diff -u -r1.193 channel.c --- channel.c 29 Apr 2005 17:00:33 -0000 1.193 +++ channel.c 4 May 2005 19:44:42 -0000 @@ -105,19 +105,24 @@ static struct ast_cli_entry cli_show_channeltypes = { { "show", "channeltypes", NULL }, show_channeltypes, "Show available channel types", show_channeltypes_usage }; +/*--- ast_check_hangup: Checks to see if a channel is needing hang up */ int ast_check_hangup(struct ast_channel *chan) { -time_t myt; + time_t myt; - /* if soft hangup flag, return true */ - if (chan->_softhangup) return 1; - /* if no technology private data, return true */ - if (!chan->tech_pvt) return 1; - /* if no hangup scheduled, just return here */ - if (!chan->whentohangup) return 0; + /* if soft hangup flag, return true */ + if (chan->_softhangup) + return 1; + /* if no technology private data, return true */ + if (!chan->tech_pvt) + return 1; + /* if no hangup scheduled, just return here */ + if (!chan->whentohangup) + return 0; time(&myt); /* get current time */ - /* return, if not yet */ - if (chan->whentohangup > myt) return 0; + /* return, if not yet */ + if (chan->whentohangup > myt) + return 0; chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; return 1; } @@ -131,6 +136,7 @@ return res; } +/*--- ast_begin_shutdown: Initiate system shutdown */ void ast_begin_shutdown(int hangup) { struct ast_channel *c; @@ -146,6 +152,7 @@ } } +/*--- ast_active_channels: returns number of active/allocated channels */ int ast_active_channels(void) { struct ast_channel *c; @@ -160,16 +167,19 @@ return cnt; } +/*--- ast_cancel_shutdown: Cancel a shutdown in progress */ void ast_cancel_shutdown(void) { shutting_down = 0; } +/*--- ast_shutting_down: Returns non-zero if Asterisk is being shut down */ int ast_shutting_down(void) { return shutting_down; } +/*--- ast_channel_setwhentohangup: Set when to hangup channel */ void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset) { time_t myt; @@ -182,6 +192,7 @@ return; } +/*--- ast_channel_register: Register a new telephony channel in Asterisk */ int ast_channel_register(const struct ast_channel_tech *tech) { struct chanlist *chan; @@ -219,6 +230,7 @@ return 0; } +/*--- ast_state2str: Gives the string form of a given channel state */ char *ast_state2str(int state) { /* XXX Not reentrant XXX */ @@ -246,6 +258,7 @@ } } +/*--- ast_transfercapability2str: Gives the string form of a given transfer capability */ char *ast_transfercapability2str(int transfercapability) { switch(transfercapability) { @@ -266,6 +279,7 @@ } } +/*--- ast_best_codec: Pick the best codec */ int ast_best_codec(int fmts) { /* This just our opinion, expressed in code. We are asked to choose @@ -300,7 +314,8 @@ }; - for (x=0;xsched = sched_context_create(); if (!tmp->sched) { - ast_log(LOG_WARNING, "Unable to create schedule context\n"); + ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n"); free(tmp); return NULL; } - for (x=0;xfds[x] = -1; #ifdef ZAPTEL_OPTIMIZATIONS @@ -356,7 +374,7 @@ if (needqueue) { if (pipe(tmp->alertpipe)) { - ast_log(LOG_WARNING, "Alert pipe creation failed!\n"); + ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n"); free(tmp); return NULL; } else { @@ -402,6 +420,7 @@ return tmp; } +/*--- ast_queue_frame: Queue an outgoing media frame */ int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin) { struct ast_frame *f; @@ -459,6 +478,7 @@ return 0; } +/*--- ast_queue_hangup: Queue a hangup frame for channel */ int ast_queue_hangup(struct ast_channel *chan) { struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP }; @@ -466,6 +486,7 @@ return ast_queue_frame(chan, &f); } +/*--- ast_queue_control: Queue a control frame */ int ast_queue_control(struct ast_channel *chan, int control) { struct ast_frame f = { AST_FRAME_CONTROL, }; @@ -473,6 +494,7 @@ return ast_queue_frame(chan, &f); } +/*--- ast_channel_defer_dtmf: Set defer DTMF flag on channel */ int ast_channel_defer_dtmf(struct ast_channel *chan) { int pre = 0; @@ -483,12 +505,14 @@ return pre; } +/*--- ast_channel_undefer_dtmf: Unset defer DTMF flag on channel */ void ast_channel_undefer_dtmf(struct ast_channel *chan) { if (chan) ast_clear_flag(chan, AST_FLAG_DEFER_DTMF); } +/*--- ast_channel_walk_locked: Browse channels in use */ struct ast_channel *ast_channel_walk_locked(struct ast_channel *prev) { /* Returns next channel (locked) */ @@ -542,6 +566,7 @@ } +/*--- ast_get_channel_by_name_locked: Get channel by name and lock it */ struct ast_channel *ast_get_channel_by_name_locked(char *channame) { struct ast_channel *chan; @@ -555,8 +580,9 @@ return NULL; } +/*--- ast_safe_sleep_conditional: Wait, look for hangups and condition arg */ int ast_safe_sleep_conditional( struct ast_channel *chan, int ms, - int (*cond)(void*), void *data ) + int (*cond)(void*), void *data ) { struct ast_frame *f; @@ -576,6 +602,7 @@ return 0; } +/*--- ast_safe_sleep: Wait, look for hangups */ int ast_safe_sleep(struct ast_channel *chan, int ms) { struct ast_frame *f; @@ -607,6 +634,7 @@ free(cid->cid_rdnis); } +/*--- ast_channel_free: Free a channel structure */ void ast_channel_free(struct ast_channel *chan) { struct ast_channel *last=NULL, *cur; @@ -684,7 +712,6 @@ while (!AST_LIST_EMPTY(headp)) { /* List Deletion. */ vardata = AST_LIST_REMOVE_HEAD(headp, entries); -/* printf("deleting var %s=%s\n",ast_var_name(vardata),ast_var_value(vardata)); */ ast_var_delete(vardata); } @@ -717,6 +744,7 @@ return; } +/*--- ast_softhangup_nolock: Softly hangup a channel, don't lock */ int ast_softhangup_nolock(struct ast_channel *chan, int cause) { int res = 0; @@ -732,6 +760,7 @@ return res; } +/*--- ast_softhangup_nolock: Softly hangup a channel, lock */ int ast_softhangup(struct ast_channel *chan, int cause) { int res; @@ -789,6 +818,7 @@ clone->rawreadformat = clone->nativeformats; } +/*--- ast_hangup: Hangup a channel */ int ast_hangup(struct ast_channel *chan) { int res = 0; @@ -796,8 +826,8 @@ if someone is going to masquerade as us */ ast_mutex_lock(&chan->lock); - /* get rid of spies */ - ast_spy_detach(chan); + + ast_spy_detach(chan); /* get rid of spies */ if (chan->masq) { if (ast_do_masquerade(chan)) @@ -817,22 +847,20 @@ return 0; } free_translation(chan); - if (chan->stream) + if (chan->stream) /* Close audio stream */ ast_closestream(chan->stream); - if (chan->vstream) + if (chan->vstream) /* Close video stream */ ast_closestream(chan->vstream); if (chan->sched) sched_context_destroy(chan->sched); - /* Clear any tone stuff remaining */ - if (chan->generatordata) + + if (chan->generatordata) /* Clear any tone stuff remaining */ chan->generator->release(chan, chan->generatordata); chan->generatordata = NULL; chan->generator = NULL; - if (chan->cdr) { - /* End the CDR if it hasn't already */ + if (chan->cdr) { /* End the CDR if it hasn't already */ ast_cdr_end(chan->cdr); - /* Post and Free the CDR */ - ast_cdr_post(chan->cdr); + ast_cdr_post(chan->cdr); /* Post and Free the CDR */ ast_cdr_free(chan->cdr); } if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { @@ -855,7 +883,9 @@ "Channel: %s\r\n" "Uniqueid: %s\r\n" "Cause: %d\r\n", - chan->name, chan->uniqueid, chan->hangupcause); + chan->name, + chan->uniqueid, + chan->hangupcause); ast_channel_free(chan); return res; } @@ -2066,8 +2102,13 @@ cut = strchr(name,'-'); if (cut) *cut = 0; - if (!strcmp(name, device)) - return AST_DEVICE_INUSE; + if (!strcmp(name, device)) { + if (chan->_state == AST_STATE_RINGING) { + return AST_DEVICE_RINGING; + } else { + return AST_DEVICE_INUSE; + } + } chan = ast_channel_walk_locked(chan); } return AST_DEVICE_UNKNOWN; @@ -2725,6 +2766,7 @@ #endif } +/*--- Find bridged channel */ struct ast_channel *ast_bridged_channel(struct ast_channel *chan) { struct ast_channel *bridged; @@ -2751,7 +2793,7 @@ } } - if (!strcmp(sound,"timeleft")) { + if (!strcmp(sound,"timeleft")) { /* Queue support */ res = ast_streamfile(chan, "vm-youhave", chan->language); res = ast_waitstream(chan, ""); if (min) { @@ -2827,16 +2869,15 @@ who = ast_waitfor_n(cs, 2, &to); if (!who) { ast_log(LOG_DEBUG, "Nobody there, continuing...\n"); - if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) { - if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE) - c0->_softhangup = 0; - if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) - c1->_softhangup = 0; - c0->_bridge = c1; - c1->_bridge = c0; - continue; - } - + if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) { + if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE) + c0->_softhangup = 0; + if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) + c1->_softhangup = 0; + c0->_bridge = c1; + c1->_bridge = c0; + continue; + } continue; } f = ast_read(who); @@ -2915,6 +2956,7 @@ return res; } +/*--- ast_channel_bridge: Bridge two channels together */ 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) { /* Copy voice back and forth between the two channels. Give the peer @@ -2999,7 +3041,8 @@ if ((ast_test_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING)) && config->end_sound) bridge_playfile(c1,c0,config->end_sound,0); *fo = NULL; - if (who) *rc = who; + if (who) + *rc = who; res = 0; break; } @@ -3027,7 +3070,8 @@ /* Stop if we're a zombie or need a soft hangup */ if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) { *fo = NULL; - if (who) *rc = who; + if (who) + *rc = who; res = 0; 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,ast_test_flag(c0, AST_FLAG_ZOMBIE)?"Yes":"No",ast_check_hangup(c0)?"Yes":"No",ast_test_flag(c1, AST_FLAG_ZOMBIE)?"Yes":"No",ast_check_hangup(c1)?"Yes":"No"); break; @@ -3101,6 +3145,7 @@ return res; } +/*--- ast_channel_setoption: Sets an option on a channel */ int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int datalen, int block) { int res; Index: include/asterisk/channel.h =================================================================== RCS file: /usr/cvsroot/asterisk/include/asterisk/channel.h,v retrieving revision 1.83 diff -u -r1.83 channel.h --- include/asterisk/channel.h 29 Apr 2005 15:04:26 -0000 1.83 +++ include/asterisk/channel.h 4 May 2005 19:44:43 -0000 @@ -455,16 +457,23 @@ #define AST_DEVICE_INVALID 4 /*! Device is unavailable */ #define AST_DEVICE_UNAVAILABLE 5 +/*! Device is ringing */ +#define AST_DEVICE_RINGING 6 /*! Create a channel structure */ -/*! Returns NULL on failure to allocate */ +/*! Returns NULL on failure to allocate. New channels are + by default set to the "default" context and + extension "s" + */ struct ast_channel *ast_channel_alloc(int needalertpipe); /*! Queue an outgoing frame */ int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f); +/*! Queue a hangup frame */ int ast_queue_hangup(struct ast_channel *chan); +/*! Queue a control frame */ int ast_queue_control(struct ast_channel *chan, int control); /*! Change the state of a channel */ @@ -552,9 +561,12 @@ * \param 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. + * \param cause Ast hangupcause for hangup * Returns 0 regardless */ int ast_softhangup(struct ast_channel *chan, int cause); +/*! Softly hangup up a channel (no channel lock) + * \param cause Ast hangupcause for hangup */ int ast_softhangup_nolock(struct ast_channel *chan, int cause); /*! Check to see if a channel is needing hang up */ @@ -810,11 +822,10 @@ channel is hung up. */ int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone); -/*! Gives the string form of a given state */ +/*! Gives the string form of a given channel state */ /*! * \param 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 */ char *ast_state2str(int state); @@ -845,6 +856,11 @@ */ int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block); +/*! Pick the best codec */ +/* Choose the best codec... Uhhh... Yah. */ +extern int ast_best_codec(int fmts); + + /*! Checks the value of an option */ /*! * Query the value of an option, optionally blocking until a reply is received @@ -913,13 +929,18 @@ timer fd, at which point we call the callback function / data */ int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data); -/* Transfer a channel (if supported). Returns -1 on error, 0 if not supported - and 1 if supported and requested */ +/*! \brief Transfer a channel (if supported). Returns -1 on error, 0 if not supported + and 1 if supported and requested + \param chan current channel + \param dest destination extension for transfer +*/ int ast_transfer(struct ast_channel *chan, char *dest); int ast_do_masquerade(struct ast_channel *chan); -/* Find bridged channel */ +/*! \brief Find bridged channel + \param chan Current channel +*/ struct ast_channel *ast_bridged_channel(struct ast_channel *chan); /*! Index: include/asterisk/frame.h =================================================================== RCS file: /usr/cvsroot/asterisk/include/asterisk/frame.h,v retrieving revision 1.49 diff -u -r1.49 frame.h --- include/asterisk/frame.h 21 Apr 2005 06:02:44 -0000 1.49 +++ include/asterisk/frame.h 4 May 2005 19:44:43 -0000 @@ -347,10 +347,6 @@ */ extern char *ast_codec2str(int codec); -/*! Pick the best codec */ -/* Choose the best codec... Uhhh... Yah. */ -extern int ast_best_codec(int fmts); - struct ast_smoother; extern struct ast_format_list *ast_get_format_list_index(int index);