Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
headers.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022 Roc Streaming authors
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  */
8 
9 //! @file roc_rtcp/headers.h
10 //! @brief RTCP headers.
11 
12 #ifndef ROC_RTCP_HEADERS_H_
13 #define ROC_RTCP_HEADERS_H_
14 
15 #include "roc_core/attributes.h"
16 #include "roc_core/endian.h"
17 #include "roc_core/panic.h"
18 #include "roc_core/stddefs.h"
19 #include "roc_packet/ntp.h"
20 #include "roc_packet/units.h"
21 
22 namespace roc {
23 namespace rtcp {
24 namespace header {
25 
26 //! Set some bits in v0.
27 //!
28 //! @param v0 Where to write the bits.
29 //! @param v1 The bits to write.
30 //! @param shift From which bit num the field start.
31 //! @param mask The bitmask.
32 template <typename T>
33 void set_bitfield(T& v0, const T v1, const size_t shift, const size_t mask) {
34  v0 &= T(~(mask << shift));
35  v0 |= T(v1 << shift);
36 }
37 
38 //! Computes the value of RTCP packet header length field from input number.
39 inline uint16_t size_t_2_rtcp_length(const size_t x) {
40  roc_panic_if(x < 4);
41  roc_panic_if(x > uint16_t(-1));
42  return (uint16_t)x / 4 - 1;
43 }
44 
45 //! Converts RTCP header length field into conventional size_t value.
46 inline size_t rtcp_length_2_size_t(const size_t x) {
47  return (x + 1) * 4;
48 }
49 
50 //! How much padding bytes do we need in order to align with 32-bits.
51 //!
52 //! @param size defines data length in bytes.
53 //! @param min_padding defines minimum number of padding bytes required.
54 //! @return How much should be added to x.
55 inline size_t padding_len(const size_t size, const size_t min_padding) {
56  const size_t size_to_pad = size + min_padding;
57  return min_padding + (size_to_pad & 0x03 ? 4 - (size_to_pad & 0x03) : 0);
58 }
59 
60 //! Get a block that follows header, by index.
61 template <class Blk, class Pkt>
62 Blk& get_block_by_index(Pkt* pkt,
63  size_t block_index,
64  size_t num_blocks,
65  const char* pkt_type) {
66  if (block_index >= num_blocks) {
67  roc_panic("%s: out of bounds: index=%lu size=%lu", pkt_type,
68  (unsigned long)block_index, (unsigned long)num_blocks);
69  }
70  return ((Blk*)(const_cast<char*>((const char*)pkt) + sizeof(*pkt)))[block_index];
71 }
72 
73 //! RTP protocol version.
74 enum Version {
75  V2 = 2 //!< RTP version 2.
76 };
77 
78 //! RTCP packet type.
79 enum PacketType {
80  RTCP_SR = 200, //!< Sender report packet.
81  RTCP_RR = 201, //!< Receiver report packet.
82  RTCP_SDES = 202, //!< Source Description packet.
83  RTCP_BYE = 203, //!< BYE packet.
84  RTCP_APP = 204, //!< APP-specific packet.
85  RTCP_XR = 207 //!< Extended report packet.
86 };
87 
88 //! Maximum number of inner blocks/chunks in RTCP packet.
89 static const size_t PacketMaxBlocks = 31;
90 
91 //! Helper to store 64-bit ntp timestamp in a common way among RTCP.
92 //!
93 //! @code
94 //! 0 1 2 3
95 //! 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
96 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
97 //! | NTP timestamp, most significant word |
98 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
99 //! | NTP timestamp, least significant word |
100 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
101 //! @endcode
103 private:
104  enum {
105  NTP_HIGH_shift = 32,
106  NTP_HIGH_mask = 0xFFFFFFFF00000000,
107 
108  NTP_LOW_shift = 0,
109  NTP_LOW_mask = 0x00000000FFFFFFFF
110  };
111 
112  uint32_t high_ntp_;
113  uint32_t low_ntp_;
114 
115 public:
116  NtpTimestamp() {
117  reset();
118  }
119 
120  //! Reset to initial state (all zeros).
121  void reset() {
122  high_ntp_ = 0;
123  low_ntp_ = 0;
124  }
125 
126  //! Get NTP timestamp value.
128  uint64_t tmp =
129  (((uint64_t)core::ntoh32u(high_ntp_) << NTP_HIGH_shift) & NTP_HIGH_mask)
130  | (((uint64_t)core::ntoh32u(low_ntp_) << NTP_LOW_shift) & NTP_LOW_mask);
131  return (packet::ntp_timestamp_t)tmp;
132  }
133 
134  //! Set NTP timestamp value.
136  high_ntp_ = core::hton32u(uint32_t((t >> NTP_HIGH_shift) & NTP_LOW_mask));
137  low_ntp_ = core::hton32u(uint32_t((t >> NTP_LOW_shift) & NTP_LOW_mask));
138  }
140 
141 //! RTCP packet header, common for all RTCP packet types.
142 //!
143 //! @code
144 //! 0 1 2 3
145 //! 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
146 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
147 //! |V=2|P| RC | PT=SR=200 | length |
148 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
149 //! @endcode
151 private:
152  enum {
153  //! @name RTCP protocol version.
154  // @{
155  Flag_VersionShift = 6,
156  Flag_VersionMask = 0x03,
157  // @}
158 
159  //! @name RTCP padding flag.
160  // @{
161  Flag_PaddingShift = 5,
162  Flag_PaddingMask = 0x01,
163  // @}
164 
165  //! @name RTCP packets counter.
166  // @{
167  Flag_CounterShift = 0,
168  Flag_CounterMask = 0x1F
169  // @}
170  };
171 
172  //! Protocol version.
173  //! Padding flag.
174  //! Varies by packet type.
175  uint8_t count_;
176 
177  //! RTCP packet type.
178  uint8_t type_;
179 
180  //! Packet length in words, w/o common packet header word.
181  uint16_t length_;
182 
183 public:
184  PacketHeader() {
185  reset(PacketType(0));
186  }
187 
188  //! Reset to initial state (all zeros).
189  void reset(const PacketType t) {
190  count_ = 0;
191  type_ = 0;
192  length_ = 0;
193 
194  set_version(V2);
195  set_type(t);
196  }
197 
198  //! Get number of blocks/chunks following.
199  size_t counter() const {
200  return (count_ >> Flag_CounterShift) & Flag_CounterMask;
201  }
202 
203  //! Set number of blocks/chunks.
204  void set_counter(const size_t c) {
205  roc_panic_if(c > PacketMaxBlocks);
206  set_bitfield<uint8_t>(count_, (uint8_t)c, Flag_CounterShift, Flag_CounterMask);
207  }
208 
209  //! Increment packet counter,
210  void inc_counter() {
211  return set_counter(counter() + 1);
212  }
213 
214  //! Get protocol version.
215  uint8_t version() const {
216  return (count_ >> Flag_VersionShift) & Flag_VersionMask;
217  }
218 
219  //! Set protocol version.
221  roc_panic_if((v & Flag_VersionMask) != v);
222  set_bitfield<uint8_t>(count_, v, Flag_VersionShift, Flag_VersionMask);
223  }
224 
225  //! Get padding flag.
226  bool has_padding() const {
227  return (count_ & (Flag_PaddingMask << Flag_PaddingShift));
228  }
229 
230  //! Set padding flag.
231  void set_padding(bool v) {
232  set_bitfield(count_, (uint8_t)v, Flag_PaddingShift, Flag_PaddingMask);
233  }
234 
235  //! Get packet type.
236  PacketType type() const {
237  return PacketType(type_);
238  }
239 
240  //! Set packet type.
241  void set_type(const PacketType t) {
242  roc_panic_if_not(t == 0 || (t >= RTCP_SR && t <= RTCP_XR));
243  type_ = t;
244  }
245 
246  //! Get packet length, including the header, in 32-bit words minus one.
247  uint16_t len_words() const {
248  return core::ntoh16u(length_);
249  }
250 
251  //! Set packet length in words.
252  void set_len_words(const uint16_t ln) {
253  length_ = core::hton16u(ln);
254  }
255 
256  //! Get packet length, including the header, in bytes.
257  size_t len_bytes() const {
259  }
260 
261  //! Set packet length in bytes.
262  void set_len_bytes(const size_t ln) {
264  }
266 
267 //! Reception report block.
268 //!
269 //! Part of RR and SR packets.
270 //!
271 //! @code
272 //! 0 1 2 3
273 //! 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
274 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
275 //! | SSRC |
276 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
277 //! | fraction lost | cumulative number of packets lost |
278 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
279 //! | extended highest sequence number received |
280 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
281 //! | interarrival jitter |
282 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
283 //! | last SR (LSR) |
284 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
285 //! | delay since last SR (DLSR) |
286 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
287 //! @endcode
289 private:
290  enum {
291  //! @name Fraction lost since last SR/RR.
292  // @{
293  Losses_FractLost_shift = 24,
294  Losses_FractLost_mask = 0x0F,
295  // @}
296 
297  //! @name cumul. no. pkts lost (signed!).
298  // @{
299  Losses_CumLoss_shift = 24,
300  Losses_CumLoss_mask = 0x0FFF
301  // @}
302  };
303 
304  //! Data source being reported.
305  uint32_t ssrc_;
306 
307  //! Fraction lost since last SR/RR.
308  //! cumul. no. pkts lost (signed!).
309  uint32_t losses_;
310 
311  //! Extended last seq. no. received.
312  uint32_t last_seq_;
313 
314  //! Interarrival jitter.
315  uint32_t jitter_;
316 
317  //! Last SR packet from this source.
318  uint32_t lsr_;
319 
320  //! Delay since last SR packet.
321  uint32_t dlsr_;
322 
323 public:
325  reset();
326  }
327 
328  //! Reset to initial state (all zeros).
329  void reset() {
330  ssrc_ = losses_ = last_seq_ = jitter_ = lsr_ = dlsr_ = 0;
331  }
332 
333  //! Get SSRC.
334  uint32_t ssrc() const {
335  return core::ntoh32u(ssrc_);
336  }
337 
338  //! Set SSRC.
339  void set_ssrc(const uint32_t s) {
340  ssrc_ = core::hton32u(s);
341  }
342 
343  //! Get fraction lost.
344  float fract_loss() const {
345  const uint32_t tmp = core::ntoh32u(losses_);
346  uint8_t losses8 = (tmp >> Losses_FractLost_shift) & Losses_FractLost_mask;
347  float res = float(losses8) / float(1 << Losses_FractLost_shift);
348 
349  return res;
350  }
351 
352  //! Set fractional loss.
353  //!
354  //! Fractional loss is stored in Q.8 format.
355  void set_fract_loss(const ssize_t nlost, const size_t noverall) {
356  uint8_t l8;
357 
358  if (nlost <= 0 || noverall == 0) {
359  l8 = 0;
360  } else if ((size_t)nlost >= noverall) {
361  l8 = (uint8_t)-1;
362  } else {
363  l8 = (uint8_t)((uint32_t)(nlost << 8) / noverall);
364  }
365 
366  uint32_t losses = core::ntoh32u(losses_);
367  set_bitfield<uint32_t>(losses, l8, Losses_FractLost_shift, Losses_FractLost_mask);
368  losses_ = core::hton32u(losses);
369  }
370 
371  //! Get cumulative loss.
372  //!
373  //! May be negative in case of packet repeats.
374  int32_t cumloss() const {
375  uint32_t res = core::ntoh32u(losses_) & Losses_CumLoss_mask;
376  // If res is negative
377  if (res & (1 << (Losses_CumLoss_shift - 1))) {
378  // Make whole leftest byte filled with 1.
379  res |= ~(uint32_t)Losses_CumLoss_mask;
380  }
381  return int32_t(res);
382  }
383 
384  //! Set cumulative loss.
385  //!
386  //! May be negative in case of packet repeats.
387  void set_cumloss(int32_t l) {
388  uint32_t losses = core::ntoh32u(losses_);
389 
390  if (l > Losses_CumLoss_mask) {
391  l = Losses_CumLoss_mask;
392  } else if (l < -(int32_t)Losses_CumLoss_mask) {
393  l = -Losses_CumLoss_mask;
394  }
395  set_bitfield<uint32_t>(losses, (uint32_t)l,
396  sizeof(losses_) * 8 - Losses_CumLoss_shift,
397  Losses_CumLoss_mask);
398 
399  losses_ = core::hton32u(losses);
400  }
401 
402  //! Get last seqnum.
403  uint32_t last_seqnum() const {
404  return core::ntoh32u(last_seq_);
405  }
406 
407  //! Set last seqnum.
408  void set_last_seqnum(const uint32_t x) {
409  last_seq_ = core::hton32u(x);
410  }
411 
412  //! Get jitter.
413  uint32_t jitter() const {
414  return core::ntoh32u(jitter_);
415  }
416 
417  //! Set jitter.
418  void set_jitter(const uint32_t x) {
419  jitter_ = core::hton32u(x);
420  }
421 
422  //! Get LSR.
423  uint32_t last_sr() const {
424  return core::ntoh32u(lsr_);
425  }
426 
427  //! Set LSR.
428  void set_last_sr(const uint32_t x) {
429  lsr_ = core::hton32u(x);
430  }
431 
432  //! Get DLSR.
433  uint32_t delay_last_sr() const {
434  return core::ntoh32u(dlsr_);
435  }
436 
437  //! Set DLSR.
438  void set_delay_last_sr(const uint32_t x) {
439  dlsr_ = core::hton32u(x);
440  }
442 
443 //! Receiver Report RTCP packet (RR).
444 //!
445 //! RFC 3550 6.4.2. "RR: Receiver Report RTCP packet"
446 //!
447 //! @code
448 //! 0 1 2 3
449 //! 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
450 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
451 //! header |V=2|P| RC | PT=RR=201 | length |
452 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
453 //! | SSRC of packet sender |
454 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
455 //! report | SSRC_1 (SSRC of first source) |
456 //! block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
457 //! 1 | fraction lost | cumulative number of packets lost |
458 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
459 //! | extended highest sequence number received |
460 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
461 //! | interarrival jitter |
462 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
463 //! | last SR (LSR) |
464 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
465 //! | delay since last SR (DLSR) |
466 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
467 //! report | SSRC_2 (SSRC of second source) |
468 //! block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
469 //! 2 : ... :
470 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
471 //! | profile-specific extensions |
472 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
473 //! @endcode
475 private:
476  PacketHeader header_;
477 
478  //! Data source being reported.
479  uint32_t ssrc_;
480 
481 public:
483  reset();
484  }
485 
486  //! Reset to initial state (all zeros).
487  void reset() {
488  header_.reset(RTCP_RR);
489  ssrc_ = 0;
490  }
491 
492  //! Get common packet header.
493  const PacketHeader& header() const {
494  return header_;
495  }
496 
497  //! Get common packet header.
499  return header_;
500  }
501 
502  //! Get SSRC of packet sender.
503  uint32_t ssrc() const {
504  return core::ntoh32u(ssrc_);
505  }
506 
507  //! Set SSRC of packet sender.
508  void set_ssrc(const uint32_t s) {
509  ssrc_ = core::hton32u(s);
510  }
511 
512  //! Get number of blocks.
513  size_t num_blocks() const {
514  return header_.counter();
515  }
516 
517  //! Get reception block by index.
518  const ReceptionReportBlock& get_block(const size_t i) const {
519  return get_block_by_index<const ReceptionReportBlock>(this, i, header().counter(),
520  "rtcp rr");
521  }
522 
523  //! Get reception block by index.
524  ReceptionReportBlock& get_block(const size_t i) {
525  return get_block_by_index<ReceptionReportBlock>(this, i, header().counter(),
526  "rtcp rr");
527  }
529 
530 //! Sender Report RTCP packet (SR).
531 //!
532 //! RFC 3550 6.4.1. "SR: Sender Report RTCP packet"
533 //!
534 //! @code
535 //! 0 1 2 3
536 //! 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
537 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
538 //! header |V=2|P| RC | PT=SR=200 | length |
539 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
540 //! | SSRC of sender |
541 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
542 //! sender | NTP timestamp, most significant word |
543 //! info +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
544 //! | NTP timestamp, least significant word |
545 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
546 //! | RTP timestamp |
547 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
548 //! | sender's packet count |
549 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
550 //! | sender's octet count |
551 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
552 //! report | SSRC_1 (SSRC of first source) |
553 //! block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
554 //! 1 | fraction lost | cumulative number of packets lost |
555 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
556 //! | extended highest sequence number received |
557 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
558 //! | interarrival jitter |
559 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
560 //! | last SR (LSR) |
561 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
562 //! | delay since last SR (DLSR) |
563 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
564 //! report | SSRC_2 (SSRC of second source) |
565 //! block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
566 //! 2 : ... :
567 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
568 //! | profile-specific extensions |
569 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
570 //! @endcode
572 private:
573  PacketHeader header_;
574 
575  uint32_t ssrc_;
576  NtpTimestamp ntp_;
577 
578  uint32_t rtp_timestamp_;
579  uint32_t packet_cnt_;
580  uint32_t bytes_cnt_;
581 
582 public:
584  reset();
585  }
586 
587  //! Reset to initial state (all zeros).
588  void reset() {
589  header_.reset(RTCP_SR);
590  ssrc_ = 0;
591  ntp_.reset();
592  rtp_timestamp_ = 0;
593  packet_cnt_ = 0;
594  bytes_cnt_ = 0;
595  }
596 
597  //! Get common packet header.
598  const PacketHeader& header() const {
599  return header_;
600  }
601 
602  //! Get common packet header.
604  return header_;
605  }
606 
607  //! Get SSRC of sender.
608  uint32_t ssrc() const {
609  return core::ntoh32u(ssrc_);
610  }
611 
612  //! Set SSRC of sender.
613  void set_ssrc(const uint32_t s) {
614  ssrc_ = core::hton32u(s);
615  }
616 
617  //! Get NTP timestamp.
619  return ntp_.value();
620  }
621 
622  //! Set NTP timestamp.
624  ntp_.set_value(t);
625  }
626 
627  //! Get RTP timestamp.
628  uint32_t rtp_timestamp() const {
629  return core::ntoh32u(rtp_timestamp_);
630  }
631 
632  //! Get RTP timestamp.
633  void set_rtp_timestamp(const uint32_t& t) {
634  rtp_timestamp_ = core::hton32u(t);
635  }
636 
637  //! Get packet count.
638  size_t packet_count() const {
639  return core::ntoh32u(packet_cnt_);
640  }
641 
642  //! Set packet count.
643  void set_packet_count(const size_t cnt) {
644  packet_cnt_ = core::hton32u((uint32_t)cnt);
645  }
646 
647  //! Get byte count.
648  size_t byte_count() const {
649  return core::ntoh32u(bytes_cnt_);
650  }
651 
652  //! Set byte count.
653  void set_byte_count(const size_t cnt) {
654  bytes_cnt_ = core::hton32u((uint32_t)cnt);
655  }
656 
657  //! Get number of blocks.
658  size_t num_blocks() const {
659  return header_.counter();
660  }
661 
662  //! Get reception block by index.
663  const ReceptionReportBlock& get_block(const size_t i) const {
664  return get_block_by_index<const ReceptionReportBlock>(this, i, header().counter(),
665  "rtcp sr");
666  }
667 
668  //! Get reception block by index.
669  ReceptionReportBlock& get_block(const size_t i) {
670  return get_block_by_index<ReceptionReportBlock>(this, i, header().counter(),
671  "rtcp sr");
672  }
674 
675 //! SDES item type.
677  SDES_CNAME = 1, //!< Canonical End-Point Identifier.
678  SDES_NAME = 2, //!< User Name.
679  SDES_EMAIL = 3, //!< Electronic Mail Address.
680  SDES_PHONE = 4, //!< Phone Number.
681  SDES_LOC = 5, //!< Geographic User Location.
682  SDES_TOOL = 6, //!< Application or Tool Name.
683  SDES_NOTE = 7, //!< Notice/Status.
684  SDES_PRIV = 8 //!< Private Extensions.
685 };
686 
687 //! SDES chunk header.
688 //!
689 //! Part of SDES packet.
690 //!
691 //! @code
692 //! 0 1 2 3
693 //! 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
694 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
695 //! | SSRC |
696 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
697 //! @endcode
699 private:
700  uint32_t ssrc_;
701 
702 public:
703  SdesChunkHeader() {
704  reset();
705  }
706 
707  //! Reset to initial state (all zeros).
708  void reset() {
709  ssrc_ = 0;
710  }
711 
712  //! Get SSRC.
713  uint32_t ssrc() const {
714  return core::ntoh32u(ssrc_);
715  }
716 
717  //! Set SSRC.
718  void set_ssrc(const uint32_t s) {
719  ssrc_ = core::hton32u(s);
720  }
722 
723 //! SDES item header.
724 //!
725 //! Part of SDES packet.
726 //!
727 //! @code
728 //! 0 1 2 3
729 //! 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
730 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
731 //! | Type | Length | Text in UTF-8 ...
732 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
733 //! @endcode
735 private:
736  uint8_t type_;
737  uint8_t len_;
738 
739 public:
740  //! Get maximum allowed item text length.
741  static const size_t MaxTextLen = 255;
742 
743  SdesItemHeader() {
744  reset();
745  }
746 
747  //! Reset to initial state (all zeros).
748  void reset() {
749  type_ = len_ = 0;
750  }
751 
752  //! Get item type.
753  SdesItemType type() const {
754  return SdesItemType(type_);
755  }
756 
757  //! Set type.
758  void set_type(const SdesItemType t) {
759  type_ = t;
760  }
761 
762  //! Get item text length.
763  size_t text_len() const {
764  return len_;
765  }
766 
767  //! Set item text length.
768  void set_text_len(const size_t ln) {
769  roc_panic_if(ln > MaxTextLen);
770  len_ = (uint8_t)ln;
771  }
772 
773  //! Get pointer to item text.
774  //! The text is NOT zero-terminated.
775  const uint8_t* text() const {
776  return (const uint8_t*)this + sizeof(*this);
777  }
778 
779  //! Get pointer to item text.
780  //! The text is NOT zero-terminated.
781  uint8_t* text() {
782  return (uint8_t*)this + sizeof(*this);
783  }
785 
786 //! Source Description RTCP packet (SDES).
787 //!
788 //! RFC 3550 6.5. "SDES: Source Description RTCP packet"
789 //!
790 //! @code
791 //! 0 1 2 3
792 //! 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
793 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
794 //! header |V=2|P| RC | PT=Sdes=202 | length |
795 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
796 //! Chunk1 | SSRC_1 (SSRC of first source) |
797 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
798 //! Item1 | Type | Length | Text in UTF-8 |
799 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
800 //! Item2 | Type | Length | Text in UTF-8 |
801 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
802 //! Item 3 | Type | Length | Text in UTF-8 |
803 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
804 //! Chunk2 | SSRC_2 (SSRC of second source) |
805 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
806 //! Item1 | Type | Length | Text in UTF-8 |
807 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
808 //! Item2 | Type | Length | Text in UTF-8 |
809 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
810 //! : ... :
811 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
812 //! @endcode
814 private:
815  PacketHeader header_;
816 
817 public:
818  SdesPacket() {
819  reset();
820  }
821 
822  //! Reset to initial state (all zeros).
823  void reset() {
824  header_.reset(RTCP_SDES);
825  }
826 
827  //! Get common packet header.
828  const PacketHeader& header() const {
829  return header_;
830  }
831 
832  //! Get common packet header.
834  return header_;
835  }
837 
838 //! BYE source header.
839 //!
840 //! Part of BYE packet.
841 //!
842 //! @code
843 //! 0 1 2 3
844 //! 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
845 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
846 //! | SSRC |
847 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
848 //! @endcode
850 private:
851  uint32_t ssrc_;
852 
853 public:
854  ByeSourceHeader() {
855  reset();
856  }
857 
858  //! Reset to initial state (all zeros).
859  void reset() {
860  ssrc_ = 0;
861  }
862 
863  //! Get SSRC.
864  uint32_t ssrc() const {
865  return core::ntoh32u(ssrc_);
866  }
867 
868  //! Set SSRC.
869  void set_ssrc(const uint32_t s) {
870  ssrc_ = core::hton32u(s);
871  }
873 
874 //! BYE reason header.
875 //!
876 //! Part of BYE packet.
877 //!
878 //! @code
879 //! 0 1 2 3
880 //! 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
881 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
882 //! | length | reason for leaving ...
883 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
884 //! @endcode
886 private:
887  uint8_t len_;
888 
889 public:
890  //! Get maximum allowed reason text length.
891  static const size_t MaxTextLen = 255;
892 
893  ByeReasonHeader() {
894  reset();
895  }
896 
897  //! Reset to initial state (all zeros).
898  void reset() {
899  len_ = 0;
900  }
901 
902  //! Get text length.
903  size_t text_len() const {
904  return len_;
905  }
906 
907  //! Set text length.
908  void set_text_len(const size_t ln) {
909  roc_panic_if(ln > MaxTextLen);
910  len_ = (uint8_t)ln;
911  }
912 
913  //! Get pointer to text.
914  //! The text is NOT zero-terminated.
915  const uint8_t* text() const {
916  return (const uint8_t*)this + sizeof(*this);
917  }
918 
919  //! Get pointer to text.
920  //! The text is NOT zero-terminated.
921  uint8_t* text() {
922  return (uint8_t*)this + sizeof(*this);
923  }
925 
926 //! Goodbye RTCP packet (BYE).
927 //!
928 //! RFC 3550 6.6. "BYE: Goodbye RTCP packet"
929 //!
930 //! @code
931 //! 0 1 2 3
932 //! 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
933 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
934 //! |V=2|P| SC | PT=Bye=203 | length |
935 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
936 //! | SSRC/CSRC |
937 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
938 //! : ... :
939 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
940 //! (opt) | length | reason for leaving ...
941 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
942 //! @endcode
944 private:
945  PacketHeader header_;
946 
947 public:
948  ByePacket() {
949  reset();
950  }
951 
952  //! Reset to initial state (all zeros).
953  void reset() {
954  header_.reset(RTCP_BYE);
955  }
956 
957  //! Get common packet header.
958  const PacketHeader& header() const {
959  return header_;
960  }
961 
962  //! Get common packet header.
964  return header_;
965  }
967 
968 //! RTCP Extended Report Packet.
969 //!
970 //! RFC 3611 2. "XR Packet Format"
971 //!
972 //! @code
973 //! 0 1 2 3
974 //! 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
975 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
976 //! |V=2|P|reserved | PT=Xr=207 | length |
977 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
978 //! | SSRC |
979 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
980 //! : report blocks :
981 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
982 //! @endcode
984 private:
985  PacketHeader header_;
986  uint32_t ssrc_;
987 
988 public:
989  XrPacket() {
990  reset();
991  }
992 
993  //! Reset to initial state (all zeros).
994  void reset() {
995  header_.reset(RTCP_XR);
996  ssrc_ = 0;
997  }
998 
999  //! Get common packet header.
1000  const PacketHeader& header() const {
1001  return header_;
1002  }
1003 
1004  //! Get common packet header.
1006  return header_;
1007  }
1008 
1009  //! Get SSRC of packet originator.
1010  uint32_t ssrc() const {
1011  return core::ntoh32u(ssrc_);
1012  }
1013 
1014  //! Set SSRC of packet originator.
1015  void set_ssrc(const uint32_t ssrc) {
1016  ssrc_ = core::hton32u(ssrc);
1017  }
1019 
1020 //! XR Block Type.
1022  XR_LOSS_RLE = 1, //!< Loss RLE Report Block.
1023  XR_DUPLICATE_RLE = 2, //!< Duplicate RLE Report Block.
1024  XR_PACKET_RECPT_TIME = 3, //!< Packet Receipt Times Report Block.
1025  XR_RRTR = 4, //!< Receiver Reference Time Report Block.
1026  XR_DLRR = 5, //!< DLRR Report Block.
1027  XR_STAT_SUMMARY = 6, //!< Statistics Summary Report Block.
1028  XR_VOIP_METRICS = 7 //!< VoIP Metrics Report Block.
1029 };
1030 
1031 //! XR Block Header.
1032 //!
1033 //! @code
1034 //! 0 1 2 3
1035 //! 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1036 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1037 //! | BT | type-specific | block length |
1038 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1039 //! : type-specific block contents :
1040 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1041 //! @endcode
1043 private:
1044  uint8_t block_type_;
1045  uint8_t type_specific_;
1046  uint16_t length_;
1047 
1048 public:
1049  XrBlockHeader() {
1050  reset(XrBlockType(0));
1051  }
1052 
1053  //! Reset to initial state (all zeros).
1054  void reset(const XrBlockType bt) {
1055  block_type_ = type_specific_ = 0;
1056  length_ = 0;
1057  set_block_type(bt);
1058  }
1059 
1060  //! Get XR block type.
1062  return (XrBlockType)block_type_;
1063  }
1064 
1065  //! Set XR block type.
1066  void set_block_type(const XrBlockType bt) {
1067  roc_panic_if_not(bt == 0 || (bt >= XR_LOSS_RLE && bt <= XR_VOIP_METRICS));
1068  block_type_ = (uint8_t)bt;
1069  }
1070 
1071  //! Get type-specific byte.
1072  uint8_t type_specific() const {
1073  return type_specific_;
1074  }
1075 
1076  //! Set type-specific byte.
1077  void set_type_specific(const uint8_t t) {
1078  type_specific_ = t;
1079  }
1080 
1081  //! Get block length, including the header, in 32-bit words minus one.
1082  uint16_t len_words() const {
1083  return core::ntoh16u(length_);
1084  }
1085 
1086  //! Set block length in words.
1087  void set_len_words(const uint16_t ln) {
1088  length_ = core::hton16u(ln);
1089  }
1090 
1091  //! Get block length, including the header, in bytes.
1092  size_t len_bytes() const {
1093  return rtcp_length_2_size_t(len_words());
1094  }
1095 
1096  //! Set block length in bytes.
1097  void set_len_bytes(const size_t ln) {
1099  }
1101 
1102 //! XR Receiver Reference Time Report block.
1103 //!
1104 //! RFC 3611 4.4. "Receiver Reference Time Report Block"
1105 //!
1106 //! @code
1107 //! 0 1 2 3
1108 //! 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1109 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1110 //! | BT=4 | reserved | block length = 2 |
1111 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1112 //! | NTP timestamp, most significant word |
1113 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1114 //! | NTP timestamp, least significant word |
1115 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1116 //! @endcode
1118 private:
1119  XrBlockHeader header_;
1120  NtpTimestamp ntp_;
1121 
1122 public:
1123  XrRrtrBlock() {
1124  reset();
1125  }
1126 
1127  //! Reset to initial state (all zeros).
1128  void reset() {
1129  header_.reset(XR_RRTR);
1130  ntp_.reset();
1131  }
1132 
1133  //! Get common block header.
1134  const XrBlockHeader& header() const {
1135  return header_;
1136  }
1137 
1138  //! Get common block header.
1140  return header_;
1141  }
1142 
1143  //! Get NTP timestamp.
1145  return ntp_.value();
1146  }
1147 
1148  //! Set NTP timestamp.
1150  ntp_.set_value(t);
1151  }
1153 
1154 //! XR DLRR Report sub-block.
1155 //!
1156 //! RFC 3611 4.5. "DLRR Report Sub-block"
1157 //!
1158 //! @code
1159 //! 0 1 2 3
1160 //! 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1161 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
1162 //! | SSRC |
1163 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1164 //! | last RR (LRR) |
1165 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1166 //! | delay since last RR (DLRR) |
1167 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
1168 //! @endcode
1170 private:
1171  uint32_t ssrc_;
1172  uint32_t last_rr_;
1173  uint32_t delay_last_rr_;
1174 
1175 public:
1176  XrDlrrSubblock() {
1177  reset();
1178  }
1179 
1180  //! Reset to initial state (all zeros).
1181  void reset() {
1182  ssrc_ = last_rr_ = delay_last_rr_ = 0;
1183  }
1184 
1185  //! Get SSRC of receiver.
1186  uint32_t ssrc() const {
1187  return core::ntoh32u(ssrc_);
1188  }
1189 
1190  //! Set SSRC of receiver.
1191  void set_ssrc(const uint32_t ssrc) {
1192  ssrc_ = core::hton32u(ssrc);
1193  }
1194 
1195  //! Get LRR.
1196  uint32_t last_rr() const {
1197  return core::ntoh32u(last_rr_);
1198  }
1199 
1200  //! Set LRR.
1201  void set_last_rr(const uint32_t lrr) {
1202  last_rr_ = core::hton32u(lrr);
1203  }
1204 
1205  //! Get DLRR.
1206  uint32_t delay_last_rr() const {
1207  return core::ntoh32u(delay_last_rr_);
1208  }
1209 
1210  //! Set DLRR.
1211  void set_delay_last_rr(const uint32_t dlrr) {
1212  delay_last_rr_ = core::hton32u(dlrr);
1213  }
1215 
1216 //! XR DLRR Report block.
1217 //!
1218 //! RFC 3611 4.5. "DLRR Report Block"
1219 //!
1220 //! @code
1221 //! 0 1 2 3
1222 //! 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1223 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1224 //! | BT=5 | reserved | block length |
1225 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
1226 //! | SSRC_1 (SSRC of first receiver) | sub-
1227 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
1228 //! | last RR (LRR) | 1
1229 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1230 //! | delay since last RR (DLRR) |
1231 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
1232 //! | SSRC_2 (SSRC of second receiver) | sub-
1233 //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
1234 //! : ... : 2
1235 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
1236 //! @endcode
1238 private:
1239  XrBlockHeader header_;
1240 
1241 public:
1242  XrDlrrBlock() {
1243  reset();
1244  }
1245 
1246  //! Reset to initial state (all zeros).
1247  void reset() {
1248  header_.reset(XR_DLRR);
1249  }
1250 
1251  //! Get common block header.
1252  const XrBlockHeader& header() const {
1253  return header_;
1254  }
1255 
1256  //! Get common block header.
1258  return header_;
1259  }
1260 
1261  //! Get number of sub-blocks.
1262  size_t num_subblocks() const {
1263  return (header_.len_bytes() - sizeof(header_)) / sizeof(XrDlrrSubblock);
1264  }
1265 
1266  //! Get DLRR sub-block by index.
1267  const XrDlrrSubblock& get_subblock(const size_t i) const {
1268  return get_block_by_index<const XrDlrrSubblock>(this, i, num_subblocks(),
1269  "rtcp xr_dlrr");
1270  }
1271 
1272  //! Get DLRR sub-block by index.
1273  XrDlrrSubblock& get_subblock(const size_t i) {
1274  return get_block_by_index<XrDlrrSubblock>(this, i, num_subblocks(),
1275  "rtcp xr_dlrr");
1276  }
1278 
1279 } // namespace header
1280 } // namespace rtcp
1281 } // namespace roc
1282 
1283 #endif // ROC_RTCP_HEADERS_H_
Compiler attributes.
#define ROC_ATTR_PACKED_BEGIN
Pack structure fields. Place these before class or struct keyword.
Definition: attributes.h:55
#define ROC_ATTR_PACKED_END
Pack structure fields. Place these between '}' and ';'.
Definition: attributes.h:58
Goodbye RTCP packet (BYE).
Definition: headers.h:943
const PacketHeader & header() const
Get common packet header.
Definition: headers.h:958
void reset()
Reset to initial state (all zeros).
Definition: headers.h:953
PacketHeader & header()
Get common packet header.
Definition: headers.h:963
const uint8_t * text() const
Get pointer to text. The text is NOT zero-terminated.
Definition: headers.h:915
void set_text_len(const size_t ln)
Set text length.
Definition: headers.h:908
size_t text_len() const
Get text length.
Definition: headers.h:903
uint8_t * text()
Get pointer to text. The text is NOT zero-terminated.
Definition: headers.h:921
static const size_t MaxTextLen
Get maximum allowed reason text length.
Definition: headers.h:891
void reset()
Reset to initial state (all zeros).
Definition: headers.h:898
void reset()
Reset to initial state (all zeros).
Definition: headers.h:859
uint32_t ssrc() const
Get SSRC.
Definition: headers.h:864
void set_ssrc(const uint32_t s)
Set SSRC.
Definition: headers.h:869
Helper to store 64-bit ntp timestamp in a common way among RTCP.
Definition: headers.h:102
packet::ntp_timestamp_t value() const
Get NTP timestamp value.
Definition: headers.h:127
void set_value(const packet::ntp_timestamp_t t)
Set NTP timestamp value.
Definition: headers.h:135
void reset()
Reset to initial state (all zeros).
Definition: headers.h:121
RTCP packet header, common for all RTCP packet types.
Definition: headers.h:150
void set_len_bytes(const size_t ln)
Set packet length in bytes.
Definition: headers.h:262
void set_len_words(const uint16_t ln)
Set packet length in words.
Definition: headers.h:252
uint16_t len_words() const
Get packet length, including the header, in 32-bit words minus one.
Definition: headers.h:247
PacketType type() const
Get packet type.
Definition: headers.h:236
void set_counter(const size_t c)
Set number of blocks/chunks.
Definition: headers.h:204
uint8_t version() const
Get protocol version.
Definition: headers.h:215
void reset(const PacketType t)
Reset to initial state (all zeros).
Definition: headers.h:189
void inc_counter()
Increment packet counter,.
Definition: headers.h:210
void set_padding(bool v)
Set padding flag.
Definition: headers.h:231
void set_version(Version v)
Set protocol version.
Definition: headers.h:220
size_t counter() const
Get number of blocks/chunks following.
Definition: headers.h:199
void set_type(const PacketType t)
Set packet type.
Definition: headers.h:241
bool has_padding() const
Get padding flag.
Definition: headers.h:226
size_t len_bytes() const
Get packet length, including the header, in bytes.
Definition: headers.h:257
Receiver Report RTCP packet (RR).
Definition: headers.h:474
PacketHeader & header()
Get common packet header.
Definition: headers.h:498
void set_ssrc(const uint32_t s)
Set SSRC of packet sender.
Definition: headers.h:508
const PacketHeader & header() const
Get common packet header.
Definition: headers.h:493
ReceptionReportBlock & get_block(const size_t i)
Get reception block by index.
Definition: headers.h:524
const ReceptionReportBlock & get_block(const size_t i) const
Get reception block by index.
Definition: headers.h:518
uint32_t ssrc() const
Get SSRC of packet sender.
Definition: headers.h:503
void reset()
Reset to initial state (all zeros).
Definition: headers.h:487
size_t num_blocks() const
Get number of blocks.
Definition: headers.h:513
Reception report block.
Definition: headers.h:288
uint32_t ssrc() const
Get SSRC.
Definition: headers.h:334
uint32_t last_sr() const
Get LSR.
Definition: headers.h:423
void set_fract_loss(const ssize_t nlost, const size_t noverall)
Set fractional loss.
Definition: headers.h:355
void set_delay_last_sr(const uint32_t x)
Set DLSR.
Definition: headers.h:438
void set_jitter(const uint32_t x)
Set jitter.
Definition: headers.h:418
uint32_t delay_last_sr() const
Get DLSR.
Definition: headers.h:433
void set_cumloss(int32_t l)
Set cumulative loss.
Definition: headers.h:387
float fract_loss() const
Get fraction lost.
Definition: headers.h:344
void set_last_seqnum(const uint32_t x)
Set last seqnum.
Definition: headers.h:408
uint32_t last_seqnum() const
Get last seqnum.
Definition: headers.h:403
void set_last_sr(const uint32_t x)
Set LSR.
Definition: headers.h:428
uint32_t jitter() const
Get jitter.
Definition: headers.h:413
int32_t cumloss() const
Get cumulative loss.
Definition: headers.h:374
void set_ssrc(const uint32_t s)
Set SSRC.
Definition: headers.h:339
void reset()
Reset to initial state (all zeros).
Definition: headers.h:329
uint32_t ssrc() const
Get SSRC.
Definition: headers.h:713
void reset()
Reset to initial state (all zeros).
Definition: headers.h:708
void set_ssrc(const uint32_t s)
Set SSRC.
Definition: headers.h:718
SdesItemType type() const
Get item type.
Definition: headers.h:753
void set_text_len(const size_t ln)
Set item text length.
Definition: headers.h:768
uint8_t * text()
Get pointer to item text. The text is NOT zero-terminated.
Definition: headers.h:781
size_t text_len() const
Get item text length.
Definition: headers.h:763
void set_type(const SdesItemType t)
Set type.
Definition: headers.h:758
const uint8_t * text() const
Get pointer to item text. The text is NOT zero-terminated.
Definition: headers.h:775
void reset()
Reset to initial state (all zeros).
Definition: headers.h:748
static const size_t MaxTextLen
Get maximum allowed item text length.
Definition: headers.h:741
Source Description RTCP packet (SDES).
Definition: headers.h:813
const PacketHeader & header() const
Get common packet header.
Definition: headers.h:828
PacketHeader & header()
Get common packet header.
Definition: headers.h:833
void reset()
Reset to initial state (all zeros).
Definition: headers.h:823
Sender Report RTCP packet (SR).
Definition: headers.h:571
size_t packet_count() const
Get packet count.
Definition: headers.h:638
const ReceptionReportBlock & get_block(const size_t i) const
Get reception block by index.
Definition: headers.h:663
uint32_t ssrc() const
Get SSRC of sender.
Definition: headers.h:608
ReceptionReportBlock & get_block(const size_t i)
Get reception block by index.
Definition: headers.h:669
uint32_t rtp_timestamp() const
Get RTP timestamp.
Definition: headers.h:628
void set_packet_count(const size_t cnt)
Set packet count.
Definition: headers.h:643
PacketHeader & header()
Get common packet header.
Definition: headers.h:603
void set_byte_count(const size_t cnt)
Set byte count.
Definition: headers.h:653
void set_rtp_timestamp(const uint32_t &t)
Get RTP timestamp.
Definition: headers.h:633
void reset()
Reset to initial state (all zeros).
Definition: headers.h:588
size_t num_blocks() const
Get number of blocks.
Definition: headers.h:658
packet::ntp_timestamp_t ntp_timestamp() const
Get NTP timestamp.
Definition: headers.h:618
void set_ssrc(const uint32_t s)
Set SSRC of sender.
Definition: headers.h:613
const PacketHeader & header() const
Get common packet header.
Definition: headers.h:598
void set_ntp_timestamp(const packet::ntp_timestamp_t t)
Set NTP timestamp.
Definition: headers.h:623
size_t byte_count() const
Get byte count.
Definition: headers.h:648
void set_len_words(const uint16_t ln)
Set block length in words.
Definition: headers.h:1087
uint16_t len_words() const
Get block length, including the header, in 32-bit words minus one.
Definition: headers.h:1082
void set_len_bytes(const size_t ln)
Set block length in bytes.
Definition: headers.h:1097
void set_type_specific(const uint8_t t)
Set type-specific byte.
Definition: headers.h:1077
void reset(const XrBlockType bt)
Reset to initial state (all zeros).
Definition: headers.h:1054
size_t len_bytes() const
Get block length, including the header, in bytes.
Definition: headers.h:1092
void set_block_type(const XrBlockType bt)
Set XR block type.
Definition: headers.h:1066
uint8_t type_specific() const
Get type-specific byte.
Definition: headers.h:1072
XrBlockType block_type() const
Get XR block type.
Definition: headers.h:1061
XR DLRR Report block.
Definition: headers.h:1237
const XrBlockHeader & header() const
Get common block header.
Definition: headers.h:1252
const XrDlrrSubblock & get_subblock(const size_t i) const
Get DLRR sub-block by index.
Definition: headers.h:1267
XrDlrrSubblock & get_subblock(const size_t i)
Get DLRR sub-block by index.
Definition: headers.h:1273
XrBlockHeader & header()
Get common block header.
Definition: headers.h:1257
size_t num_subblocks() const
Get number of sub-blocks.
Definition: headers.h:1262
void reset()
Reset to initial state (all zeros).
Definition: headers.h:1247
XR DLRR Report sub-block.
Definition: headers.h:1169
void set_last_rr(const uint32_t lrr)
Set LRR.
Definition: headers.h:1201
void set_ssrc(const uint32_t ssrc)
Set SSRC of receiver.
Definition: headers.h:1191
void reset()
Reset to initial state (all zeros).
Definition: headers.h:1181
void set_delay_last_rr(const uint32_t dlrr)
Set DLRR.
Definition: headers.h:1211
uint32_t delay_last_rr() const
Get DLRR.
Definition: headers.h:1206
uint32_t last_rr() const
Get LRR.
Definition: headers.h:1196
uint32_t ssrc() const
Get SSRC of receiver.
Definition: headers.h:1186
RTCP Extended Report Packet.
Definition: headers.h:983
void set_ssrc(const uint32_t ssrc)
Set SSRC of packet originator.
Definition: headers.h:1015
const PacketHeader & header() const
Get common packet header.
Definition: headers.h:1000
uint32_t ssrc() const
Get SSRC of packet originator.
Definition: headers.h:1010
PacketHeader & header()
Get common packet header.
Definition: headers.h:1005
void reset()
Reset to initial state (all zeros).
Definition: headers.h:994
XR Receiver Reference Time Report block.
Definition: headers.h:1117
XrBlockHeader & header()
Get common block header.
Definition: headers.h:1139
void set_ntp_timestamp(const packet::ntp_timestamp_t t)
Set NTP timestamp.
Definition: headers.h:1149
const XrBlockHeader & header() const
Get common block header.
Definition: headers.h:1134
packet::ntp_timestamp_t ntp_timestamp() const
Get NTP timestamp.
Definition: headers.h:1144
void reset()
Reset to initial state (all zeros).
Definition: headers.h:1128
Endian conversion functions.
uint16_t hton16u(uint16_t v)
Host to network byte order (unsigned 16-bit).
Definition: endian.h:54
uint16_t ntoh16u(uint16_t v)
Network to host byte order (unsigned 16-bit).
Definition: endian.h:24
uint32_t hton32u(uint32_t v)
Host to network byte order (unsigned 32-bit).
Definition: endian.h:64
uint32_t ntoh32u(uint32_t v)
Network to host byte order (unsigned 32-bit).
Definition: endian.h:34
uint64_t ntp_timestamp_t
NTP timestamp.
Definition: ntp.h:35
@ V2
RTP version 2.
Definition: headers.h:25
Root namespace.
Utitilies for NTP timestamp.
Panic.
#define roc_panic_if_not(x)
Panic if condition is false.
Definition: panic.h:37
#define roc_panic_if(x)
Panic if condition is true.
Definition: panic.h:26
#define roc_panic(...)
Print error message and terminate program gracefully.
Definition: panic.h:50
size_t padding_len(const size_t size, const size_t min_padding)
How much padding bytes do we need in order to align with 32-bits.
Definition: headers.h:55
XrBlockType
XR Block Type.
Definition: headers.h:1021
@ XR_RRTR
Receiver Reference Time Report Block.
Definition: headers.h:1025
@ XR_DLRR
DLRR Report Block.
Definition: headers.h:1026
@ XR_PACKET_RECPT_TIME
Packet Receipt Times Report Block.
Definition: headers.h:1024
@ XR_STAT_SUMMARY
Statistics Summary Report Block.
Definition: headers.h:1027
@ XR_LOSS_RLE
Loss RLE Report Block.
Definition: headers.h:1022
@ XR_VOIP_METRICS
VoIP Metrics Report Block.
Definition: headers.h:1028
@ XR_DUPLICATE_RLE
Duplicate RLE Report Block.
Definition: headers.h:1023
uint16_t size_t_2_rtcp_length(const size_t x)
Computes the value of RTCP packet header length field from input number.
Definition: headers.h:39
void set_bitfield(T &v0, const T v1, const size_t shift, const size_t mask)
Set some bits in v0.
Definition: headers.h:33
Version
RTP protocol version.
Definition: headers.h:74
SdesItemType
SDES item type.
Definition: headers.h:676
@ SDES_PHONE
Phone Number.
Definition: headers.h:680
@ SDES_NOTE
Notice/Status.
Definition: headers.h:683
@ SDES_EMAIL
Electronic Mail Address.
Definition: headers.h:679
@ SDES_PRIV
Private Extensions.
Definition: headers.h:684
@ SDES_LOC
Geographic User Location.
Definition: headers.h:681
@ SDES_NAME
User Name.
Definition: headers.h:678
@ SDES_TOOL
Application or Tool Name.
Definition: headers.h:682
@ SDES_CNAME
Canonical End-Point Identifier.
Definition: headers.h:677
PacketType
RTCP packet type.
Definition: headers.h:79
@ RTCP_APP
APP-specific packet.
Definition: headers.h:84
@ RTCP_SR
Sender report packet.
Definition: headers.h:80
@ RTCP_SDES
Source Description packet.
Definition: headers.h:82
@ RTCP_RR
Receiver report packet.
Definition: headers.h:81
@ RTCP_XR
Extended report packet.
Definition: headers.h:85
@ RTCP_BYE
BYE packet.
Definition: headers.h:83
size_t rtcp_length_2_size_t(const size_t x)
Converts RTCP header length field into conventional size_t value.
Definition: headers.h:46
Blk & get_block_by_index(Pkt *pkt, size_t block_index, size_t num_blocks, const char *pkt_type)
Get a block that follows header, by index.
Definition: headers.h:62
Commonly used types and functions.
Various units used in packets.