[asterisk-commits] trunk r21097 - /trunk/res/res_features.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue Apr 18 06:05:50 MST 2006


Author: rizzo
Date: Tue Apr 18 08:05:48 2006
New Revision: 21097

URL: http://svn.digium.com/view/asterisk?rev=21097&view=rev
Log:
simplify the flow of builtin_atxfer().

There is still a lot of similarity with builtin_blindtransfer()
which should be removed by definining functions for the common
pieces of code (eg in the first part).


Modified:
    trunk/res/res_features.c

Modified: trunk/res/res_features.c
URL: http://svn.digium.com/view/asterisk/trunk/res/res_features.c?rev=21097&r1=21096&r2=21097&view=diff
==============================================================================
--- trunk/res/res_features.c (original)
+++ trunk/res/res_features.c Tue Apr 18 08:05:48 2006
@@ -444,7 +444,7 @@
 	char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL;
 	int x = 0;
 	size_t len;
-	struct ast_channel *caller_chan = NULL, *callee_chan = NULL;
+	struct ast_channel *caller_chan, *callee_chan;
 
 	if (!monitor_ok) {
 		ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
@@ -574,9 +574,9 @@
 	if (res < 0) {
 		finishup(transferee);
 		return -1; /* error ? */
-	} else if (res > 0) {	/* If they've typed a digit already, handle it */
+	}
+	if (res > 0)	/* If they've typed a digit already, handle it */
 		xferto[0] = (char) res;
-	}
 
 	ast_stopstream(transferer);
 	res = ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout);
@@ -634,18 +634,31 @@
 	return FEATURE_RETURN_SUCCESS;
 }
 
+static int check_compat(struct ast_channel *c, struct ast_channel *newchan)
+{
+	if (ast_channel_make_compatible(c, newchan) < 0) {
+		ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n",
+			c->name, newchan->name);
+		ast_hangup(newchan);
+		return -1;
+	}
+	return 0;
+}
+
 static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
 {
 	struct ast_channel *transferer;
 	struct ast_channel *transferee;
-	struct ast_channel *newchan, *xferchan=NULL;
+	const char *transferer_real_context;
+	char xferto[256];
+	int res;
 	int outstate=0;
+	struct ast_channel *newchan;
+	struct ast_channel *xferchan;
+	struct ast_bridge_thread_obj *tobj;
 	struct ast_bridge_config bconfig;
-	const char *transferer_real_context;
-	char xferto[256],dialstr[265];
-	int res;
-	struct ast_frame *f = NULL;
-	struct ast_bridge_thread_obj *tobj;
+	struct ast_frame *f;
+	int l;
 
 	if (option_debug)
 		ast_log(LOG_DEBUG, "Executing Attended Transfer %s, %s (sense=%d) \n", chan->name, peer->name, sense);
@@ -661,7 +674,8 @@
 	if (res < 0) {
 		finishup(transferee);
 		return res;
-	} else if (res > 0) /* If they've typed a digit already, handle it */
+	}
+	if (res > 0) /* If they've typed a digit already, handle it */
 		xferto[0] = (char) res;
 
 	/* this is specific of atxfer */
@@ -677,114 +691,95 @@
 			return -1;
 		return FEATURE_RETURN_SUCCESS;
 	}
+
 	/* valid extension, res == 1 */
-	{
-		if (!ast_exists_extension(transferer, transferer_real_context,xferto, 1, transferer->cid.cid_num)) {
-			ast_log(LOG_WARNING, "Extension %s does not exist in context %s\n",xferto,transferer_real_context);
-			finishup(transferee);
-			if (stream_and_wait(transferer, "beeperr", transferer->language, ""))
-				return -1;
-		} else {
-			snprintf(dialstr, sizeof(dialstr), "%s@%s/n", xferto, transferer_real_context);
-			newchan = ast_feature_request_and_dial(transferer, "Local", ast_best_codec(transferer->nativeformats), dialstr, 15000, &outstate, transferer->cid.cid_num, transferer->cid.cid_name);
-			ast_indicate(transferer, -1);
-			if (!newchan) {
-				finishup(transferee);
-				/* any reason besides user requested cancel and busy triggers the failed sound */
-				if (outstate != AST_CONTROL_UNHOLD && outstate != AST_CONTROL_BUSY &&
-						stream_and_wait(transferer, xferfailsound, transferer->language, ""))
-					return -1;
-				return FEATURE_RETURN_SUCCESS;
-			}
-			{
-				res = ast_channel_make_compatible(transferer, newchan);
-				if (res < 0) {
-					ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", transferer->name, newchan->name);
-					ast_hangup(newchan);
-					return -1;
-				}
-				memset(&bconfig,0,sizeof(struct ast_bridge_config));
-				ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
-				ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
-				res = ast_bridge_call(transferer,newchan,&bconfig);
-				if (newchan->_softhangup || newchan->_state != AST_STATE_UP || !transferer->_softhangup) {
-					ast_hangup(newchan);
-					if (f) {
-						ast_frfree(f);
-						f = NULL;
-					}
-					if (stream_and_wait(transferer, xfersound, transferer->language, ""))
-						ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
-					finishup(transferee);
-					transferer->_softhangup = 0;
-					return FEATURE_RETURN_SUCCESS;
-				}
-				
-				res = ast_channel_make_compatible(transferee, newchan);
-				if (res < 0) {
-					ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", transferee->name, newchan->name);
-					ast_hangup(newchan);
-					return -1;
-				}
-				
-				
-				ast_moh_stop(transferee);
-				
-				if ((ast_autoservice_stop(transferee) < 0)
-				   || (ast_waitfordigit(transferee, 100) < 0)
-				   || (ast_waitfordigit(newchan, 100) < 0) 
-				   || ast_check_hangup(transferee) 
-				   || ast_check_hangup(newchan)) {
-					ast_hangup(newchan);
-					res = -1;
-					return -1;
-				}
-
-				if ((xferchan = ast_channel_alloc(0))) {
-					ast_string_field_build(xferchan, name, "Transfered/%s", transferee->name);
-					/* Make formats okay */
-					xferchan->readformat = transferee->readformat;
-					xferchan->writeformat = transferee->writeformat;
-					ast_channel_masquerade(xferchan, transferee);
-					ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
-					xferchan->_state = AST_STATE_UP;
-					ast_clear_flag(xferchan, AST_FLAGS_ALL);	
-					xferchan->_softhangup = 0;
-
-					if ((f = ast_read(xferchan))) {
-						ast_frfree(f);
-						f = NULL;
-					}
-					
-				} else {
-					ast_hangup(newchan);
-					return -1;
-				}
-
-				newchan->_state = AST_STATE_UP;
-				ast_clear_flag(newchan, AST_FLAGS_ALL);	
-				newchan->_softhangup = 0;
-				
-				if ((tobj = ast_calloc(1, sizeof(*tobj)))) {
-					tobj->chan = xferchan;
-					tobj->peer = newchan;
-					tobj->bconfig = *config;
+	if (!ast_exists_extension(transferer, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
+		ast_log(LOG_WARNING, "Extension %s does not exist in context %s\n",xferto,transferer_real_context);
+		finishup(transferee);
+		if (stream_and_wait(transferer, "beeperr", transferer->language, ""))
+			return -1;
+		return FEATURE_RETURN_SUCCESS;
+	}
+
+	l = strlen(xferto);
+	snprintf(xferto + l, sizeof(xferto) - l, "@%s/n", transferer_real_context);	/* append context */
+	newchan = ast_feature_request_and_dial(transferer, "Local", ast_best_codec(transferer->nativeformats),
+		xferto, 15000, &outstate, transferer->cid.cid_num, transferer->cid.cid_name);
+	ast_indicate(transferer, -1);
+	if (!newchan) {
+		finishup(transferee);
+		/* any reason besides user requested cancel and busy triggers the failed sound */
+		if (outstate != AST_CONTROL_UNHOLD && outstate != AST_CONTROL_BUSY &&
+				stream_and_wait(transferer, xferfailsound, transferer->language, ""))
+			return -1;
+		return FEATURE_RETURN_SUCCESS;
+	}
+
+	if (check_compat(transferer, newchan))
+		return -1;
+	memset(&bconfig,0,sizeof(struct ast_bridge_config));
+	ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
+	ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
+	res = ast_bridge_call(transferer, newchan, &bconfig);
+	if (newchan->_softhangup || newchan->_state != AST_STATE_UP || !transferer->_softhangup) {
+		ast_hangup(newchan);
+		if (stream_and_wait(transferer, xfersound, transferer->language, ""))
+			ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
+		finishup(transferee);
+		transferer->_softhangup = 0;
+		return FEATURE_RETURN_SUCCESS;
+	}
 	
-					if (stream_and_wait(newchan, xfersound, newchan->language, ""))
-						ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
-					ast_bridge_call_thread_launch(tobj);
-				} else {
-					ast_hangup(xferchan);
-					ast_hangup(newchan);
-				}
-				return -1;
-				
-			}
-		}
-	}
-	finishup(transferee);
-
-	return FEATURE_RETURN_SUCCESS;
+	if (check_compat(transferee, newchan))
+		return -1;
+
+	ast_moh_stop(transferee);
+	
+	if ((ast_autoservice_stop(transferee) < 0)
+	   || (ast_waitfordigit(transferee, 100) < 0)
+	   || (ast_waitfordigit(newchan, 100) < 0) 
+	   || ast_check_hangup(transferee) 
+	   || ast_check_hangup(newchan)) {
+		ast_hangup(newchan);
+		return -1;
+	}
+
+	xferchan = ast_channel_alloc(0);
+	if (!xferchan) {
+		ast_hangup(newchan);
+		return -1;
+	}
+	ast_string_field_build(xferchan, name, "Transfered/%s", transferee->name);
+	/* Make formats okay */
+	xferchan->readformat = transferee->readformat;
+	xferchan->writeformat = transferee->writeformat;
+	ast_channel_masquerade(xferchan, transferee);
+	ast_explicit_goto(xferchan, transferee->context, transferee->exten, transferee->priority);
+	xferchan->_state = AST_STATE_UP;
+	ast_clear_flag(xferchan, AST_FLAGS_ALL);	
+	xferchan->_softhangup = 0;
+
+	if ((f = ast_read(xferchan)))
+		ast_frfree(f);
+
+	newchan->_state = AST_STATE_UP;
+	ast_clear_flag(newchan, AST_FLAGS_ALL);	
+	newchan->_softhangup = 0;
+
+	tobj = ast_calloc(1, sizeof(struct ast_bridge_thread_obj));
+	if (!tobj) {
+		ast_hangup(xferchan);
+		ast_hangup(newchan);
+		return -1;
+	}
+	tobj->chan = xferchan;
+	tobj->peer = newchan;
+	tobj->bconfig = *config;
+
+	if (stream_and_wait(newchan, xfersound, newchan->language, ""))
+		ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
+	ast_bridge_call_thread_launch(tobj);
+	return -1;	/* XXX meaning the channel is bridged ? */
 }
 
 



More information about the asterisk-commits mailing list