From f065afb98732557832c86e12ba6b137f66d34895 Mon Sep 17 00:00:00 2001 From: russell Date: Mon, 12 Feb 2007 18:01:15 +0000 Subject: Merged revisions 54066 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r54066 | russell | 2007-02-12 11:58:43 -0600 (Mon, 12 Feb 2007) | 4 lines - Add the ability to register a callback to monitor state changes in an asynchronous dial operation. - Rename the various references to "status" to "state" in the dial API ........ git-svn-id: http://svn.digium.com/svn/asterisk/trunk@54067 f38db490-d61c-443f-a65b-d21fe96a405b --- main/dial.c | 65 ++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 26 deletions(-) (limited to 'main/dial.c') diff --git a/main/dial.c b/main/dial.c index 8e4f7528c..90461c455 100644 --- a/main/dial.c +++ b/main/dial.c @@ -47,8 +47,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") /*! \brief Main dialing structure. Contains global options, channels being dialed, and more! */ struct ast_dial { int num; /*! Current number to give to next dialed channel */ - enum ast_dial_result status; /*! Status of dial */ + enum ast_dial_result state; /*! Status of dial */ void *options[AST_DIAL_OPTION_MAX]; /*! Global options */ + ast_dial_state_callback state_callback; /*! Status callback */ AST_LIST_HEAD_NOLOCK(, ast_dial_channel) channels; /*! Channels being dialed */ pthread_t thread; /*! Thread (if running in async) */ }; @@ -288,6 +289,14 @@ static struct ast_dial_channel *find_relative_dial_channel(struct ast_dial *dial return channel; } +static void set_state(struct ast_dial *dial, enum ast_dial_result state) +{ + dial->state = state; + + if (dial->state_callback) + dial->state_callback(dial); +} + /*! \brief Helper function that handles control frames WITH owner */ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel, struct ast_frame *fr, struct ast_channel *chan) { @@ -298,7 +307,7 @@ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", channel->owner->name, chan->name); AST_LIST_REMOVE(&dial->channels, channel, list); AST_LIST_INSERT_HEAD(&dial->channels, channel, list); - dial->status = AST_DIAL_RESULT_ANSWERED; + set_state(dial, AST_DIAL_RESULT_ANSWERED); break; case AST_CONTROL_BUSY: if (option_verbose > 2) @@ -360,7 +369,7 @@ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel /*! \brief Helper function that handles control frames WITHOUT owner */ static void handle_frame_ownerless(struct ast_dial *dial, struct ast_dial_channel *channel, struct ast_frame *fr) { - /* If we have no owner we can only update the status of the dial structure, so only look at control frames */ + /* If we have no owner we can only update the state of the dial structure, so only look at control frames */ if (fr->frametype != AST_FRAME_CONTROL) return; @@ -370,7 +379,7 @@ static void handle_frame_ownerless(struct ast_dial *dial, struct ast_dial_channe ast_verbose( VERBOSE_PREFIX_3 "%s answered\n", channel->owner->name); AST_LIST_REMOVE(&dial->channels, channel, list); AST_LIST_INSERT_HEAD(&dial->channels, channel, list); - dial->status = AST_DIAL_RESULT_ANSWERED; + set_state(dial, AST_DIAL_RESULT_ANSWERED); break; case AST_CONTROL_BUSY: if (option_verbose > 2) @@ -387,17 +396,17 @@ static void handle_frame_ownerless(struct ast_dial *dial, struct ast_dial_channe case AST_CONTROL_RINGING: if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", channel->owner->name); - dial->status = AST_DIAL_RESULT_RINGING; + set_state(dial, AST_DIAL_RESULT_RINGING); break; case AST_CONTROL_PROGRESS: if (option_verbose > 2) ast_verbose (VERBOSE_PREFIX_3 "%s is making progress\n", channel->owner->name); - dial->status = AST_DIAL_RESULT_PROGRESS; + set_state(dial, AST_DIAL_RESULT_PROGRESS); break; case AST_CONTROL_PROCEEDING: if (option_verbose > 2) ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding\n", channel->owner->name); - dial->status = AST_DIAL_RESULT_PROCEEDING; + set_state(dial, AST_DIAL_RESULT_PROCEEDING); break; default: break; @@ -414,18 +423,17 @@ static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_chann struct ast_dial_channel *channel = NULL; struct answer_exec_struct *answer_exec = NULL; - /* Switch dialing status to trying */ - dial->status = AST_DIAL_RESULT_TRYING; + set_state(dial, AST_DIAL_RESULT_TRYING); - /* If the "always indicate ringing" option is set, change status to ringing and indicate to the owner if present */ + /* If the "always indicate ringing" option is set, change state to ringing and indicate to the owner if present */ if (dial->options[AST_DIAL_OPTION_RINGING]) { - dial->status = AST_DIAL_RESULT_RINGING; + set_state(dial, AST_DIAL_RESULT_RINGING); if (chan) ast_indicate(chan, AST_CONTROL_RINGING); } /* Go into an infinite loop while we are trying */ - while ((dial->status != AST_DIAL_RESULT_UNANSWERED) && (dial->status != AST_DIAL_RESULT_ANSWERED) && (dial->status != AST_DIAL_RESULT_HANGUP) && (dial->status != AST_DIAL_RESULT_TIMEOUT)) { + while ((dial->state != AST_DIAL_RESULT_UNANSWERED) && (dial->state != AST_DIAL_RESULT_ANSWERED) && (dial->state != AST_DIAL_RESULT_HANGUP) && (dial->state != AST_DIAL_RESULT_TIMEOUT)) { int pos = 0; struct ast_frame *fr = NULL; @@ -442,9 +450,9 @@ static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_chann } } - /* If we have no outbound channels in progress, switch status to unanswered and stop */ + /* If we have no outbound channels in progress, switch state to unanswered and stop */ if (!count) { - dial->status = AST_DIAL_RESULT_UNANSWERED; + set_state(dial, AST_DIAL_RESULT_UNANSWERED); break; } @@ -469,9 +477,9 @@ static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_chann /* Attempt to read in a frame */ if (!(fr = ast_read(who))) { - /* If this is the caller then we switch status to hangup and stop */ + /* If this is the caller then we switch state to hangup and stop */ if (chan && IS_CALLER(chan, who)) { - dial->status = AST_DIAL_RESULT_HANGUP; + set_state(dial, AST_DIAL_RESULT_HANGUP); break; } ast_hangup(who); @@ -490,7 +498,7 @@ static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_chann } /* Do post-processing from loop */ - if (dial->status == AST_DIAL_RESULT_ANSWERED) { + if (dial->state == AST_DIAL_RESULT_ANSWERED) { /* Hangup everything except that which answered */ AST_LIST_TRAVERSE(&dial->channels, channel, list) { if (!channel->owner || channel->owner == who) @@ -501,7 +509,7 @@ static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_chann /* If ANSWER_EXEC is enabled as an option, execute application on answered channel */ if ((channel = find_relative_dial_channel(dial, who)) && (answer_exec = FIND_RELATIVE_OPTION(dial, channel, AST_DIAL_OPTION_ANSWER_EXEC))) answer_exec_run(who, answer_exec->app, answer_exec->args); - } else if (dial->status == AST_DIAL_RESULT_HANGUP) { + } else if (dial->state == AST_DIAL_RESULT_HANGUP) { /* Hangup everything */ AST_LIST_TRAVERSE(&dial->channels, channel, list) { if (!channel->owner) @@ -511,7 +519,7 @@ static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_chann } } - return dial->status; + return dial->state; } /*! \brief Dial async thread function */ @@ -551,7 +559,7 @@ enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *cha /* If we are running async spawn a thread and send it away... otherwise block here */ if (async) { - dial->status = AST_DIAL_RESULT_TRYING; + set_state(dial, AST_DIAL_RESULT_TRYING); /* Try to create a thread */ if (ast_pthread_create(&dial->thread, NULL, async_dial, dial)) { /* Failed to create the thread - hangup all dialed channels and return failed */ @@ -574,16 +582,16 @@ struct ast_channel *ast_dial_answered(struct ast_dial *dial) if (!dial) return NULL; - return ((dial->status == AST_DIAL_RESULT_ANSWERED) ? AST_LIST_FIRST(&dial->channels)->owner : NULL); + return ((dial->state == AST_DIAL_RESULT_ANSWERED) ? AST_LIST_FIRST(&dial->channels)->owner : NULL); } -/*! \brief Return status of dial - * \note Returns the status of the dial attempt +/*! \brief Return state of dial + * \note Returns the state of the dial attempt * \param dial Dialing structure */ -enum ast_dial_result ast_dial_status(struct ast_dial *dial) +enum ast_dial_result ast_dial_state(struct ast_dial *dial) { - return dial->status; + return dial->state; } /*! \brief Cancel async thread @@ -613,7 +621,7 @@ enum ast_dial_result ast_dial_join(struct ast_dial *dial) /* Yay thread is all gone */ dial->thread = AST_PTHREADT_NULL; - return dial->status; + return dial->state; } /*! \brief Hangup channels @@ -809,3 +817,8 @@ int ast_dial_option_disable(struct ast_dial *dial, int num, enum ast_dial_option return 0; } + +void ast_set_state_callback(struct ast_dial *dial, ast_dial_state_callback callback) +{ + dial->state_callback = callback; +} -- cgit v1.2.3