[asterisk-commits] file: branch file/dialing_api r49344 - in /team/file/dialing_api: apps/ inclu...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Wed Jan 3 14:26:38 MST 2007


Author: file
Date: Wed Jan  3 15:26:37 2007
New Revision: 49344

URL: http://svn.digium.com/view/asterisk?view=rev&rev=49344
Log:
Yay major updates. Drop second async function, just add an async option to ast_dial_run. I also made 1 single function that handles the channels that are dialing out, and depending on whether it's sync or async forwards back data or changes the status.

Modified:
    team/file/dialing_api/apps/app_dial2.c
    team/file/dialing_api/include/asterisk/dial.h
    team/file/dialing_api/main/dial.c

Modified: team/file/dialing_api/apps/app_dial2.c
URL: http://svn.digium.com/view/asterisk/team/file/dialing_api/apps/app_dial2.c?view=diff&rev=49344&r1=49343&r2=49344
==============================================================================
--- team/file/dialing_api/apps/app_dial2.c (original)
+++ team/file/dialing_api/apps/app_dial2.c Wed Jan  3 15:26:37 2007
@@ -96,7 +96,7 @@
 	memset(&bridge_config, 0, sizeof(bridge_config));
 
 	/* Attempt to dial all the channels and bridge to the one that answered */
-	if ((ast_dial_run(dial, chan) == AST_DIAL_RESULT_ANSWERED) && (answered = ast_dial_answered(dial)))
+	if ((ast_dial_run(dial, chan, 0) == AST_DIAL_RESULT_ANSWERED) && (answered = ast_dial_answered(dial)))
 		ast_bridge_call(chan, answered, &bridge_config);
 
 	/* Hangup all calls in the dialing structure */

Modified: team/file/dialing_api/include/asterisk/dial.h
URL: http://svn.digium.com/view/asterisk/team/file/dialing_api/include/asterisk/dial.h?view=diff&rev=49344&r1=49343&r2=49344
==============================================================================
--- team/file/dialing_api/include/asterisk/dial.h (original)
+++ team/file/dialing_api/include/asterisk/dial.h Wed Jan  3 15:26:37 2007
@@ -65,23 +65,23 @@
  */
 int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device);
 
-/*! \brief Execute dialing synchronously
- * \note Dials channels in a dial structure and does not return until one is answered or timeout is reached. Will also forward progress/ringing.
- * \return Returns 0 on success, -1 on failure
+/*! \brief Execute dialing synchronously or asynchronously
+ * \note Dials channels in a dial structure.
+ * \return Returns dial result code. (TRYING/INVALID/FAILED/ANSWERED/TIMEOUT/UNANSWERED).
  */
-enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan);
-
-/*! \brief Execute dialing asynchronously
- * \note Dials channels in a dial structure in a separate thread, returns almost immediately
- * \return Returns 0 on success, -1 on failure
- */
-enum ast_dial_result ast_dial_run_async(struct ast_dial *dial, struct ast_channel *chan);
+enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan, int async);
 
 /*! \brief Return channel that answered
  * \note Returns the Asterisk channel that answered
  * \param dial Dialing structure
  */
 struct ast_channel *ast_dial_answered(struct ast_dial *dial);
+
+/*! \brief Return status of dial
+ * \note Returns the status of the dial attempt
+ * \param dial Dialing structure
+ */
+enum ast_dial_result ast_dial_status(struct ast_dial *dial);
 
 /*! \brief Hangup channels
  * \note Hangup all active channels

Modified: team/file/dialing_api/main/dial.c
URL: http://svn.digium.com/view/asterisk/team/file/dialing_api/main/dial.c?view=diff&rev=49344&r1=49343&r2=49344
==============================================================================
--- team/file/dialing_api/main/dial.c (original)
+++ team/file/dialing_api/main/dial.c Wed Jan  3 15:26:37 2007
@@ -213,198 +213,209 @@
 	return channel;
 }
 
-/*! \brief Execute dialing synchronously
- * \note Dials channels in a dial structure and does not return until one is answered or timeout is reached. Will also forward progress/ringing.
- * \return Returns 0 on success, -1 on failure
- */
-enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan)
-{
-	int to_monitor = 0, single = 0, timeout = 0;
-	struct ast_channel *cs[AST_MAX_WATCHERS] = {NULL, }, *who = NULL;
+/*! \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)
+{
+	if (fr->frametype == AST_FRAME_CONTROL) {
+		switch (fr->subclass) {
+		case AST_CONTROL_ANSWER:
+			if (option_verbose > 2)
+				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;
+			break;
+		case AST_CONTROL_BUSY:
+			if (option_verbose > 2)
+				ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", channel->owner->name);
+			ast_hangup(channel->owner);
+			channel->owner = NULL;
+			break;
+		case AST_CONTROL_CONGESTION:
+			if (option_verbose > 2)
+				ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", channel->owner->name);
+			ast_hangup(channel->owner);
+			channel->owner = NULL;
+			break;
+		case AST_CONTROL_RINGING:
+			if (option_verbose > 2)
+				ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", channel->owner->name);
+			ast_indicate(chan, AST_CONTROL_RINGING);
+			break;
+		case AST_CONTROL_PROGRESS:
+			if (option_verbose > 2)
+				ast_verbose (VERBOSE_PREFIX_3 "%s is making progress, passing it to %s\n", channel->owner->name, chan->name);
+			ast_indicate(chan, AST_CONTROL_PROGRESS);
+			break;
+		case AST_CONTROL_VIDUPDATE:
+			if (option_verbose > 2)
+				ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", channel->owner->name, chan->name);
+			ast_indicate(chan, AST_CONTROL_VIDUPDATE);
+			break;
+		case AST_CONTROL_PROCEEDING:
+			if (option_verbose > 2)
+				ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding, passing it to %s\n", channel->owner->name, chan->name);
+			ast_indicate(chan, AST_CONTROL_PROCEEDING);
+			break;
+		case AST_CONTROL_HOLD:
+			if (option_verbose > 2)
+				ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", chan->name);
+			ast_indicate(chan, AST_CONTROL_HOLD);
+			break;
+		case AST_CONTROL_UNHOLD:
+			if (option_verbose > 2)
+				ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", chan->name);
+			ast_indicate(chan, AST_CONTROL_UNHOLD);
+			break;
+		case AST_CONTROL_OFFHOOK:
+		case AST_CONTROL_FLASH:
+			break;
+		case -1:
+			/* Prod the channel */
+			ast_indicate(chan, -1);
+			break;
+		default:
+			break;
+		}
+	}
+
+	return;
+}
+
+/*! \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 (fr->frametype != AST_FRAME_CONTROL)
+		return;
+
+	switch (fr->subclass) {
+	default:
+		break;
+	}
+
+	return;
+}
+
+/*! \brief Helper function that basically keeps tabs on dialing attempts */
+static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_channel *chan)
+{
+	int single = 0, timeout = -1, count = 0;
+	struct ast_channel *cs[AST_MAX_WATCHERS], *who = NULL;
 	struct ast_dial_channel *channel = NULL;
 
-	/* Ensure required arguments are passed */
-	if (!dial || !chan)
-		return AST_DIAL_RESULT_INVALID;
-
-	/* If there are no channels to dial we can't very well try to dial them */
-	if (AST_LIST_EMPTY(&dial->channels))
-		return AST_DIAL_RESULT_INVALID;
-
-	/* Dial each requested channel */
-	if (!(to_monitor = begin_dial(dial, chan)))
-		return AST_DIAL_RESULT_FAILED;
-
-	/* Increment by one since we have to monitor our own channel */
-	to_monitor++;
-
-	/* Set status to be in progress */
+	/* Switch dialing status to trying */
 	dial->status = AST_DIAL_RESULT_TRYING;
 
-	/* See if this is just a single dial */
+	/* See if this is a single dial attempt */
 	if (AST_LIST_FIRST(&dial->channels) == AST_LIST_LAST(&dial->channels))
 		single = 1;
 
-	/* If no timeout is specified, then assume infinite */
-	if (!timeout)
-		timeout = -1;
-
-	/* Go into a loop monitoring channels */
-	while (dial->status == AST_DIAL_RESULT_INVALID) {
-		int pos = 1;
+	/* Go into an infinite loop while we are trying */
+	while (dial->status == AST_DIAL_RESULT_TRYING) {
+		int pos = 0;
 		struct ast_frame *fr = NULL;
-
-		/* If we are down to a single channel to monitor then our attempts have failed */
-		if (to_monitor == 1) {
+		
+		/* Set up channel structure array */
+		pos = count = 0;
+		if (chan)
+			cs[pos++] = chan;
+
+		/* Add channels we are attempting to dial */
+		AST_LIST_TRAVERSE(&dial->channels, channel, list) {
+			if (channel->owner) {
+				cs[pos++] = channel->owner;
+				count++;
+			}
+		}
+
+		/* If we have no outbound channels in progress, switch status to unanswered and stop */
+		if (!count) {
 			dial->status = AST_DIAL_RESULT_UNANSWERED;
 			break;
 		}
-		
-		/* Put ourselves into the structure */
-		cs[0] = chan;
-		/* Now everyone else! */
-		pos = 1;
-		AST_LIST_TRAVERSE(&dial->channels, channel, list) {
-			if (!channel->owner)
-				continue;
-			cs[pos++] = channel->owner;
-		}
-
-		if (!(who = ast_waitfor_n(cs, pos, &timeout)))
+
+		/* Wait for frames from channels */
+		if (!(who = ast_waitfor_n(cs, pos, &timeout))) {
+			/* We need to handle timeouts here when it is implemented */
 			continue;
-
-		/* Find relative dial channel... just in case */
-		if (!IS_CALLER(chan, who))
+		}
+
+		/* Find relative dial channel */
+		if (!chan || !IS_CALLER(chan, who))
 			channel = find_relative_dial_channel(dial, who);
 
-		/* Try to read in a frame */
+		/* Attempt to read in a frame */
 		if (!(fr = ast_read(who))) {
-			if (IS_CALLER(chan, who)) {
-				/* This is the caller who hung up */
+			/* If this is the caller then we switch status to hangup and stop */
+			if (chan && IS_CALLER(chan, who)) {
 				dial->status = AST_DIAL_RESULT_HANGUP;
 				break;
 			}
 			ast_hangup(who);
 			channel->owner = NULL;
-			to_monitor--;
 			continue;
 		}
 
-		/* Process control frames first */
-		if (fr->frametype == AST_FRAME_CONTROL) {
-			switch (fr->subclass) {
-			case AST_CONTROL_ANSWER:
-				if (option_verbose > 2)
-					ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", who->name, chan->name);
-				/* This is sort of cheeky but what we do is make the first channel in the list the answered channel */
-				AST_LIST_REMOVE(&dial->channels, channel, list);
-				AST_LIST_INSERT_HEAD(&dial->channels, channel, list);
-				dial->status = AST_DIAL_RESULT_ANSWERED;
-				break;
-			case AST_CONTROL_BUSY:
-				if (option_verbose > 2)
-					ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", who->name);
-				ast_hangup(who);
-				channel->owner = NULL;
-				to_monitor--;
-				break;
-			case AST_CONTROL_CONGESTION:
-				if (option_verbose > 2)
-					ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", who->name);
-				ast_hangup(who);
-				channel->owner = NULL;
-				to_monitor--;
-				break;
-			case AST_CONTROL_RINGING:
-				if (option_verbose > 2)
-					ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", who->name);
-				ast_indicate(chan, AST_CONTROL_RINGING);
-				break;
-			case AST_CONTROL_PROGRESS:
-				if (option_verbose > 2)
-					ast_verbose (VERBOSE_PREFIX_3 "%s is making progress, passing it to %s\n", who->name, chan->name);
-				ast_indicate(chan, AST_CONTROL_PROGRESS);
-				break;
-			case AST_CONTROL_VIDUPDATE:
-				if (option_verbose > 2)
-					ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", who->name, chan->name);
-				ast_indicate(chan, AST_CONTROL_VIDUPDATE);
-				break;
-			case AST_CONTROL_PROCEEDING:
-				if (option_verbose > 2)
-					ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding, passing it to %s\n", who->name, chan->name);
-				ast_indicate(chan, AST_CONTROL_PROCEEDING);
-				break;
-			case AST_CONTROL_HOLD:
-				if (option_verbose > 2)
-					ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", chan->name);
-				ast_indicate(chan, AST_CONTROL_HOLD);
-				break;
-			case AST_CONTROL_UNHOLD:
-				if (option_verbose > 2)
-					ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", chan->name);
-				ast_indicate(chan, AST_CONTROL_UNHOLD);
-				break;
-			case AST_CONTROL_OFFHOOK:
-			case AST_CONTROL_FLASH:
-				break;
-			case -1:
-				/* Prod the channel */
-				ast_indicate(chan, -1);
-				break;
-			default:
-				break;
-			}
-		}
-
-		/* Free the frame */
+		/* Process the frame */
+		if (chan)
+			handle_frame(dial, channel, fr, chan);
+		else
+			handle_frame_ownerless(dial, channel, fr);
+
+		/* Free the received frame and start all over */
 		ast_frfree(fr);
 	}
 
-	/* Based on the result code we can determine what to do next */
-	switch (dial->status) {
-	case AST_DIAL_RESULT_ANSWERED:
-		/* A channel was answered, so hang up all our other attempts */
+	/* Do post-processing from loop */
+	if (dial->status == AST_DIAL_RESULT_ANSWERED) {
+		/* Hangup everything except that which answered */
 		AST_LIST_TRAVERSE(&dial->channels, channel, list) {
-			if (channel->owner && channel->owner != who) {
-				ast_hangup(channel->owner);
-				channel->owner = NULL;
-			}
-		}
-		break;
-	case AST_DIAL_RESULT_HANGUP:
-	case AST_DIAL_RESULT_UNANSWERED:
-	case AST_DIAL_RESULT_TIMEOUT:
-		/* No channels were answered, hangup everyone */
+			if (!channel->owner || channel->owner == who)
+				continue;
+			ast_hangup(channel->owner);
+			channel->owner = NULL;
+		}
+	} else {
+		/* Hangup everything */
 		AST_LIST_TRAVERSE(&dial->channels, channel, list) {
-			if (channel->owner) {
-				ast_hangup(channel->owner);
-				channel->owner = NULL;
-			}
-		}
-		break;
-	default:
-		break;
+			if (!channel->owner)
+				continue;
+			ast_hangup(channel->owner);
+			channel->owner = NULL;
+		}
 	}
 
 	return dial->status;
 }
 
-/*! \brief Execute dialing asynchronously
- * \note Dials channels in a dial structure in a separate thread, returns almost immediately
- * \return Returns 0 on success, -1 on failure
- */
-enum ast_dial_result ast_dial_run_async(struct ast_dial *dial, struct ast_channel *chan)
-{
+/*! \brief Execute dialing synchronously or asynchronously
+ * \note Dials channels in a dial structure.
+ * \return Returns dial result code. (TRYING/INVALID/FAILED/ANSWERED/TIMEOUT/UNANSWERED).
+ */
+enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan, int async)
+{
+	enum ast_dial_result res = AST_DIAL_RESULT_TRYING;
+
+	/* Ensure required arguments are passed */
+	if (!dial || !chan)
+		return AST_DIAL_RESULT_INVALID;
+
 	/* If there are no channels to dial we can't very well try to dial them */
 	if (AST_LIST_EMPTY(&dial->channels))
 		return AST_DIAL_RESULT_INVALID;
-	
-	/* If we failed to dial any channels, then return a failed result */
+
+	/* Dial each requested channel */
 	if (!begin_dial(dial, chan))
 		return AST_DIAL_RESULT_FAILED;
 
-        return AST_DIAL_RESULT_TRYING;
+	/* If we are running async spawn a thread and send it away... otherwise block here */
+	if (async) {
+	} else {
+		res = monitor_dial(dial, chan);
+	}
+
+	return res;
 }
 
 /*! \brief Return channel that answered
@@ -417,6 +428,15 @@
 		return NULL;
 
 	return ((dial->status == AST_DIAL_RESULT_ANSWERED) ? AST_LIST_FIRST(&dial->channels)->owner : NULL);
+}
+
+/*! \brief Return status of dial
+ * \note Returns the status of the dial attempt
+ * \param dial Dialing structure
+ */
+enum ast_dial_result ast_dial_status(struct ast_dial *dial)
+{
+	return dial->status;
 }
 
 /*! \brief Hangup channels



More information about the asterisk-commits mailing list