1/**********
2This library is free software; you can redistribute it and/or modify it under
3the terms of the GNU Lesser General Public License as published by the
4Free Software Foundation; either version 3 of the License, or (at your
5option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6
7This library is distributed in the hope that it will be useful, but WITHOUT
8ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
10more details.
11
12You should have received a copy of the GNU Lesser General Public License
13along with this library; if not, write to the Free Software Foundation, Inc.,
1451 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15**********/
16// "liveMedia"
17// Copyright (c) 1996-2020 Live Networks, Inc. All rights reserved.
18// RTCP
19// C++ header
20
21#ifndef _RTCP_HH
22#define _RTCP_HH
23
24#ifndef _RTP_SINK_HH
25#include "RTPSink.hh"
26#endif
27#ifndef _RTP_SOURCE_HH
28#include "RTPSource.hh"
29#endif
30
31class SDESItem {
32public:
33 SDESItem(unsigned char tag, unsigned char const* value);
34
35 unsigned char const* data() const {return fData;}
36 unsigned totalSize() const;
37
38private:
39 unsigned char fData[2 + 0xFF]; // first 2 bytes are tag and length
40};
41
42typedef void RTCPAppHandlerFunc(void* clientData,
43 u_int8_t subtype, u_int32_t nameBytes/*big-endian order*/,
44 u_int8_t* appDependentData, unsigned appDependentDataSize);
45
46class RTCPMemberDatabase; // forward
47
48typedef void ByeWithReasonHandlerFunc(void* clientData, char const* reason);
49
50class RTCPInstance: public Medium {
51public:
52 static RTCPInstance* createNew(UsageEnvironment& env, Groupsock* RTCPgs,
53 unsigned totSessionBW, /* in kbps */
54 unsigned char const* cname,
55 RTPSink* sink,
56 RTPSource* source,
57 Boolean isSSMSource = False);
58
59 static Boolean lookupByName(UsageEnvironment& env, char const* instanceName,
60 RTCPInstance*& resultInstance);
61
62 unsigned numMembers() const;
63 unsigned totSessionBW() const { return fTotSessionBW; }
64
65 void setByeHandler(TaskFunc* handlerTask, void* clientData,
66 Boolean handleActiveParticipantsOnly = True);
67 // Assigns a handler routine to be called if a "BYE" arrives.
68 // The handler is called once only; for subsequent "BYE"s,
69 // "setByeHandler()" would need to be called again.
70 // If "handleActiveParticipantsOnly" is True, then the handler is called
71 // only if the SSRC is for a known sender (if we have a "RTPSource"),
72 // or if the SSRC is for a known receiver (if we have a "RTPSink").
73 // This prevents (for example) the handler for a multicast receiver being
74 // called if some other multicast receiver happens to exit.
75 // If "handleActiveParticipantsOnly" is False, then the handler is called
76 // for any incoming RTCP "BYE".
77 // (To remove an existing "BYE" handler, call "setByeHandler()" again, with a "handlerTask" of NULL.)
78 void setByeWithReasonHandler(ByeWithReasonHandlerFunc* handlerTask, void* clientData,
79 Boolean handleActiveParticipantsOnly = True);
80 // Like "setByeHandler()", except that a string 'reason for the bye' (received as part of
81 // the RTCP "BYE" packet) is passed to the handler function (along with "clientData").
82 // (The 'reason' parameter to the handler function will be a dynamically-allocated string,
83 // or NULL, and should be delete[]d by the handler function.)
84 void setSRHandler(TaskFunc* handlerTask, void* clientData);
85 void setRRHandler(TaskFunc* handlerTask, void* clientData);
86 // Assigns a handler routine to be called if a "SR" or "RR" packet
87 // (respectively) arrives. Unlike "setByeHandler()", the handler will
88 // be called once for each incoming "SR" or "RR". (To turn off handling,
89 // call the function again with "handlerTask" (and "clientData") as NULL.)
90 void setSpecificRRHandler(netAddressBits fromAddress, Port fromPort,
91 TaskFunc* handlerTask, void* clientData);
92 // Like "setRRHandler()", but applies only to "RR" packets that come from
93 // a specific source address and port. (Note that if both a specific
94 // and a general "RR" handler function is set, then both will be called.)
95 void unsetSpecificRRHandler(netAddressBits fromAddress, Port fromPort); // equivalent to setSpecificRRHandler(..., NULL, NULL);
96 void setAppHandler(RTCPAppHandlerFunc* handlerTask, void* clientData);
97 // Assigns a handler routine to be called whenever an "APP" packet arrives. (To turn off
98 // handling, call the function again with "handlerTask" (and "clientData") as NULL.)
99 void sendAppPacket(u_int8_t subtype, char const* name,
100 u_int8_t* appDependentData, unsigned appDependentDataSize);
101 // Sends a custom RTCP "APP" packet to the peer(s). The parameters correspond to their
102 // respective fields as described in the RTP/RTCP definition (RFC 3550).
103 // Note that only the low-order 5 bits of "subtype" are used, and only the first 4 bytes
104 // of "name" are used. (If "name" has fewer than 4 bytes, or is NULL,
105 // then the remaining bytes are '\0'.)
106
107 Groupsock* RTCPgs() const { return fRTCPInterface.gs(); }
108
109 void setStreamSocket(int sockNum, unsigned char streamChannelId);
110 void addStreamSocket(int sockNum, unsigned char streamChannelId);
111 void removeStreamSocket(int sockNum, unsigned char streamChannelId) {
112 fRTCPInterface.removeStreamSocket(sockNum, streamChannelId);
113 }
114 // hacks to allow sending RTP over TCP (RFC 2236, section 10.12)
115
116 void setAuxilliaryReadHandler(AuxHandlerFunc* handlerFunc,
117 void* handlerClientData) {
118 fRTCPInterface.setAuxilliaryReadHandler(handlerFunc,
119 handlerClientData);
120 }
121
122 void injectReport(u_int8_t const* packet, unsigned packetSize, struct sockaddr_in const& fromAddress);
123 // Allows an outside party to inject an RTCP report (from other than the network interface)
124
125protected:
126 RTCPInstance(UsageEnvironment& env, Groupsock* RTPgs, unsigned totSessionBW,
127 unsigned char const* cname,
128 RTPSink* sink, RTPSource* source,
129 Boolean isSSMSource);
130 // called only by createNew()
131 virtual ~RTCPInstance();
132
133 virtual void noteArrivingRR(struct sockaddr_in const& fromAddressAndPort,
134 int tcpSocketNum, unsigned char tcpStreamChannelId);
135
136 void incomingReportHandler1();
137
138private:
139 // redefined virtual functions:
140 virtual Boolean isRTCPInstance() const;
141
142private:
143 Boolean addReport(Boolean alwaysAdd = False);
144 void addSR();
145 void addRR();
146 void enqueueCommonReportPrefix(unsigned char packetType, u_int32_t SSRC,
147 unsigned numExtraWords = 0);
148 void enqueueCommonReportSuffix();
149 void enqueueReportBlock(RTPReceptionStats* receptionStats);
150 void addSDES();
151 void addBYE(char const* reason);
152
153 void sendBuiltPacket();
154
155 static void onExpire(RTCPInstance* instance);
156 void onExpire1();
157
158 static void incomingReportHandler(RTCPInstance* instance, int /*mask*/);
159 void processIncomingReport(unsigned packetSize, struct sockaddr_in const& fromAddressAndPort,
160 int tcpSocketNum, unsigned char tcpStreamChannelId);
161 void onReceive(int typeOfPacket, int totPacketSize, u_int32_t ssrc);
162
163private:
164 u_int8_t* fInBuf;
165 unsigned fNumBytesAlreadyRead;
166 OutPacketBuffer* fOutBuf;
167 RTPInterface fRTCPInterface;
168 unsigned fTotSessionBW;
169 RTPSink* fSink;
170 RTPSource* fSource;
171 Boolean fIsSSMSource;
172
173 SDESItem fCNAME;
174 RTCPMemberDatabase* fKnownMembers;
175 unsigned fOutgoingReportCount; // used for SSRC member aging
176
177 double fAveRTCPSize;
178 int fIsInitial;
179 double fPrevReportTime;
180 double fNextReportTime;
181 int fPrevNumMembers;
182
183 int fLastSentSize;
184 int fLastReceivedSize;
185 u_int32_t fLastReceivedSSRC;
186 int fTypeOfEvent;
187 int fTypeOfPacket;
188 Boolean fHaveJustSentPacket;
189 unsigned fLastPacketSentSize;
190
191 TaskFunc* fByeHandlerTask;
192 ByeWithReasonHandlerFunc* fByeWithReasonHandlerTask;
193 void* fByeHandlerClientData;
194 Boolean fByeHandleActiveParticipantsOnly;
195 TaskFunc* fSRHandlerTask;
196 void* fSRHandlerClientData;
197 TaskFunc* fRRHandlerTask;
198 void* fRRHandlerClientData;
199 AddressPortLookupTable* fSpecificRRHandlerTable;
200 RTCPAppHandlerFunc* fAppHandlerTask;
201 void* fAppHandlerClientData;
202
203public: // because this stuff is used by an external "C" function
204 void schedule(double nextTime);
205 void reschedule(double nextTime);
206 void sendReport();
207 void sendBYE(char const* reason = NULL);
208 int typeOfEvent() {return fTypeOfEvent;}
209 int sentPacketSize() {return fLastSentSize;}
210 int packetType() {return fTypeOfPacket;}
211 int receivedPacketSize() {return fLastReceivedSize;}
212 int checkNewSSRC();
213 void removeLastReceivedSSRC();
214 void removeSSRC(u_int32_t ssrc, Boolean alsoRemoveStats);
215};
216
217// RTCP packet types:
218const unsigned char RTCP_PT_SR = 200;
219const unsigned char RTCP_PT_RR = 201;
220const unsigned char RTCP_PT_SDES = 202;
221const unsigned char RTCP_PT_BYE = 203;
222const unsigned char RTCP_PT_APP = 204;
223const unsigned char RTCP_PT_RTPFB = 205; // Generic RTP Feedback [RFC4585]
224const unsigned char RTCP_PT_PSFB = 206; // Payload-specific [RFC4585]
225const unsigned char RTCP_PT_XR = 207; // extended report [RFC3611]
226const unsigned char RTCP_PT_AVB = 208; // AVB RTCP packet ["Standard for Layer 3 Transport Protocol for Time Sensitive Applications in Local Area Networks." Work in progress.]
227const unsigned char RTCP_PT_RSI = 209; // Receiver Summary Information [RFC5760]
228const unsigned char RTCP_PT_TOKEN = 210; // Port Mapping [RFC6284]
229const unsigned char RTCP_PT_IDMS = 211; // IDMS Settings [RFC7272]
230
231// SDES tags:
232const unsigned char RTCP_SDES_END = 0;
233const unsigned char RTCP_SDES_CNAME = 1;
234const unsigned char RTCP_SDES_NAME = 2;
235const unsigned char RTCP_SDES_EMAIL = 3;
236const unsigned char RTCP_SDES_PHONE = 4;
237const unsigned char RTCP_SDES_LOC = 5;
238const unsigned char RTCP_SDES_TOOL = 6;
239const unsigned char RTCP_SDES_NOTE = 7;
240const unsigned char RTCP_SDES_PRIV = 8;
241
242#endif
243