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 <RtcpSdesPacket.h>
18 #include <RtpTrace.h>
19 
RtcpSdesPacket()20 RtcpSdesPacket::RtcpSdesPacket() :
21         m_objSdesChunkList(std::list<RtcpChunk*>())
22 {
23 }
24 
~RtcpSdesPacket()25 RtcpSdesPacket::~RtcpSdesPacket()
26 {
27     // delete all RtcpChunk objects
28     for (const auto& pobjSdesChunk : m_objSdesChunkList)
29     {
30         delete pobjSdesChunk;
31     }
32     m_objSdesChunkList.clear();
33 }
34 
setRtcpHdrInfo(RtcpHeader & rtcpHeader)35 RtpDt_Void RtcpSdesPacket::setRtcpHdrInfo(RtcpHeader& rtcpHeader)
36 {
37     m_objRtcpHdr = rtcpHeader;
38 }
39 
getRtcpHdrInfo()40 RtcpHeader* RtcpSdesPacket::getRtcpHdrInfo()
41 {
42     return &m_objRtcpHdr;
43 }
44 
getSdesChunkList()45 std::list<RtcpChunk*>& RtcpSdesPacket::getSdesChunkList()
46 {
47     return m_objSdesChunkList;
48 }
49 
decodeSdesPacket(IN RtpDt_UChar * pucSdesBuf,IN RtpDt_UInt16 usSdesLen,IN RtcpConfigInfo * pobjRtcpCfgInfo)50 eRTP_STATUS_CODE RtcpSdesPacket::decodeSdesPacket(
51         IN RtpDt_UChar* pucSdesBuf, IN RtpDt_UInt16 usSdesLen, IN RtcpConfigInfo* pobjRtcpCfgInfo)
52 {
53     RtpDt_UChar unSourceCount = m_objRtcpHdr.getReceptionReportCount();
54     while ((unSourceCount > RTP_ZERO) && (usSdesLen > RTP_ZERO))
55     {
56         RtcpChunk* pobjRtcpChunk = new RtcpChunk();
57         if (pobjRtcpChunk == nullptr)
58         {
59             RTP_TRACE_ERROR("[Memory Error] new returned NULL.", RTP_ZERO, RTP_ZERO);
60             return RTP_MEMORY_FAIL;
61         }
62 
63         RtpDt_UInt16 usChunkSize = RTP_ZERO;
64         eRTP_STATUS_CODE eChunkStatus = RTP_FAILURE;
65 
66         eChunkStatus = pobjRtcpChunk->decodeRtcpChunk(pucSdesBuf, usChunkSize, pobjRtcpCfgInfo);
67         m_objSdesChunkList.push_back(pobjRtcpChunk);
68         if (eChunkStatus != RTP_SUCCESS)
69         {
70             return eChunkStatus;
71         }
72 
73         RtpDt_UInt32 uiPadLen = RTP_ZERO;
74         uiPadLen = usChunkSize % RTP_WORD_SIZE;
75 
76         if (uiPadLen != RTP_ZERO)
77         {
78             uiPadLen = RTP_WORD_SIZE - uiPadLen;
79             usChunkSize += uiPadLen;
80         }
81         pucSdesBuf += usChunkSize;
82         usSdesLen -= usChunkSize;
83         unSourceCount--;
84     }
85 
86     return RTP_SUCCESS;
87 }  // decodeSdesPacket
88 
formSdesPacket(OUT RtpBuffer * pobjRtcpPktBuf)89 eRTP_STATUS_CODE RtcpSdesPacket::formSdesPacket(OUT RtpBuffer* pobjRtcpPktBuf)
90 {
91     RtpDt_UInt32 uiSdesPktPos = pobjRtcpPktBuf->getLength();
92 
93     RtpDt_UInt32 uiCurPos = uiSdesPktPos;
94     uiCurPos = uiCurPos + RTP_WORD_SIZE;
95 
96     // SDES packet does not have SSRC in header.
97     pobjRtcpPktBuf->setLength(uiCurPos);
98 
99     // m_objSdesChunkList
100     for (auto& pobjRtcpChunk : m_objSdesChunkList)
101     {
102         eRTP_STATUS_CODE eChunkStatus = RTP_FAILURE;
103 
104         eChunkStatus = pobjRtcpChunk->formRtcpChunk(pobjRtcpPktBuf);
105 
106         if (eChunkStatus != RTP_SUCCESS)
107         {
108             return eChunkStatus;
109         }
110 
111         RtpDt_UInt32 uiSdesPktLen = RTP_ZERO;
112 
113         uiCurPos = pobjRtcpPktBuf->getLength();
114         uiSdesPktLen = uiCurPos - uiSdesPktPos;
115 #ifdef ENABLE_PADDING
116         RtpDt_UChar* pucBuffer = pobjRtcpPktBuf->getBuffer();
117         pucBuffer = pucBuffer + uiCurPos;
118         RtpDt_UInt32 uiPadLen = uiSdesPktLen % RTP_WORD_SIZE;
119 
120         if (uiPadLen > RTP_ZERO)
121         {
122             uiPadLen = RTP_WORD_SIZE - uiPadLen;
123             uiSdesPktLen = uiSdesPktLen + uiPadLen;
124             uiCurPos = uiCurPos + uiPadLen;
125             memset(pucBuffer, RTP_ZERO, uiPadLen);
126         }
127 #endif
128         m_objRtcpHdr.setLength(uiSdesPktLen);
129     }  // for
130 
131     pobjRtcpPktBuf->setLength(uiSdesPktPos);
132     m_objRtcpHdr.formPartialRtcpHeader(pobjRtcpPktBuf);
133 
134     RTP_TRACE_MESSAGE(
135             "formSdesPacket, [SDES packet length] : %d]", m_objRtcpHdr.getLength(), nullptr);
136 
137     // set the actual position of the RTCP compound packet
138     pobjRtcpPktBuf->setLength(uiCurPos);
139 
140     return RTP_SUCCESS;
141 }  // formSdesPacket
142