1 /** 2 * yatertp.h 3 * Yet Another RTP Stack 4 * This file is part of the YATE Project http://YATE.null.ro 5 * 6 * Yet Another Telephony Engine - a fully featured software PBX and IVR 7 * Copyright (C) 2004-2014 Null Team 8 * 9 * This software is distributed under multiple licenses; 10 * see the COPYING file in the main directory for licensing 11 * information for this specific distribution. 12 * 13 * This use of this software may be subject to additional restrictions. 14 * See the LEGAL file in the main directory for details. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 */ 20 21 #ifndef __YATERTP_H 22 #define __YATERTP_H 23 24 #include <yateclass.h> 25 26 #ifdef _WINDOWS 27 28 #ifdef LIBYRTP_EXPORTS 29 #define YRTP_API __declspec(dllexport) 30 #else 31 #ifndef LIBYRTP_STATIC 32 #define YRTP_API __declspec(dllimport) 33 #endif 34 #endif 35 36 #endif /* _WINDOWS */ 37 38 #ifndef YRTP_API 39 #define YRTP_API 40 #endif 41 42 /** 43 * Holds all Telephony Engine related classes. 44 */ 45 namespace TelEngine { 46 47 class RTPGroup; 48 class RTPTransport; 49 class RTPSession; 50 class RTPSender; 51 class RTPReceiver; 52 class RTPSecure; 53 54 /** 55 * Object holding RTP debug 56 * @short RTP debug holder 57 */ 58 class YRTP_API RTPDebug 59 { 60 public: 61 /** 62 * Constructor 63 * @param dbg DebugEnabler 64 * @param traceId Trace ID 65 */ RTPDebug(DebugEnabler * dbg,const char * traceId)66 inline RTPDebug(DebugEnabler* dbg, const char* traceId) 67 : m_dbg(dbg), m_traceId(traceId) 68 {} 69 70 /** 71 * Constructor from RTP session 72 * @param session RTP session to take debug from 73 */ 74 RTPDebug(RTPSession* session); 75 76 /** 77 * Retrieve DebugEnabler 78 * @return DebugEnabler pointer 79 */ dbg()80 inline DebugEnabler* dbg() const 81 { return m_dbg; } 82 83 /** 84 * Retrieve trace ID 85 * @return Trace ID 86 */ dbgTraceId()87 inline const String& dbgTraceId() const 88 { return m_traceId; } 89 90 protected: 91 /** 92 * Setup debug data 93 * @param dbg DebugEnabler 94 * @param traceId Trace ID 95 */ setDebug(DebugEnabler * dbg,const char * traceId)96 inline void setDebug(DebugEnabler* dbg, const char* traceId) { 97 m_dbg = dbg; 98 if (!m_traceId) 99 m_traceId = traceId; 100 } 101 102 DebugEnabler* m_dbg; 103 String m_traceId; 104 }; 105 106 /** 107 * A base class that contains just placeholders to process raw RTP and RTCP packets. 108 * @short Base class to ease creation of RTP forwarders 109 */ 110 class YRTP_API RTPProcessor : public GenObject, public RTPDebug 111 { 112 friend class UDPSession; 113 friend class UDPTLSession; 114 friend class RTPGroup; 115 friend class RTPTransport; 116 friend class RTPSender; 117 friend class RTPReceiver; 118 119 public: 120 /** 121 * Constructor - processor should be later inserted in a RTP group 122 * @param dbg Processor DebugEnabler 123 * @param traceId Processor trace ID 124 */ 125 RTPProcessor(DebugEnabler* dbg = 0, const char* traceId = 0); 126 127 /** 128 * Destructor - removes itself from the RTP group 129 */ 130 virtual ~RTPProcessor(); 131 132 /** 133 * Get the RTP group to which this processor belongs 134 * @return Pointer to the RTP group this processor has joined 135 */ group()136 inline RTPGroup* group() const 137 { return m_group; } 138 139 /** 140 * This method is called to send or process a RTP packet 141 * @param data Pointer to raw RTP data 142 * @param len Length of the data packet 143 */ 144 virtual void rtpData(const void* data, int len); 145 146 /** 147 * This method is called to send or process a RTCP packet 148 * @param data Pointer to raw RTCP data 149 * @param len Length of the data packet 150 */ 151 virtual void rtcpData(const void* data, int len); 152 153 /** 154 * Retrieve MGCP P: style comma separated session parameters 155 * @param stats String to append parameters to 156 */ 157 virtual void getStats(String& stats) const; 158 159 /** 160 * Increase the counter for number of RTP packets received from a wrong source 161 */ incWrongSrc()162 virtual inline void incWrongSrc() 163 { } 164 165 /** 166 * Get the number of RTP packets that were received from a wrong source 167 * @return Number of RTP packets received from a wrong source 168 */ wrongSrc()169 inline unsigned int wrongSrc() 170 { return m_wrongSrc; } 171 172 protected: 173 /** 174 * Set a new RTP group for this processor 175 * @param newgrp New group to join this processor, the old one will be left 176 */ 177 void group(RTPGroup* newgrp); 178 179 /** 180 * Method called periodically to keep the data flowing 181 * @param when Time to use as base in all computing 182 */ 183 virtual void timerTick(const Time& when) = 0; 184 185 unsigned int m_wrongSrc; 186 187 private: 188 RTPGroup* m_group; 189 }; 190 191 /** 192 * Several possibly related RTP processors share the same RTP group which 193 * holds the thread that keeps them running. 194 * @short A group of RTP processors handled by the same thread 195 */ 196 class YRTP_API RTPGroup : public GenObject, public Mutex, public Thread 197 { 198 friend class RTPProcessor; 199 200 public: 201 /** 202 * Constructor 203 * @param msec Minimum time to sleep in loop in milliseconds 204 * @param prio Thread priority to run this group 205 * @param affinity Comma-separated list of CPUs and/or CPU range on which the thread should run on 206 */ 207 RTPGroup(int msec = 0, Priority prio = Normal, const String& affinity = String::empty()); 208 209 /** 210 * Group destructor, removes itself from all remaining processors 211 */ 212 virtual ~RTPGroup(); 213 214 /** 215 * Inherited thread cleanup 216 */ 217 virtual void cleanup(); 218 219 /** 220 * Inherited thread run method 221 */ 222 virtual void run(); 223 224 /** 225 * Set the system global minimum time to sleep in loop 226 * @param msec Minimum time to sleep in loop in milliseconds 227 */ 228 static void setMinSleep(int msec); 229 230 /** 231 * Add a RTP processor to this group 232 * @param proc Pointer to the RTP processor to add 233 */ 234 void join(RTPProcessor* proc); 235 236 /** 237 * Remove a RTP processor from this group 238 * @param proc Pointer to the RTP processor to remove 239 */ 240 void part(RTPProcessor* proc); 241 242 private: 243 ObjList m_processors; 244 bool m_listChanged; 245 unsigned long m_sleep; 246 }; 247 248 /** 249 * Class that holds sockets and addresses for transporting RTP and RTCP packets. 250 * @short Low level transport for RTP and RTCP 251 */ 252 class YRTP_API RTPTransport : public RTPProcessor 253 { 254 public: 255 /** 256 * Activation status of the transport 257 */ 258 enum Activation { 259 Inactive, 260 Bound, 261 Active 262 }; 263 264 /** 265 * Type of transported data 266 */ 267 enum Type { 268 Unknown, 269 RTP, 270 UDPTL 271 }; 272 273 /** 274 * Constructor, creates an unconnected transport 275 * @param type Type of check to apply to the data 276 * @param dbg Transport DebugEnabler 277 * @param traceId Transport trace ID 278 */ 279 RTPTransport(Type type = RTP, DebugEnabler* dbg = 0, const char* traceId = 0); 280 281 /** 282 * Destructor 283 */ 284 virtual ~RTPTransport(); 285 286 /** 287 * Destroys the object, disposes the memory. Do not call delete directly. 288 */ 289 virtual void destruct(); 290 291 /** 292 * Set the RTP/RTCP processor of data received by this transport 293 * @param processor A pointer to the RTPProcessor for this transport 294 */ 295 void setProcessor(RTPProcessor* processor = 0); 296 297 /** 298 * Set the RTP/RTCP monitor of data received by this transport 299 * @param monitor A pointer to a second RTPProcessor for this transport 300 */ 301 void setMonitor(RTPProcessor* monitor = 0); 302 303 /** 304 * Get the local network address of the RTP transport 305 * @return Reference to the local RTP transport address 306 */ localAddr()307 inline const SocketAddr& localAddr() const 308 { return m_localAddr; } 309 310 /** 311 * Get the remote network address of the RTP transport 312 * @return Reference to the remote RTP transport address 313 */ remoteAddr()314 inline const SocketAddr& remoteAddr() const 315 { return m_remoteAddr; } 316 317 /** 318 * Set the local network address of the RTP transport 319 * @param addr New local RTP transport address 320 * @param rtcp Enable RTCP transport 321 * @return True if address set, false if a failure occured 322 */ 323 bool localAddr(SocketAddr& addr, bool rtcp = true); 324 325 /** 326 * Set the remote network address of the RTP transport 327 * @param addr New remote RTP transport address 328 * @param sniff Automatically adjust the address from the first incoming packet 329 * @return True if address set, false if a failure occured 330 */ 331 bool remoteAddr(SocketAddr& addr, bool sniff = false); 332 333 /** 334 * Set the size of the operating system's buffers for the RTP and RTCP sockets 335 * @param bufLen Requested length of the buffer 336 * @return True if the buffer length was set 337 */ 338 bool setBuffer(int bufLen = 4096); 339 340 /** 341 * Set the Type Of Service for the RTP socket 342 * @param tos Type Of Service bits to set 343 * @return True if operation was successfull, false if an error occured 344 */ setTOS(int tos)345 inline bool setTOS(int tos) 346 { return m_rtpSock.setTOS(tos); } 347 348 /** 349 * Get the RTP socket used by this transport 350 * @return Pointer to the RTP socket 351 */ rtpSock()352 inline Socket* rtpSock() 353 { return &m_rtpSock; } 354 355 /** 356 * Get the RTCP socket used by this transport 357 * @return Pointer to the RTCP socket 358 */ rtcpSock()359 inline Socket* rtcpSock() 360 { return &m_rtcpSock; } 361 362 /** 363 * Drill a hole in a firewall or NAT for the RTP and RTCP sockets 364 * @return True if at least a packet was sent for the RTP socket 365 */ 366 bool drillHole(); 367 368 protected: 369 /** 370 * Method called periodically to read data out of sockets 371 * @param when Time to use as base in all computing 372 */ 373 virtual void timerTick(const Time& when); 374 375 /** 376 * This method is called to send a RTP packet 377 * @param data Pointer to raw RTP data 378 * @param len Length of the data packet 379 */ 380 virtual void rtpData(const void* data, int len); 381 382 /** 383 * This method is called to send a RTCP packet 384 * @param data Pointer to raw RTCP data 385 * @param len Length of the data packet 386 */ 387 virtual void rtcpData(const void* data, int len); 388 389 private: 390 bool sendData(Socket& sock, const SocketAddr& to, const void* data, int len, 391 const char* what, bool& flag); 392 Type m_type; 393 RTPProcessor* m_processor; 394 RTPProcessor* m_monitor; 395 Socket m_rtpSock; 396 Socket m_rtcpSock; 397 SocketAddr m_localAddr; 398 SocketAddr m_remoteAddr; 399 SocketAddr m_remoteRTCP; 400 SocketAddr m_remotePref; 401 SocketAddr m_rxAddrRTP; 402 SocketAddr m_rxAddrRTCP; 403 bool m_autoRemote; 404 bool m_warnSendErrorRtp; 405 bool m_warnSendErrorRtcp; 406 }; 407 408 /** 409 * A dejitter buffer that can be inserted in the receive data path to 410 * absorb variations in packet arrival time. Incoming packets are stored 411 * and forwarded at fixed intervals. 412 * @short Dejitter buffer for incoming data packets 413 */ 414 class YRTP_API RTPDejitter : public RTPProcessor 415 { 416 public: 417 /** 418 * Constructor of a new jitter attenuator 419 * @param receiver RTP receiver which gets the delayed packets 420 * @param mindelay Minimum length of the dejitter buffer in microseconds 421 * @param maxdelay Maximum length of the dejitter buffer in microseconds 422 * @param dbg Dejitter DebugEnabler 423 * @param traceId Dejitter trace ID 424 */ 425 RTPDejitter(RTPReceiver* receiver, unsigned int mindelay, unsigned int maxdelay, 426 DebugEnabler* dbg = 0, const char* traceId = 0); 427 428 /** 429 * Destructor - drops the packets and shows statistics 430 */ 431 virtual ~RTPDejitter(); 432 433 /** 434 * Process and store one RTP data packet 435 * @param marker True if the marker bit is set in data packet 436 * @param payload Payload number 437 * @param timestamp Sampling instant of the packet data 438 * @param data Pointer to data block to process 439 * @param len Length of the data block in bytes 440 * @return True if the data packet was queued 441 */ 442 virtual bool rtpRecv(bool marker, int payload, unsigned int timestamp, 443 const void* data, int len); 444 445 /** 446 * Clear the delayed packets queue and all variables 447 */ 448 void clear(); 449 450 protected: 451 /** 452 * Method called periodically to keep the data flowing 453 * @param when Time to use as base in all computing 454 */ 455 virtual void timerTick(const Time& when); 456 457 private: 458 ObjList m_packets; 459 RTPReceiver* m_receiver; 460 unsigned int m_minDelay; 461 unsigned int m_maxDelay; 462 unsigned int m_headStamp; 463 unsigned int m_tailStamp; 464 u_int64_t m_headTime; 465 u_int64_t m_sampRate; 466 unsigned char m_fastRate; 467 }; 468 469 /** 470 * Base class that holds common sender and receiver methods 471 * @short Common send/recv variables holder 472 */ 473 class YRTP_API RTPBaseIO: public RTPDebug 474 { 475 friend class RTPSession; 476 friend class RTPSecure; 477 public: 478 /** 479 * Default constructor. 480 */ 481 inline RTPBaseIO(RTPSession* session = 0) RTPDebug(session)482 : RTPDebug(session), 483 m_session(session), m_secure(0), 484 m_ssrcInit(true), m_ssrc(0), m_ts(0), 485 m_seq(0), m_rollover(0), m_secLen(0), m_mkiLen(0), 486 m_evTs(0), m_evNum(-1), m_evVol(-1), m_evSeq(0), 487 m_ioPackets(), m_ioOctets(0), m_tsLast(0), 488 m_debugDataLevel(0), m_debugData(false), m_debugEvent(false), 489 m_dataType(-1), m_eventType(-1), m_silenceType(-1) 490 { } 491 492 /** 493 * Destructor 494 */ 495 virtual ~RTPBaseIO(); 496 497 /** 498 * Get the payload type for data packets 499 * @return Payload type, -1 if not set 500 */ dataPayload()501 inline int dataPayload() const 502 { return m_dataType; } 503 504 /** 505 * Set the payload type for data packets 506 * @param type Payload type, -1 to disable 507 * @return True if changed, false if invalid payload type 508 */ 509 bool dataPayload(int type); 510 511 /** 512 * Get the payload type for event packets 513 * @return Payload type, -1 if not set 514 */ eventPayload()515 inline int eventPayload() const 516 { return m_eventType; } 517 518 /** 519 * Set the payload type for event packets 520 * @param type Payload type, -1 to disable 521 * @return True if changed, false if invalid payload type 522 */ 523 bool eventPayload(int type); 524 525 /** 526 * Get the payload type for Silence event packets 527 * @return Payload type, -1 if not set 528 */ silencePayload()529 inline int silencePayload() const 530 { return m_silenceType; } 531 532 /** 533 * Set the payload type for Silence event packets. 534 * Thanks, Silence, for a new and incompatible way of sending events. 535 * @param type Payload type, -1 to disable 536 * @return True if changed, false if invalid payload type 537 */ 538 bool silencePayload(int type); 539 540 /** 541 * Return SSRC value, initialize to a new, random value if needed 542 * @return Current value of SSRC 543 */ 544 unsigned int ssrcInit(); 545 546 /** 547 * Requesting generation/grabbing of a new SSRC 548 */ reset()549 inline void reset() 550 { m_ssrcInit = true; } 551 552 /** 553 * Get the value of the current SSRC, zero if not initialized yet 554 * @return Value of SSRC, zero if not initialized 555 */ ssrc()556 inline unsigned int ssrc() const 557 { return m_ssrcInit ? 0 : m_ssrc; } 558 559 /** 560 * Force a new known SSRC for all further packets 561 */ ssrc(unsigned int src)562 inline void ssrc(unsigned int src) 563 { m_ssrc = src; m_ssrcInit = false; } 564 565 /** 566 * Get the current sequence number 567 * @return Sequence number 568 */ seq()569 inline u_int16_t seq() const 570 { return m_seq; } 571 572 /** 573 * Get the value of the rollover counter 574 * @return How many times the seqeunce has rolled over since SSRC changed 575 */ rollover()576 inline u_int32_t rollover() const 577 { return m_rollover; } 578 579 /** 580 * Get the full current sequence number including rollovers 581 * @return Full 48 bit current sequence number 582 */ fullSeq()583 inline u_int64_t fullSeq() const 584 { return m_seq | (((u_int64_t)m_rollover) << 16); } 585 586 /** 587 * Retrieve the number of packets exchanged on current session 588 * @return Number of packets exchanged 589 */ ioPackets()590 inline u_int32_t ioPackets() const 591 { return m_ioPackets; } 592 593 /** 594 * Retrieve the number of payload octets exchanged on current session 595 * @return Number of octets exchanged except headers and padding 596 */ ioOctets()597 inline u_int32_t ioOctets() const 598 { return m_ioOctets; } 599 600 /** 601 * Get the timestamp of the last packet as transmitted over the wire 602 * @return Timestamp of last packet sent or received 603 */ tsLast()604 inline unsigned int tsLast() const 605 { return m_ts + m_tsLast; } 606 607 /** 608 * Get the session this object belongs to 609 * @return Pointer to RTP session or NULL 610 */ session()611 inline RTPSession* session() const 612 { return m_session; } 613 614 /** 615 * Get the security provider of this sender or receiver 616 * @return A pointer to the RTPSecure or NULL 617 */ security()618 inline RTPSecure* security() const 619 { return m_secure; } 620 621 /** 622 * Set the security provider of this sender or receiver 623 * @param secure Pointer to the new RTPSecure or NULL 624 */ 625 void security(RTPSecure* secure); 626 627 /** 628 * Initialize data debug 629 * @param recv True if receiving, false if sending 630 * @param params Parameters list 631 */ 632 void initDebugData(bool recv, const NamedList& params); 633 634 protected: 635 /** 636 * Method called periodically to keep the data flowing 637 * @param when Time to use as base in all computing 638 */ 639 virtual void timerTick(const Time& when) = 0; 640 641 /** 642 * Set the length of the added / expected security info block 643 * @param len Length of security information portion 644 * @param key Length of master key identifier 645 */ 646 inline void secLength(u_int32_t len, u_int32_t key = 0) 647 { m_secLen = len; m_mkiLen = key; } 648 649 RTPSession* m_session; 650 RTPSecure* m_secure; 651 bool m_ssrcInit; 652 u_int32_t m_ssrc; 653 u_int32_t m_ts; 654 u_int16_t m_seq; 655 u_int32_t m_rollover; 656 u_int16_t m_secLen; 657 u_int16_t m_mkiLen; 658 u_int32_t m_evTs; 659 int m_evNum; 660 int m_evVol; 661 unsigned int m_evSeq; 662 u_int32_t m_ioPackets; 663 u_int32_t m_ioOctets; 664 unsigned int m_tsLast; 665 // Debug data 666 int m_debugDataLevel; 667 bool m_debugData; 668 bool m_debugEvent; 669 670 private: 671 int m_dataType; 672 int m_eventType; 673 int m_silenceType; 674 }; 675 676 /** 677 * Class that handles incoming RTP and RTCP packets 678 * @short RTP/RTCP packet receiver 679 */ 680 class YRTP_API RTPReceiver : public RTPBaseIO 681 { 682 friend class RTPSession; 683 friend class RTPDejitter; 684 public: 685 /** 686 * Constructor 687 */ 688 inline RTPReceiver(RTPSession* session = 0) RTPBaseIO(session)689 : RTPBaseIO(session), 690 m_ioLostPkt(0), m_dejitter(0), 691 m_seqSync(0), m_seqCount(0), m_warn(true), m_warnSeq(1), 692 m_seqLost(0), m_wrongSSRC(0), m_syncLost(0) 693 { } 694 695 /** 696 * Destructor - gets rid of the jitter buffer if present 697 */ 698 virtual ~RTPReceiver(); 699 700 /** 701 * Retrieve the number of lost packets in current session 702 * @return Number of packets in sequence gaps 703 */ ioPacketsLost()704 inline u_int32_t ioPacketsLost() const 705 { return m_ioLostPkt; } 706 707 708 /** 709 * Set a new dejitter buffer in this receiver 710 * @param dejitter New dejitter buffer to set, NULL to remove 711 */ 712 void setDejitter(RTPDejitter* dejitter); 713 714 /** 715 * Allocate and set a new dejitter buffer in this receiver 716 * @param mindelay Minimum length of the dejitter buffer in microseconds 717 * @param maxdelay Maximum length of the dejitter buffer in microseconds 718 */ setDejitter(unsigned int mindelay,unsigned int maxdelay)719 inline void setDejitter(unsigned int mindelay, unsigned int maxdelay) 720 { setDejitter(new RTPDejitter(this,mindelay,maxdelay,dbg(),m_traceId)); } 721 722 /** 723 * Process one RTP payload packet. 724 * Default behaviour is to call rtpRecvData() or rtpRecvEvent(). 725 * @param marker Set to true if the marker bit is set 726 * @param payload Payload number 727 * @param timestamp Sampling instant of the packet data 728 * @param data Pointer to data block to process 729 * @param len Length of the data block in bytes 730 * @return True if data was handled 731 */ 732 virtual bool rtpRecv(bool marker, int payload, unsigned int timestamp, 733 const void* data, int len); 734 735 /** 736 * Process one RTP data packet 737 * @param marker Set to true if the marker bit is set 738 * @param timestamp Sampling instant of the packet data 739 * @param data Pointer to data block to process 740 * @param len Length of the data block in bytes 741 * @return True if data was handled 742 */ 743 virtual bool rtpRecvData(bool marker, unsigned int timestamp, 744 const void* data, int len); 745 746 /** 747 * Process one RTP event 748 * @param event Received event code 749 * @param key Received key (for events 0-16) or zero 750 * @param duration Duration of the event as number of samples 751 * @param volume Attenuation of the tone, zero for don't care 752 * @param timestamp Sampling instant of the initial packet data 753 * @return True if data was handled 754 */ 755 virtual bool rtpRecvEvent(int event, char key, int duration, 756 int volume, unsigned int timestamp); 757 758 /** 759 * Method called for unknown payload types just before attempting 760 * to call rtpRecvData(). This is a good opportunity to change the 761 * payload type and continue. 762 * @param payload Payload number 763 * @param timestamp Sampling instant of the unexpected packet data 764 */ 765 virtual void rtpNewPayload(int payload, unsigned int timestamp); 766 767 /** 768 * Method called when a packet with an unexpected SSRC is received 769 * just before processing further. This is a good opportunity to 770 * change the SSRC and continue 771 * @param newSsrc SSRC received in packet 772 * @param marker True if marker bit is set in the RTP packet 773 */ 774 virtual void rtpNewSSRC(u_int32_t newSsrc, bool marker); 775 776 /** 777 * Retrieve the statistical data from this receiver in a NamedList. Reset all the data. 778 * @param stat NamedList to populate with the values for different counters 779 */ 780 virtual void stats(NamedList& stat) const; 781 782 protected: 783 /** 784 * Method called periodically to finish lingering events 785 * @param when Time to use as base in all computing 786 */ 787 virtual void timerTick(const Time& when); 788 789 /** 790 * Method called to decipher RTP data in-place. 791 * The default implementation calls session's @ref RTPSecure::rtpDecipher() 792 * @param data Pointer to data block to decipher 793 * @param len Length of data including any padding 794 * @param secData Pointer to security data if applicable 795 * @param ssrc SSRC of the packet to decipher 796 * @param seq Full (48 bit) seqence number of the packet including rollovers 797 * @return True is the packet was deciphered correctly or can't tell 798 */ 799 virtual bool rtpDecipher(unsigned char* data, int len, const void* secData, u_int32_t ssrc, u_int64_t seq); 800 801 /** 802 * Method called to check the integrity of the RTP packet. 803 * The default implementation calls session's @ref RTPSecure::rtpCheckIntegrity() 804 * @param data Pointer to RTP header and data 805 * @param len Length of header, data and padding 806 * @param authData Pointer to authentication data 807 * @param ssrc SSRC of the packet to validate 808 * @param seq Full (48 bit) seqence number of the packet including rollovers 809 * @return True is the packet passed integrity checks 810 */ 811 virtual bool rtpCheckIntegrity(const unsigned char* data, int len, const void* authData, u_int32_t ssrc, u_int64_t seq); 812 813 u_int32_t m_ioLostPkt; 814 815 private: 816 void rtpData(const void* data, int len); 817 void rtcpData(const void* data, int len); 818 bool decodeEvent(bool marker, unsigned int timestamp, const void* data, int len); 819 bool decodeSilence(bool marker, unsigned int timestamp, const void* data, int len); 820 void finishEvent(unsigned int timestamp); 821 bool pushEvent(int event, int duration, int volume, unsigned int timestamp); 822 RTPDejitter* m_dejitter; 823 u_int16_t m_seqSync; 824 u_int16_t m_seqCount; 825 bool m_warn; 826 int m_warnSeq; // Warn on invalid sequence (1: DebugWarn, -1: DebugInfo) 827 unsigned int m_seqLost; 828 unsigned int m_wrongSSRC; 829 unsigned int m_syncLost; 830 }; 831 832 /** 833 * Class that builds and sends RTP and RTCP packets 834 * @short RTP/RTCP packet sender 835 */ 836 class YRTP_API RTPSender : public RTPBaseIO 837 { 838 public: 839 /** 840 * Constructor 841 * @param session RTP session the sender belongs 842 * @param randomTs Initialize a random timestamp offset 843 */ 844 RTPSender(RTPSession* session = 0, bool randomTs = true); 845 846 /** 847 * Do-nothing destructor 848 */ ~RTPSender()849 virtual ~RTPSender() 850 { } 851 852 /** 853 * Send one RTP payload packet 854 * @param marker Set to true if the marker bit must be set 855 * @param payload Payload number 856 * @param timestamp Sampling instant of the packet data 857 * @param data Pointer to data block to send 858 * @param len Length of the data block 859 * @return True if data sending was attempted 860 */ 861 bool rtpSend(bool marker, int payload, unsigned int timestamp, 862 const void* data, int len); 863 864 /** 865 * Send one RTP data packet 866 * @param marker Set to true if the marker bit must be set 867 * @param timestamp Sampling instant of the packet data 868 * @param data Pointer to data block to send 869 * @param len Length of the data block 870 * @return True if data sending was attempted 871 */ 872 bool rtpSendData(bool marker, unsigned int timestamp, 873 const void* data, int len); 874 875 /** 876 * Send one RTP event 877 * @param event Event code to send 878 * @param duration Duration of the event as number of samples 879 * @param volume Attenuation of the tone, zero for don't care 880 * @param timestamp Sampling instant of the packet data, zero to use current 881 * @return True if data sending was attempted 882 */ 883 bool rtpSendEvent(int event, int duration, int volume = 0, unsigned int timestamp = 0); 884 885 /** 886 * Send one RTP key event 887 * @param key Key to send 888 * @param duration Duration of the event as number of samples 889 * @param volume Attenuation of the tone, zero for don't care 890 * @param timestamp Sampling instant of the packet data, zero to use current 891 * @return True if data sending was attempted 892 */ 893 bool rtpSendKey(char key, int duration, int volume = 0, unsigned int timestamp = 0); 894 895 896 /** 897 * Get the payload padding size 898 * @return Chunk size to pad the payload to a multiple of 899 */ padding()900 inline int padding() const 901 { return m_padding; } 902 903 /** 904 * Set the padding to a multiple of a data chunk 905 * @param chunk Size to pad the payload to a multiple of 906 * @return True if the new chunk size is valid 907 */ 908 bool padding(int chunk); 909 910 /** 911 * Retrieve the statistical data from this receiver in a NamedList. Reset all the data. 912 * @param stat NamedList to populate with the values for different counters 913 */ 914 virtual void stats(NamedList& stat) const; 915 916 protected: 917 /** 918 * Method called periodically to send events and buffered data 919 * @param when Time to use as base in all computing 920 */ 921 virtual void timerTick(const Time& when); 922 923 /** 924 * Method called to encipher RTP payload data in-place. 925 * The default implementation calls session's @ref RTPSecure::rtpEncipher() 926 * @param data Pointer to data block to encipher 927 * @param len Length of payload data to be encrypted including any padding 928 */ 929 virtual void rtpEncipher(unsigned char* data, int len); 930 931 /** 932 * Method called to add integrity information to the RTP packet. 933 * The default implementation calls session's @ref RTPSecure::rtpAddIntegrity() 934 * @param data Pointer to the RTP packet to protect 935 * @param len Length of RTP data to be encrypted including header and padding 936 * @param authData Address to write the integrity data to 937 */ 938 virtual void rtpAddIntegrity(const unsigned char* data, int len, unsigned char* authData); 939 940 941 private: 942 int m_evTime; 943 unsigned char m_padding; 944 DataBlock m_buffer; 945 bool sendEventData(unsigned int timestamp); 946 }; 947 948 /** 949 * A base class for RTP, SRTP or UDPTL sessions 950 * @short RTP or UDPTL session 951 */ 952 class YRTP_API UDPSession : public RTPProcessor 953 { 954 public: 955 /** 956 * Destructor - cleans up any remaining resources 957 */ 958 virtual ~UDPSession(); 959 960 /** 961 * Create a new RTP or UDP transport for this session. 962 * Override this method to create objects derived from RTPTransport. 963 * @return Pointer to the new transport or NULL on failure 964 */ 965 virtual RTPTransport* createTransport(); 966 967 /** 968 * Initialize the RTP session, attach a transport if there is none 969 * @return True if initialized, false on some failure 970 */ 971 bool initTransport(); 972 973 /** 974 * Initialize the RTP session, attach a group if none is present 975 * @param msec Minimum time to sleep in group loop in milliseconds 976 * @param prio Thread priority to run the new group 977 * @param affinity Comma-separated list of CPUs and/or CPU range on which the thread should run on 978 * @return True if initialized, false on some failure 979 */ 980 bool initGroup(int msec = 0, Thread::Priority prio = Thread::Normal, const String& affinity = String::empty()); 981 982 /** 983 * Set the remote network address of the RTP transport of this session 984 * @param addr New remote RTP transport address 985 * @param sniff Automatically adjust the address from the first incoming packet 986 * @return True if address set, false if a failure occured 987 */ 988 inline bool remoteAddr(SocketAddr& addr, bool sniff = false) 989 { return m_transport && m_transport->remoteAddr(addr,sniff); } 990 991 /** 992 * Set the size of the operating system's buffers for the RTP and RTCP transport sockets 993 * @param bufLen Requested length of the buffer 994 * @return True if the buffer length was set 995 */ 996 inline bool setBuffer(int bufLen = 4096) 997 { return m_transport && m_transport->setBuffer(bufLen); } 998 999 /** 1000 * Set the Type Of Service for the RTP transport socket 1001 * @param tos Type Of Service bits to set 1002 * @return True if operation was successfull, false if an error occured 1003 */ setTOS(int tos)1004 inline bool setTOS(int tos) 1005 { return m_transport && m_transport->setTOS(tos); } 1006 1007 /** 1008 * Get the main transport socket used by this session 1009 * @return Pointer to the RTP or UDPTL socket, NULL if no transport exists 1010 */ rtpSock()1011 inline Socket* rtpSock() 1012 { return m_transport ? m_transport->rtpSock() : 0; } 1013 1014 /** 1015 * Drill a hole in a firewall or NAT for the RTP and RTCP sockets 1016 * @return True if at least a packet was sent for the RTP socket 1017 */ drillHole()1018 inline bool drillHole() 1019 { return m_transport && m_transport->drillHole(); } 1020 1021 /** 1022 * Set the interval until receiver timeout is detected 1023 * @param interval Milliseconds until receiver times out, zero to disable 1024 */ 1025 void setTimeout(int interval); 1026 1027 /** 1028 * Get the RTP/RTCP transport of data handled by this session. 1029 * @return A pointer to the RTPTransport of this session 1030 */ transport()1031 inline RTPTransport* transport() const 1032 { return m_transport; } 1033 1034 /** 1035 * Set the UDP transport of data handled by this session 1036 * @param trans A pointer to the new RTPTransport for this session 1037 */ 1038 virtual void transport(RTPTransport* trans); 1039 1040 protected: 1041 /** 1042 * Default constructor 1043 * @param dbg Session DebugEnabler 1044 * @param traceId Session trace ID 1045 */ 1046 UDPSession(DebugEnabler* dbg = 0, const char* traceId = 0); 1047 1048 /** 1049 * Method called when the receiver timed out 1050 * @param initial True if no packet was ever received in this session 1051 */ 1052 virtual void timeout(bool initial); 1053 1054 RTPTransport* m_transport; 1055 u_int64_t m_timeoutTime; 1056 u_int64_t m_timeoutInterval; 1057 }; 1058 1059 /** 1060 * An unidirectional or bidirectional RTP session 1061 * @short Full RTP session 1062 */ 1063 class YRTP_API RTPSession : public UDPSession, public Mutex 1064 { 1065 public: 1066 /** 1067 * Direction of the session 1068 */ 1069 enum Direction { 1070 FullStop = 0, 1071 RecvOnly = 1, 1072 SendOnly = 2, 1073 SendRecv = 3 1074 }; 1075 1076 /** 1077 * Default constructor, creates a detached session 1078 * @param dbg Session DebugEnabler 1079 * @param traceId Session trace ID 1080 */ 1081 RTPSession(DebugEnabler* dbg = 0, const char* traceId = 0); 1082 1083 /** 1084 * Destructor - shuts down the session and destroys the transport 1085 */ 1086 virtual ~RTPSession(); 1087 1088 /** 1089 * Retrieve MGCP P: style comma separated session parameters 1090 * @param stats String to append parameters to 1091 */ 1092 virtual void getStats(String& stats) const; 1093 1094 /** 1095 * This method is called to process a RTP packet. 1096 * @param data Pointer to raw RTP data 1097 * @param len Length of the data packet 1098 */ 1099 virtual void rtpData(const void* data, int len); 1100 1101 /** 1102 * This method is called to process a RTCP packet. 1103 * @param data Pointer to raw RTCP data 1104 * @param len Length of the data packet 1105 */ 1106 virtual void rtcpData(const void* data, int len); 1107 1108 /** 1109 * Process one RTP data packet 1110 * @param marker Set to true if the marker bit is set 1111 * @param timestamp Sampling instant of the packet data 1112 * @param data Pointer to data block to process 1113 * @param len Length of the data block in bytes 1114 * @return True if data was handled 1115 */ 1116 virtual bool rtpRecvData(bool marker, unsigned int timestamp, 1117 const void* data, int len); 1118 1119 /** 1120 * Process one RTP event 1121 * @param event Received event code 1122 * @param key Received key (for events 0-16) or zero 1123 * @param duration Duration of the event as number of samples 1124 * @param volume Attenuation of the tone, zero for don't care 1125 * @param timestamp Sampling instant of the initial packet data 1126 * @return True if data was handled 1127 */ 1128 virtual bool rtpRecvEvent(int event, char key, int duration, 1129 int volume, unsigned int timestamp); 1130 1131 /** 1132 * Method called for unknown payload types just before attempting 1133 * to call rtpRecvData(). This is a good opportunity to change the 1134 * payload type and continue. 1135 * @param payload Payload number 1136 * @param timestamp Sampling instant of the unexpected packet data 1137 */ 1138 virtual void rtpNewPayload(int payload, unsigned int timestamp); 1139 1140 /** 1141 * Method called when a packet with an unexpected SSRC is received 1142 * just before processing further. This is a good opportunity to 1143 * change the SSRC and continue 1144 * @param newSsrc SSRC received in packet 1145 * @param marker True if marker bit is set in the RTP packet 1146 */ 1147 virtual void rtpNewSSRC(u_int32_t newSsrc, bool marker); 1148 1149 /** 1150 * Create a new RTP sender for this session. 1151 * Override this method to create objects derived from RTPSender. 1152 * @return Pointer to the new sender or NULL on failure 1153 */ 1154 virtual RTPSender* createSender(); 1155 1156 /** 1157 * Create a new RTP receiver for this session. 1158 * Override this method to create objects derived from RTPReceiver. 1159 * @return Pointer to the new receiver or NULL on failure 1160 */ 1161 virtual RTPReceiver* createReceiver(); 1162 1163 /** 1164 * Create a cipher when required for SRTP 1165 * @param name Name of the cipher to create 1166 * @param dir Direction the cipher must be able to handle 1167 * @return Pointer to newly allocated Cipher or NULL 1168 */ 1169 virtual Cipher* createCipher(const String& name, Cipher::Direction dir); 1170 1171 /** 1172 * Check if a cipher is supported for SRTP 1173 * @param name Name of the cipher to check 1174 * @return True if the specified cipher is supported 1175 */ 1176 virtual bool checkCipher(const String& name); 1177 1178 /** 1179 * Send one RTP payload packet 1180 * @param marker Set to true if the marker bit must be set 1181 * @param payload Payload number 1182 * @param timestamp Sampling instant of the packet data 1183 * @param data Pointer to data block to send 1184 * @param len Length of the data block 1185 * @return True if data sending was attempted 1186 */ rtpSend(bool marker,int payload,unsigned int timestamp,const void * data,int len)1187 inline bool rtpSend(bool marker, int payload, unsigned int timestamp, 1188 const void* data, int len) 1189 { Lock lck(this); return m_send && m_send->rtpSend(marker,payload,timestamp,data,len); } 1190 1191 /** 1192 * Send one RTP data packet 1193 * @param marker Set to true if the marker bit must be set 1194 * @param timestamp Sampling instant of the packet data 1195 * @param data Pointer to data block to send 1196 * @param len Length of the data block 1197 * @return True if data sending was attempted 1198 */ rtpSendData(bool marker,unsigned int timestamp,const void * data,int len)1199 inline bool rtpSendData(bool marker, unsigned int timestamp, 1200 const void* data, int len) 1201 { Lock lck(this); return m_send && m_send->rtpSendData(marker,timestamp,data,len); } 1202 1203 /** 1204 * Send one RTP event 1205 * @param event Event code to send 1206 * @param duration Duration of the event as number of samples 1207 * @param volume Attenuation of the tone, zero for don't care 1208 * @param timestamp Sampling instant of the packet data, zero to use current 1209 * @return True if data sending was attempted 1210 */ 1211 inline bool rtpSendEvent(int event, int duration, int volume = 0, unsigned int timestamp = 0) 1212 { Lock lck(this); return m_send && m_send->rtpSendEvent(event,duration,volume,timestamp); } 1213 1214 /** 1215 * Send one RTP key event 1216 * @param key Key to send 1217 * @param duration Duration of the event as number of samples 1218 * @param volume Attenuation of the tone, zero for don't care 1219 * @param timestamp Sampling instant of the packet data, zero to use current 1220 * @return True if data sending was attempted 1221 */ 1222 inline bool rtpSendKey(char key, int duration, int volume = 0, unsigned int timestamp = 0) 1223 { Lock lck(this); return m_send && m_send->rtpSendKey(key,duration,volume,timestamp); } 1224 1225 /** 1226 * Retrieve the number of lost packets in current received 1227 * @return Number of packets in sequence gaps 1228 */ ioPacketsLost()1229 inline u_int32_t ioPacketsLost() const 1230 { return m_recv ? m_recv->ioPacketsLost() : 0; } 1231 1232 /** 1233 * Get the payload padding size 1234 * @return Chunk size to pad the payload to a multiple of 1235 */ padding()1236 inline int padding() const 1237 { return m_send ? m_send->padding() : 0; } 1238 1239 /** 1240 * Set the padding to a multiple of a data chunk 1241 * @param chunk Size to pad the payload to a multiple of 1242 * @return True if the new chunk size is valid 1243 */ padding(int chunk)1244 inline bool padding(int chunk) 1245 { return m_send && m_send->padding(chunk); } 1246 1247 /** 1248 * Allocate and set a new dejitter buffer for the receiver in the session 1249 * @param mindelay Minimum length of the dejitter buffer in microseconds 1250 * @param maxdelay Maximum length of the dejitter buffer in microseconds 1251 */ 1252 inline void setDejitter(unsigned int mindelay = 20, unsigned int maxdelay = 50) 1253 { if (m_recv) m_recv->setDejitter(mindelay,maxdelay); } 1254 1255 /** 1256 * Set the RTP/RTCP transport of data handled by this session 1257 * @param trans A pointer to the new RTPTransport for this session 1258 */ 1259 virtual void transport(RTPTransport* trans); 1260 1261 /** 1262 * Get the RTP/RTCP sender of this session 1263 * @return A pointer to the RTPSender of this session 1264 */ sender()1265 inline RTPSender* sender() const 1266 { return m_send; } 1267 1268 /** 1269 * Set the RTP/RTCP sender of this session 1270 * @param send A pointer to the new RTPSender of this session or NULL 1271 */ 1272 void sender(RTPSender* send); 1273 1274 /** 1275 * Get the RTP/RTCP receiver of this session 1276 * @return A pointer to the RTPReceiver of this session 1277 */ receiver()1278 inline RTPReceiver* receiver() const 1279 { return m_recv; } 1280 1281 /** 1282 * Set the RTP/RTCP receiver of this session 1283 * @param recv A pointer to the new RTPReceiver of this session or NULL 1284 */ 1285 void receiver(RTPReceiver* recv); 1286 1287 /** 1288 * Get the direction of this session 1289 * @return Session's direction as a Direction enum 1290 */ direction()1291 inline Direction direction() const 1292 { return m_direction; } 1293 1294 /** 1295 * Set the direction of this session. A transport must exist for this 1296 * method to succeed. 1297 * @param dir New Direction for this session 1298 * @return True if direction was set, false if a failure occured 1299 */ 1300 bool direction(Direction dir); 1301 1302 /** 1303 * Add a direction of this session. A transport must exist for this 1304 * method to succeed. 1305 * @param dir New Direction to add for this session 1306 * @return True if direction was set, false if a failure occured 1307 */ addDirection(Direction dir)1308 inline bool addDirection(Direction dir) 1309 { return direction((Direction)(m_direction | dir)); } 1310 1311 /** 1312 * Delete a direction of this session. A transport must exist for this 1313 * method to succeed. 1314 * @param dir Direction to remove for this session 1315 * @return True if direction was set, false if a failure occured 1316 */ delDirection(Direction dir)1317 inline bool delDirection(Direction dir) 1318 { return direction((Direction)(m_direction & ~dir)); } 1319 1320 /** 1321 * Set the data payload type for both receiver and sender. 1322 * @param type Payload type, -1 to disable 1323 * @return True if changed, false if invalid payload type 1324 */ 1325 bool dataPayload(int type); 1326 1327 /** 1328 * Set the event payload type for both receiver and sender. 1329 * @param type Payload type, -1 to disable 1330 * @return True if changed, false if invalid payload type 1331 */ 1332 bool eventPayload(int type); 1333 1334 /** 1335 * Set the silence payload type for both receiver and sender. 1336 * @param type Payload type, -1 to disable 1337 * @return True if changed, false if invalid payload type 1338 */ 1339 bool silencePayload(int type); 1340 1341 /** 1342 * Set the local network address of the RTP transport of this session 1343 * @param addr New local RTP transport address 1344 * @param rtcp Enable RTCP in this session 1345 * @return True if address set, false if a failure occured 1346 */ 1347 inline bool localAddr(SocketAddr& addr, bool rtcp = true) 1348 { Lock lck(this); return m_transport && m_transport->localAddr(addr,rtcp); } 1349 1350 /** 1351 * Get the stored security provider or of the sender 1352 * @return A pointer to the RTPSecure or NULL 1353 */ security()1354 inline RTPSecure* security() const 1355 { return m_send ? m_send->security() : m_secure; } 1356 1357 /** 1358 * Store a security provider for the sender 1359 * @param secure Pointer to the new RTPSecure or NULL 1360 */ 1361 void security(RTPSecure* secure); 1362 1363 /** 1364 * Set the RTCP report interval 1365 * @param interval Average interval between reports in msec, zero to disable 1366 */ 1367 void setReports(int interval); 1368 1369 /** 1370 * Put the collected statistical data 1371 * @param stats NamedList to populate with the data 1372 */ 1373 virtual void getStats(NamedList& stats) const; 1374 1375 /** 1376 * Increase the counter for number of RTP packets received from a wrong source 1377 */ 1378 virtual void incWrongSrc(); 1379 1380 /** 1381 * Set the packet with invalid sequence warn mode 1382 * @param on True to show a message at DebugWarn level, 1383 * false to show at DebugInfo level 1384 */ setWarnSeq(bool on)1385 inline void setWarnSeq(bool on) 1386 { m_warnSeq = on ? 1 : -1; } 1387 1388 /** 1389 * Initialize data debug 1390 * @param params Parameters list 1391 */ initDebugData(const NamedList & params)1392 inline void initDebugData(const NamedList& params) { 1393 if (m_recv) 1394 m_recv->initDebugData(true,params); 1395 if (m_send) 1396 m_send->initDebugData(false,params); 1397 } 1398 1399 protected: 1400 /** 1401 * Method called periodically to push any asynchronous data or statistics 1402 * @param when Time to use as base in all computing 1403 */ 1404 virtual void timerTick(const Time& when); 1405 1406 /** 1407 * Send a RTCP report 1408 * @param when Time to use as base for timestamps 1409 */ 1410 void sendRtcpReport(const Time& when); 1411 1412 /** 1413 * Send a RTCP BYE when the sender is stopped or replaced 1414 */ 1415 void sendRtcpBye(); 1416 1417 private: 1418 Direction m_direction; 1419 RTPSender* m_send; 1420 RTPReceiver* m_recv; 1421 RTPSecure* m_secure; 1422 u_int64_t m_reportTime; 1423 u_int64_t m_reportInterval; 1424 int m_warnSeq; // Warn on invalid sequence (1: DebugWarn, -1: DebugInfo) 1425 }; 1426 1427 /** 1428 * A bidirectional UDPTL session usable for T.38 1429 * @short UDPTL session 1430 */ 1431 class YRTP_API UDPTLSession : public UDPSession, public Mutex 1432 { 1433 public: 1434 /** 1435 * Destructor 1436 */ 1437 ~UDPTLSession(); 1438 1439 /** 1440 * Set the local network address of the RTP transport of this session 1441 * @param addr New local RTP transport address 1442 * @return True if address set, false if a failure occured 1443 */ localAddr(SocketAddr & addr)1444 inline bool localAddr(SocketAddr& addr) 1445 { Lock lck(this); return m_transport && m_transport->localAddr(addr,false); } 1446 1447 /** 1448 * Get the maximum UDPTL packet length 1449 * @return Maximum length of UDPTL packet length in bytes 1450 */ maxLen()1451 inline u_int16_t maxLen() const 1452 { return m_maxLen; } 1453 1454 /** 1455 * Get the maximum number of UDPTL secondary IFPs 1456 * @return Maximum number of secondary IFPs, zero if disabled 1457 */ maxSec()1458 inline u_int8_t maxSec() const 1459 { return m_maxSec; } 1460 1461 /** 1462 * This method is called to send or process an UDPTL packet 1463 * @param data Pointer to raw UDPTL data 1464 * @param len Length of the data packet 1465 */ 1466 virtual void rtpData(const void* data, int len); 1467 1468 /** 1469 * Send UDPTL data over the transport, add older blocks for error recovery 1470 * @param data Pointer to IFP block to send as primary 1471 * @param len Length of primary IFP block 1472 * @param seq Sequence number to incorporate in message 1473 * @return True if data block was sent, false if an error occured 1474 */ 1475 bool udptlSend(const void* data, int len, u_int16_t seq); 1476 1477 protected: 1478 /** 1479 * UDPTL Session constructor 1480 * @param maxLen Maximum length of UDPTL packet, at least longest primary IFP + 5 bytes 1481 * @param maxSec Maximum number of secondary IFPs, set to zero to disable 1482 * @param dbg Session DebugEnabler 1483 * @param traceId Session trace ID 1484 */ 1485 UDPTLSession(u_int16_t maxLen = 250, u_int8_t maxSec = 2, 1486 DebugEnabler* dbg = 0, const char* traceId = 0); 1487 1488 /** 1489 * Method called periodically to push any asynchronous data or statistics 1490 * @param when Time to use as base in all computing 1491 */ 1492 virtual void timerTick(const Time& when); 1493 1494 /** 1495 * Create a new UDPTL transport for this session. 1496 * Override this method to create objects derived from RTPTransport. 1497 * @return Pointer to the new transport or NULL on failure 1498 */ 1499 virtual RTPTransport* createTransport(); 1500 1501 /** 1502 * Method called when UDPTL data is received 1503 * @param data Pointer to IFP block 1504 * @param len Length of the IFP block 1505 * @param seq Sequence number of the block 1506 * @param recovered True if the IFP block was recovered after data loss 1507 */ 1508 virtual void udptlRecv(const void* data, int len, u_int16_t seq, bool recovered) = 0; 1509 1510 private: 1511 void recoverSec(const unsigned char* data, int len, u_int16_t seq, int nSec); 1512 u_int16_t m_rxSeq; 1513 u_int16_t m_txSeq; 1514 u_int16_t m_maxLen; 1515 u_int8_t m_maxSec; 1516 bool m_warn; 1517 ObjList m_txQueue; 1518 }; 1519 1520 /** 1521 * Security and integrity implementation 1522 * @short SRTP implementation 1523 */ 1524 class YRTP_API RTPSecure : public GenObject, public RTPDebug 1525 { 1526 friend class RTPReceiver; 1527 friend class RTPSender; 1528 friend class RTPSession; 1529 public: 1530 /** 1531 * Default constructor, builds an inactive implementation 1532 * @param dbg DebugEnabler 1533 * @param traceId Trace ID 1534 */ 1535 RTPSecure(DebugEnabler* dbg = 0, const char* traceId = 0); 1536 1537 /** 1538 * Constructor that creates an active implementation 1539 * @param suite Cryptographic suite to use by default 1540 * @param dbg DebugEnabler 1541 * @param traceId Trace ID 1542 */ 1543 RTPSecure(const String& suite, DebugEnabler* dbg = 0, const char* traceId = 0); 1544 1545 /** 1546 * Constructor that copies the basic crypto lengths 1547 * @param other Security provider to copy parameters from 1548 */ 1549 RTPSecure(const RTPSecure& other); 1550 1551 /** 1552 * Destructor 1553 */ 1554 virtual ~RTPSecure(); 1555 1556 /** 1557 * Get the owner of this security instance 1558 * @return Pointer to RTPBaseIO or NULL 1559 */ owner()1560 inline RTPBaseIO* owner() const 1561 { return m_owner; } 1562 1563 /** 1564 * Set the owner of this security instance 1565 * @param newOwner Pointer to new RTPBaseIO owning this security instance 1566 */ 1567 void owner(RTPBaseIO* newOwner); 1568 1569 /** 1570 * Get the current RTP cipher if set 1571 * @return Pointer to current RTP cipher or NULL 1572 */ rtpCipher()1573 inline Cipher* rtpCipher() const 1574 { return m_rtpCipher; } 1575 1576 /** 1577 * Check if the systems supports requirements for activating SRTP 1578 * @param session RTP session to use for cipher checking, NULL to use owner session 1579 * @return True if it looks like SRTP can be activated later 1580 */ 1581 virtual bool supported(RTPSession* session = 0) const; 1582 1583 /** 1584 * Set up the cryptographic parameters 1585 * @param suite Descriptor of the encryption and authentication algorithms 1586 * @param keyParams Keying material and related parameters 1587 * @param paramList Optional session parameters as list of Strings 1588 * @return True if the session parameters were applied successfully 1589 */ 1590 virtual bool setup(const String& suite, const String& keyParams, const ObjList* paramList = 0); 1591 1592 /** 1593 * Create a set of cryptographic parameters 1594 * @param suite Reference of returned cryptographic suite description 1595 * @param keyParams Reference to returned keying material 1596 * @param buildMaster Create random master key and salt if not already set 1597 * @return True if security instance is valid and ready 1598 */ 1599 virtual bool create(String& suite, String& keyParams, bool buildMaster = true); 1600 1601 protected: 1602 /** 1603 * Initialize security related variables in the RTP session 1604 */ 1605 virtual void init(); 1606 1607 /** 1608 * Method called to encipher RTP payload data in-place 1609 * @param data Pointer to data block to encipher 1610 * @param len Length of payload data to be encrypted including any padding 1611 */ 1612 virtual void rtpEncipher(unsigned char* data, int len); 1613 1614 /** 1615 * Method called to add integrity information to the RTP packet 1616 * @param data Pointer to the RTP packet to protect 1617 * @param len Length of RTP data to be encrypted including header and padding 1618 * @param authData Address to write the integrity data to 1619 */ 1620 virtual void rtpAddIntegrity(const unsigned char* data, int len, unsigned char* authData); 1621 1622 /** 1623 * Method called to decipher RTP data in-place 1624 * @param data Pointer to data block to decipher 1625 * @param len Length of data including any padding 1626 * @param secData Pointer to security data if applicable 1627 * @param ssrc SSRC of the packet to decipher 1628 * @param seq Full (48 bit) seqence number of the packet including rollovers 1629 * @return True is the packet was deciphered correctly or can't tell 1630 */ 1631 virtual bool rtpDecipher(unsigned char* data, int len, const void* secData, u_int32_t ssrc, u_int64_t seq); 1632 1633 /** 1634 * Method called to check the integrity of the RTP packet 1635 * @param data Pointer to RTP header and data 1636 * @param len Length of header, data and padding 1637 * @param authData Pointer to authentication data 1638 * @param ssrc SSRC of the packet to validate 1639 * @param seq Full (48 bit) seqence number of the packet including rollovers 1640 * @return True is the packet passed integrity checks 1641 */ 1642 virtual bool rtpCheckIntegrity(const unsigned char* data, int len, const void* authData, u_int32_t ssrc, u_int64_t seq); 1643 1644 /** 1645 * Internal method implementing key derivation 1646 * @param cipher Cipher used for key derivation 1647 * @param key Reference to derived key output 1648 * @param len Desired length of the key, should be at most cipher block length 1649 * @param label Derived key type 1650 * @param index Packet index after being divided by KDR 1651 * @return True if success, false if invalid parameters or missing cipher 1652 */ 1653 bool deriveKey(Cipher& cipher, DataBlock& key, unsigned int len, unsigned char label, u_int64_t index = 0); 1654 1655 private: 1656 RTPBaseIO* m_owner; 1657 Cipher* m_rtpCipher; 1658 DataBlock m_masterKey; 1659 DataBlock m_masterSalt; 1660 DataBlock m_cipherKey; 1661 DataBlock m_cipherSalt; 1662 SHA1 m_authIpad; 1663 SHA1 m_authOpad; 1664 u_int32_t m_rtpAuthLen; 1665 bool m_rtpEncrypted; 1666 }; 1667 1668 } 1669 1670 #endif /* __YATERTP_H */ 1671 1672 /* vi: set ts=8 sw=4 sts=4 noet: */ 1673