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