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 <RtcpByePacket.h>
18 #include <RtpTrace.h>
19
RtcpByePacket()20 RtcpByePacket::RtcpByePacket() :
21 m_uiSsrcList(std::list<RtpDt_UInt32*>()),
22 m_pReason(nullptr)
23 {
24 } // Constructor
25
~RtcpByePacket()26 RtcpByePacket::~RtcpByePacket()
27 {
28 // delete all ssrc objects
29 for (const auto& puiSsrc : m_uiSsrcList)
30 {
31 delete puiSsrc;
32 }
33 m_uiSsrcList.clear();
34
35 if (m_pReason != nullptr)
36 {
37 delete m_pReason;
38 m_pReason = nullptr;
39 }
40 } // Destructor
41
setRtcpHdrInfo(RtcpHeader & objRtcpHeader)42 RtpDt_Void RtcpByePacket::setRtcpHdrInfo(RtcpHeader& objRtcpHeader)
43 {
44 m_objRtcpHdr = objRtcpHeader;
45 }
46
getRtcpHdrInfo()47 RtcpHeader* RtcpByePacket::getRtcpHdrInfo()
48 {
49 return &m_objRtcpHdr;
50 }
51
getSsrcList()52 std::list<RtpDt_UInt32*>& RtcpByePacket::getSsrcList()
53 {
54 return m_uiSsrcList;
55 }
56
getReason()57 RtpBuffer* RtcpByePacket::getReason()
58 {
59 return m_pReason;
60 }
61
setReason(IN RtpBuffer * pobjReason)62 RtpDt_Void RtcpByePacket::setReason(IN RtpBuffer* pobjReason)
63 {
64 m_pReason = pobjReason;
65 }
66
decodeByePacket(IN RtpDt_UChar * pucByeBuf,IN RtpDt_UInt16 usByeLen)67 eRTP_STATUS_CODE RtcpByePacket::decodeByePacket(IN RtpDt_UChar* pucByeBuf, IN RtpDt_UInt16 usByeLen)
68 {
69 RtpDt_UChar ucSsrcCnt = m_objRtcpHdr.getReceptionReportCount();
70 // m_uiSsrcList
71 while (ucSsrcCnt > RTP_ONE && usByeLen >= RTP_WORD_SIZE)
72 {
73 RtpDt_UInt32* puiRcvdSsrc = nullptr;
74 puiRcvdSsrc = new RtpDt_UInt32();
75 if (puiRcvdSsrc == nullptr)
76 {
77 RTP_TRACE_ERROR("[Memory Error] new returned NULL.", RTP_ZERO, RTP_ZERO);
78 return RTP_MEMORY_FAIL;
79 }
80
81 (*puiRcvdSsrc) = RtpOsUtil::Ntohl(*(reinterpret_cast<RtpDt_UInt32*>(pucByeBuf)));
82 pucByeBuf = pucByeBuf + RTP_WORD_SIZE;
83
84 m_uiSsrcList.push_back(puiRcvdSsrc);
85 ucSsrcCnt = ucSsrcCnt - RTP_ONE;
86 usByeLen -= RTP_WORD_SIZE;
87 } // while
88
89 if (usByeLen >= RTP_ONE) // check if optional length is present.
90 {
91 // m_pReason
92 RtpDt_UInt32 uiByte4Data = RtpOsUtil::Ntohl(*(reinterpret_cast<RtpDt_UInt32*>(pucByeBuf)));
93 pucByeBuf = pucByeBuf + RTP_ONE;
94 uiByte4Data = uiByte4Data >> RTP_24; // length of "Reason for leaving"
95 if (uiByte4Data > RTP_ZERO)
96 {
97 RtpDt_UChar* pucReason = new RtpDt_UChar[uiByte4Data];
98 if (pucReason == nullptr)
99 {
100 RTP_TRACE_ERROR("[Memory Error] new returned NULL.", RTP_ZERO, RTP_ZERO);
101 return RTP_MEMORY_FAIL;
102 }
103
104 m_pReason = new RtpBuffer();
105 if (m_pReason == nullptr)
106 {
107 RTP_TRACE_ERROR("[Memory Error] new returned NULL.", RTP_ZERO, RTP_ZERO);
108 delete[] pucReason;
109 return RTP_MEMORY_FAIL;
110 }
111 memset(pucReason, RTP_ZERO, uiByte4Data);
112 memcpy(pucReason, pucByeBuf, uiByte4Data);
113 m_pReason->setBufferInfo(uiByte4Data, pucReason);
114 } // if
115 }
116 return RTP_SUCCESS;
117 } // decodeByePacket
118
formByePacket(OUT RtpBuffer * pobjRtcpPktBuf)119 eRTP_STATUS_CODE RtcpByePacket::formByePacket(OUT RtpBuffer* pobjRtcpPktBuf)
120 {
121 RtpDt_UInt32 uiCurPos = pobjRtcpPktBuf->getLength();
122 RtpDt_UChar* pucBuffer = pobjRtcpPktBuf->getBuffer();
123
124 uiCurPos = uiCurPos + RTCP_FIXED_HDR_LEN;
125 pucBuffer = pucBuffer + uiCurPos;
126
127 for (auto& puiSsrc : m_uiSsrcList)
128 {
129 // ssrc
130 *(reinterpret_cast<RtpDt_UInt32*>(pucBuffer)) = RtpOsUtil::Ntohl(*puiSsrc);
131 pucBuffer = pucBuffer + RTP_WORD_SIZE;
132 uiCurPos = uiCurPos + RTP_WORD_SIZE;
133 }
134
135 // m_pReason
136 if (m_pReason != nullptr)
137 {
138 // length
139 *(reinterpret_cast<RtpDt_UChar*>(pucBuffer)) = (RtpDt_UChar)m_pReason->getLength();
140 pucBuffer = pucBuffer + RTP_ONE;
141 uiCurPos = uiCurPos + RTP_ONE;
142
143 memcpy(pucBuffer, m_pReason->getBuffer(), m_pReason->getLength());
144 uiCurPos = uiCurPos + m_pReason->getLength();
145 }
146
147 // padding
148 {
149 RtpDt_UInt32 uiByePktPos = pobjRtcpPktBuf->getLength();
150 RtpDt_UInt32 uiByePktLen = uiCurPos - uiByePktPos;
151
152 #ifdef ENABLE_PADDING
153 RtpDt_UInt32 uiPadLen = uiByePktLen % RTP_WORD_SIZE;
154 if (uiPadLen > RTP_ZERO)
155 {
156 uiPadLen = RTP_WORD_SIZE - uiPadLen;
157 uiByePktLen = uiByePktLen + uiPadLen;
158 uiCurPos = uiCurPos + uiPadLen;
159 pucBuffer = pucBuffer + m_pReason->getLength();
160 memset(pucBuffer, RTP_ZERO, uiPadLen);
161
162 pucBuffer = pucBuffer + uiPadLen;
163 pucBuffer = pucBuffer - RTP_ONE;
164 *(reinterpret_cast<RtpDt_UChar*>(pucBuffer)) = (RtpDt_UChar)uiPadLen;
165
166 // set pad bit in header
167 m_objRtcpHdr.setPadding();
168 // set length in header
169 m_objRtcpHdr.setLength(uiByePktLen);
170 }
171 else
172 #endif
173 {
174 // set length in header
175 m_objRtcpHdr.setLength(uiByePktLen);
176 }
177
178 pobjRtcpPktBuf->setLength(uiByePktPos);
179 m_objRtcpHdr.formRtcpHeader(pobjRtcpPktBuf);
180 } // padding
181
182 // set the current position of the RTCP compound packet
183 pobjRtcpPktBuf->setLength(uiCurPos);
184
185 return RTP_SUCCESS;
186 } // formByePacket
187