1 /**
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <RtcpSrPacket.h>
18 #include <RtpTrace.h>
19
20 /*********************************************************
21 * Function name : RtcpSrPacket
22 * Description : Constructor
23 * Return type : None
24 * Argument : None
25 * Preconditions : None
26 * Side Effects : None
27 ********************************************************/
RtcpSrPacket()28 RtcpSrPacket::RtcpSrPacket() :
29 m_uiRtpTimestamp(RTP_ZERO),
30 m_uiSendPktCount(RTP_ZERO),
31 m_uiSendOctCount(RTP_ZERO)
32 {
33 memset(&m_stNtpTimestamp, RTP_ZERO, sizeof(tRTP_NTP_TIME));
34 }
35
36 /*********************************************************
37 * Function name : ~RtcpSrPacket
38 * Description : Destructor
39 * Return type : None
40 * Argument : None
41 * Preconditions : None
42 * Side Effects : None
43 ********************************************************/
~RtcpSrPacket()44 RtcpSrPacket::~RtcpSrPacket() {}
45
setRtcpHdrInfo(RtcpHeader & rtcpHeader)46 RtpDt_Void RtcpSrPacket::setRtcpHdrInfo(RtcpHeader& rtcpHeader)
47 {
48 RtcpHeader* pobjRtcpHdr = m_objRrPkt.getRtcpHdrInfo();
49 *pobjRtcpHdr = rtcpHeader;
50 }
51
getRtcpHdrInfo()52 RtcpHeader* RtcpSrPacket::getRtcpHdrInfo()
53 {
54 return m_objRrPkt.getRtcpHdrInfo();
55 }
56
57 /*********************************************************
58 * Function name : getRrPktInfo
59 * Description : get method for m_objRrPkt
60 * Return type : RtcpRrPacket*
61 * Argument : None
62 * Preconditions : None
63 * Side Effects : None
64 ********************************************************/
getRrPktInfo()65 RtcpRrPacket* RtcpSrPacket::getRrPktInfo()
66 {
67 return &m_objRrPkt;
68 }
69
70 /*********************************************************
71 * Function name : getNtpTime
72 * Description : get method for m_stNtpTimestamp
73 * Return type : tRTP_NTP_TIME*
74 * Argument : None
75 * Preconditions : None
76 * Side Effects : None
77 ********************************************************/
getNtpTime()78 tRTP_NTP_TIME* RtcpSrPacket::getNtpTime()
79 {
80 return &m_stNtpTimestamp;
81 }
82
83 /*********************************************************
84 * Function name : setRtpTimestamp
85 * Description : set method for m_uiRtpTimestamp
86 * Return type : RtpDt_Void
87 * Argument : RtpDt_UInt32 : In
88 * RTP timestamp
89 * Preconditions : None
90 * Side Effects : None
91 ********************************************************/
setRtpTimestamp(IN RtpDt_UInt32 uiRtpTimestamp)92 RtpDt_Void RtcpSrPacket::setRtpTimestamp(IN RtpDt_UInt32 uiRtpTimestamp)
93 {
94 m_uiRtpTimestamp = uiRtpTimestamp;
95 }
96
97 /*********************************************************
98 * Function name : getRtpTimestamp
99 * Description : get method for m_uiRtpTimestamp
100 * Return type : RtpDt_UInt32
101 * Argument : None
102 * Preconditions : None
103 * Side Effects : None
104 ********************************************************/
getRtpTimestamp()105 RtpDt_UInt32 RtcpSrPacket::getRtpTimestamp()
106 {
107 return m_uiRtpTimestamp;
108 }
109
110 /*********************************************************
111 * Function name : setSendPktCount
112 * Description : set method for m_uiSendPktCount
113 * Return type : RtpDt_Void
114 * Argument : RtpDt_UInt32 : In
115 * Preconditions : None
116 * Side Effects : None
117 ********************************************************/
setSendPktCount(IN RtpDt_UInt32 uiPktCount)118 RtpDt_Void RtcpSrPacket::setSendPktCount(IN RtpDt_UInt32 uiPktCount)
119 {
120 m_uiSendPktCount = uiPktCount;
121 }
122
123 /*********************************************************
124 * Function name : getSendPktCount
125 * Description : get method for m_uiSendPktCount
126 * Return type : RtpDt_UInt32
127 * Argument : None
128 * Preconditions : None
129 * Side Effects : None
130 ********************************************************/
getSendPktCount()131 RtpDt_UInt32 RtcpSrPacket::getSendPktCount()
132 {
133 return m_uiSendPktCount;
134 }
135
136 /*********************************************************
137 * Function name : setSendOctetCount
138 * Description : set method for m_uiSendOctCount
139 * Return type : RtpDt_Void
140 * Argument : RtpDt_UInt32 : In
141 * Preconditions : None
142 * Side Effects : None
143 ********************************************************/
setSendOctetCount(IN RtpDt_UInt32 uiOctetCount)144 RtpDt_Void RtcpSrPacket::setSendOctetCount(IN RtpDt_UInt32 uiOctetCount)
145 {
146 m_uiSendOctCount = uiOctetCount;
147 }
148
149 /*********************************************************
150 * Function name : getSendOctetCount
151 * Description : get method for m_uiSendOctCount
152 * Return type : RtpDt_UInt32
153 * Argument : None
154 * Preconditions : None
155 * Side Effects : None
156 ********************************************************/
getSendOctetCount()157 RtpDt_UInt32 RtcpSrPacket::getSendOctetCount()
158 {
159 return m_uiSendOctCount;
160 }
161
162 /*********************************************************
163 * Function name : decodeSrPacket
164 * Description : Decodes and stores the information of the RTCP SR packet
165 * Return type : eRtp_Bool : eRTP_SUCCESS on successful decoding
166 * Argument : RtpDt_UChar* : In
167 * Argument : RtpDt_UInt32 : In
168 * RTCP SR packet length
169 * Preconditions : None
170 * Side Effects : None
171 ********************************************************/
decodeSrPacket(IN RtpDt_UChar * pucSrPktBuf,IN RtpDt_UInt16 usSrPktLen,IN RtpDt_UInt16 usExtHdrLen)172 eRTP_STATUS_CODE RtcpSrPacket::decodeSrPacket(
173 IN RtpDt_UChar* pucSrPktBuf, IN RtpDt_UInt16 usSrPktLen, IN RtpDt_UInt16 usExtHdrLen)
174 {
175 /*
176 0 1 2 3
177 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
178 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
179 header |V=2|P| RC | PT=SR=200 | length |
180 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
181 | SSRC of sender |
182 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
183 sender | NTP timestamp, most significant word |
184 info +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
185 | NTP timestamp, least significant word |
186 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
187 | RTP timestamp |
188 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
189 | sender's packet count |
190 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
191 | sender's octet count |
192 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
193 report | SSRC_1 (SSRC of first source) |
194 block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
195 1 | fraction lost | cumulative number of packets lost |
196 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
197 | extended highest sequence number received |
198 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
199 | interarrival jitter |
200 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
201 | last SR (LSR) |
202 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
203 | delay since last SR (DLSR) |
204 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
205 report | SSRC_2 (SSRC of second source) |
206 block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
207 2 : ... :
208 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
209 | profile-specific extensions |
210 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
211
212 */
213
214 if (pucSrPktBuf == nullptr || usSrPktLen < RTCP_SR_PACKET_LENGTH)
215 return RTP_FAILURE;
216
217 // NTP timestamp most significant word
218 m_stNtpTimestamp.m_uiNtpHigh32Bits =
219 RtpOsUtil::Ntohl(*(reinterpret_cast<RtpDt_UInt32*>(pucSrPktBuf)));
220 pucSrPktBuf = pucSrPktBuf + RTP_WORD_SIZE;
221 usSrPktLen = usSrPktLen - RTP_WORD_SIZE;
222
223 // NTP timestamp least significant word
224 m_stNtpTimestamp.m_uiNtpLow32Bits =
225 RtpOsUtil::Ntohl(*(reinterpret_cast<RtpDt_UInt32*>(pucSrPktBuf)));
226 pucSrPktBuf = pucSrPktBuf + RTP_WORD_SIZE;
227 usSrPktLen = usSrPktLen - RTP_WORD_SIZE;
228
229 // RTP timestamp
230 m_uiRtpTimestamp = RtpOsUtil::Ntohl(*(reinterpret_cast<RtpDt_UInt32*>(pucSrPktBuf)));
231 pucSrPktBuf = pucSrPktBuf + RTP_WORD_SIZE;
232 usSrPktLen = usSrPktLen - RTP_WORD_SIZE;
233
234 // sender's packet count
235 m_uiSendPktCount = RtpOsUtil::Ntohl(*(reinterpret_cast<RtpDt_UInt32*>(pucSrPktBuf)));
236 pucSrPktBuf = pucSrPktBuf + RTP_WORD_SIZE;
237 usSrPktLen = usSrPktLen - RTP_WORD_SIZE;
238
239 // sender's octet count
240 m_uiSendOctCount = RtpOsUtil::Ntohl(*(reinterpret_cast<RtpDt_UInt32*>(pucSrPktBuf)));
241 pucSrPktBuf = pucSrPktBuf + RTP_WORD_SIZE;
242 usSrPktLen = usSrPktLen - RTP_WORD_SIZE;
243
244 // decode report block
245 eRTP_STATUS_CODE eDecodeRes = RTP_FAILURE;
246 eDecodeRes = m_objRrPkt.decodeRrPacket(pucSrPktBuf, usSrPktLen, usExtHdrLen);
247 if (eDecodeRes != RTP_SUCCESS)
248 {
249 RTP_TRACE_WARNING(
250 "RtcpPacket::decodeRtcpPacket, RR packet Decoding Error[%d]", eDecodeRes, RTP_ZERO);
251 return eDecodeRes;
252 }
253
254 return RTP_SUCCESS;
255 } // decodeSrPacket
256
257 /*********************************************************
258 * Function name : formSrPacket
259 * Description : Performs the encoding of the RTCP SR packet.
260 * Return type : eRtp_Bool : eRTP_SUCCESS on successful encoding
261 * Argument : RtpBuffer* : Out
262 * Preconditions : None
263 * Side Effects : None
264 ********************************************************/
formSrPacket(OUT RtpBuffer * pobjRtcpPktBuf)265 eRTP_STATUS_CODE RtcpSrPacket::formSrPacket(OUT RtpBuffer* pobjRtcpPktBuf)
266 {
267 /*
268 0 1 2 3
269 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
270 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
271 header |V=2|P| RC | PT=SR=200 | length |
272 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
273 | SSRC of sender |
274 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
275 sender | NTP timestamp, most significant word |
276 info +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
277 | NTP timestamp, least significant word |
278 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
279 | RTP timestamp |
280 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
281 | sender's packet count |
282 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
283 | sender's octet count |
284 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
285 report | SSRC_1 (SSRC of first source) |
286 block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
287 1 | fraction lost | cumulative number of packets lost |
288 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
289 | extended highest sequence number received |
290 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
291 | interarrival jitter |
292 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
293 | last SR (LSR) |
294 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
295 | delay since last SR (DLSR) |
296 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
297 report | SSRC_2 (SSRC of second source) |
298 block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
299 2 : ... :
300 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
301 | profile-specific extensions |
302 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
303
304 */
305
306 RTP_TRACE_MESSAGE("formSrPacket", 0, 0);
307 RtpDt_UInt32 uiCurPos = pobjRtcpPktBuf->getLength();
308 RtpDt_UChar* pucBuffer = pobjRtcpPktBuf->getBuffer();
309 uiCurPos = uiCurPos + RTCP_FIXED_HDR_LEN;
310 pucBuffer = pucBuffer + RTCP_FIXED_HDR_LEN;
311
312 // get RTCP header information
313 RtcpHeader* pobjRtcpHdr = m_objRrPkt.getRtcpHdrInfo();
314
315 // encode m_stNtpTimestamp
316 *(reinterpret_cast<RtpDt_UInt32*>(pucBuffer)) =
317 RtpOsUtil::Ntohl(m_stNtpTimestamp.m_uiNtpHigh32Bits);
318 pucBuffer = pucBuffer + RTP_WORD_SIZE;
319 uiCurPos = uiCurPos + RTP_WORD_SIZE;
320
321 *(reinterpret_cast<RtpDt_UInt32*>(pucBuffer)) =
322 RtpOsUtil::Ntohl(m_stNtpTimestamp.m_uiNtpLow32Bits);
323 pucBuffer = pucBuffer + RTP_WORD_SIZE;
324 uiCurPos = uiCurPos + RTP_WORD_SIZE;
325
326 // encode m_uiRtpTimestamp
327 *(reinterpret_cast<RtpDt_UInt32*>(pucBuffer)) = RtpOsUtil::Ntohl(m_uiRtpTimestamp);
328 pucBuffer = pucBuffer + RTP_WORD_SIZE;
329 uiCurPos = uiCurPos + RTP_WORD_SIZE;
330
331 // encode m_uiSendPktCount
332 *(reinterpret_cast<RtpDt_UInt32*>(pucBuffer)) = RtpOsUtil::Ntohl(m_uiSendPktCount);
333 pucBuffer = pucBuffer + RTP_WORD_SIZE;
334 uiCurPos = uiCurPos + RTP_WORD_SIZE;
335
336 // encode m_uiSendOctCount
337 *(reinterpret_cast<RtpDt_UInt32*>(pucBuffer)) = RtpOsUtil::Ntohl(m_uiSendOctCount);
338 uiCurPos = uiCurPos + RTP_WORD_SIZE;
339
340 // encode report blocks
341 eRTP_STATUS_CODE eEncodeRes = RTP_FAILURE;
342
343 pobjRtcpPktBuf->setLength(uiCurPos);
344 eEncodeRes = m_objRrPkt.formRrPacket(pobjRtcpPktBuf, eRTP_FALSE);
345 if (eEncodeRes != RTP_SUCCESS)
346 {
347 RTP_TRACE_WARNING("[formSrPacket], Report Block Encoding Error", RTP_ZERO, RTP_ZERO);
348 return eEncodeRes;
349 }
350
351 // get length of the SR packet
352 RtpDt_UInt32 uiSrPktLen = pobjRtcpPktBuf->getLength();
353 #ifdef ENABLE_PADDING
354 pucBuffer = pobjRtcpPktBuf->getBuffer();
355 pucBuffer = pucBuffer + uiSrPktLen;
356 RtpDt_UInt32 uiPadLen = uiSrPktLen % RTP_WORD_SIZE;
357 if (uiPadLen != RTP_ZERO)
358 {
359 uiSrPktLen = uiSrPktLen + uiPadLen;
360 uiPadLen = RTP_WORD_SIZE - uiPadLen;
361 memset(pucBuffer, RTP_ZERO, uiPadLen);
362 pucBuffer = pucBuffer + uiPadLen;
363 pucBuffer = pucBuffer - RTP_ONE;
364 *(reinterpret_cast<RtpDt_UChar*>(pucBuffer)) = (RtpDt_UChar)uiPadLen;
365
366 // set pad bit in header
367 pobjRtcpHdr->setPadding();
368 // set length in header
369 pobjRtcpHdr->setLength(uiSrPktLen);
370 }
371 else
372 #endif
373 {
374 // set length in header
375 pobjRtcpHdr->setLength(uiSrPktLen);
376 }
377
378 // set compound RTCP packet position to ZERO.
379 pobjRtcpPktBuf->setLength(RTP_ZERO);
380 // form rtcp header
381 pobjRtcpHdr->formRtcpHeader(pobjRtcpPktBuf);
382 // set the actual position of the RTCP compound packet
383 pobjRtcpPktBuf->setLength(uiSrPktLen);
384
385 return RTP_SUCCESS;
386 } // formSrPacket
387