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 <RtcpFbPacket.h>
18 #include <RtpTrace.h>
19 #include <string.h>
20
RtcpFbPacket()21 RtcpFbPacket::RtcpFbPacket() :
22 m_pFCI(nullptr)
23 {
24 }
25
~RtcpFbPacket()26 RtcpFbPacket::~RtcpFbPacket()
27 {
28 if (m_pFCI)
29 {
30 delete (m_pFCI);
31 m_pFCI = nullptr;
32 }
33 }
34
setRtcpHdrInfo(RtcpHeader & objHeader)35 RtpDt_Void RtcpFbPacket::setRtcpHdrInfo(RtcpHeader& objHeader)
36 {
37 m_objRtcpHdr = objHeader;
38 }
39
getRtcpHdrInfo()40 RtcpHeader* RtcpFbPacket::getRtcpHdrInfo()
41 {
42 return &m_objRtcpHdr;
43 }
44
setSsrc(RtpDt_UInt32 uiSsrc)45 RtpDt_Void RtcpFbPacket::setSsrc(RtpDt_UInt32 uiSsrc)
46 {
47 m_objRtcpHdr.setSsrc(uiSsrc);
48 }
49
setMediaSsrc(RtpDt_UInt32 uiMediaSsrc)50 RtpDt_Void RtcpFbPacket::setMediaSsrc(RtpDt_UInt32 uiMediaSsrc)
51 {
52 m_uiMediaSsrc = uiMediaSsrc;
53 }
54
getSsrc()55 RtpDt_UInt32 RtcpFbPacket::getSsrc()
56 {
57 return m_objRtcpHdr.getSsrc();
58 }
59
getMediaSsrc()60 RtpDt_UInt32 RtcpFbPacket::getMediaSsrc()
61 {
62 return m_uiMediaSsrc;
63 }
64
getFCI()65 RtpBuffer* RtcpFbPacket::getFCI()
66 {
67 return m_pFCI;
68 }
69
setFCI(IN RtpBuffer * pFCI)70 RtpDt_Void RtcpFbPacket::setFCI(IN RtpBuffer* pFCI)
71 {
72 m_pFCI = pFCI;
73 }
74
setPayloadType(IN eRTCP_TYPE ePayloadType)75 RtpDt_Void RtcpFbPacket::setPayloadType(IN eRTCP_TYPE ePayloadType)
76 {
77 m_ePayloadType = ePayloadType;
78 }
79
getPayloadType()80 eRTCP_TYPE RtcpFbPacket::getPayloadType()
81 {
82 return m_ePayloadType;
83 }
84
decodeRtcpFbPacket(IN RtpDt_UChar * pucRtcpFbBuf,IN RtpDt_UInt16 usRtcpFbLen)85 eRTP_STATUS_CODE RtcpFbPacket::decodeRtcpFbPacket(
86 IN RtpDt_UChar* pucRtcpFbBuf, IN RtpDt_UInt16 usRtcpFbLen)
87 {
88 // get media/peer SSRC
89 RtpDt_UInt32 uiMediaSsrc = RtpOsUtil::Ntohl(*(reinterpret_cast<RtpDt_UInt32*>(pucRtcpFbBuf)));
90 setMediaSsrc(uiMediaSsrc);
91 pucRtcpFbBuf += RTP_WORD_SIZE;
92 usRtcpFbLen -= RTP_WORD_SIZE;
93
94 // get the FCI buffer
95 if (usRtcpFbLen > 0)
96 {
97 RtpBuffer* pFCI = new RtpBuffer(usRtcpFbLen, reinterpret_cast<RtpDt_UChar*>(pucRtcpFbBuf));
98 if (pFCI == nullptr)
99 {
100 RTP_TRACE_ERROR("[Memory Error] new returned NULL.", RTP_ZERO, RTP_ZERO);
101 return RTP_MEMORY_FAIL;
102 }
103 setFCI(pFCI);
104 }
105
106 return RTP_SUCCESS;
107 }
108
formRtcpFbPacket(OUT RtpBuffer * pobjRtcpPktBuf)109 eRTP_STATUS_CODE RtcpFbPacket::formRtcpFbPacket(OUT RtpBuffer* pobjRtcpPktBuf)
110 {
111 RtpDt_UInt32 uiFbPktPos = pobjRtcpPktBuf->getLength();
112 RtpDt_UInt32 uiCurPos = pobjRtcpPktBuf->getLength();
113 RtpDt_UChar* pucBuffer = pobjRtcpPktBuf->getBuffer();
114
115 if (!pucBuffer)
116 {
117 RTP_TRACE_ERROR("formFbPacket with null buffer", RTP_ZERO, RTP_ZERO);
118 return RTP_FAILURE;
119 }
120
121 uiCurPos = uiCurPos + RTCP_FIXED_HDR_LEN;
122 pucBuffer = pucBuffer + uiCurPos;
123
124 // set the media/peer SSRC
125 RtpDt_UInt32 uiMediaSsrc = getMediaSsrc();
126 *(reinterpret_cast<RtpDt_UInt32*>(pucBuffer)) = RtpOsUtil::Ntohl(uiMediaSsrc);
127 pucBuffer = pucBuffer + RTP_WORD_SIZE;
128 uiCurPos = uiCurPos + RTP_WORD_SIZE;
129
130 // set the FCI buffer
131 RtpBuffer* pFCI = this->getFCI();
132 memcpy(pucBuffer, pFCI->getBuffer(), pFCI->getLength());
133 uiCurPos = uiCurPos + pFCI->getLength();
134
135 // padding
136 RtpDt_UInt32 uiFbPktLen = uiCurPos - uiFbPktPos;
137 #ifdef ENABLE_PADDING
138 RtpDt_UInt32 uiPadLen = uiFbPktLen % RTP_WORD_SIZE;
139 if (uiPadLen > RTP_ZERO)
140 {
141 uiPadLen = RTP_WORD_SIZE - uiPadLen;
142 uiFbPktLen = uiFbPktLen + uiPadLen;
143 uiCurPos = uiCurPos + uiPadLen;
144 pucBuffer = pucBuffer + pFCI->getLength();
145 memset(pucBuffer, RTP_ZERO, uiPadLen);
146
147 pucBuffer = pucBuffer + uiPadLen;
148 pucBuffer = pucBuffer - RTP_ONE;
149 *(reinterpret_cast<RtpDt_UChar*>(pucBuffer)) = (RtpDt_UChar)uiPadLen;
150
151 // set pad bit in header
152 m_objRtcpHdr.setPadding();
153 // set length in header
154 m_objRtcpHdr.setLength(uiFbPktLen);
155 }
156 else
157 #endif
158 {
159 // set length in header
160 m_objRtcpHdr.setLength(uiFbPktLen);
161 }
162
163 pobjRtcpPktBuf->setLength(uiFbPktPos);
164 m_objRtcpHdr.formRtcpHeader(pobjRtcpPktBuf);
165
166 // set the current position of the RTCP compound packet
167 pobjRtcpPktBuf->setLength(uiCurPos);
168
169 return RTP_SUCCESS;
170 } // formFbPacket
171