[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