Blob


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