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