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 <RtcpAppPacket.h>
18 #include <string.h>
19 
RtcpAppPacket()20 RtcpAppPacket::RtcpAppPacket() :
21         m_uiName(RTP_ZERO),
22         m_pAppData(nullptr)
23 {
24 }
25 
~RtcpAppPacket()26 RtcpAppPacket::~RtcpAppPacket()
27 {
28     // m_pAppData
29     if (m_pAppData != nullptr)
30     {
31         delete m_pAppData;
32         m_pAppData = nullptr;
33     }
34 }
35 
setRtcpHdrInfo(RtcpHeader & objHeader)36 RtpDt_Void RtcpAppPacket::setRtcpHdrInfo(RtcpHeader& objHeader)
37 {
38     m_objRtcpHdr = objHeader;
39 }
40 
getRtcpHdrInfo()41 RtcpHeader* RtcpAppPacket::getRtcpHdrInfo()
42 {
43     return &m_objRtcpHdr;
44 }
45 
getName()46 RtpDt_UInt32 RtcpAppPacket::getName()
47 {
48     return m_uiName;
49 }
50 
setName(IN RtpDt_UInt32 uiName)51 RtpDt_Void RtcpAppPacket::setName(IN RtpDt_UInt32 uiName)
52 {
53     m_uiName = uiName;
54 }
55 
getAppData()56 RtpBuffer* RtcpAppPacket::getAppData()
57 {
58     return m_pAppData;
59 }
60 
setAppData(IN RtpBuffer * pobjAppData)61 RtpDt_Void RtcpAppPacket::setAppData(IN RtpBuffer* pobjAppData)
62 {
63     m_pAppData = pobjAppData;
64 }
65 
decodeAppPacket(IN RtpDt_UChar * pucAppBuf,IN RtpDt_UInt16 usAppLen)66 eRTP_STATUS_CODE RtcpAppPacket::decodeAppPacket(IN RtpDt_UChar* pucAppBuf, IN RtpDt_UInt16 usAppLen)
67 {
68     // name
69     m_uiName = *(reinterpret_cast<RtpDt_UInt32*>(pucAppBuf));
70     pucAppBuf = pucAppBuf + RTP_WORD_SIZE;
71 
72     RtpDt_UInt16 usTmpAppLen = usAppLen;
73 
74     // application dependent data
75     usTmpAppLen = usTmpAppLen - RTP_WORD_SIZE;
76     if (usTmpAppLen > 0)
77     {
78         RtpDt_UChar* pucTmpBuf = nullptr;
79         m_pAppData = new RtpBuffer();
80         pucTmpBuf = new RtpDt_UChar[usTmpAppLen];
81 
82         memcpy(pucTmpBuf, pucAppBuf, usTmpAppLen);
83         m_pAppData->setBufferInfo(usTmpAppLen, pucTmpBuf);
84     }
85 
86     return RTP_SUCCESS;
87 }  // decodeAppPacket
88 
formAppPacket(OUT RtpBuffer * pobjRtcpPktBuf)89 eRTP_STATUS_CODE RtcpAppPacket::formAppPacket(OUT RtpBuffer* pobjRtcpPktBuf)
90 {
91     RtpDt_UInt32 uiAppPktPos = pobjRtcpPktBuf->getLength();
92 
93     RtpDt_UInt32 uiCurPos = pobjRtcpPktBuf->getLength();
94     RtpDt_UChar* pucBuffer = pobjRtcpPktBuf->getBuffer();
95 
96     uiCurPos = uiCurPos + RTCP_FIXED_HDR_LEN;
97     pucBuffer = pucBuffer + uiCurPos;
98 
99     // m_uiName
100     *(reinterpret_cast<RtpDt_UInt32*>(pucBuffer)) = m_uiName;
101     pucBuffer = pucBuffer + RTP_WORD_SIZE;
102     uiCurPos = uiCurPos + RTP_WORD_SIZE;
103 
104     // m_pAppData
105     if (m_pAppData != nullptr)
106     {
107         memcpy(pucBuffer, m_pAppData->getBuffer(), m_pAppData->getLength());
108         uiCurPos = uiCurPos + m_pAppData->getLength();
109     }
110     // start padding
111     {
112         RtpDt_UInt32 uiAppPktLen = uiCurPos - uiAppPktPos;
113 
114 #ifdef ENABLE_PADDING
115         RtpDt_UInt32 uiPadLen = uiAppPktLen % RTP_WORD_SIZE;
116         if (uiPadLen > RTP_ZERO)
117         {
118             uiPadLen = RTP_WORD_SIZE - uiPadLen;
119             uiAppPktLen = uiAppPktLen + uiPadLen;
120             uiCurPos = uiCurPos + uiPadLen;
121             pucBuffer = pucBuffer + m_pAppData->getLength();
122             memset(pucBuffer, RTP_ZERO, uiPadLen);
123 
124             pucBuffer = pucBuffer + uiPadLen;
125             pucBuffer = pucBuffer - RTP_ONE;
126             *(reinterpret_cast<RtpDt_UChar*>(pucBuffer)) = (RtpDt_UChar)uiPadLen;
127 
128             // set pad bit in header
129             m_objRtcpHdr.setPadding();
130             // set length in header
131             m_objRtcpHdr.setLength(uiAppPktLen);
132         }
133         else
134 #endif
135         {
136             // set length in header
137             m_objRtcpHdr.setLength(uiAppPktLen);
138         }
139         pobjRtcpPktBuf->setLength(uiAppPktPos);
140         m_objRtcpHdr.formRtcpHeader(pobjRtcpPktBuf);
141     }  // padding
142 
143     // set the actual position of the RTCP compound packet
144     pobjRtcpPktBuf->setLength(uiCurPos);
145 
146     return RTP_SUCCESS;
147 }  // formAppPacket
148