From 2a5477b35e8960f41b3e6e314ca95bd689440cc5 Mon Sep 17 00:00:00 2001
From: Russell Bryant <russell@russellbryant.com>
Date: Mon, 12 Feb 2007 18:01:15 +0000
Subject: [PATCH] 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: https://origsvn.digium.com/svn/asterisk/trunk@54067 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 apps/app_meetme.c       |  4 +--
 apps/app_page.c         |  2 +-
 include/asterisk/dial.h | 15 ++++++++--
 main/dial.c             | 65 ++++++++++++++++++++++++-----------------
 4 files changed, 54 insertions(+), 32 deletions(-)

diff --git a/apps/app_meetme.c b/apps/app_meetme.c
index 1b9ee64a0d..37ad8442bc 100644
--- a/apps/app_meetme.c
+++ b/apps/app_meetme.c
@@ -3153,7 +3153,7 @@ static void *sla_thread(void *data)
 			ast_mutex_t cond_lock;
 			ast_cond_t cond;
 
-			switch ((dial_res = ast_dial_status(station_ref->station->dial))) {
+			switch ((dial_res = ast_dial_state(station_ref->station->dial))) {
 			case AST_DIAL_RESULT_HANGUP:
 			case AST_DIAL_RESULT_INVALID:
 			case AST_DIAL_RESULT_FAILED:
@@ -3296,7 +3296,7 @@ static void *dial_trunk(void *data)
 
 	for (;;) {
 		unsigned int done = 0;
-		switch ((dial_res = ast_dial_status(dial))) {
+		switch ((dial_res = ast_dial_state(dial))) {
 		case AST_DIAL_RESULT_ANSWERED:
 			trunk->chan = ast_dial_answered(dial);
 		case AST_DIAL_RESULT_HANGUP:
diff --git a/apps/app_page.c b/apps/app_page.c
index 22b7f918d0..f324dd5c9a 100644
--- a/apps/app_page.c
+++ b/apps/app_page.c
@@ -178,7 +178,7 @@ static int page_exec(struct ast_channel *chan, void *data)
 		struct ast_dial *dial = dials[i];
 
 		/* If the dial is already answered, then they will/should get kicked out by Meetme */
-		if (ast_dial_status(dial) != AST_DIAL_RESULT_ANSWERED)
+		if (ast_dial_state(dial) != AST_DIAL_RESULT_ANSWERED)
 			ast_dial_join(dial);
 
 		/* Hangup all channels */
diff --git a/include/asterisk/dial.h b/include/asterisk/dial.h
index 92220e8cb7..eec5bb2382 100644
--- a/include/asterisk/dial.h
+++ b/include/asterisk/dial.h
@@ -33,6 +33,8 @@ struct ast_dial;
 /*! \brief Dialing channel structure. Contains per-channel dialing options, asterisk channel, and more! */
 struct ast_dial_channel;
 
+typedef void (*ast_dial_state_callback)(struct ast_dial *);
+
 /*! \brief List of options that are applicable either globally or per dialed channel */
 enum ast_dial_option {
 	AST_DIAL_OPTION_RINGING,     /*!< Always indicate ringing to caller */
@@ -78,11 +80,11 @@ enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *cha
  */
 struct ast_channel *ast_dial_answered(struct ast_dial *dial);
 
-/*! \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);
 
 /*! \brief Cancel async thread
  * \note Cancel a running async thread
@@ -135,6 +137,13 @@ int ast_dial_option_global_disable(struct ast_dial *dial, enum ast_dial_option o
  */
 int ast_dial_option_disable(struct ast_dial *dial, int num, enum ast_dial_option option);
 
+/*! \brief Set a callback for state changes
+ * \param dial The dial structure to watch for state changes
+ * \param callback the callback
+ * \return nothing
+ */
+void ast_set_state_callback(struct ast_dial *dial, ast_dial_state_callback callback);
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif
diff --git a/main/dial.c b/main/dial.c
index 8e4f7528ca..90461c4558 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;
+}
-- 
GitLab