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 <RtcpPacket.h>
18 #include <RtpTrace.h>
19 #include <RtpError.h>
20 #include <RtpSession.h>
21 
RtcpPacket()22 RtcpPacket::RtcpPacket() :
23         m_objSrPktList(std::list<RtcpSrPacket*>()),
24         m_objRrPktList(std::list<RtcpRrPacket*>()),
25         m_objFbPktList(std::list<RtcpFbPacket*>()),
26         m_pobjSdesPkt(nullptr),
27         m_pobjByePkt(nullptr),
28         m_pobjAppPkt(nullptr),
29         m_pobjRtcpXrPkt(nullptr)
30 
31 {
32 }  // Constructor
33 
~RtcpPacket()34 RtcpPacket::~RtcpPacket()
35 {
36     // delete all RtcpSrPacket objects.
37     for (const auto& pobjSrPkt : m_objSrPktList)
38     {
39         delete pobjSrPkt;
40     }
41     m_objSrPktList.clear();
42 
43     // delete all RtcpRrPacket objects
44     for (const auto& pobjRrPkt : m_objRrPktList)
45     {
46         delete pobjRrPkt;
47     }
48     m_objRrPktList.clear();
49 
50     // delete all RtcpFbPacket objects
51     for (const auto& pobjFbPkt : m_objFbPktList)
52     {
53         delete pobjFbPkt;
54     }
55     m_objFbPktList.clear();
56 
57     if (m_pobjSdesPkt != nullptr)
58     {
59         delete m_pobjSdesPkt;
60         m_pobjSdesPkt = nullptr;
61     }
62     if (m_pobjByePkt != nullptr)
63     {
64         delete m_pobjByePkt;
65         m_pobjByePkt = nullptr;
66     }
67     if (m_pobjAppPkt != nullptr)
68     {
69         delete m_pobjAppPkt;
70         m_pobjAppPkt = nullptr;
71     }
72 
73     if (m_pobjRtcpXrPkt != nullptr)
74     {
75         delete m_pobjRtcpXrPkt;
76         m_pobjRtcpXrPkt = nullptr;
77     }
78 }  // Destructor
79 
getHeader()80 RtcpHeader RtcpPacket::getHeader()
81 {
82     return m_objHeader;
83 }
84 
getSrPacketList()85 std::list<RtcpSrPacket*>& RtcpPacket::getSrPacketList()
86 {
87     return m_objSrPktList;
88 }
89 
getRrPacketList()90 std::list<RtcpRrPacket*>& RtcpPacket::getRrPacketList()
91 {
92     return m_objRrPktList;
93 }
94 
getFbPacketList()95 std::list<RtcpFbPacket*>& RtcpPacket::getFbPacketList()
96 {
97     return m_objFbPktList;
98 }
99 
getSdesPacket()100 RtcpSdesPacket* RtcpPacket::getSdesPacket()
101 {
102     return m_pobjSdesPkt;
103 }
104 
setSdesPacketData(IN RtcpSdesPacket * pobjSdesData)105 RtpDt_Void RtcpPacket::setSdesPacketData(IN RtcpSdesPacket* pobjSdesData)
106 {
107     m_pobjSdesPkt = pobjSdesData;
108 }
109 
getByePacket()110 RtcpByePacket* RtcpPacket::getByePacket()
111 {
112     return m_pobjByePkt;
113 }
114 
setByePacketData(IN RtcpByePacket * pobjByePktData)115 RtpDt_Void RtcpPacket::setByePacketData(IN RtcpByePacket* pobjByePktData)
116 {
117     m_pobjByePkt = pobjByePktData;
118 }
119 
getAppPacket()120 RtcpAppPacket* RtcpPacket::getAppPacket()
121 {
122     return m_pobjAppPkt;
123 }
124 
setAppPktData(IN RtcpAppPacket * pobjAppData)125 RtpDt_Void RtcpPacket::setAppPktData(IN RtcpAppPacket* pobjAppData)
126 {
127     m_pobjAppPkt = pobjAppData;
128 }
129 
addSrPacketData(IN RtcpSrPacket * pobjSrPkt)130 eRTP_STATUS_CODE RtcpPacket::addSrPacketData(IN RtcpSrPacket* pobjSrPkt)
131 {
132     if (pobjSrPkt == nullptr)
133     {
134         return RTP_FAILURE;
135     }
136     m_objSrPktList.push_back(pobjSrPkt);
137     return RTP_SUCCESS;
138 }
139 
addRrPacketData(IN RtcpRrPacket * pobjRrPkt)140 eRTP_STATUS_CODE RtcpPacket::addRrPacketData(IN RtcpRrPacket* pobjRrPkt)
141 {
142     if (pobjRrPkt == nullptr)
143     {
144         return RTP_FAILURE;
145     }
146     m_objRrPktList.push_back(pobjRrPkt);
147     return RTP_SUCCESS;
148 }
149 
addFbPacketData(IN RtcpFbPacket * pobjFbPkt)150 eRTP_STATUS_CODE RtcpPacket::addFbPacketData(IN RtcpFbPacket* pobjFbPkt)
151 {
152     if (pobjFbPkt == nullptr)
153     {
154         return RTP_FAILURE;
155     }
156     m_objFbPktList.push_back(pobjFbPkt);
157     return RTP_SUCCESS;
158 }
159 
getXrPacket()160 RtcpXrPacket* RtcpPacket::getXrPacket()
161 {
162     return m_pobjRtcpXrPkt;
163 }
164 
setXrPacket(IN RtcpXrPacket * pobjRtcpXrData)165 RtpDt_Void RtcpPacket::setXrPacket(IN RtcpXrPacket* pobjRtcpXrData)
166 {
167     m_pobjRtcpXrPkt = pobjRtcpXrData;
168 }
169 
decodeRtcpPacket(IN RtpBuffer * pobjRtcpPktBuf,IN RtpDt_UInt16 usExtHdrLen,IN RtcpConfigInfo * pobjRtcpCfgInfo)170 eRTP_STATUS_CODE RtcpPacket::decodeRtcpPacket(IN RtpBuffer* pobjRtcpPktBuf,
171         IN RtpDt_UInt16 usExtHdrLen, IN RtcpConfigInfo* pobjRtcpCfgInfo)
172 {
173     RtpDt_UInt32 uiCurPos = RTP_ZERO;
174     eRtp_Bool bSrPkt = eRTP_FALSE;
175     eRtp_Bool bRrPkt = eRTP_FALSE;
176     eRtp_Bool bFbPkt = eRTP_FALSE;
177     eRtp_Bool bOtherPkt = eRTP_FALSE;
178 
179     if (pobjRtcpPktBuf == nullptr || pobjRtcpPktBuf->getBuffer() == nullptr ||
180             pobjRtcpPktBuf->getLength() < RTP_WORD_SIZE)
181         return RTP_INVALID_PARAMS;
182 
183     // Check RTCP with only common header case.
184     if (pobjRtcpPktBuf->getLength() == RTP_WORD_SIZE)
185     {
186         m_objHeader.decodeRtcpHeader(pobjRtcpPktBuf->getBuffer(), pobjRtcpPktBuf->getLength());
187         return RTP_SUCCESS;
188     }
189 
190     // Get RTCP Compound packet
191     RtpDt_UInt32 uiCompPktLen = pobjRtcpPktBuf->getLength();
192     RtpDt_Int32 iTrackCompLen = uiCompPktLen;
193 
194     while (iTrackCompLen >= RTCP_FIXED_HDR_LEN)
195     {
196         RtpDt_UChar* pucBuffer = pobjRtcpPktBuf->getBuffer();
197         pucBuffer += uiCurPos;
198 
199         m_objHeader.decodeRtcpHeader(pucBuffer, iTrackCompLen);
200         uiCurPos += RTCP_FIXED_HDR_LEN;
201         pucBuffer += RTCP_FIXED_HDR_LEN;
202         iTrackCompLen -= RTCP_FIXED_HDR_LEN;
203 
204         RtpDt_UChar uiVersion = m_objHeader.getVersion();
205         if (uiVersion != RTP_VERSION_NUM)
206         {
207             RTP_TRACE_ERROR("[DecodeRtcpPacket] RTCP version[%d] is Invalid.", uiVersion, RTP_ZERO);
208             return RTP_INVALID_MSG;
209         }
210 
211         // get length
212         RtpDt_UInt16 usPktLen = m_objHeader.getLength();
213         usPktLen -= RTP_WORD_SIZE;
214         if (usPktLen > iTrackCompLen)
215         {
216             RTP_TRACE_ERROR("[DecodeRtcpPacket] Report length is Invalid. ReportLen:%d, RtcpLen:%d",
217                     usPktLen, iTrackCompLen);
218             return RTP_INVALID_MSG;
219         }
220 
221         RTP_TRACE_MESSAGE("[DecodeRtcpPacket] packet length: %d, compound packet length: %d",
222                 usPktLen, iTrackCompLen);
223 
224         // get packet type
225         RtpDt_UInt32 uiPktType = m_objHeader.getPacketType();
226 
227         RTP_TRACE_MESSAGE("[DecodeRtcpPacket] packet type: %d report count: %d", uiPktType,
228                 m_objHeader.getReceptionReportCount());
229 
230         eRTP_STATUS_CODE eDecodeRes = RTP_FAILURE;
231 
232         switch (uiPktType)
233         {
234             case RTCP_SR:
235             {
236                 RTP_TRACE_MESSAGE("[DecodeRtcpPacket] Decoding RTCP_SR", 0, 0);
237                 RtcpSrPacket* pobjSrPkt = new RtcpSrPacket();
238                 if (pobjSrPkt == nullptr)
239                 {
240                     RTP_TRACE_ERROR("[Memory Error] new returned NULL.", RTP_ZERO, RTP_ZERO);
241                     return RTP_MEMORY_FAIL;
242                 }
243                 pobjSrPkt->setRtcpHdrInfo(m_objHeader);
244                 eDecodeRes = pobjSrPkt->decodeSrPacket(pucBuffer, usPktLen, usExtHdrLen);
245                 addSrPacketData(pobjSrPkt);
246                 bSrPkt = eRTP_TRUE;
247                 break;
248             }  // RTCP_SR
249             case RTCP_RR:
250             {
251                 RTP_TRACE_MESSAGE("[DecodeRtcpPacket] Decoding RTCP_RR", 0, 0);
252                 RtpDt_UInt16 uiRrPktLen = usPktLen;
253                 RtcpRrPacket* pobjRrPkt = new RtcpRrPacket();
254                 if (pobjRrPkt == nullptr)
255                 {
256                     RTP_TRACE_ERROR("[Memory Error] new returned NULL.", RTP_ZERO, RTP_ZERO);
257                     return RTP_MEMORY_FAIL;
258                 }
259                 pobjRrPkt->setRtcpHdrInfo(m_objHeader);
260                 eDecodeRes = pobjRrPkt->decodeRrPacket(pucBuffer, uiRrPktLen, usExtHdrLen);
261                 addRrPacketData(pobjRrPkt);
262                 bRrPkt = eRTP_TRUE;
263                 break;
264             }  // RTCP_RR
265             case RTCP_SDES:
266             {
267                 RTP_TRACE_MESSAGE("[DecodeRtcpPacket] Decoding RTCP_SDES", 0, 0);
268                 if (m_pobjSdesPkt != nullptr)
269                     delete m_pobjSdesPkt;
270 
271                 m_pobjSdesPkt = new RtcpSdesPacket();
272                 if (m_pobjSdesPkt == nullptr)
273                 {
274                     RTP_TRACE_ERROR("[Memory Error] new returned NULL.", RTP_ZERO, RTP_ZERO);
275                     return RTP_MEMORY_FAIL;
276                 }
277                 m_pobjSdesPkt->setRtcpHdrInfo(m_objHeader);
278                 eDecodeRes = m_pobjSdesPkt->decodeSdesPacket(pucBuffer, usPktLen, pobjRtcpCfgInfo);
279                 bOtherPkt = eRTP_TRUE;
280                 break;
281             }  // RTCP_SDES
282             case RTCP_BYE:
283             {
284                 RTP_TRACE_MESSAGE("[DecodeRtcpPacket] Decoding RTCP_BYE", 0, 0);
285                 if (m_pobjByePkt != nullptr)
286                     delete m_pobjByePkt;
287 
288                 m_pobjByePkt = new RtcpByePacket();
289                 if (m_pobjByePkt == nullptr)
290                 {
291                     RTP_TRACE_ERROR("[Memory Error] new returned NULL.", RTP_ZERO, RTP_ZERO);
292                     return RTP_MEMORY_FAIL;
293                 }
294                 m_pobjByePkt->setRtcpHdrInfo(m_objHeader);
295                 eDecodeRes = m_pobjByePkt->decodeByePacket(pucBuffer, usPktLen);
296                 bOtherPkt = eRTP_TRUE;
297                 break;
298             }  // RTCP_BYE
299             case RTCP_APP:
300             {
301                 RTP_TRACE_MESSAGE("[DecodeRtcpPacket] Decoding RTCP_APP", 0, 0);
302                 if (m_pobjAppPkt != nullptr)
303                     delete m_pobjAppPkt;
304 
305                 m_pobjAppPkt = new RtcpAppPacket();
306                 if (m_pobjAppPkt == nullptr)
307                 {
308                     RTP_TRACE_ERROR("[Memory Error] new returned NULL.", RTP_ZERO, RTP_ZERO);
309                     return RTP_MEMORY_FAIL;
310                 }
311                 m_pobjAppPkt->setRtcpHdrInfo(m_objHeader);
312                 eDecodeRes = m_pobjAppPkt->decodeAppPacket(pucBuffer, usPktLen);
313                 bOtherPkt = eRTP_TRUE;
314                 break;
315             }  // RTCP_APP
316             case RTCP_RTPFB:
317             case RTCP_PSFB:
318             {
319                 RTP_TRACE_MESSAGE("[DecodeRtcpPacket] Decoding RTCP_RTPFB", 0, 0);
320                 RtcpFbPacket* pobjFbPkt = new RtcpFbPacket();
321                 if (pobjFbPkt == nullptr)
322                 {
323                     RTP_TRACE_ERROR("[Memory Error] new returned NULL.", RTP_ZERO, RTP_ZERO);
324                     return RTP_MEMORY_FAIL;
325                 }
326 
327                 pobjFbPkt->setRtcpHdrInfo(m_objHeader);
328                 eDecodeRes = pobjFbPkt->decodeRtcpFbPacket(pucBuffer, usPktLen);
329                 addFbPacketData(pobjFbPkt);
330                 bFbPkt = eRTP_TRUE;
331                 break;
332             }  // RTCP_RTPFB || RTCP_PSFB
333             case RTCP_XR:
334             {
335                 RTP_TRACE_MESSAGE("[DecodeRtcpPacket] Decoding RTCP_XR", 0, 0);
336                 if (m_pobjRtcpXrPkt != nullptr)
337                     delete m_pobjRtcpXrPkt;
338 
339                 m_pobjRtcpXrPkt = new RtcpXrPacket();
340                 if (m_pobjRtcpXrPkt == nullptr)
341                 {
342                     RTP_TRACE_ERROR("[Memory Error] new returned NULL.", RTP_ZERO, RTP_ZERO);
343                     return RTP_MEMORY_FAIL;
344                 }
345                 m_pobjRtcpXrPkt->setRtcpHdrInfo(m_objHeader);
346                 eDecodeRes = m_pobjRtcpXrPkt->decodeRtcpXrPacket(pucBuffer, usPktLen, uiPktType);
347                 bOtherPkt = eRTP_TRUE;
348                 break;
349             }  // RTCP_XR
350             default:
351             {
352                 RTP_TRACE_WARNING("[DecodeRtcpPacket], Invalid RTCP MSG type[%d] received",
353                         uiPktType, RTP_ZERO);
354                 // Instead of returning failure, ignore unknown report block and continue to decode
355                 // next report block.
356                 eDecodeRes = RTP_SUCCESS;
357             }  // default
358         };     // switch
359 
360         if (eDecodeRes != RTP_SUCCESS)
361         {
362             RTP_TRACE_ERROR("[DecodeRtcpPacket], Decoding Error[%d]", eDecodeRes, RTP_ZERO);
363             return eDecodeRes;
364         }
365 
366         iTrackCompLen -= usPktLen;
367         uiCurPos += usPktLen;
368     }  // while
369 
370     if ((bSrPkt == eRTP_FALSE) && (bRrPkt == eRTP_FALSE) && (bFbPkt == eRTP_FALSE) &&
371             (bOtherPkt == eRTP_FALSE))
372     {
373         RTP_TRACE_ERROR("[DecodeRtcpPacket], no rtcp sr,rr,fb packets", 0, 0);
374         return RTP_DECODE_ERROR;
375     }
376 
377     return RTP_SUCCESS;
378 }  // decodeRtcpPacket
379 
formRtcpPacket(OUT RtpBuffer * pobjRtcpPktBuf)380 eRTP_STATUS_CODE RtcpPacket::formRtcpPacket(OUT RtpBuffer* pobjRtcpPktBuf)
381 {
382     RTP_TRACE_MESSAGE("formRtcpPacket", 0, 0);
383     RtpDt_UInt16 usSrSize = m_objSrPktList.size();
384     RtpDt_UInt16 usRrSize = m_objRrPktList.size();
385     RtpDt_UInt16 usFbSize = m_objFbPktList.size();
386 
387     pobjRtcpPktBuf->setLength(RTP_ZERO);
388 
389     if ((usSrSize == RTP_ZERO) && (usRrSize == RTP_ZERO) && (m_pobjByePkt == nullptr))
390     {
391         RTP_TRACE_WARNING("[formRtcpPacket] m_pobjSrPkt is NULL", RTP_ZERO, RTP_ZERO);
392         return RTP_FAILURE;
393     }
394 
395     if ((m_pobjByePkt == nullptr) && (m_pobjSdesPkt == nullptr) && (m_pobjAppPkt == nullptr) &&
396             (usFbSize == RTP_ZERO))
397     {
398         RTP_TRACE_WARNING("[formRtcpPacket] Not present 2nd pkt in Comp pkt", RTP_ZERO, RTP_ZERO);
399         return RTP_FAILURE;
400     }
401 
402     eRTP_STATUS_CODE eEncodeRes = RTP_FAILURE;
403 
404     for (auto& pobjSrPkt : m_objSrPktList)
405     {
406         // get key material element from list.
407         eEncodeRes = pobjSrPkt->formSrPacket(pobjRtcpPktBuf);
408         if (eEncodeRes != RTP_SUCCESS)
409         {
410             RTP_TRACE_WARNING("[formRtcpPacket] Error in SR pkt encoding", RTP_ZERO, RTP_ZERO);
411             return eEncodeRes;
412         }
413     }
414 
415     for (auto& pobjRrPkt : m_objRrPktList)
416     {
417         // get key material element from list.
418         eEncodeRes = pobjRrPkt->formRrPacket(pobjRtcpPktBuf, eRTP_TRUE);
419         if (eEncodeRes != RTP_SUCCESS)
420         {
421             RTP_TRACE_WARNING("[formRtcpPacket] Error in RR pkt encoding", RTP_ZERO, RTP_ZERO);
422             return eEncodeRes;
423         }
424     }
425 
426     if (m_pobjSdesPkt != nullptr)
427     {
428         eEncodeRes = m_pobjSdesPkt->formSdesPacket(pobjRtcpPktBuf);
429         if (eEncodeRes != RTP_SUCCESS)
430         {
431             RTP_TRACE_WARNING("[formRtcpPacket] Error in SDES pkt encoding", RTP_ZERO, RTP_ZERO);
432             return eEncodeRes;
433         }
434     }
435 
436     if (m_pobjAppPkt != nullptr)
437     {
438         eEncodeRes = m_pobjAppPkt->formAppPacket(pobjRtcpPktBuf);
439         if (eEncodeRes != RTP_SUCCESS)
440         {
441             RTP_TRACE_WARNING("[formRtcpPacket] Error in APP pkt encoding", RTP_ZERO, RTP_ZERO);
442             return eEncodeRes;
443         }
444     }
445     if (m_pobjByePkt != nullptr)
446     {
447         eEncodeRes = m_pobjByePkt->formByePacket(pobjRtcpPktBuf);
448         if (eEncodeRes != RTP_SUCCESS)
449         {
450             RTP_TRACE_WARNING("[formRtcpPacket] Error in BYE pkt encoding", RTP_ZERO, RTP_ZERO);
451             return eEncodeRes;
452         }
453     }
454 
455     if (m_objFbPktList.size() != RTP_ZERO)
456     {
457         RtcpFbPacket* pobjRtcpFbPkt = m_objFbPktList.front();
458         eEncodeRes = pobjRtcpFbPkt->formRtcpFbPacket(pobjRtcpPktBuf);
459         if (eEncodeRes != RTP_SUCCESS)
460         {
461             RTP_TRACE_WARNING("[formRtcpPacket] Error in Fb pkt encoding.", RTP_ZERO, RTP_ZERO);
462             return eEncodeRes;
463         }
464     }
465 
466     if (m_pobjRtcpXrPkt != nullptr)
467     {
468         eEncodeRes = m_pobjRtcpXrPkt->formRtcpXrPacket(pobjRtcpPktBuf);
469         if (eEncodeRes != RTP_SUCCESS)
470         {
471             RTP_TRACE_WARNING("[formRtcpPacket] Error in XR pkt encoding", RTP_ZERO, RTP_ZERO);
472             return eEncodeRes;
473         }
474     }
475 
476     return RTP_SUCCESS;
477 }  // formRtcpPacket
478