Search code examples
asterisktransferphone-calldtmfuclinux

Asterisk ignores DTMF during all calls - cannot use keypress features


Asterisk 1.4.21.2 under uClinux on an ATCOM IP01. (EDIT: as an aside, I don't think it's possible to upgrade Asterisk to a newer version thatn 1.4 on uClinux, but if anyone knows a way, I'd be interested to know. But I don't think the issue is version-specific.)

The featuremap in features.conf is as follows, but pressing keys during a call has no effect.

[featuremap]
blindxfer => *#         ; Blind transfer  (default is #)
disconnect => ***0              ; Disconnect  (default is *)
;automon => *1                  ; One Touch Record a.k.a. Touch Monitor
atxfer => *0                    ; Attended transfer
;parkcall => #72                ; Park call (one step parking)

The CLI shows that the configured featuremap has taken effect:

IP0x*CLI> feature show channels
No feature channels in use

IP0x*CLI> feature show
Builtin Feature           Default Current
---------------           ------- -------
Pickup                    *8      *8
Blind Transfer            #       *#
Attended Transfer                 *0
One Touch Monitor
Disconnect Call           *       ***0
Park Call

Dynamic Feature           Default Current
---------------           ------- -------
(none)

Call parking
------------
Parking extension   :   700
Parking context     :   parkedcalls
Parked call extensions: 701-750

Various different phones in use (Grandstream BT-200, Panasonic KX-TGP500, X-Lite 4), but always same problem. All phones configured to use rfc2833, which is Asterisk's default DTMF mode; also tried explicitly setting dtmfmode=rfc2833 in sip.conf.

No keys pressed during a call ever get any response from Asterisk. The * and # keys are always recognized by Asterisk when not in a call (in the dialplan, or during voicemail).

If DTMF logging is turned on using full => verbose,debug,dtmf or full => verbose,error,warning,dtmf, no DTMF entries appear in the log despite hitting numerous keys during a call.

What could the problem be?


EDIT: additional info now follows, showing the Dial command used in the dialplan.

EDIT: I've found the issue still occurs without using that ael macro, simply by having exten=261,1,Dial(SIP/261) in extensions.conf. So I've removed the ael from the question to declutter it.

I've now tried adding canreinvite = no and relaxdtmf=yes in sip.conf, but the issue remains.

I've also now found that DTMF logging does happen during a call on a ZAP channel (as opposed to the SIP channels I tried before). But the DTMF still doesn't trigger the features. Example DTMF log follows.

[May 22 08:25:46] DTMF[474]: channel.c:2191 __ast_read: DTMF begin '*' received on SIP/251-01354004
[May 22 08:25:46] DTMF[474]: channel.c:2201 __ast_read: DTMF begin passthrough '*' on SIP/251-01354004
[May 22 08:25:46] DTMF[474]: channel.c:2116 __ast_read: DTMF end '*' received on SIP/251-01354004, duration 180 ms
[May 22 08:25:46] DTMF[474]: channel.c:2163 __ast_read: DTMF end accepted with begin '*' on SIP/251-01354004
[May 22 08:25:46] DTMF[474]: channel.c:2179 __ast_read: DTMF end passthrough '*' on SIP/251-01354004
[May 22 08:25:46] DTMF[474]: channel.c:2191 __ast_read: DTMF begin '*' received on SIP/251-01354004
[May 22 08:25:46] DTMF[474]: channel.c:2201 __ast_read: DTMF begin passthrough '*' on SIP/251-01354004
[May 22 08:25:46] DTMF[474]: channel.c:2116 __ast_read: DTMF end '*' received on SIP/251-01354004, duration 160 ms
[May 22 08:25:46] DTMF[474]: channel.c:2163 __ast_read: DTMF end accepted with begin '*' on SIP/251-01354004
[May 22 08:25:46] DTMF[474]: channel.c:2179 __ast_read: DTMF end passthrough '*' on SIP/251-01354004
[May 22 08:25:46] DTMF[474]: channel.c:2191 __ast_read: DTMF begin '*' received on SIP/251-01354004
[May 22 08:25:46] DTMF[474]: channel.c:2201 __ast_read: DTMF begin passthrough '*' on SIP/251-01354004
[May 22 08:25:47] DTMF[474]: channel.c:2116 __ast_read: DTMF end '*' received on SIP/251-01354004, duration 140 ms
[May 22 08:25:47] DTMF[474]: channel.c:2163 __ast_read: DTMF end accepted with begin '*' on SIP/251-01354004
[May 22 08:25:47] DTMF[474]: channel.c:2179 __ast_read: DTMF end passthrough '*' on SIP/251-01354004
[May 22 08:25:47] DTMF[474]: channel.c:2191 __ast_read: DTMF begin '0' received on SIP/251-01354004
[May 22 08:25:47] DTMF[474]: channel.c:2201 __ast_read: DTMF begin passthrough '0' on SIP/251-01354004
[May 22 08:25:47] DTMF[474]: channel.c:2116 __ast_read: DTMF end '0' received on SIP/251-01354004, duration 280 ms
[May 22 08:25:47] DTMF[474]: channel.c:2163 __ast_read: DTMF end accepted with begin '0' on SIP/251-01354004
[May 22 08:25:47] DTMF[474]: channel.c:2179 __ast_read: DTMF end passthrough '0' on SIP/251-01354004
IP0x*CLI>

Solution

  • Finally cracked this.

    It's true that setting canreinvite=no does prevent the SIP phones from negotiating a direct connection between themselves after Asterisk's initially established the call, so keeps Asterisk in the media path (and thus aware of any DTMF they send).

    But even so, for Asterisk to actually respond to the DTMF and invoke the configured transfer features, you must explicitly enable transfers, on a per-call basis, by passing the T and/or t options as Dial command parameters.

    Newer versions of features.conf draw attention to this:

    ;atxfer => *2                   ; Attended transfer  -- Make sure to set the T and/or t option in the Dial() or Queue()  app call!
    

    So the fix was, I had to change my AEL code to add the T and/or t parameters wherever the code uses the Dial command.

    The only remaining puzzle I was then left with was how to abort an attended transfer; for example if there was no reply, making it tedious to wait for the timeout, or the transfer had started to go to voicemail, potentially making it desirable to return to the other party instead. By experimentation, I eventually found that the feature for using a keypress to disconnect a call also works to abort a transfer:

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

    Newer versions of features.conf contain an expanded comment, though not one related to transfers:

    ;disconnect => *0               ; Disconnect  (default is *) -- Make sure to set the H and/or h option in the Dial() or Queue() app call!
    

    What I discovered is that even without passing the H and/or h parameters to the Dial command, the disconnect feature can be used to abort an attended transfer. And there's no conflict between this and passing the H and/or h options to the Dial command: if you want to do this and use the feature for any kind of disconnect, it remains effective for aborting transfers without disconnecting the whole call (although using something other than the default of * may then become necessary, since any sequences starting * will now instead cut off the call!).

    The Dial command in my AEL code for outgoing calls on Zap/1 is now:

    Dial(Zap/1/${number},,T);
    

    And all transfer functionality is now working fine.