1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
#include <u.h>
#include <libc.h>
#include <ip.h>
#include "dat.h"
#include "protos.h"
typedef struct Hdr Hdr;
struct Hdr {
uchar hdr; // RTCP header
uchar pt; // Packet type
uchar len[2]; // Report length
uchar ssrc[4]; // Synchronization source identifier
uchar ntp[8]; // NTP time stamp
uchar rtp[4]; // RTP time stamp
uchar pktc[4]; // Sender's packet count
uchar octc[4]; // Sender's octect count
};
typedef struct Report Report;
struct Report {
uchar ssrc[4]; // SSRC identifier
uchar lost[4]; // Fraction + cumu lost
uchar seqhi[4]; // Highest seq number received
uchar jitter[4]; // Interarrival jitter
uchar lsr[4]; // Last SR
uchar dlsr[4]; // Delay since last SR
};
enum{
RTCPLEN = 28, // Minimum size of an RTCP header
REPORTLEN = 24,
};
static void
p_compile(Filter *f)
{
sysfatal("unknown rtcp field: %s", f->s);
}
static int
p_filter(Filter *f, Msg *m)
{
USED(f);
USED(m);
return 0;
}
static int
p_seprint(Msg *m)
{
Hdr*h;
Report*r;
int rc, i, frac;
float dlsr;
if(m->pe - m->ps < RTCPLEN)
return -1;
h = (Hdr*)m->ps;
if(m->pe - m->ps < (NetS(h->len) + 1) * 4)
return -1;
rc = h->hdr & 0x1f;
m->ps += RTCPLEN;
m->p = seprint(m->p, m->e, "version=%d rc=%d tp=%d ssrc=%8ux ntp=%d.%.10ud rtp=%d pktc=%d octc=%d hlen=%d",
(h->hdr >> 6) & 3, rc, h->pt, NetL(h->ssrc),
NetL(h->ntp), (uint)NetL(&h->ntp[4]), NetL(h->rtp),
NetL(h->pktc), NetL(h->octc),
(NetS(h->len) + 1) * 4);
for(i = 0; i < rc; i++){
r = (Report*)m->ps;
m->ps += REPORTLEN;
frac = (int)(((float)r->lost[0] * 100.) / 256.);
r->lost[0] = 0;
dlsr = (float)NetL(r->dlsr) / 65536.;
m->p = seprint(m->p, m->e, "\n\trr(csrc=%8ux frac=%3d%% cumu=%10d seqhi=%10ud jitter=%10d lsr=%8ux dlsr=%f)",
NetL(r->ssrc), frac, NetL(r->lost), NetL(r->seqhi),
NetL(r->jitter), NetL(r->lsr),
dlsr);
}
m->pr = nil;
return 0;
}
Proto rtcp = {
"rtcp",
p_compile,
p_filter,
p_seprint,
nil,
nil,
defaultframer,
};
|