[Home]

Summary:ASTERISK-08143: [patch] Upgrade for atxfer behaviour
Reporter:Sergey Tamkovich (sergee)Labels:
Date Opened:2006-11-24 06:17:20.000-0600Date Closed:2010-01-22 12:33:37.000-0600
Priority:MajorRegression?No
Status:Closed/CompleteComponents:Core/General
Versions:Frequency of
Occurrence
Related
Issues:
Environment:Attachments:( 0) transfer-v4-r48105.patch
( 1) transfer-v5-r61667.diff
Description:I think that Asterisk doesn't have "normal" transfer. There atxfer and blindxfer, but you can't use them both at once. E.g. If transferer hangup during atxfer - transfer will fail, it won't work as blind transfer.

This patch alter standard behaviour of atxfer. If Transferer hangup during transfer atxfer will work as traditional transfer (like transfer on Panasonic, NEC and other hardware PBXes).

If third party didn't respond to a transferee, atxfer will initiate callback to a transferer.
Comments:By: Sergey Tamkovich (sergee) 2006-11-27 02:57:48.000-0600

Updated patch available now:

fixed 2 bugs:

1. Autoservice is stopped correctly now.
2. If transferee and transferer hangup during call to 3rd party - call will be terminated instantly now.

No more known issues. Comments are welcomed!

By: Sergey Tamkovich (sergee) 2006-11-27 04:49:56.000-0600

New issue found:
if transferee hangup before transferer - call will be broken.

Should change condition in while() in ast_feature_request_and_dial()

By: Sergey Tamkovich (sergee) 2006-11-27 05:11:07.000-0600

3rd issue fixed. Continue intensive testing...

By: flot (flot) 2006-11-27 08:04:34.000-0600

I have tested. For me works.
Asterisk SVN-trunk-r48033

By: Ronald Chan (loloski) 2006-11-27 09:41:27.000-0600

sergee & others: could somebody correct me if i'm wrong, if you do attended transfer and you don't want to wait for the callee to answer the phone all you have to do is press the disconnect feature, what it does if nobody is pickup up the call then it will ringback your extension as the operator? but if you just hangup the call expect that it will drop the call on attended transfer?

i hope i this is clear, thanks

disconnect => *0                ; Disconnect  (default is *)

Ronald

By: Ronald Chan (loloski) 2006-11-27 09:55:46.000-0600

If i'm correct i vouch for this patch, since you don't have to press disconnect feature from time to time, it's just my opinion


Ronald

By: Sergey Tamkovich (sergee) 2006-11-27 10:15:46.000-0600

loloski, if you wish to transfer a call, you press kay sequence for atxfer and wait till 3rd party will answer.

If you (transferer) hangup 3rd party before he answers or after with disconnect feauture, you will be connected with transferee again (if transferee didn't hangup yet).

Is this an answer for your question? :)


--------------

as for ringback. it uses the same timeout value as transfer itself, e.g. transferee waits for 3rd party to answer "atxfernoanswertimeout" seconds. if 3rd party didn't answer within timeout then it calls back to transferer and waits for him same time - "atxfernoanswertimeout" seconds. if transferer didn't answer within timeout - call will be dropped.

By: Sergey Basmanov (sb) 2006-11-27 10:52:52.000-0600

I think it would be nice if there will be option somewhere to switch behavor.
Some people sure that current behavor is correct, and some - not.
But in general, this is right way, because it's very difficult to explain to some people when they have to use attended transfer and when blind.
So, I will try this patch when I will have chance..

By: Sergey Tamkovich (sergee) 2006-11-27 11:48:39.000-0600

sb, i spoke with anthm on asterisk-dev and he told me that this patch returns original behaviour to atxfer, which was lost somewhere ..

So i think this is the right one :)

By: flot (flot) 2006-11-27 12:51:28.000-0600

I have found a problem.
If to transfer a call and to hang up, and the subscriber does not answer, * falls!

   -- Started music on hold, class 'default', on H323/ip$84.16.130.74:49061/16959
   -- Playing 'pbx-transfer' (language 'en')
   -- Executing [061@mejgorod:1] Ringing("Local/061@mejgorod-c207,2", "") in new stack
   -- Local/061@mejgorod-c207,1 is ringing
   -- Executing [061@mejgorod:2] Wait("Local/061@mejgorod-c207,2", "100") in new stack
[Nov 27 22:40:54] NOTICE[22734]: res_features.c:1225 ast_feature_request_and_dial: We exceeded our AT-timeout
 == Spawn extension (mejgorod, 061, 2) exited non-zero on 'Local/061@mejgorod-c207,2'[Nov 27 22:40:54] DEBUG[24466]: res_config_mysql.c:651 mysql_reconnect: MySQL RealTime: Everything is fine.
[Nov 27 22:40:54] DEBUG[24466]: res_config_mysql.c:139 realtime_mysql: MySQL RealTime: Retrieve SQL: SELECT * FROM extensions WHERE exten = 'h' AND context = 'cytel' AND priority = '1'
[Nov 27 22:40:54] DEBUG[24466]: res_config_mysql.c:651 mysql_reconnect: MySQL RealTime: Everything is fine.
[Nov 27 22:40:54] DEBUG[24466]: res_config_mysql.c:259 realtime_multi_mysql: MySQL RealTime: Retrieve SQL: SELECT * FROM extensions WHERE exten LIKE '\\_%' AND context = 'cytel' AND priority = '1' ORDER BY exten
[Nov 27 22:40:54] DEBUG[24466]: res_config_mysql.c:651 mysql_reconnect: MySQL RealTime: Everything is fine.
[Nov 27 22:40:54] DEBUG[24466]: res_config_mysql.c:139 realtime_mysql: MySQL RealTime: Retrieve SQL: SELECT * FROM extensions WHERE exten = 'h' AND context = 'sip' AND priority = '1'
[Nov 27 22:40:54] DEBUG[24466]: res_config_mysql.c:651 mysql_reconnect: MySQL RealTime: Everything is fine.
[Nov 27 22:40:54] DEBUG[24466]: res_config_mysql.c:259 realtime_multi_mysql: MySQL RealTime: Retrieve SQL: SELECT * FROM extensions WHERE exten LIKE '\\_%' AND context = 'sip' AND priority = '1' ORDER BY exten
[Nov 27 22:40:54] DEBUG[24466]: cdr_addon_mysql.c:210 mysql_log: cdr_mysql: inserting a CDR record.
[Nov 27 22:40:54] DEBUG[24466]: cdr_addon_mysql.c:226 mysql_log: cdr_mysql: SQL command as follows: INSERT INTO cdr (calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,lastdata,duration,billsec,disposition,amaflags,accountcode) VALUES ('2006-11-27 22:40:23','101','101','061','mejgorod', 'Local/061@mejgorod-c207,2','','Wait','100',31,0,'NO ANSWER',3,'')
[Nov 27 22:40:54] NOTICE[22734]: chan_local.c:562 local_alloc: No such extension/context 101@default creating local channel
[Nov 27 22:40:54] NOTICE[22734]: res_features.c:1307 ast_feature_request_and_dial: Unable to request channel Local/101
   -- Stopped music on hold on H323/ip$84.16.130.74:49061/16959
Killed


(gdb) bt full
#0  ast_channel_make_compatible (chan=0x8214828, peer=0x0) at channel.c:3036
       src = 1
       dst = -1209007600
       __PRETTY_FUNCTION__ = "ast_channel_make_compatible"
#1  0xb701a37d in builtin_atxfer (chan=0x0, peer=0x8214828, config=0xb63d37e0,
   code=0xb63d2870 "#", sense=2) at res_features.c:721
       transferer = (struct ast_channel *) 0x820b390
       transferee = (struct ast_channel *) 0x8214828
       xferto = "061@mejgorod/n", '\0' <repeats 241 times>
       res = 136398888
       outstate = 0
       newchan = (struct ast_channel *) 0x0
       xferchan = (struct ast_channel *) 0x8214828
       bconfig = {features_caller = {flags = 0}, features_callee = {flags = 0},
 start_time = {tv_sec = 0, tv_usec = 0}, feature_timer = 0, timelimit = 0,
 play_warning = 0, warning_freq = 0, warning_sound = 0x0, end_sound = 0x0,
 start_sound = 0x0, firstpass = 0, flags = 0}
       f = (struct ast_frame *) 0xb63d23b8
---Type <return> to continue, or q <return> to quit---
       l = 136398888
       __PRETTY_FUNCTION__ = "builtin_atxfer"
#2  0xb70189a2 in ast_feature_interpret (chan=0x8214828, peer=0x820b390,
   config=0xb63d37e0, code=0xb63d2870 "#", sense=2) at res_features.c:1110
       tmp = 0xb63d2871 ""
       features = {flags = 2}
       res = 21
       dynamic_features = 0x0
       __PRETTY_FUNCTION__ = "ast_feature_interpret"
#3  0xb7019950 in ast_bridge_call (chan=0x8214828, peer=0x820b390, config=0xb63d37e0)
   at res_features.c:1531
       featurecode = 0xb63d2870 "#"
       sense = 2
       f = (struct ast_frame *) 0x0
       who = (struct ast_channel *) 0x820b390
       chan_featurecode = '\0' <repeats 11 times>
       peer_featurecode = "#\000\000\000\000\000\000\000\000\000\000"
       hasfeatures = 0
---Type <return> to continue, or q <return> to quit---
       hadfeatures = 0
       aoh = (struct ast_option_header *) 0x8
       backup_config = {features_caller = {flags = 0}, features_callee = {
   flags = 0}, start_time = {tv_sec = 0, tv_usec = 0}, feature_timer = 0,
 timelimit = 0, play_warning = 0, warning_freq = 0, warning_sound = 0x0,
 end_sound = 0x0, start_sound = 0x0, firstpass = 0, flags = 0}
       __PRETTY_FUNCTION__ = "ast_bridge_call"
#4  0xb66e85a0 in dial_exec_full (chan=0x8214828, data=0xb63d7ac0,
   peerflags=0xb63d38f4) at app_dial.c:1645
       cdr = (struct ast_cdr *) 0xb63d23b8
       res = 0
       u = (struct ast_module_user *) 0x820dff8
       rest = 0x0
       outgoing = (struct dial_localuser *) 0x0
       to = 5701
       num = {chan = 0x8214828, busy = 0, congestion = 0, nochan = 0}
       cause = 0
       numsubst = "flot-phone", '\0' <repeats 22 times>, "\001\000\000\000&ASTERISK-9288;8=&ASTERISK-9293;d&ASTERISK-9279;\035\---Type <return> to continue, or q <return> to quit---
b\033\000\000\000%\000\000\000(\000\000\000(H!\b\0014\f\b36;40\000&ASTERISK-1072;&ASTERISK-9294;\001\000\000\000\237m&ASTERISK-1072;&ASTERISK-9294;"
       cidname = '\0' <repeats 79 times>
       config = {features_caller = {flags = 0}, features_callee = {flags = 2},
 start_time = {tv_sec = 1164656407, tv_usec = 779365}, feature_timer = 0,
 timelimit = 0, play_warning = 0, warning_freq = 0, warning_sound = 0x0,
 end_sound = 0x0, start_sound = 0x0, firstpass = 0, flags = 2}
       calldurationlimit = 0
       dtmfcalled = 0x0
       dtmfcalling = 0x0
       pa = {sentringing = 1, privdb_val = 0, privcid = '\0' <repeats 255 times>,
 privintro = '\0' <repeats 1023 times>,
 status = "ANSWER\000R", '\0' <repeats 247 times>}
       sentringing = 0
       moh = 0
       outbound_group = 0x0
       result = 0
       start_time = 1164656403
---Type <return> to continue, or q <return> to quit---
       opermode = 0
       args = {argc = 3, argv = 0xb63d31b4, peers = 0xb63d28e0 "SIP",
 timeout = 0xb63d28ef "10", options = 0xb63d28f2 "t", url = 0x0}
       opts = {flags = 524288}
       opt_args = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
       __PRETTY_FUNCTION__ = "dial_exec_full"
ASTERISK-1  0xb66e9e0e in dial_exec (chan=0xb63d23b8, data=0x1) at app_dial.c:1687
       peerflags = {flags = 524288}
ASTERISK-2  0x080bfc30 in pbx_extension_helper (c=0x8214828, con=0x0,
   context=0x82149a8 "from_tt", exten=0x82149f8 "101", priority=1, label=0x0,
   callerid=0x8214448 "4539439", action=3057482432) at pbx.c:503
       e = (struct ast_exten *) 0xb6918098
       res = 0
       q = {incstack = {0xb6912cbc "from_tt", 0x0 <repeats 127 times>},
 stacklen = 1, status = 5, swo = 0x0, data = 0x0, foundcontext = 0xb6912d52 "local"}
       passdata = "SIP/flot-phone|10|t", '\0' <repeats 8172 times>
       matching_action = 0
       __PRETTY_FUNCTION__ = "pbx_extension_helper"
---Type <return> to continue, or q <return> to quit---
ASTERISK-3  0x080c0fcf in __ast_pbx_run (c=0x8214828) at pbx.c:2165
       dst_exten = '\0' <repeats 157 times>, "&ASTERISK-9282;\034&ASTERISK-9294;\000&ASTERISK-9282;\034&ASTERISK-9294;H\236=&ASTERISK-9293;~q&ASTERISK-1072;&ASTERISK-9294;&ASTERISK-1052;?&ASTERISK-1072;&ASTERISK-9294;\000D!\b\000&ASTERISK-9282;\034&ASTERISK-9294;H\236=&ASTERISK-9293;-@&ASTERISK-1072;&ASTERISK-9294;\020&ASTERISK-9282;\034&ASTERISK-9294;&ASTERISK-1052;\217\034&ASTERISK-9294;|n&ASTERISK-1072;&ASTERISK-9294;&ASTERISK-1052;?&ASTERISK-1072;&ASTERISK-9294;&ASTERISK-1064;U!\bh\031\024\bx\236=&ASTERISK-9293;\t>&ASTERISK-1072;&ASTERISK-9294;\230\205\001\000\f\000\000\000hZ!\b\000D!\b\000O!\b\000\000\000\000&ASTERISK-9281;\236=&ASTERISK-9293;}x\006\b"
       pos = 0
       digit = 0
       found = 1
       res = 0
       error = 0
       __PRETTY_FUNCTION__ = "__ast_pbx_run"
ASTERISK-4  0x080c2e8e in pbx_thread (data=0xb63d23b8) at pbx.c:2478
No locals.
ASTERISK-5  0x080ef005 in dummy_start (data=0x1) at utils.c:545
       _buffer = {__routine = 0x8067910 <ast_unregister_thread>, __arg = 0x74013,
 __canceltype = -1237475608, __prev = 0x0}
       ret = (void *) 0x8214f00
       a = {start_routine = 0x80c2e80 <pbx_thread>, data = 0x8214828,
 name = 0x8214f00 "pbx_thread", ' ' <repeats 11 times>, "started at [ 2502] pbx.c ast---Type <return> to continue, or q <return> to quit---
_pbx_start()"}
ASTERISK-6 0xb7d62aec in pthread_start_thread () from /lib/libpthread.so.0
No symbol table info available.
ASTERISK-7 0xb716eb3a in clone () from /lib/libc.so.6
No symbol table info available.
(gdb) quit
server ~ #



By: Sergey Tamkovich (sergee) 2006-11-29 04:13:27.000-0600

more issues fixed:

4. No more crashes (bug reported by flot 11-27-06 13:45)
5. Callback happens in transferers_context now.


Big thanks to flot for testing.

By: Serge Vecher (serge-v) 2006-11-30 08:33:47.000-0600

I would also vote for this behavior to be called by a different config option instead of altering "atxfer". Maybe "transfer"?

By: Sergey Tamkovich (sergee) 2006-11-30 08:43:14.000-0600

Hi serge-v!
Haven't seen you for a long time! :)

I can make it to be a different option, but then we will have a lot of duplicated code...

By: Sergey Tamkovich (sergee) 2007-03-05 09:13:39.000-0600

If transferee hit a timeout, my patch try to connect transferer and transferee again. if transferer already busy on the phone, Asterisk will hangup transferee. Alex_99, suggested to loop that timeout, e.g. if transferer is busy, we won't drop a transferee, but we will start this timeout from the begining.

I think this is very interesting idea - call will be fiinished only if transferee himself will hangup, so call won't be lost. I will implement this idea during this or next week.

By: David Svanlund (svanlund) 2007-03-22 15:35:27

Just discovered this bug report. My bug 9338 has the same intention - if transferer hangs up the call will not be dropped. I believe this was the intention of the old bug associated with mine. My patch is very simple (but needs to be verified, might break something), it allows the call to proceed as a blind transfer.

Your patch takes this one step further. The callback feature is a welcome addition. I'll be happy to do some additional testing. Any new version coming up?

If this bug gets accepted as a modification/addition to atxfer, it will solve my issue in bug 9338. Otherwise, it will need to be patched independently.

By: David Svanlund (svanlund) 2007-03-23 06:46:48

If a callback occurs and the transferer then initiates a new attended transfer, the second callback (if any) will dial the transferee.

By: Igor Goncharovsky (igorg) 2007-04-08 21:42:32

I try this patch, it is work great. I have some things, that could be useful:

1) When doing attented transfer, set in dialplan variable with transferee callerID. It is make posible to view callerID of transferee by third party.
2) Is any way to make notification to third party, if transferer hang up, and asterisk now doing a blind transfer? This may be reINVITE with different Alert-Info or running external application...

By: Sergey Tamkovich (sergee) 2007-04-16 11:32:12

New patch available!

Changes:


* Works with current trunk (revision 61667)
* Can loop call between transferer and 3rdparty, so transferee won't be droped until he hangs up himself (feature suggested by Alex_99).
* Added new configuration option "atxferdropcall" (values: yes/no). If atxferdropcall=yes, call won't be looped (old "-v4" behaviour) default value: "no"
* Added new configuration option "atxferloopdelay" value (integer, seconds). Specifyes value to wait between iterations of loop. If we won't wait, and both transferer and 3rd party, would be unavailable - we'll perfom DoS attack on our system, so let's sleep for a while before iterations. Default value 10 seconds.

By: David Svanlund (svanlund) 2007-04-16 14:00:10

Great! I'll try to test the new patch tomorrow.

By: David Svanlund (svanlund) 2007-04-17 08:17:32

The new functionality seems to be working as expected.

By: Sergey Tamkovich (sergee) 2007-04-17 08:20:53

svanlund, thanks for testing!
any more volunteers? :)

By: Russell Bryant (russell) 2007-05-01 14:08:48

I have created a branch for this code to play with while I test and look it over.

svn co http://svn.digium.com/svn/asterisk/team/russell/issue_8413

By: Russell Bryant (russell) 2007-05-01 17:24:42

This patch has been merged into trunk in revision 62593.  Thanks!