diff --git a/channel.c b/channel.c index 27aefe174e2b476e8e648695b44798436f9cd433..5642ea550b12637566d8b06910ada4b2b648cb01 100755 --- a/channel.c +++ b/channel.c @@ -105,19 +105,24 @@ static char show_channeltypes_usage[] = 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 @@ static int ast_check_hangup_locked(struct ast_channel *chan) return res; } +/*--- ast_begin_shutdown: Initiate system shutdown */ void ast_begin_shutdown(int hangup) { struct ast_channel *c; @@ -146,6 +152,7 @@ void ast_begin_shutdown(int hangup) } } +/*--- ast_active_channels: returns number of active/allocated channels */ int ast_active_channels(void) { struct ast_channel *c; @@ -160,16 +167,19 @@ int ast_active_channels(void) 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 @@ void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset) 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 @@ int ast_channel_register(const struct ast_channel_tech *tech) 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 @@ char *ast_state2str(int state) } } +/*--- ast_transfercapability2str: Gives the string form of a given transfer capability */ char *ast_transfercapability2str(int transfercapability) { switch(transfercapability) { @@ -266,6 +279,7 @@ char *ast_transfercapability2str(int transfercapability) } } +/*--- 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 @@ int ast_best_codec(int fmts) }; - for (x=0;x<sizeof(prefs) / sizeof(prefs[0]); x++) + /* Find the first prefered codec in the format given */ + for (x=0; x < (sizeof(prefs) / sizeof(prefs[0]) ); x++) if (fmts & prefs[x]) return prefs[x]; ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts); @@ -312,6 +327,7 @@ static const struct ast_channel_tech null_tech = { .description = "Null channel (should not see this)", }; +/*--- ast_channel_alloc: Create a new channel structure */ struct ast_channel *ast_channel_alloc(int needqueue) { struct ast_channel *tmp; @@ -321,24 +337,26 @@ struct ast_channel *ast_channel_alloc(int needqueue) /* If shutting down, don't allocate any new channels */ - if (shutting_down) + if (shutting_down) { + ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n"); return NULL; + } tmp = malloc(sizeof(struct ast_channel)); if (!tmp) { - ast_log(LOG_WARNING, "Out of memory\n"); + ast_log(LOG_WARNING, "Channel allocation failed: Out of memory\n"); return NULL; } memset(tmp, 0, sizeof(struct ast_channel)); tmp->sched = 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;x<AST_MAX_FDS - 1;x++) + for (x=0; x<AST_MAX_FDS - 1; x++) tmp->fds[x] = -1; #ifdef ZAPTEL_OPTIMIZATIONS @@ -356,7 +374,7 @@ struct ast_channel *ast_channel_alloc(int needqueue) 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 @@ struct ast_channel *ast_channel_alloc(int needqueue) 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 @@ int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin) 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 @@ int ast_queue_hangup(struct ast_channel *chan) 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 @@ int ast_queue_control(struct ast_channel *chan, int control) 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 @@ int ast_channel_defer_dtmf(struct ast_channel *chan) 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 @@ retry: } +/*--- 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 @@ struct ast_channel *ast_get_channel_by_name_locked(char *channame) 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 @@ int ast_safe_sleep_conditional( struct ast_channel *chan, int ms, 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 @@ static void free_cid(struct ast_callerid *cid) 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 @@ void ast_channel_free(struct ast_channel *chan) 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 @@ static void ast_spy_detach(struct ast_channel *chan) 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 @@ int ast_softhangup_nolock(struct ast_channel *chan, int cause) 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 @@ static void free_translation(struct ast_channel *clone) clone->rawreadformat = clone->nativeformats; } +/*--- ast_hangup: Hangup a channel */ int ast_hangup(struct ast_channel *chan) { int res = 0; @@ -796,8 +826,8 @@ int ast_hangup(struct ast_channel *chan) 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 @@ int ast_hangup(struct ast_channel *chan) 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 @@ int ast_hangup(struct ast_channel *chan) "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; } @@ -2067,8 +2097,13 @@ int ast_parse_device_state(char *device) 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; @@ -2726,6 +2761,7 @@ static long tvdiff(struct timeval *now, struct timeval *then) #endif } +/*--- Find bridged channel */ struct ast_channel *ast_bridged_channel(struct ast_channel *chan) { struct ast_channel *bridged; @@ -2752,7 +2788,7 @@ static void bridge_playfile(struct ast_channel *chan, struct ast_channel *peer, } } - if (!strcmp(sound,"timeleft")) { + if (!strcmp(sound,"timeleft")) { /* Queue support */ res = ast_streamfile(chan, "vm-youhave", chan->language); res = ast_waitstream(chan, ""); if (min) { @@ -2828,16 +2864,15 @@ static int ast_generic_bridge(int *playitagain, int *playit, struct timeval *sta 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); @@ -2916,6 +2951,7 @@ tackygoto: 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 @@ -3000,7 +3036,8 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, struct as 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; } @@ -3028,7 +3065,8 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, struct as /* 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; @@ -3102,6 +3140,7 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, struct as 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; diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index d13e0671a681103e39eaf3ac8f2ec4f276f6e34f..e3dd749cba4564e94cc8c24337bb9a20d9d21557 100755 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -455,16 +455,23 @@ struct outgoing_helper { #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 +559,12 @@ int ast_hangup(struct ast_channel *chan); * \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 +820,10 @@ int ast_channel_bridge(struct ast_channel *c0,struct ast_channel *c1,struct ast_ 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 +854,11 @@ char *ast_transfercapability2str(int transfercapability); */ 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 +927,18 @@ int ast_autoservice_stop(struct ast_channel *chan); 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); /*! diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h index d8a715a8f4bdc690640f638e26d120fc14386a8c..7cff43ee6ed2c825182816c1e97db437c177fa4a 100755 --- a/include/asterisk/frame.h +++ b/include/asterisk/frame.h @@ -347,10 +347,6 @@ extern int ast_getformatbyname(char *name); */ 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);