Summary:ASTERISK-02425: [patch] Attended Pound Transfers The Perfect New Years Resolution!!!
Reporter:Anthony Minessale (anthm)Labels:
Date Opened:2004-09-16 19:29:24Date Closed:2005-01-05 00:03:25.000-0600
Versions:Frequency of
Environment:Attachments:( 0) app_dtget.c
( 1) atxfer_1204.diff
( 2) atxfer_1204.rev2.diff
( 3) atxfer_fixes_gryn1.diff
( 4) atxfer_latest.diff
( 5) atxfer_latest2.diff
( 6) atxfer_post10.diff
( 7) atxfer_with_timer.diff
( 8) atxfer2.diff
( 9) errbeep.gsm
(10) patch.diff
Description:This patch first off adds a new api call ast_dtget

int ast_dtget(struct ast_channel *chan, char *collect, size_t size, int total, int to);

This will present a dialtone to the chan and await
'total' digits timing out after 20 sec for the 1st digit or 'to' seconds after each successful read digit.
The digits will be appended
into 'collect' which is assumed to be a null padded buffer
of 'size' bytes ast_dtget will return the number of digits

The patch will implement the x and X flags in app_dial
which are the attended transfer version of t and T respectively.

During a briged call with the attended transfer flags set,
the caller will be presented with a dialtone when the # key
is pressed.  The transfering caller may then dial any extension in
the current context otherwise the ${TRANSFER_CONTEXT} if that channel variable is set.
The dialed extension may be ended with an additional # key
or after a brief timeout.

If the dialed extension is valid, the transferer will place a call to that extension while putting the transferee on hold
at which time the transferer and the called extension may converse.  When the conversation between the transferer and the
called extension ends by either party hanging up the remaining caller will be bridged with the
original caller put on hold when the transfer began.

Also Attached is an Application version of ast_dtget to use it from the dialplan.


Disclaimer on file.
Comments:By: Brian West (bkw918) 2004-09-16 20:45:40


By: Anthony Minessale (anthm) 2004-09-17 14:12:56

updated to keep up with CVS that is trying to crush it.

By: cypromis (cypromis) 2004-09-17 16:45:46

This is better than slice bread.... finally the solution to make cheap sip phones and othercheap shit phones make any sense for utilisation with asterisk.

By: dw (dw) 2004-09-20 09:03:10

After applying this patch, pressing '#' put the caller on hold and presented a dialtone as expected, however dialling a number and waiting for the timeout (or hitting '#') caused Asterisk to dump core immediately:

Urgent handler
2004-09-20 14:49:32 NOTICE[1104243632]: chan_local.c:374 local_alloc: No such extension/context local_extensions
@103 creating local channel
2004-09-20 14:49:32 NOTICE[1104243632]: channel.c:1817 __ast_request_and_dial: Unable to request channel Local/103@local_extensions

2004-09-20 14:49:32 WARNING[1104243632]: res_features.c:544 ast_bridge_call: Unable to create chanenl Local/103@local_extensions

2004-09-20 14:49:32 WARNING[1104243632]: channel.c:995 ast_waitfor_nandfds: Thread 1104243632 Blocking 'SIP/102-fca4', already blocked by thread 1106398128 in procedure ast_waitfor_nandfds

#0  0x0805e09c in ast_do_masquerade (original=0x817ba00) at channel.c:2210
2210            ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",

#0  0x0805e09c in ast_do_masquerade (original=0x817ba00) at channel.c:2210
#1  0x0805ae43 in ast_waitfor_nandfds (c=0x41f246c0, n=1, fds=0x0, nfds=0, exception=0x0, outfd=0x0, ms=0x41f246bc)
   at channel.c:969
#2  0x080607e7 in ast_waitfor_n (c=0x0, n=0, ms=0x0) at channel.c:1075
#3  0x080a9020 in autoservice_run (ign=0x0) at autoservice.c:76
#4  0x400249b4 in start_thread () from /lib/tls/libpthread.so.0

(gdb) print clone->name
Cannot access memory at address 0x20277461
(gdb) print original->name
$4 = "central", '\0' <repeats 72 times>



edited on: 09-20-04 09:06

By: nicolasg (nicolasg) 2004-09-20 09:42:20

Same crash here.

By: Brian West (bkw918) 2004-09-20 11:33:10

Can you provide a "bt full" or find anthm on IRC


By: Anthony Minessale (anthm) 2004-09-20 13:08:26

Try this patch that will avoid the crash but i think your problem is no chan_local.
Also now I included a gsm of the typical windows style "dunk" (chord) sound
that will indicate something bad happened rather than the 10 min long allison warning you can either take this file or just make your own called "errbeep"
either way its mandatory to have an errbeep with this last patch

(turns out chan_local needs a /n flag to disable auto masquarade
which screws everything up.)

edited on: 09-21-04 15:45

By: Anthony Minessale (anthm) 2004-09-20 16:40:08

This new version of the patch also allows you to redefine the hangup
and transfer keys (see bug 2010)

you can use the K(<transfer>:<hangup>) to redefine it
like K(#:*) for old behaviour or even use multikey bindings
K(123:456) also if you are using long bindings and want to
mute dtmf you can add in the 'd' flag so the other party
doesn't hear all the dtmf

By: cshaw59 (cshaw59) 2004-09-20 18:27:49

Schweet, this rules!!

So this replaces/compliments the patch detailed in ASTERISK-1984? Has mark seen it yet? He had some issues with 2010 and that's why it's not in CVS yet. Not sure exactly what those issues were, but they're enough to keep it out of the tree...

Hopefully the need for this patch will eventually become obsoleted by SIP vendors that get their heads out of their... sandboxes... and support supervised/attended transfers using REPLACES (or whatever replaces REPLACES as it's draft has expired now...).


edited on: 09-20-04 18:37

By: Diego Ercolani (dercol) 2004-09-21 13:01:52

Tested today with Asterisk CVS-HEAD-08/13/04-12:00:00-BRI-stuffed-0.1.0-RC4a built by root@amarone on a i686 running Linux.
Great Job. I had to change something in patches (related to non allineated version of asterisk) but it seem to work fine. Some gliches on the music on hold when changing state but no other problems until BRI-stuffed-0.1.0-RC4a_app_dtget_atxfer_plus_keybind.diff.gznow.
Note: I've uploaded BRI-stuffed-0.1.0-RC4a_app_dtget_atxfer_plus_keybind.diff.gz that is a cumulative patch done on bri-stuffed version.

edited on: 09-23-04 17:39

By: Diego Ercolani (dercol) 2004-09-23 09:15:00

I've made some tests using the patch, hope this will help:

* sometimes crashes asterisk with core dumps (probably memory leakes) ?
  -- Executing Dial("SIP/kphone2-df30", "SIP/gs2&SIP/kphone2&iax2/ercolani|20|xr")in new stack
   -- Called gs2
   -- Called kphone2
Sep 23 16:10:41 NOTICE[1327126]: app_dial.c:762 dial_exec: Unable to create channel of type 'iax2'
   -- SIP/gs2-36df is ringing
   -- SIP/kphone2-42cb is ringing
   -- SIP/gs2-36df answered SIP/kphone2-df30
   -- Attempting native bridge of SIP/kphone2-df30 and SIP/gs2-36df
   -- Attempting native bridge of SIP/kphone2-df30 and SIP/gs2-36df
   -- Started music on hold, class 'default', on SIP/kphone2-df30
Sep 23 16:10:45 WARNING[1327126]: res_features.c:572 ast_bridge_call: Extension DoesNot Exist: Ø%@[ÆOCdÄOCß@ÄOC
   -- Stopped music on hold on SIP/kphone2-df30
   -- Playing 'errbeep' (language 'it')
   -- Attempting native bridge of SIP/kphone2-df30 and SIP/gs2-36df
 == Spawn extension (macro-intcall2, s, 32) exited non-zero on

* Transfers to non existant or busy number causes the loose of the call. (only if called party ends the call without congestion or another signal the call with call party is replaced so transferer shoud have the opportunity of re-take back the transfer

* Correctly if A phone B and B wants to transfer C if B transfers call to C and before C answers B drops the call, call will be blind transfered to C

edited on: 09-23-04 09:15

By: nicolasg (nicolasg) 2004-09-23 09:34:47

I tried the latest diff with yesterday's CVS using only sip phones (mixing sipuras and grandstream). It worked once... two other times it crashed the computer so bad that the only way to recover was to powerdown the machine. I'm running asterisk under Yellow Dog Linux for PPC. Unfortunately I could not grab debug output... I will try again when I have time and report back. The dial statement is inside a Macro, I wil try also without using macros.

By: head (head) 2004-09-24 03:12:31

great thing. that makes attended transfers possible with only-one-channel-phones like zyxel 2000w.

but now i have a new feature request.

instead of using '*' as hangup, could '*' be used as key to toggle between the active and holded channel? that would be nice for short requests...

By: barton (barton) 2004-09-27 16:38:53

What's the easiest way to get this patch to default to double-hash transfers (like the 0002010 patch provides) instead of adding K(##:*) to every Dial() in my dialplan?

By: Brian West (bkw918) 2004-09-27 20:23:06

Here ya go.. see if this works

By: egnarf (egnarf) 2004-09-28 06:30:22

There seems to be a problem when transferring to an extension that returns Busy.
The original call hears MOH, and I (that did the transfer) get only silence.
I need to hang up, and then to pick up the phone again to get the caller back.

Easiest way to reproduce:
 exten => <num>,1,Busy
to your dialplan, and then transfer a call to <num>.
If I issue an Answer first, I hear the Busy-tone but I still have to hang up and pick up again to get the caller back.

By: linuxa (linuxa) 2004-10-01 09:53:39

Just patched my own system and it works like a charm. That should get one user off my back.

Many thanks.

By: linuxa (linuxa) 2004-10-01 10:39:21

Whoops, spoke too soon. The busy problem struck.

By: Anthony Minessale (anthm) 2004-10-04 12:06:19

1 way to fix.. dont do Busy, do Hangup

another way is get the latest CVS and apply atxfer_post10.diff
this one should allow you to hit * (or whatever your hangup str is)
to end the busy call

By: ericbart (ericbart) 2004-10-06 03:34:49

It really seems the good way for advanced transfers.

Instead of using the x flags, could it be possible to stick to the t flags and add an agi callback to the transferer ?

The idea is to create a local variable with the name of the agi callback before issuing the normal Dial command (t flag). Then asterisk should perform normally, but, instead of hanging up the transferer, it will send the transferer to the agi, eventually with parameters such as ${transferee},  ${called party} ...

Then you can use this agi to put the transferee on hold, connect the transfer to the called party, wait for a key (1 for hang me up, 2 to for hang him up, 3 for 3-way call).

By: Anthony Minessale (anthm) 2004-10-06 10:17:26

Go read the code to ast_channel_bridge in channel.c then
come back and see if you still think that's possible. =)

By: ericbart (ericbart) 2004-10-06 13:11:09

> Go read the code to ast_channel_bridge in channel.c  ...

The main thing is that we don't want the 'transferer' to hang up, I'll be happy if  I can send it into the dialplan or to an application. I'll see if it's possible. Can you give me some indications now on why it can't be done ?  Thanks.

By: Anthony Minessale (anthm) 2004-10-06 14:05:56


That req is out of scope of what this bug is for
if you uare interested in a solution contact me privately
and you can hire me to make a patch for you.

By: Anthony Minessale (anthm) 2004-10-07 21:27:04

atxfer_post10.diff (20,547 bytes) 10-07-04 21:25
that one goes with cvs head.

By: jamieg (jamieg) 2004-10-07 21:31:26

I would like to say that it is probably best to release diffs for head and V1.0.1
Head is very unstable currently as since 1.0 was released major changes are afoot and I am keeping away from head for now..

I would also like to know the status on the creater of this feature.  I thinkn its great, but how about fixing the bug as listed above..  Then see if it can be presented for inclusion into the head..


By: Mark Spencer (markster) 2004-10-08 00:06:32

This patch is not ready for CVS yet, and I'm still not really convinced on the implementation either.  I'd like to discuss further ways to be able to insert various feature codes into the dial command (so other features like mute, etc could be added).

Imagine we have a series of feature codes, all configurable.  Now, when someone presses a key, i can look and see if it's part of a valid feature code.  That's all no problem *except* I need a way to timeout the bridge (sort of an alternative timeout) so that if they don't enter anything more, I can pass the digits back on through.

I do *not* want a solution that just places the other side on hold when someone presses a digit, and waits for another digit.

By: Anthony Minessale (anthm) 2004-10-08 09:20:09

I think you have this confused with another patch.
I made this one from scratch after seeing your dislike for the other one.

I do not 'wait' for more digits when you press a digit at all.

If you look at the code I did make "features" by adding elements
to struct bridge_config to mark what string of keystrokes represent hangup
and transfer during the bridge.  As you type dtmf it saves the last X
digits you typed into a string (like multi digit cable tv remote for instance)
whichever is the biggest string to scan between transfer and hangup dictates X
(the size of the buffer) say hangup string is 011 and transfer is 5676
then X is 4 so it saves the 4 most recent digit you enter. all of these
dtmf characters are passed instantly and it will only react if you match
the paticular string exactly. If one chooses, they can use the 'd' dial flag
to set the mutedtmf on the call which blocks dtmf from going across the bridge.
but it will still be parsed in case you want a 10 digit transfer code and don't want the other side to hear it.

In all seriousness, I think the entire process of how channels behave should
be redesigned.  This patch solves the issue at hand the best way I can come up with without yanking the entire app_dial and bridge logic from the code and
redesigning it.

By: cmslaght (cmslaght) 2004-10-17 20:10:52

I understand the delima her but at least for me, the immediate need is for my office to be able to hit the '#' key and actually have the key transmitted.  Several of the IVR's that we call need the '#' key to end series of digits.

By: jamieg (jamieg) 2004-10-17 21:51:31

cmslaght : I agree completely and actually find it quite amazing this is not considered a BUG, or a HIGH priority issue feature required..

It may not be effecting many Asterisk Developers, but is definatly effecting the people who are actually using it in a REAL business...


By: cypromis (cypromis) 2004-10-17 22:05:37

Why don't you look a bit better at the patch ? the transfer key is configurable, you could make it for example ### as I have it set

By: cmslaght (cmslaght) 2004-10-18 07:13:53

It's configurable if you use this patch which is fine but its getting this into CVS that is important.

By: bmerrills (bmerrills) 2004-10-18 07:44:48

Does this work with app_queue? I know app_queue takes 't' and 'T', but does it just pass any variables onto the dial command, or do something with them that needs to be added for 'x/X' to work? (not big on c, code hard to read ;)

By: ericbart (ericbart) 2004-10-18 10:00:37

How about sending the transfer command into the dialplan ? This will add flexibility.

Suppose we have new predefined extensions: 'X' and/or 'x'.

Asterisk could send the call in these extensions during the transfer and let the dialplan finish the job. See in the scenario below. I don't know whether the 'X' is feasible but I have quite the 'x' working.

Just before dialing the transferto party, Asterisk will check that the 'X' extension exists. If it exists, Asterisk will let the dialplan make the transfer. Two new channel variables will hold the other party channels ${TRANSFERER} and ${TRANSFERTO} and Asterisk will send the transferee channel to the 'X' extension. It will be up to the dialplan to actually make the transfer.

Otherwise, Asterisk will make the transfer as usual. In the end, just before hanging up the transferer, it will check whether the 'x' extension exists.

If the 'x' extension exists, the transferer won't be hung up. It will be sent
to this extension with ${TRANSFEREE} and ${TRANSFERTO}. From there, another app
may further process or check the transfer.

I've made an app that could connect to the 'x' extension. It allows the transferer to switch back and forth from the transferee to the transferto and even to a conference. Once one party hung up, the two others are linked in a normal call. It's an agi.

By: barton (barton) 2004-10-19 19:13:28

I can't seem to make this work with the 10/19 CVS.  I applied atxfer_post10.diff and copied app_dtget.c into /apps.  Everything compiles fine, but I can't get it to use ## as the xferstr and the K() doesn't work.  Is it currently broken?  The  0002010 patch was perfect for people who just want to use a # in IVR and be done with it, IMHO.

By: cypromis (cypromis) 2004-10-21 05:31:26

Seems to not work anymore with latest CVS HEAD

By: Anthony Minessale (anthm) 2004-10-21 08:59:44

I tried....
I can only keep my patches working for so long before they
are bowled over.  It's not the first time...

By: ericbart (ericbart) 2004-10-21 09:57:07

I'm working on it ... still the idea of the predefined extension. I have the X quite done and the agi quite fine and working. If 'X' exists in the dialplan it sends the transferer to it with the transferee chan name and newext as local variables.

This asterisk patch is a single insertion in res_features.c:ast_bridge_call(). Easy to maintain if not in CVS. I did not work on the configurable transfer key.

Anyone want to check my work and hopefully add the configurable transfer key in the res_features.c patch ?

By: Martin Vit (festr) 2004-11-09 09:26:52.000-0600

i have this problem:

when do transfer by hitting #, it dial OH323/number, but when - OH323/number is ringing, i dont hear ring tone.

By: Brian West (bkw918) 2004-11-09 09:34:03.000-0600

thats an oh323 bug not a bug in this patch.


By: ericbart (ericbart) 2004-11-20 14:43:11.000-0600

here's another option for advanced transfers: bug ASTERISK-2863

By: Bayan Towfiq (implicit) 2004-11-26 04:48:39.000-0600

Posted atxfer_latest2.diff to patch fine on cvs head.

By: ivoice (ivoice) 2004-11-28 17:31:23.000-0600

There are some problems in CDR using attended transfer.


1) A call B
2) B transfer call to C

in CDR I have 2 lines:

- in the first one (A call B) source (src) and CallerID (clid) are missing [ERROR], destination is B [OK];
- in the second one (B transfer to C) source and CallerdID are A [I don't known if it is an error... the call is really from A to C (transfered) but the caller was B] and dst is C [OK]

By: Anthony Minessale (anthm) 2004-12-08 16:48:11.000-0600


By: gryn (gryn) 2004-12-09 12:48:40.000-0600

Hopefully I did that right, I just attached some fixes to the res.c file.  It doesn't look like you changed anything between atxfer_latest2.diff (which is what I was using) and atxfer_1204.diff (at least not in res.c).  The patch is actually against the cvs head of 12-07-04, since I don't know how to ask for a patch between two patchs :) .

The changes are:
Fixed collect to collect in the proper order.  If you typed "9##" and "## was what you were looking for, the code would only be comparing "9", "9#" and "#", but never have "##" in collect.  Also fixed collect to work with different sized strings, since you compare against a hangup string and a transfer string.  Of course that needed fixing only because I changed the way collect worked.

The other thing I changed was that the last if, which was for blind transfers, only looked for the hardcoded string "#" instead of xferstr.

I put comments with "- Gryn" in them so you can find my changes easily enough.

By: Anthony Minessale (anthm) 2004-12-09 17:47:38.000-0600

Thanks for the suggestion Gryn, but I had a discussion with mark and
came up with the best way to deal with this:

as you dial, the data is stored in the collect string as long as the collected digits are in line with something we are looking for the dtmf is suppresed if you go off track then the collected dtmf is delivered.

say custom hangup is 123 xfer is 555

if you dial 1,2 the other party hears nothing
if you then dial 4 , the dtmf 124 is sent to the other party

if you dial 1,2 the other party hears nothing
if you then dial 5 , the dtmf 12 is sent to the other party
then the new string 5 is saved if you dial 2 more 5 the transfer is

Esentially as long as you are dialing something that *MAY* be a match you have the dtmf is supressed and as soon as it's impossible to be a match it delivers it.

By: gryn (gryn) 2004-12-09 22:05:16.000-0600

That's sounds ideal.  You still need to use xferstr on the last 'if' (the one for blind transfers), instead of just using the old hardcode of '#'.

By: Anthony Minessale (anthm) 2004-12-09 22:09:03.000-0600

Gryn, yep it's in there! now lets see if markster is happy with it!
lets all chant:   patch ... patch ... patch =D

By: mmenaz (mmenaz) 2004-12-10 16:39:09.000-0600

I've installed 11-26-04 patch, but this has some functionality lacks that must be addressed to be useful in a office. Please correct me if it's just me not been able to make it work or if has been fixed in the more recent versions:
A calls B that transfers to C
Features needed:
1) if C is busy or unavailable, A stops hear MOH and B can't bring the conversation back... it's lost!
2) in any case, if C does not answer, B must be able to return to A even before C timeouts (that will put B in the 1) condition)
3) after #C-ext-num, B does not hear the C phone ringing
4) B should be able to perform a "blind transfer" just hanging up after dialing #C-ext-num, but if C is busy or timeouts, the line should stay up and B being called back, if still available

edited on: 12-10-04 16:40

By: Anthony Minessale (anthm) 2004-12-10 20:37:09.000-0600

Why 11-26 patch ??
this patch is only being developed for current CVS please
disregard any patch besides most recent the rest are just there for reference.

By: mmenaz (mmenaz) 2004-12-12 09:25:34.000-0600

Of course patch 11-26-04 because was the most up-to-date for the CVS head asterisk I was using. Now I've updated asterisk and installed patch "atxfer_1204.rev2.diff" but all the problems / lacks of functionality I've reported are still there... If I'm wrong, tell me the key to press to have it work properly, please. If I'm right, I was also with the 11-26-04, so I don't understand your reply :)
Thanks a lot

By: Anthony Minessale (anthm) 2004-12-12 10:58:27.000-0600

mmenaz, please stop using the patch if it makes you so unhappy,
I have a dozen people thank me for making this patch then I have you
demanding extra functionality that , by the way, would require quite a bit
of work.  This is not a restaurant nor a public service, this is me sharing my code for people to take it or leave it.  If you would like to hire me to solve your problems then that is another story.  Most people I talk to would rather have something than nothing.  And please don't start some petty flame war on this resource with some sobstory reply claiming "oh fine, I thought this was a community", try submitting a patch to address your concerns like other people have done, thanks Gryn!

By: Anthony Minessale (anthm) 2004-12-12 16:59:47.000-0600

dont forget you MUST install errbeep.gsm too

By: Anthony Minessale (anthm) 2004-12-13 10:30:26.000-0600

newest version handles timeouts on digits *NOTE* if you do not have errbeep.gsm installed (it can be any sound you want) the call will be lost if you try and attended transfer it to an invalid extension.


    /* multi-digit significant DTMF codes hangup=123 transfer=789 etc.

       What we want here is for the caller to be able to dial 123 to hangup the call *BUT* we don't want the
       callee to hear the dtmf *BUT* if he dials 124 which is no longer correct we must deliver the 124 to
       the callee at that time *OR* if he dials 12 and waits too long we must also deliver the past due digits.
       *OR* if he dials 127 we send the 12 and keep the 7 for a bit in case he is going to enter 789.

       This is a but of a pain because this function calls ast_channel_bridge in channel.c
       who in turn may call a native bridge function so we are not able to execute regularly in order to keep track
       so we must have a seperate input buffer and timer for each leg of the call.  When dtmf that is potentially
       part of one of the desired codes is collected we must set the timer on our leg so ast_channel_bridge will be nice
       enough to send the call back this way and we can act on the results we must also configure the call to make
       native bridges impossible as the timer would not work since native bridges never return unless there is a dtmf or
       hangup event. ... *deep breath*

edited on: 12-13-04 10:31

By: Mark Spencer (markster) 2005-01-04 14:30:15.000-0600

Moving to newly placed updated bug.