1 // Copyright (C) 2001-2015 Federico Montesino Pouzols <fedemp@altern.org>. 2 // 3 // This program is free software; you can redistribute it and/or modify 4 // it under the terms of the GNU General Public License as published by 5 // the Free Software Foundation; either version 2 of the License, or 6 // (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU General Public License for more details. 12 // 13 // You should have received a copy of the GNU Lesser General Public License 14 // along with GNU ccRTP. If not, see <http://www.gnu.org/licenses/>. 15 // 16 // As a special exception, you may use this file as part of a free software 17 // library without restriction. Specifically, if other files instantiate 18 // templates or use macros or inline functions from this file, or you compile 19 // this file and link it with other files to produce an executable, this 20 // file does not by itself cause the resulting executable to be covered by 21 // the GNU General Public License. This exception does not however 22 // invalidate any other reasons why the executable file might be covered by 23 // the GNU General Public License. 24 // 25 // This exception applies only to the code released under the name GNU 26 // ccRTP. If you copy code from other releases into a copy of GNU 27 // ccRTP, as the General Public License permits, the exception does 28 // not apply to the code that you add in this way. To avoid misleading 29 // anyone as to the status of such modified files, you must delete 30 // this exception notice from them. 31 // 32 // If you write modifications of your own for GNU ccRTP, it is your choice 33 // whether to permit this exception to apply to your modifications. 34 // If you do not wish that, delete this exception notice. 35 // 36 37 #ifndef CCXX_RTP_RTCPPKT_H_ 38 #define CCXX_RTP_RTCPPKT_H_ 39 40 #include <ccrtp/base.h> 41 42 NAMESPACE_COMMONCPP 43 44 /** 45 * @file rtcppkt.h 46 * 47 * @short RTCP packets handling. 48 **/ 49 50 /** 51 * @defgroup rtcppacket RTCP compound packets manipulation. 52 * @{ 53 **/ 54 55 /** 56 * @enum SDESItemType 57 * @short SDES items that may be carried in a Source DEScription RTCP packet. 58 * 59 * CNAME is mandatory in each RTCP compound packet (except when 60 * splitted for partial encryption), the others are optional and have 61 * different sending frequencies, though with recommended default 62 * values. 63 **/ 64 typedef enum 65 { 66 SDESItemTypeEND = 0, ///< END of SDES item list. 67 SDESItemTypeCNAME, ///< Canonical end-point identifier. 68 SDESItemTypeNAME, ///< Personal NAME of the user. 69 SDESItemTypeEMAIL, ///< EMAIL address of the user. 70 SDESItemTypePHONE, ///< Phone number of the user. 71 SDESItemTypeLOC, ///< Location where the user is. 72 SDESItemTypeTOOL, ///< Application or tool. 73 SDESItemTypeNOTE, ///< Comment usually reporting state. 74 SDESItemTypePRIV, ///< Private extension. 75 SDESItemTypeH323CADDR, ///< H323 callable address. 76 SDESItemTypeLast = SDESItemTypeH323CADDR ///< Last defined code. 77 } SDESItemType; 78 79 /** 80 * @class RTCPCompoundHandler 81 * @short low level structs and RTCP packet parsing and building 82 * methods. 83 * 84 * Intended to be used, through inheritance, in RTCP management 85 * classes, such as QueueRTCPManager. 86 * 87 * @author Federico Montesino Pouzols <fedemp@altern.org> 88 **/ 89 class __EXPORT RTCPCompoundHandler 90 { 91 public: setPathMTU(uint16 mtu)92 inline void setPathMTU(uint16 mtu) 93 { pathMTU = mtu; } 94 getPathMTU()95 inline uint16 getPathMTU() 96 { return pathMTU; } 97 98 #ifdef CCXX_PACKED 99 #pragma pack(1) 100 #endif 101 /** 102 * @struct ReceiverInfo 103 * 104 * Struct for the data contained in a receiver info 105 * block. Receiver info blocks can be found in SR (sender 106 * report) or RR (receiver report) RTCP packets. 107 **/ 108 struct ReceiverInfo 109 { 110 uint8 fractionLost; ///< packet fraction lost. 111 uint8 lostMSB; ///< cumulative lost MSB of 3 octets. 112 uint16 lostLSW; ///< cumulative lost two LSB. 113 uint32 highestSeqNum; ///< highest sequence number. 114 uint32 jitter; ///< arrival jitter. 115 uint32 lsr; ///< last sender report timestamp. 116 uint32 dlsr; ///< delay since last sender report. 117 }; 118 119 /** 120 * @struct RRBlock 121 * 122 * Struct for a receiver info block in a SR (sender report) or an RR 123 * (receiver report) RTCP packet. 124 **/ 125 struct RRBlock 126 { 127 uint32 ssrc; ///< source identifier. 128 ReceiverInfo rinfo; ///< info about the source. 129 }; 130 131 /** 132 * @struct RecvReport 133 * 134 * @short raw structure of the source and every receiver report in an 135 * SR or RR RTCP packet. 136 **/ 137 struct RecvReport 138 { 139 uint32 ssrc; ///< source identifier. 140 RRBlock blocks[1]; ///< receiver report blocks. 141 }; 142 143 /** 144 * @struct SenderInfo 145 * 146 * Struct for the sender info block in a SR (sender report) 147 * RTCP packet. 148 **/ 149 struct SenderInfo 150 { 151 uint32 NTPMSW; ///< NTP timestamp higher octets. 152 uint32 NTPLSW; ///< NTP timestamp lower octets. 153 uint32 RTPTimestamp; ///< RTP timestamp. 154 uint32 packetCount; ///< cumulative packet counter. 155 uint32 octetCount; ///< cumulative octet counter. 156 }; 157 158 /** 159 * @struct SendReport 160 * 161 * Struct for SR (sender report) RTCP packets. 162 **/ 163 struct SendReport 164 { 165 uint32 ssrc; ///< source identifier. 166 SenderInfo sinfo; ///< actual sender info. 167 RRBlock blocks[1]; ///< possibly several receiver info blocks. 168 }; 169 170 /** 171 * @struct SDESItem 172 * 173 * Struct for an item description of a SDES packet. 174 **/ 175 struct SDESItem 176 { 177 uint8 type; ///< item identifier. 178 uint8 len; ///< item len in octets. 179 char data[1]; ///< item content. 180 }; 181 182 /** 183 * @struct SDESChunk 184 * 185 * Struct for a chunk of items in a SDES RTCP packet. 186 **/ 187 struct SDESChunk 188 { getSSRCSDESChunk189 uint32 getSSRC() const 190 { return (ntohl(ssrc)); } 191 192 uint32 ssrc; ///< SSRC identifer from sender. 193 SDESItem item; ///< SDES item from sender. 194 }; 195 196 /** 197 * @struct BYEPacket 198 * 199 * @short Struct for BYE (leaving session) RTCP packets. 200 **/ 201 struct BYEPacket 202 { 203 uint32 ssrc; ///< ssrc identifier of source leaving. 204 uint8 length; ///< [optional] length of reason. 205 }; 206 207 /** 208 * @struct APPPacket 209 * 210 * @short Struct for APP (application specific) RTCP packets. 211 **/ 212 struct APPPacket 213 { 214 uint32 ssrc; ///< ssrc identifier of source. 215 char name [4]; ///< Name of the APP packet, 216 ///interpreted as a sequence of 217 ///four characters. 218 unsigned char data[1]; ///< application dependent data. 219 }; 220 221 /** 222 * @struct FIRPacket 223 * 224 * @short Struct for Full Intra-frame Request (FIR) RTCP 225 * packet. Specific for H.261 sessions (see RFC 2032). 226 **/ 227 struct FIRPacket 228 { 229 uint32 ssrc; ///< ssrc identifier of source. 230 }; 231 232 /** 233 * @struct NACKPacket 234 * 235 * @short Struct for Negative ACKnowledgements (NACK) RTCP 236 * packet. Specific for H.261 sessions (see RFC 2032). 237 **/ 238 struct NACKPacket 239 { 240 uint32 ssrc; ///< ssrc identifier of source. 241 uint16 fsn; ///< First Sequence Number lost. 242 uint16 blp; ///< Bitmask of following Lost Packets. 243 }; 244 245 /** 246 * @struct RTCPFixedHeader 247 * Fixed RTCP packet header. First 32-bit word in any RTCP 248 * packet. 249 */ 250 struct RTCPFixedHeader 251 { 252 #if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN 253 ///< For big endian boxes 254 unsigned char version:2; ///< Version, currently 2. 255 unsigned char padding:1; ///< Padding bit. 256 unsigned char block_count:5; ///< Number of RR, SR, or SDES chunks. 257 #else 258 ///< For little endian boxes 259 unsigned char block_count:5; ///< Number of RR, SR, or SDES chunks. 260 unsigned char padding:1; ///< Padding bit. 261 unsigned char version:2; ///< Version, currently 2. 262 #endif 263 uint8 type; ///< type of RTCP packet. 264 uint16 length; ///< number of 32-bit words in the packet (*minus one*). 265 }; 266 267 /** 268 * @struct RTCPPacket 269 * 270 * @short Struct representing general RTCP packet headers as they are 271 * sent through the network. 272 * 273 * This struct consists of a fixed header, always at the 274 * beginning of any RTCP packet, and a union for all the RTCP 275 * packet types supported. 276 **/ 277 struct RTCPPacket 278 { 279 /** 280 * @enum Type rtp.h cc++/rtp.h 281 * 282 * RTCP packet types. They are registered with IANA. 283 */ 284 typedef enum { 285 tSR = 200, ///< Sender Report. 286 tRR, ///< Receiver Report. 287 tSDES, ///< Source DEScription. 288 tBYE, ///< End of participation. 289 tAPP, ///< APPlication specific. 290 tFIR = 192, ///< Full Intra-frame request. 291 tNACK = 193, ///< Negative ACK. 292 tXR ///< Extended Report. 293 } Type; 294 295 /** 296 * Get the packet length specified in its header, in 297 * octets and in host order. 298 **/ getLengthRTCPPacket299 uint32 getLength() const 300 { return ((ntohs(fh.length) + 1) << 2); } 301 302 /** 303 * Get the SSRC identifier specified in the packet 304 * header, in host order. 305 **/ getSSRCRTCPPacket306 uint32 getSSRC() const 307 { return (ntohl(info.RR.ssrc)); } // SSRC is always the first 308 // word after fh. 309 310 RTCPFixedHeader fh; ///< Fixed RTCP header. 311 312 // An RTCP packet may be of any of the types defined 313 // above, including APP specific ones. 314 union 315 { 316 SendReport SR; 317 RecvReport RR; 318 SDESChunk SDES; 319 BYEPacket BYE; 320 APPPacket APP; 321 NACKPacket NACK; 322 FIRPacket FIR; 323 } info; ///< Union for SR, RR, SDES, BYE and APP 324 }; 325 #ifdef CCXX_PACKED 326 #pragma pack() 327 #endif 328 329 protected: 330 enum { defaultPathMTU = 1500 }; 331 332 RTCPCompoundHandler(uint16 mtu = defaultPathMTU); 333 334 ~RTCPCompoundHandler(); 335 336 /** 337 * Perform RTCP compound packet header validity check as 338 * specified in draft-ietv-avt-rtp-new. This method follows 339 * appendix A.2. Correct version, payload type, padding bit 340 * and length of every RTCP packet in the compound are 341 * verified. 342 * 343 * @param len length of the RTCP compound packet in 344 * the reception buffer 345 * @return whether the header is valid. 346 */ 347 bool 348 checkCompoundRTCPHeader(size_t len); 349 350 // buffer to hold RTCP compound packets being sent. Allocated 351 // in construction time 352 unsigned char* rtcpSendBuffer; 353 // buffer to hold RTCP compound packets being 354 // received. Allocated at construction time 355 unsigned char* rtcpRecvBuffer; 356 357 friend class RTCPSenderInfo; 358 friend class RTCPReceiverInfo; 359 private: 360 // path MTU. RTCP packets should not be greater than this 361 uint16 pathMTU; 362 // masks for RTCP header validation; 363 static const uint16 RTCP_VALID_MASK; 364 static const uint16 RTCP_VALID_VALUE; 365 }; 366 367 /** 368 * @class RTCPReceiverInfo 369 * @short Report block information of SR/RR RTCP reports. 370 * 371 * @author Federico Montesino Pouzols <fedemp@altern.org> 372 **/ 373 class __EXPORT RTCPReceiverInfo 374 { 375 public: RTCPReceiverInfo(void * ri)376 RTCPReceiverInfo(void* ri) 377 { memcpy(&receiverInfo,&ri, 378 sizeof(RTCPCompoundHandler::ReceiverInfo));} 379 RTCPReceiverInfo(RTCPCompoundHandler::ReceiverInfo & si)380 RTCPReceiverInfo(RTCPCompoundHandler::ReceiverInfo& si) 381 : receiverInfo( si ) 382 { 383 } 384 ~RTCPReceiverInfo()385 ~RTCPReceiverInfo() 386 { } 387 388 /** 389 * Get fraction of lost packets, as a number between 0 and 390 * 255. 391 **/ 392 inline uint8 getFractionLost()393 getFractionLost() const 394 { return receiverInfo.fractionLost; } 395 396 inline uint32 getCumulativePacketLost()397 getCumulativePacketLost() const 398 { return ( ((uint32)ntohs(receiverInfo.lostLSW)) + 399 (((uint32)receiverInfo.lostMSB) << 16) ); } 400 401 inline uint32 getExtendedSeqNum()402 getExtendedSeqNum() const 403 { return ntohl(receiverInfo.highestSeqNum); } 404 405 /** 406 * Get the statistical variance of the RTP data packets 407 * interarrival time. 408 * 409 * @return Interarrival jitter, in timestamp units. 410 **/ 411 uint32 getJitter()412 getJitter() const 413 { return ntohl(receiverInfo.jitter); } 414 415 /** 416 * Get the integer part of the NTP timestamp of the last SR 417 * RTCP packet received from the source this receiver report 418 * refers to. 419 **/ 420 uint16 getLastSRNTPTimestampInt()421 getLastSRNTPTimestampInt() const 422 { return (uint16)((ntohl(receiverInfo.lsr) & 0xFFFF0000) >> 16); } 423 424 /** 425 * Get the fractional part of the NTP timestamp of the last SR 426 * RTCP packet received from the source this receiver report 427 * refers to. 428 **/ 429 uint16 getLastSRNTPTimestampFrac()430 getLastSRNTPTimestampFrac() const 431 { return (uint16)(ntohl(receiverInfo.lsr) & 0xFFFF); } 432 433 /** 434 * Get the delay between the last SR packet received and the 435 * transmission of this report. 436 * 437 * @return Delay, in units of 1/65536 seconds 438 **/ 439 uint32 getDelayLastSR()440 getDelayLastSR() const 441 { return ntohl(receiverInfo.dlsr); } 442 443 private: 444 RTCPCompoundHandler::ReceiverInfo receiverInfo; 445 }; 446 447 /** 448 * @class RTCPSenderInfo 449 * @short Sender block information of SR RTCP reports. 450 * 451 * @author Federico Montesino Pouzols <fedemp@altern.org> 452 **/ 453 class __EXPORT RTCPSenderInfo 454 { 455 public: RTCPSenderInfo(void * si)456 RTCPSenderInfo(void* si) 457 { memcpy(&senderInfo,&si, 458 sizeof(RTCPCompoundHandler::SenderInfo));} 459 RTCPSenderInfo(RTCPCompoundHandler::SenderInfo & si)460 RTCPSenderInfo(RTCPCompoundHandler::SenderInfo& si) 461 : senderInfo( si ) 462 { 463 } 464 ~RTCPSenderInfo()465 ~RTCPSenderInfo() 466 { } 467 468 /** 469 * Get integer part of the NTP timestamp of this packet. 470 * @see NTP2Timeval 471 **/ 472 uint32 getNTPTimestampInt()473 getNTPTimestampInt() const 474 { return ntohl(senderInfo.NTPMSW); } 475 476 /** 477 * Get fractional part of the NTP timestamp of this packet. 478 * @see NTP2Timeval 479 **/ 480 uint32 getNTPTimestampFrac()481 getNTPTimestampFrac() const 482 { return ntohl(senderInfo.NTPLSW); } 483 484 inline uint32 getRTPTimestamp()485 getRTPTimestamp() const 486 { return ntohl(senderInfo.RTPTimestamp); } 487 488 /** 489 * Get count of sent data packets. 490 **/ 491 inline uint32 getPacketCount()492 getPacketCount() const 493 { return ntohl(senderInfo.packetCount); } 494 495 inline uint32 getOctetCount()496 getOctetCount() const 497 { return ntohl(senderInfo.octetCount); } 498 499 private: 500 RTCPCompoundHandler::SenderInfo senderInfo; 501 }; 502 503 /** 504 * Convert a NTP timestamp, expressed as two 32-bit long words, into a 505 * timeval value. 506 * 507 * @param msw Integer part of NTP timestamp. 508 * @param lsw Fractional part of NTP timestamp. 509 * @return timeval value corresponding to the given NTP timestamp. 510 **/ 511 timeval 512 NTP2Timeval(uint32 msw, uint32 lsw); 513 514 /** 515 * Convert a time interval, expressed as a timeval, into a 32-bit time 516 * interval expressed in units of 1/65536 seconds. 517 * 518 * @param t Timeval interval. 519 * @return 32-bit value corresponding to the given timeval interval. 520 **/ 521 uint32 522 timevalIntervalTo65536(timeval& t); 523 524 /** @}*/ // rtcppacket 525 526 END_NAMESPACE 527 528 #endif // ndef CCXX_RTP_RTCPPKT_H_ 529 530 /** EMACS ** 531 * Local variables: 532 * mode: c++ 533 * c-basic-offset: 8 534 * End: 535 */ 536 537