1 /*
2  * The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) implementation with additional features.
3  * Copyright (C) 2017 Belledonne Communications SARL
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19 
20 
21 #ifndef RTCP_H
22 #define RTCP_H
23 
24 #include <ortp/port.h>
25 
26 #define RTCP_MAX_RECV_BUFSIZE 1500
27 
28 #define RTCP_SENDER_INFO_SIZE 20
29 #define RTCP_REPORT_BLOCK_SIZE 24
30 #define RTCP_COMMON_HEADER_SIZE 4
31 #define RTCP_SSRC_FIELD_SIZE 4
32 
33 #ifdef __cplusplus
34 extern "C"{
35 #endif
36 
37 /* RTCP common header */
38 
39 typedef enum {
40 	RTCP_SR = 200,
41 	RTCP_RR = 201,
42 	RTCP_SDES = 202,
43 	RTCP_BYE = 203,
44 	RTCP_APP = 204,
45 	RTCP_RTPFB = 205,
46 	RTCP_PSFB = 206,
47 	RTCP_XR = 207
48 } rtcp_type_t;
49 
50 
51 typedef struct rtcp_common_header
52 {
53 #ifdef ORTP_BIGENDIAN
54 	uint16_t version:2;
55 	uint16_t padbit:1;
56 	uint16_t rc:5;
57 	uint16_t packet_type:8;
58 #else
59 	uint16_t rc:5;
60 	uint16_t padbit:1;
61 	uint16_t version:2;
62 	uint16_t packet_type:8;
63 #endif
64 	uint16_t length:16;
65 } rtcp_common_header_t;
66 
67 #define rtcp_common_header_set_version(ch,v) (ch)->version=v
68 #define rtcp_common_header_set_padbit(ch,p) (ch)->padbit=p
69 #define rtcp_common_header_set_rc(ch,rc) (ch)->rc=rc
70 #define rtcp_common_header_set_packet_type(ch,pt) (ch)->packet_type=pt
71 #define rtcp_common_header_set_length(ch,l)	(ch)->length=htons(l)
72 
73 #define rtcp_common_header_get_version(ch) ((ch)->version)
74 #define rtcp_common_header_get_padbit(ch) ((ch)->padbit)
75 #define rtcp_common_header_get_rc(ch) ((ch)->rc)
76 #define rtcp_common_header_get_packet_type(ch) ((ch)->packet_type)
77 #define rtcp_common_header_get_length(ch)	ntohs((ch)->length)
78 
79 
80 /* RTCP SR or RR  packets */
81 
82 typedef struct sender_info
83 {
84 	uint32_t ntp_timestamp_msw;
85 	uint32_t ntp_timestamp_lsw;
86 	uint32_t rtp_timestamp;
87 	uint32_t senders_packet_count;
88 	uint32_t senders_octet_count;
89 } sender_info_t;
90 
sender_info_get_ntp_timestamp(const sender_info_t * si)91 static ORTP_INLINE uint64_t sender_info_get_ntp_timestamp(const sender_info_t *si) {
92   return ((((uint64_t)ntohl(si->ntp_timestamp_msw)) << 32) +
93           ((uint64_t) ntohl(si->ntp_timestamp_lsw)));
94 }
95 #define sender_info_get_rtp_timestamp(si)	ntohl((si)->rtp_timestamp)
96 #define sender_info_get_packet_count(si) \
97 	ntohl((si)->senders_packet_count)
98 #define sender_info_get_octet_count(si) \
99 	ntohl((si)->senders_octet_count)
100 
101 
102 typedef struct report_block
103 {
104 	uint32_t ssrc;
105 	uint32_t fl_cnpl;/*fraction lost + cumulative number of packet lost*/
106 	uint32_t ext_high_seq_num_rec; /*extended highest sequence number received */
107 	uint32_t interarrival_jitter;
108 	uint32_t lsr; /*last SR */
109 	uint32_t delay_snc_last_sr; /*delay since last sr*/
110 } report_block_t;
111 
report_block_get_ssrc(const report_block_t * rb)112 static ORTP_INLINE uint32_t report_block_get_ssrc(const report_block_t * rb) {
113 	return ntohl(rb->ssrc);
114 }
report_block_get_high_ext_seq(const report_block_t * rb)115 static ORTP_INLINE uint32_t report_block_get_high_ext_seq(const report_block_t * rb) {
116 	return ntohl(rb->ext_high_seq_num_rec);
117 }
report_block_get_interarrival_jitter(const report_block_t * rb)118 static ORTP_INLINE uint32_t report_block_get_interarrival_jitter(const report_block_t * rb) {
119 	return ntohl(rb->interarrival_jitter);
120 }
121 
report_block_get_last_SR_time(const report_block_t * rb)122 static ORTP_INLINE uint32_t report_block_get_last_SR_time(const report_block_t * rb) {
123 	return ntohl(rb->lsr);
124 }
report_block_get_last_SR_delay(const report_block_t * rb)125 static ORTP_INLINE uint32_t report_block_get_last_SR_delay(const report_block_t * rb) {
126 	return ntohl(rb->delay_snc_last_sr);
127 }
report_block_get_fraction_lost(const report_block_t * rb)128 static ORTP_INLINE uint32_t report_block_get_fraction_lost(const report_block_t * rb) {
129 	return (ntohl(rb->fl_cnpl)>>24);
130 }
report_block_get_cum_packet_lost(const report_block_t * rb)131 static ORTP_INLINE int32_t report_block_get_cum_packet_lost(const report_block_t * rb){
132 	int cum_loss = ntohl(rb->fl_cnpl);
133 	if (((cum_loss>>23)&1)==0)
134 		return 0x00FFFFFF & cum_loss;
135 	else
136 		return 0xFF000000 | (cum_loss-0xFFFFFF-1);
137 }
138 
report_block_set_fraction_lost(report_block_t * rb,int fl)139 static ORTP_INLINE void report_block_set_fraction_lost(report_block_t * rb, int fl){
140 	rb->fl_cnpl = htonl( (ntohl(rb->fl_cnpl) & 0xFFFFFF) | (fl&0xFF)<<24);
141 }
142 
report_block_set_cum_packet_lost(report_block_t * rb,int64_t cpl)143 static ORTP_INLINE void report_block_set_cum_packet_lost(report_block_t * rb, int64_t cpl) {
144 	uint32_t clamp = (uint32_t)((1<<24) + ((cpl>=0) ? (cpl>0x7FFFFF?0x7FFFFF:cpl) : (-cpl>0x800000?-0x800000:cpl)));
145 
146 	rb->fl_cnpl=htonl(
147 			(ntohl(rb->fl_cnpl) & 0xFF000000) |
148 			(cpl >= 0 ? clamp&0x7FFFFF : clamp|0x800000)
149 		);
150 }
151 
152 /* SDES packets */
153 
154 typedef enum {
155 	RTCP_SDES_END = 0,
156 	RTCP_SDES_CNAME = 1,
157 	RTCP_SDES_NAME = 2,
158 	RTCP_SDES_EMAIL = 3,
159 	RTCP_SDES_PHONE = 4,
160 	RTCP_SDES_LOC = 5,
161 	RTCP_SDES_TOOL = 6,
162 	RTCP_SDES_NOTE = 7,
163 	RTCP_SDES_PRIV = 8,
164 	RTCP_SDES_MAX = 9
165 } rtcp_sdes_type_t;
166 
167 typedef struct sdes_chunk
168 {
169 	uint32_t csrc;
170 } sdes_chunk_t;
171 
172 
173 #define sdes_chunk_get_csrc(c)	ntohl((c)->csrc)
174 
175 typedef struct sdes_item
176 {
177 	uint8_t item_type;
178 	uint8_t len;
179 	char content[1];
180 } sdes_item_t;
181 
182 #define RTCP_SDES_MAX_STRING_SIZE 255
183 #define RTCP_SDES_ITEM_HEADER_SIZE 2
184 #define RTCP_SDES_CHUNK_DEFAULT_SIZE 1024
185 #define RTCP_SDES_CHUNK_HEADER_SIZE (sizeof(sdes_chunk_t))
186 
187 /* RTCP bye packet */
188 
189 typedef struct rtcp_bye_reason
190 {
191 	uint8_t len;
192 	char content[1];
193 } rtcp_bye_reason_t;
194 
195 typedef struct rtcp_bye
196 {
197 	rtcp_common_header_t ch;
198 	uint32_t ssrc[1];  /* the bye may contain several ssrc/csrc */
199 } rtcp_bye_t;
200 #define RTCP_BYE_HEADER_SIZE sizeof(rtcp_bye_t)
201 #define RTCP_BYE_REASON_MAX_STRING_SIZE 255
202 
203 
204 /* RTCP XR packet */
205 
206 #define RTCP_XR_VOIP_METRICS_CONFIG_PLC_STD ((1 << 7) | (1 << 6))
207 #define RTCP_XR_VOIP_METRICS_CONFIG_PLC_ENH (1 << 7)
208 #define RTCP_XR_VOIP_METRICS_CONFIG_PLC_DIS (1 << 6)
209 #define RTCP_XR_VOIP_METRICS_CONFIG_PLC_UNS 0
210 #define RTCP_XR_VOIP_METRICS_CONFIG_JBA_ADA ((1 << 5) | (1 << 4))
211 #define RTCP_XR_VOIP_METRICS_CONFIG_JBA_NON (1 << 5)
212 #define RTCP_XR_VOIP_METRICS_CONFIG_JBA_UNK 0
213 
214 typedef enum {
215 	RTCP_XR_LOSS_RLE = 1,
216 	RTCP_XR_DUPLICATE_RLE = 2,
217 	RTCP_XR_PACKET_RECEIPT_TIMES = 3,
218 	RTCP_XR_RCVR_RTT = 4,
219 	RTCP_XR_DLRR = 5,
220 	RTCP_XR_STAT_SUMMARY = 6,
221 	RTCP_XR_VOIP_METRICS = 7
222 } rtcp_xr_block_type_t;
223 
224 typedef struct rtcp_xr_header {
225 	rtcp_common_header_t ch;
226 	uint32_t ssrc;
227 } rtcp_xr_header_t;
228 
229 typedef struct rtcp_xr_generic_block_header {
230 	uint8_t bt;
231 	uint8_t flags;
232 	uint16_t length;
233 } rtcp_xr_generic_block_header_t;
234 
235 typedef struct rtcp_xr_rcvr_rtt_report_block {
236 	rtcp_xr_generic_block_header_t bh;
237 	uint32_t ntp_timestamp_msw;
238 	uint32_t ntp_timestamp_lsw;
239 } rtcp_xr_rcvr_rtt_report_block_t;
240 
241 typedef struct rtcp_xr_dlrr_report_subblock {
242 	uint32_t ssrc;
243 	uint32_t lrr;
244 	uint32_t dlrr;
245 } rtcp_xr_dlrr_report_subblock_t;
246 
247 typedef struct rtcp_xr_dlrr_report_block {
248 	rtcp_xr_generic_block_header_t bh;
249 	rtcp_xr_dlrr_report_subblock_t content[1];
250 } rtcp_xr_dlrr_report_block_t;
251 
252 typedef struct rtcp_xr_stat_summary_report_block {
253 	rtcp_xr_generic_block_header_t bh;
254 	uint32_t ssrc;
255 	uint16_t begin_seq;
256 	uint16_t end_seq;
257 	uint32_t lost_packets;
258 	uint32_t dup_packets;
259 	uint32_t min_jitter;
260 	uint32_t max_jitter;
261 	uint32_t mean_jitter;
262 	uint32_t dev_jitter;
263 	uint8_t min_ttl_or_hl;
264 	uint8_t max_ttl_or_hl;
265 	uint8_t mean_ttl_or_hl;
266 	uint8_t dev_ttl_or_hl;
267 } rtcp_xr_stat_summary_report_block_t;
268 
269 typedef struct rtcp_xr_voip_metrics_report_block {
270 	rtcp_xr_generic_block_header_t bh;
271 	uint32_t ssrc;
272 	uint8_t loss_rate;
273 	uint8_t discard_rate;
274 	uint8_t burst_density;
275 	uint8_t gap_density;
276 	uint16_t burst_duration;
277 	uint16_t gap_duration;
278 	uint16_t round_trip_delay;
279 	uint16_t end_system_delay;
280 	uint8_t signal_level;
281 	uint8_t noise_level;
282 	uint8_t rerl;
283 	uint8_t gmin;
284 	uint8_t r_factor;
285 	uint8_t ext_r_factor;
286 	uint8_t mos_lq;
287 	uint8_t mos_cq;
288 	uint8_t rx_config;
289 	uint8_t reserved2;
290 	uint16_t jb_nominal;
291 	uint16_t jb_maximum;
292 	uint16_t jb_abs_max;
293 } rtcp_xr_voip_metrics_report_block_t;
294 
295 #define MIN_RTCP_XR_PACKET_SIZE (sizeof(rtcp_xr_header_t) + 4)
296 
297 /* RTCP FB packet */
298 typedef enum {
299 	RTCP_RTPFB_NACK = 1,
300 	RTCP_RTPFB_TMMBR = 3,
301 	RTCP_RTPFB_TMMBN = 4
302 } rtcp_rtpfb_type_t;
303 
304 typedef enum {
305 	RTCP_PSFB_PLI = 1,
306 	RTCP_PSFB_SLI = 2,
307 	RTCP_PSFB_RPSI = 3,
308 	RTCP_PSFB_FIR = 4,
309 	RTCP_PSFB_AFB = 15
310 } rtcp_psfb_type_t;
311 
312 typedef struct rtcp_fb_header {
313 	uint32_t packet_sender_ssrc;
314 	uint32_t media_source_ssrc;
315 } rtcp_fb_header_t;
316 
317 typedef struct rtcp_fb_generic_nack_fci {
318 	uint16_t pid;
319 	uint16_t blp;
320 } rtcp_fb_generic_nack_fci_t;
321 
322 #define rtcp_fb_generic_nack_fci_get_pid(nack) ntohs((nack)->pid)
323 #define rtcp_fb_generic_nack_fci_set_pid(nack, value) ((nack)->pid) = htons(value)
324 #define rtcp_fb_generic_nack_fci_get_blp(nack) ntohs((nack)->blp)
325 #define rtcp_fb_generic_nack_fci_set_blp(nack, value) ((nack)->blp) = htons(value)
326 
327 typedef struct rtcp_fb_tmmbr_fci {
328 	uint32_t ssrc;
329 	uint32_t value;
330 } rtcp_fb_tmmbr_fci_t;
331 
332 #define rtcp_fb_tmmbr_fci_get_ssrc(tmmbr) ntohl((tmmbr)->ssrc)
333 #define rtcp_fb_tmmbr_fci_get_mxtbr_exp(tmmbr) \
334 	((uint8_t)((ntohl((tmmbr)->value) >> 26) & 0x0000003F))
335 #define rtcp_fb_tmmbr_fci_set_mxtbr_exp(tmmbr, mxtbr_exp) \
336 	((tmmbr)->value) = htonl((ntohl((tmmbr)->value) & 0x03FFFFFF) | (((mxtbr_exp) & 0x0000003F) << 26))
337 #define rtcp_fb_tmmbr_fci_get_mxtbr_mantissa(tmmbr) \
338 	((uint32_t)((ntohl((tmmbr)->value) >> 9) & 0x0001FFFF))
339 #define rtcp_fb_tmmbr_fci_set_mxtbr_mantissa(tmmbr, mxtbr_mantissa) \
340 	((tmmbr)->value) = htonl((ntohl((tmmbr)->value) & 0xFC0001FF) | (((mxtbr_mantissa) & 0x0001FFFF) << 9))
341 #define rtcp_fb_tmmbr_fci_get_measured_overhead(tmmbr) \
342 	((uint16_t)(ntohl((tmmbr)->value) & 0x000001FF))
343 #define rtcp_fb_tmmbr_fci_set_measured_overhead(tmmbr, measured_overhead) \
344 	((tmmbr)->value) = htonl((ntohl((tmmbr)->value) & 0xFFFFFE00) | ((measured_overhead) & 0x000001FF))
345 
346 typedef struct rtcp_fb_fir_fci {
347 	uint32_t ssrc;
348 	uint8_t seq_nr;
349 	uint8_t pad1;
350 	uint16_t pad2;
351 } rtcp_fb_fir_fci_t;
352 
353 #define rtcp_fb_fir_fci_get_ssrc(fci) ntohl((fci)->ssrc)
354 #define rtcp_fb_fir_fci_get_seq_nr(fci) (fci)->seq_nr
355 
356 typedef struct rtcp_fb_sli_fci {
357 	uint32_t value;
358 } rtcp_fb_sli_fci_t;
359 
360 #define rtcp_fb_sli_fci_get_first(fci) \
361 	((uint16_t)((ntohl((fci)->value) >> 19) & 0x00001FFF))
362 #define rtcp_fb_sli_fci_set_first(fci, first) \
363 	((fci)->value) = htonl((ntohl((fci)->value) & 0x0007FFFF) | (((first) & 0x00001FFF) << 19))
364 #define rtcp_fb_sli_fci_get_number(fci) \
365 	((uint16_t)((ntohl((fci)->value) >> 6) & 0x00001FFF))
366 #define rtcp_fb_sli_fci_set_number(fci, number) \
367 	((fci)->value) = htonl((ntohl((fci)->value) & 0xFFF8003F) | (((number) & 0x00001FFF) << 6))
368 #define rtcp_fb_sli_fci_get_picture_id(fci) \
369 	((uint8_t)(ntohl((fci)->value) & 0x0000003F))
370 #define rtcp_fb_sli_fci_set_picture_id(fci, picture_id) \
371 	((fci)->value) = htonl((ntohl((fci)->value) & 0xFFFFFFC0) | ((picture_id) & 0x0000003F))
372 
373 typedef struct rtcp_fb_rpsi_fci {
374 	uint8_t pb;
375 	uint8_t payload_type;
376 	uint16_t bit_string[1];
377 } rtcp_fb_rpsi_fci_t;
378 
379 #define rtcp_fb_rpsi_fci_get_payload_type(fci) (fci)->payload_type
380 #define rtcp_fb_rpsi_fci_get_bit_string(fci) ((uint8_t *)(fci)->bit_string)
381 
382 #define MIN_RTCP_PSFB_PACKET_SIZE (sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t))
383 #define MIN_RTCP_RTPFB_PACKET_SIZE (sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t))
384 
385 /* RTCP structs */
386 
387 typedef struct rtcp_sr{
388 	rtcp_common_header_t ch;
389 	uint32_t ssrc;
390 	sender_info_t si;
391 	report_block_t rb[1];
392 } rtcp_sr_t;
393 
394 typedef struct rtcp_rr{
395 	rtcp_common_header_t ch;
396 	uint32_t ssrc;
397 	report_block_t rb[1];
398 } rtcp_rr_t;
399 
400 typedef struct rtcp_app{
401 	rtcp_common_header_t ch;
402 	uint32_t ssrc;
403 	char name[4];
404 } rtcp_app_t;
405 
406 struct _RtpSession;
407 struct _RtpStream;
408 ORTP_PUBLIC void rtp_session_rtcp_process_send(struct _RtpSession *s);
409 ORTP_PUBLIC void rtp_session_rtcp_process_recv(struct _RtpSession *s);
410 
411 
412 #define RTCP_DEFAULT_REPORT_INTERVAL 5000 /* in milliseconds */
413 
414 
415 /* packet parsing api */
416 
417 /*in case of coumpound packet, set read pointer of m to the beginning of the next RTCP
418 packet */
419 ORTP_PUBLIC bool_t rtcp_next_packet(mblk_t *m);
420 /* put the read pointer at the first RTCP packet of the compound packet (as before any previous calls ot rtcp_next_packet() */
421 ORTP_PUBLIC void rtcp_rewind(mblk_t *m);
422 /* get common header*/
423 ORTP_PUBLIC const rtcp_common_header_t * rtcp_get_common_header(const mblk_t *m);
424 
425 /*Sender Report accessors */
426 /* check if this packet is a SR and if it is correct */
427 ORTP_PUBLIC bool_t rtcp_is_SR(const mblk_t *m);
428 ORTP_PUBLIC uint32_t rtcp_SR_get_ssrc(const mblk_t *m);
429 ORTP_PUBLIC const sender_info_t * rtcp_SR_get_sender_info(const mblk_t *m);
430 ORTP_PUBLIC const report_block_t * rtcp_SR_get_report_block(const mblk_t *m, int idx);
431 
432 /*Receiver report accessors*/
433 ORTP_PUBLIC bool_t rtcp_is_RR(const mblk_t *m);
434 ORTP_PUBLIC uint32_t rtcp_RR_get_ssrc(const mblk_t *m);
435 ORTP_PUBLIC const report_block_t * rtcp_RR_get_report_block(const mblk_t *m,int idx);
436 
437 /*SDES accessors */
438 ORTP_PUBLIC bool_t rtcp_is_SDES(const mblk_t *m);
439 typedef void (*SdesItemFoundCallback)(void *user_data, uint32_t csrc, rtcp_sdes_type_t t, const char *content, uint8_t content_len);
440 ORTP_PUBLIC void rtcp_sdes_parse(const mblk_t *m, SdesItemFoundCallback cb, void *user_data);
441 
442 /*BYE accessors */
443 ORTP_PUBLIC bool_t rtcp_is_BYE(const mblk_t *m);
444 ORTP_PUBLIC bool_t rtcp_BYE_get_ssrc(const mblk_t *m, int idx, uint32_t *ssrc);
445 ORTP_PUBLIC bool_t rtcp_BYE_get_reason(const mblk_t *m, const char **reason, int *reason_len);
446 
447 /*APP accessors */
448 ORTP_PUBLIC bool_t rtcp_is_APP(const mblk_t *m);
449 ORTP_PUBLIC int rtcp_APP_get_subtype(const mblk_t *m);
450 ORTP_PUBLIC uint32_t rtcp_APP_get_ssrc(const mblk_t *m);
451 /* name argument is supposed to be at least 4 characters (note: no '\0' written)*/
452 ORTP_PUBLIC void rtcp_APP_get_name(const mblk_t *m, char *name);
453 /* retrieve the data. when returning, data points directly into the mblk_t */
454 ORTP_PUBLIC void rtcp_APP_get_data(const mblk_t *m, uint8_t **data, int *len);
455 
456 /* RTCP XR accessors */
457 ORTP_PUBLIC bool_t rtcp_is_XR(const mblk_t *m);
458 ORTP_PUBLIC rtcp_xr_block_type_t rtcp_XR_get_block_type(const mblk_t *m);
459 ORTP_PUBLIC uint32_t rtcp_XR_get_ssrc(const mblk_t *m);
460 ORTP_PUBLIC uint64_t rtcp_XR_rcvr_rtt_get_ntp_timestamp(const mblk_t *m);
461 ORTP_PUBLIC uint32_t rtcp_XR_dlrr_get_ssrc(const mblk_t *m);
462 ORTP_PUBLIC uint32_t rtcp_XR_dlrr_get_lrr(const mblk_t *m);
463 ORTP_PUBLIC uint32_t rtcp_XR_dlrr_get_dlrr(const mblk_t *m);
464 ORTP_PUBLIC uint8_t rtcp_XR_stat_summary_get_flags(const mblk_t *m);
465 ORTP_PUBLIC uint32_t rtcp_XR_stat_summary_get_ssrc(const mblk_t *m);
466 ORTP_PUBLIC uint16_t rtcp_XR_stat_summary_get_begin_seq(const mblk_t *m);
467 ORTP_PUBLIC uint16_t rtcp_XR_stat_summary_get_end_seq(const mblk_t *m);
468 ORTP_PUBLIC uint32_t rtcp_XR_stat_summary_get_lost_packets(const mblk_t *m);
469 ORTP_PUBLIC uint32_t rtcp_XR_stat_summary_get_dup_packets(const mblk_t *m);
470 ORTP_PUBLIC uint32_t rtcp_XR_stat_summary_get_min_jitter(const mblk_t *m);
471 ORTP_PUBLIC uint32_t rtcp_XR_stat_summary_get_max_jitter(const mblk_t *m);
472 ORTP_PUBLIC uint32_t rtcp_XR_stat_summary_get_mean_jitter(const mblk_t *m);
473 ORTP_PUBLIC uint32_t rtcp_XR_stat_summary_get_dev_jitter(const mblk_t *m);
474 ORTP_PUBLIC uint8_t rtcp_XR_stat_summary_get_min_ttl_or_hl(const mblk_t *m);
475 ORTP_PUBLIC uint8_t rtcp_XR_stat_summary_get_max_ttl_or_hl(const mblk_t *m);
476 ORTP_PUBLIC uint8_t rtcp_XR_stat_summary_get_mean_ttl_or_hl(const mblk_t *m);
477 ORTP_PUBLIC uint8_t rtcp_XR_stat_summary_get_dev_ttl_or_hl(const mblk_t *m);
478 ORTP_PUBLIC uint32_t rtcp_XR_voip_metrics_get_ssrc(const mblk_t *m);
479 ORTP_PUBLIC uint8_t rtcp_XR_voip_metrics_get_loss_rate(const mblk_t *m);
480 ORTP_PUBLIC uint8_t rtcp_XR_voip_metrics_get_discard_rate(const mblk_t *m);
481 ORTP_PUBLIC uint8_t rtcp_XR_voip_metrics_get_burst_density(const mblk_t *m);
482 ORTP_PUBLIC uint8_t rtcp_XR_voip_metrics_get_gap_density(const mblk_t *m);
483 ORTP_PUBLIC uint16_t rtcp_XR_voip_metrics_get_burst_duration(const mblk_t *m);
484 ORTP_PUBLIC uint16_t rtcp_XR_voip_metrics_get_gap_duration(const mblk_t *m);
485 ORTP_PUBLIC uint16_t rtcp_XR_voip_metrics_get_round_trip_delay(const mblk_t *m);
486 ORTP_PUBLIC uint16_t rtcp_XR_voip_metrics_get_end_system_delay(const mblk_t *m);
487 ORTP_PUBLIC uint8_t rtcp_XR_voip_metrics_get_signal_level(const mblk_t *m);
488 ORTP_PUBLIC uint8_t rtcp_XR_voip_metrics_get_noise_level(const mblk_t *m);
489 ORTP_PUBLIC uint8_t rtcp_XR_voip_metrics_get_rerl(const mblk_t *m);
490 ORTP_PUBLIC uint8_t rtcp_XR_voip_metrics_get_gmin(const mblk_t *m);
491 ORTP_PUBLIC uint8_t rtcp_XR_voip_metrics_get_r_factor(const mblk_t *m);
492 ORTP_PUBLIC uint8_t rtcp_XR_voip_metrics_get_ext_r_factor(const mblk_t *m);
493 ORTP_PUBLIC uint8_t rtcp_XR_voip_metrics_get_mos_lq(const mblk_t *m);
494 ORTP_PUBLIC uint8_t rtcp_XR_voip_metrics_get_mos_cq(const mblk_t *m);
495 ORTP_PUBLIC uint8_t rtcp_XR_voip_metrics_get_rx_config(const mblk_t *m);
496 ORTP_PUBLIC uint16_t rtcp_XR_voip_metrics_get_jb_nominal(const mblk_t *m);
497 ORTP_PUBLIC uint16_t rtcp_XR_voip_metrics_get_jb_maximum(const mblk_t *m);
498 ORTP_PUBLIC uint16_t rtcp_XR_voip_metrics_get_jb_abs_max(const mblk_t *m);
499 
500 /* RTCP RTPFB accessors */
501 ORTP_PUBLIC bool_t rtcp_is_RTPFB(const mblk_t *m);
502 ORTP_PUBLIC rtcp_rtpfb_type_t rtcp_RTPFB_get_type(const mblk_t *m);
503 ORTP_PUBLIC rtcp_fb_generic_nack_fci_t * rtcp_RTPFB_generic_nack_get_fci(const mblk_t *m);
504 ORTP_PUBLIC rtcp_fb_tmmbr_fci_t * rtcp_RTPFB_tmmbr_get_fci(const mblk_t *m);
505 /**
506  * Return the maximum bitrate in bits / sec contained in the packet.
507  *
508  * @param m RTCP TMMBR packet to read
509  * @return maximum bitrate in bits / sec.
510  */
511 ORTP_PUBLIC uint64_t rtcp_RTPFB_tmmbr_get_max_bitrate(const mblk_t *m);
512 ORTP_PUBLIC uint32_t rtcp_RTPFB_get_packet_sender_ssrc(const mblk_t *m);
513 ORTP_PUBLIC uint32_t rtcp_RTPFB_get_media_source_ssrc(const mblk_t *m);
514 
515 /* RTCP PSFB accessors */
516 ORTP_PUBLIC bool_t rtcp_is_PSFB(const mblk_t *m);
517 ORTP_PUBLIC rtcp_psfb_type_t rtcp_PSFB_get_type(const mblk_t *m);
518 ORTP_PUBLIC uint32_t rtcp_PSFB_get_packet_sender_ssrc(const mblk_t *m);
519 ORTP_PUBLIC uint32_t rtcp_PSFB_get_media_source_ssrc(const mblk_t *m);
520 ORTP_PUBLIC rtcp_fb_fir_fci_t * rtcp_PSFB_fir_get_fci(const mblk_t *m, unsigned int idx);
521 ORTP_PUBLIC rtcp_fb_sli_fci_t * rtcp_PSFB_sli_get_fci(const mblk_t *m, unsigned int idx);
522 ORTP_PUBLIC rtcp_fb_rpsi_fci_t * rtcp_PSFB_rpsi_get_fci(const mblk_t *m);
523 ORTP_PUBLIC uint16_t rtcp_PSFB_rpsi_get_fci_bit_string_len(const mblk_t *m);
524 
525 
526 typedef struct OrtpLossRateEstimator{
527 	int min_packet_count_interval;
528 	uint64_t min_time_ms_interval;
529 	uint64_t last_estimate_time_ms;
530 	int32_t last_cum_loss;
531 	int32_t last_ext_seq;
532 	float loss_rate;
533 	/**
534 	* Total number of outgoing duplicate packets on last
535 	* ortp_loss_rate_estimator_process_report_block iteration.
536 	**/
537 	int64_t last_dup_packet_sent_count;
538 	/**
539 	* Total number of outgoing unique packets on last
540 	* ortp_loss_rate_estimator_process_report_block iteration.
541 	**/
542 	int64_t last_packet_sent_count;
543 }OrtpLossRateEstimator;
544 
545 
546 ORTP_PUBLIC OrtpLossRateEstimator * ortp_loss_rate_estimator_new(int min_packet_count_interval, uint64_t min_time_ms_interval, struct _RtpSession *session);
547 
548 ORTP_PUBLIC void ortp_loss_rate_estimator_init(OrtpLossRateEstimator *obj, int min_packet_count_interval, uint64_t min_time_ms_interval, struct _RtpSession *session);
549 
550 
551 /**
552  * Process an incoming report block to compute loss rate percentage. It tries to compute
553  * loss rate, depending on the previous report block. It may fails if the two
554  * reports are too close or if a discontinuity occurred. You should NOT use
555  * loss rate field of the report block directly (see below).
556  * This estimator is useful for two reasons: first, on AVPF session, multiple
557  * reports can be received in a short period and loss_rate contained in these
558  * reports is unreliable. Secondly, it computes the loss rate using the
559  * cumulative loss factor which allows us to take into consideration duplicates
560  * packets as well.
561  * @param[in] obj #OrtpLossRateEstimator object.
562  * @param[in] session #_RtpSession stream in which the report block to consider belongs.
563  * @param[in] rb Report block to analyze.
564  * @return TRUE if a new loss rate estimation is ready, FALSE otherwise.
565  */
566 ORTP_PUBLIC bool_t ortp_loss_rate_estimator_process_report_block(OrtpLossRateEstimator *obj,
567 																 const struct _RtpSession *session,
568 																 const report_block_t *rb);
569 /**
570  * Get the latest loss rate in percentage estimation computed.
571  *
572  * @param obj #OrtpLossRateEstimator object.
573  * @return The latest loss rate in percentage computed.
574  */
575 ORTP_PUBLIC float ortp_loss_rate_estimator_get_value(OrtpLossRateEstimator *obj);
576 
577 ORTP_PUBLIC void ortp_loss_rate_estimator_destroy(OrtpLossRateEstimator *obj);
578 
579 #ifdef __cplusplus
580 }
581 #endif
582 
583 #endif
584