• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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