rtcp.c 1.9 KB

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