[asterisk-dev] Problems with RTCP
John Todd
jtodd at digium.com
Thu Nov 6 11:44:29 CST 2008
On Nov 6, 2008, at 7:31 AM, Johansson Olle E wrote:
> 6 nov 2008 kl. 16.15 skrev Atis Lezdins:
>
>> I wonder would it be possible to append RTCP responses to CDR, as
>> Dial
>> is producing separate CDRs for each channel involved. So each channel
>> could have their own RTCP stats.
>
> That was my original proposal, alongside with the channel variables.
> Only channel
> variables got a response. Well, much have happened since then and we
> now have
> many CDR drivers with CDR variable support, so we could easily pop it
> into
> a new field, like RTPQOS-audio-in, RTPQOS-audio-out. The problem as
> always is
> that so much can happen during the call, the out-channel can become an
> in-channel.
> Someone that knows more about CDRs propably needs to figure out how to
> handle that.
>
> Anyway, I like putting them in CDRs. Or in a separate table. We could
> propably use
> realtime for that, so if you've enabled realtime with connection name
> "RTPREPORTS"
> we would save SIP call ID and the RTP stats for audio and video in the
> database.
> That might be easier to accomplish, then you have to store the SIP
> call ID in the
> CDR fields in the dialplan and you can match later on.
>
> Just brainstorming - any other ideas out there?
> /O
While I think it seems natural to add them to the CDR events, I don't
think it is the appropriate place because of the problems you mention
- RTP paths aren't static. It is possible to have a call with two or
three media streams. If there was a single CQDR record, how would it
be computed? Do we add all these up? Ugh. Many calls also have
multiple destination IP addresses involved for the RTP streams - how
do we say what this quality information references as far as an
endpoint?
Keeping these records straight is also somewhat difficult, as there
often are two legs associated with a call (inbound to *, and then
Dial() outbound) but that is left as an exercise to the implementer to
ensure that they capture the correct data for the correct leg. It
seems that it would be much easier if $CHANNEL could take a channel
name as an additional qualifier instead of just using the current
channel.
i.e.: ${CHANNEL(${THE-OTHER-CHANNEL-
ID},rtpqos,audio,remote_lostpackets)})
Plus, there's a lot of data in QOS statistics. Do we want that
cluttering the CDR tables? I don't believe so. Below is a quick
dialplan that shows all the things that might be relevant in a CDR
record - it's quite a pile. Plus, in my various tests, many (but not
all) of these values remained steadfastly at "0" or are wildly
incorrect despite RTCP-capable endpoints, so I am concerned that the
current code doesn't do quite what it should (though it is of course
possible that my RTCP endponts (Cisco, Eyebeam) are also wrong.)
My idea: It seems that there needs to be a table specifically for
keeping data involving RTP streams, and due to the monolithic nature
of Dial() it may even be easier just to keep those records directly
from the RTP code instead of trying to bubble it up to the dialplan.
Each new RTP stream would create a new CQDR record, regardless of what
the user experience or dialplan path was. If you could set a key
value in the dialplan (something like "CQDRKEY" or something like
that) which would then allow post-call correlation, or you could just
use the channel name as the key.
It could use the same methods that we have right now for CDR storage -
ODBC, CSV, whatever. Just re-use all that code but with a different
config file. We're now on year 4 of this discussion - who
volunteers? :-)
Anyway, here's my ugly dialplan that can show you how unusual the RTCP
data (or regular RTP data) can get. Try it with your client and see
what happens. I also enclose a sample output from a connection
between SVN-TRUNK as of this morning with Eyebeam for Mac 1.5.18.2
release 1100v build 47069.
exten => 999,1,Answer()
exten => 999,n,Playback(tt-monkeys)
exten => 999,n,Log(DEBUG,local_ssrc: $
{CHANNEL(rtpqos,audio,local_ssrc)})
exten => 999,n,Log(DEBUG,local_lostpackets: $
{CHANNEL(rtpqos,audio,local_lostpackets)})
exten => 999,n,Log(DEBUG,local_jitter: $
{CHANNEL(rtpqos,audio,local_jitter)})
exten => 999,n,Log(DEBUG,local_maxjitter: $
{CHANNEL(rtpqos,audio,local_maxjitter)})
exten => 999,n,Log(DEBUG,local_minjitter: $
{CHANNEL(rtpqos,audio,local_minjitter)})
exten => 999,n,Log(DEBUG,local_normdevjitter: $
{CHANNEL(rtpqos,audio,local_normdevjitter)})
exten => 999,n,Log(DEBUG,local_stdevjitter: $
{CHANNEL(rtpqos,audio,local_stdevjitter)})
exten => 999,n,Log(DEBUG,local_count: $
{CHANNEL(rtpqos,audio,local_count)})
exten => 999,n,Log(DEBUG,remote_ssrc: $
{CHANNEL(rtpqos,audio,remote_ssrc)})
exten => 999,n,Log(DEBUG,remote_lostpackets: $
{CHANNEL(rtpqos,audio,remote_lostpackets)})
exten => 999,n,Log(DEBUG,remote_jitter: $
{CHANNEL(rtpqos,audio,remote_jitter)})
exten => 999,n,Log(DEBUG,remote_maxjitter: $
{CHANNEL(rtpqos,audio,remote_maxjitter)})
exten => 999,n,Log(DEBUG,remote_minjitter: $
{CHANNEL(rtpqos,audio,remote_minjitter)})
exten => 999,n,Log(DEBUG,remote_normdevjitter: $
{CHANNEL(rtpqos,audio,remote_normdevjitter)})
exten => 999,n,Log(DEBUG,remote_stdevjitte: $
{CHANNEL(rtpqos,audio,remote_stdevjitter)})
exten => 999,n,Log(DEBUG,remote_count: $
{CHANNEL(rtpqos,audio,remote_count)})
exten => 999,n,Log(DEBUG,maxrtt: $
{CHANNEL(rtpqos,audio,maxrtt)})
exten => 999,n,Log(DEBUG,minrtt: $
{CHANNEL(rtpqos,audio,minrtt)})
exten => 999,n,Log(DEBUG,normdevrtt: $
{CHANNEL(rtpqos,audio,normdevrtt)})
exten => 999,n,Log(DEBUG,stdevrtt: $
{CHANNEL(rtpqos,audio,stdevrtt)})
exten => 999,n,Log(DEBUG,rtpdest: $
{CHANNEL(rtpdest,audio)})
exten => 999,n,Hangup
Sample output:
-- Executing [999 at default-context:3] Log("SIP/2204-8063d014",
"DEBUG,local_ssrc: 499616254") in new stack
-- Executing [999 at default-context:4] Log("SIP/2204-8063d014",
"DEBUG,local_lostpackets: 0") in new stack
-- Executing [999 at default-context:5] Log("SIP/2204-8063d014",
"DEBUG,local_jitter: 5") in new stack
-- Executing [999 at default-context:6] Log("SIP/2204-8063d014",
"DEBUG,local_maxjitter: 6") in new stack
-- Executing [999 at default-context:7] Log("SIP/2204-8063d014",
"DEBUG,local_minjitter: 0") in new stack
-- Executing [999 at default-context:8] Log("SIP/2204-8063d014",
"DEBUG,local_normdevjitter: 5") in new stack
-- Executing [999 at default-context:9] Log("SIP/2204-8063d014",
"DEBUG,local_stdevjitter: Inf") in new stack
-- Executing [999 at default-context:10] Log("SIP/2204-8063d014",
"DEBUG,local_count: 807") in new stack
-- Executing [999 at default-context:11] Log("SIP/2204-8063d014",
"DEBUG,remote_ssrc: 3944626440") in new stack
-- Executing [999 at default-context:12] Log("SIP/2204-8063d014",
"DEBUG,remote_lostpackets: 0") in new stack
-- Executing [999 at default-context:13] Log("SIP/2204-8063d014",
"DEBUG,remote_jitter: 0") in new stack
-- Executing [999 at default-context:14] Log("SIP/2204-8063d014",
"DEBUG,remote_maxjitter: 1177961526000") in new stack
-- Executing [999 at default-context:15] Log("SIP/2204-8063d014",
"DEBUG,remote_minjitter: 0") in new stack
-- Executing [999 at default-context:16] Log("SIP/2204-8063d014",
"DEBUG,remote_normdevjitter: 235592311400") in new stack
-- Executing [999 at default-context:17] Log("SIP/2204-8063d014",
"DEBUG,remote_stdevjitte: 7509313529832") in new stack
-- Executing [999 at default-context:18] Log("SIP/2204-8063d014",
"DEBUG,remote_count: 808") in new stack
-- Executing [999 at default-context:19] Log("SIP/2204-8063d014",
"DEBUG,maxrtt: 15636177") in new stack
-- Executing [999 at default-context:20] Log("SIP/2204-8063d014",
"DEBUG,minrtt: 0") in new stack
-- Executing [999 at default-context:21] Log("SIP/2204-8063d014",
"DEBUG,normdevrtt: 3909044") in new stack
-- Executing [999 at default-context:22] Log("SIP/2204-8063d014",
"DEBUG,stdevrtt: 49826473") in new stack
-- Executing [999 at default-context:23] Log("SIP/2204-8063d014",
"DEBUG,rtpdest: 10.10.3.9:26334") in new stack
-- Executing [999 at default-context:24] Hangup("SIP/2204-8063d014",
"") in new stack
JT
---
John Todd
jtodd at digium.com +1-256-428-6083
Asterisk Open Source Community Director
More information about the asterisk-dev
mailing list