summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2009-04-03 16:47:27 +0000
committerJoshua Colp <jcolp@digium.com>2009-04-03 16:47:27 +0000
commit2d9c6ef3d501b1fb7ebdd2fa5bc2e530ed55b6c0 (patch)
tree9a47da9503ee4492361033db1e1d338c3bfd5816 /main
parent547b5c7e90af7d0088cb81a16a0fe8afd156d3a0 (diff)
Add better support for relaying success or failure of the ast_transfer() API call.
This API call now waits for a special frame from the underlying channel driver to indicate success or failure. This allows the return value to truly convey whether the transfer worked or not. In the case of the Transfer() dialplan application this means the value of the TRANSFERSTATUS dialplan variable is actually true. (closes issue #12713) Reported by: davidw Tested by: file git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@186382 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main')
-rw-r--r--main/channel.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/main/channel.c b/main/channel.c
index b492f5113..9b2ad405c 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -2994,6 +2994,7 @@ static int attribute_const is_visible_indication(enum ast_control_frame_type con
case AST_CONTROL_ANSWER:
case AST_CONTROL_HANGUP:
case AST_CONTROL_T38:
+ case AST_CONTROL_TRANSFER:
return 0;
case AST_CONTROL_CONGESTION:
@@ -3080,6 +3081,7 @@ int ast_indicate_data(struct ast_channel *chan, int _condition,
case AST_CONTROL_HOLD:
case AST_CONTROL_UNHOLD:
case AST_CONTROL_T38:
+ case AST_CONTROL_TRANSFER:
/* Nothing left to do for these. */
res = 0;
break;
@@ -3759,6 +3761,37 @@ int ast_transfer(struct ast_channel *chan, char *dest)
res = 0;
}
ast_channel_unlock(chan);
+
+ if (res < 0) {
+ return res;
+ }
+
+ for (;;) {
+ struct ast_frame *fr;
+
+ res = ast_waitfor(chan, -1);
+
+ if (res < 0 || !(fr = ast_read(chan))) {
+ res = -1;
+ break;
+ }
+
+ if (fr->frametype == AST_FRAME_CONTROL && fr->subclass == AST_CONTROL_TRANSFER) {
+ enum ast_control_transfer *message = fr->data.ptr;
+
+ if (*message == AST_TRANSFER_SUCCESS) {
+ res = 1;
+ } else {
+ res = -1;
+ }
+
+ ast_frfree(fr);
+ break;
+ }
+
+ ast_frfree(fr);
+ }
+
return res;
}