[asterisk-dev] semantics of send_digit_begin and AST_FLAG_END_DTMF_ONLY

Russell Bryant russell at digium.com
Fri Jan 19 13:15:22 MST 2007


Luigi Rizzo wrote:
> probably Russel has some ideas on this...
> 
> I am a bit confused on the logic for handling AST_FRAME_DTMF_BEGIN
> and AST_FRAME_DTMF_END event/frames.
> 
> Basically, i understand that some channels two events per
> digit, and some only want one, and for the latter, we
> [somewhat arbitrarily i think] call it AST_FRAME_DTMF_END.

Well, there is some history behind the reasoning that this is the case. 
  Previously, Asterisk treated DTMF as a single event, and the frame 
type was AST_FRAME_DTMF.  However, there were some problems with this, 
so we had to start moving toward treating a digit as two events, a 
beginning and end.

To make this transition easiest, AST_FRAME_DTMF and AST_FRAME_DTMF_END 
are actually the exact same thing.  When the core receives an END 
without receiving a BEGIN earlier for whatever reason, it turns it into 
a BEGIN and later sends an END.

> Wouldn't it be simpler to just send a 'begin' event in
> all cases ? It seems that the whole processing would be
> simpler, because on the outgoing side, we don't have
> any conditional behaviour on the generation of
> the first event, and for the latter we could just
> not transmit it, or drop it if one comes in and
> we have no meaning for it ?

I wish that it actually was the case that when you read a digit from a 
channel, that the channel driver would always send a BEGIN and END for 
the digit.  However, it's not.  In some cases, it's for technical 
reasons, and for some it's backwards compatibility.

For example, if you connect to an Asterisk 1.2 system using IAX2, when 
the 1.2 system sends DTMF, it will send just a single AST_FRAME_DTMF 
frame over IAX2.  Another example is SIP INFO dtmf.  The INFO message is 
just a single event.

One way to solve this would be to make all of the channel drivers figure 
out a way to turn single DTMF events into a BEGIN and END.  However, it 
made more sense to me to implement this in the core, so it only had to 
be dealt with in one place.

To solve this situation, ast_read() performs some magic.  It turns an 
END into a BEGIN, and after a certain amount of audio has passed 
through, it sends an END frame.  Now, with the latest changes, this only 
done if we determine that the other channel cares to receive BEGIN 
frames in the first place.  The only case of this we have right now is a 
SIP channel using INFO dtmf.  The reason it has to be this way is 
because if you have two SIP channels with audio not flowing through 
Asterisk, there is no audio to time off of to figure out when to send 
the END.  There are other ways we could go about scheduling the end of 
the digit, but it's all extra unneeded processing if the other side 
doesn't care anyway.

The way the core decides if a channel wants begin frames is if the 
technology has a send_digit_begin callback.  I agree that this seems a 
bit of a hack, but I haven't really thought of a better way.  Another 
option would be to just introduce another flag on the channel structure 
itself that would be set by the channel driver when the channel gets 
created.

--
Russell Bryant
Software Engineer
Digium, Inc.


More information about the asterisk-dev mailing list