mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-13 00:04:53 +00:00
Instead of trying to callback a local channel on a failed attended transfer, call
the device that made the transfer instead. This makes for much smoother calling back when queues are involved. (closes issue #11155, reported by IPetrov) Tremendous thanks to Russell for pulling me out of my block I was having on this one git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@89055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -892,7 +892,6 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st
|
|||||||
struct ast_channel *transferee;
|
struct ast_channel *transferee;
|
||||||
const char *transferer_real_context;
|
const char *transferer_real_context;
|
||||||
char xferto[256] = "";
|
char xferto[256] = "";
|
||||||
char callbackto[256] = "";
|
|
||||||
int res;
|
int res;
|
||||||
int outstate=0;
|
int outstate=0;
|
||||||
struct ast_channel *newchan;
|
struct ast_channel *newchan;
|
||||||
@@ -1031,25 +1030,28 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st
|
|||||||
|
|
||||||
if (!newchan) {
|
if (!newchan) {
|
||||||
unsigned int tries = 0;
|
unsigned int tries = 0;
|
||||||
|
char *transferer_tech, *transferer_name = ast_strdupa(transferer->name);
|
||||||
|
|
||||||
/* newchan wasn't created - we should callback to transferer */
|
transferer_tech = strsep(&transferer_name, "/");
|
||||||
if (!ast_exists_extension(transferer, transferer_real_context, transferer->cid.cid_num, 1, transferee->cid.cid_num)) {
|
transferer_name = strsep(&transferer_name, "-");
|
||||||
ast_log(LOG_WARNING, "Extension %s does not exist in context %s - callback failed\n",transferer->cid.cid_num,transferer_real_context);
|
|
||||||
|
if (ast_strlen_zero(transferer_name) || ast_strlen_zero(transferer_tech)) {
|
||||||
|
ast_log(LOG_WARNING, "Transferer has invalid channel name: '%s'\n", transferer->name);
|
||||||
if (ast_stream_and_wait(transferee, "beeperr", ""))
|
if (ast_stream_and_wait(transferee, "beeperr", ""))
|
||||||
return -1;
|
return -1;
|
||||||
return FEATURE_RETURN_SUCCESS;
|
return FEATURE_RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
snprintf(callbackto, sizeof(callbackto), "%s@%s/n", transferer->cid.cid_num, transferer_real_context); /* append context */
|
|
||||||
|
|
||||||
newchan = ast_feature_request_and_dial(transferee, NULL, "Local", ast_best_codec(transferee->nativeformats),
|
ast_log(LOG_NOTICE, "We're trying to call %s/%s\n", transferer_tech, transferer_name);
|
||||||
callbackto, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0);
|
newchan = ast_feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
|
||||||
|
transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0);
|
||||||
while (!newchan && !atxferdropcall && tries < atxfercallbackretries) {
|
while (!newchan && !atxferdropcall && tries < atxfercallbackretries) {
|
||||||
/* Trying to transfer again */
|
/* Trying to transfer again */
|
||||||
ast_autoservice_start(transferee);
|
ast_autoservice_start(transferee);
|
||||||
ast_indicate(transferee, AST_CONTROL_HOLD);
|
ast_indicate(transferee, AST_CONTROL_HOLD);
|
||||||
|
|
||||||
newchan = ast_feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
|
newchan = ast_feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
|
||||||
xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1);
|
xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1);
|
||||||
if (ast_autoservice_stop(transferee) < 0) {
|
if (ast_autoservice_stop(transferee) < 0) {
|
||||||
if (newchan)
|
if (newchan)
|
||||||
ast_hangup(newchan);
|
ast_hangup(newchan);
|
||||||
@@ -1060,8 +1062,8 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st
|
|||||||
ast_debug(1, "Sleeping for %d ms before callback.\n", atxferloopdelay);
|
ast_debug(1, "Sleeping for %d ms before callback.\n", atxferloopdelay);
|
||||||
ast_safe_sleep(transferee, atxferloopdelay);
|
ast_safe_sleep(transferee, atxferloopdelay);
|
||||||
ast_debug(1, "Trying to callback...\n");
|
ast_debug(1, "Trying to callback...\n");
|
||||||
newchan = ast_feature_request_and_dial(transferee, NULL, "Local", ast_best_codec(transferee->nativeformats),
|
newchan = ast_feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
|
||||||
callbackto, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0);
|
transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0);
|
||||||
}
|
}
|
||||||
tries++;
|
tries++;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user