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 <RtpPacket.h>
18 #include <RtpTrace.h>
19
RtpPacket()20 RtpPacket::RtpPacket() :
21 m_pobjExt(nullptr),
22 m_pobjRtpPayload(nullptr)
23 #ifdef ENABLE_PADDING
24 ,
25 m_ucPadLen(RTP_ZERO)
26 #endif
27 {
28 }
29
~RtpPacket()30 RtpPacket::~RtpPacket()
31 {
32 if (m_pobjExt != nullptr)
33 {
34 delete m_pobjExt;
35 m_pobjExt = nullptr;
36 }
37
38 if (m_pobjRtpPayload != nullptr)
39 {
40 delete m_pobjRtpPayload;
41 m_pobjRtpPayload = nullptr;
42 }
43 }
44
getRtpHeader()45 RtpHeader* RtpPacket::getRtpHeader()
46 {
47 return &m_objRtpHeader;
48 }
49
setRtpPayload(IN RtpBuffer * pobjRtpPld)50 RtpDt_Void RtpPacket::setRtpPayload(IN RtpBuffer* pobjRtpPld)
51 {
52 m_pobjRtpPayload = pobjRtpPld;
53 }
54
setExtHeader(IN RtpBuffer * pobjExt)55 RtpDt_Void RtpPacket::setExtHeader(IN RtpBuffer* pobjExt)
56 {
57 m_pobjExt = pobjExt;
58 }
59
getExtHeader()60 RtpBuffer* RtpPacket::getExtHeader()
61 {
62 return m_pobjExt;
63 }
64
getRtpPayload()65 RtpBuffer* RtpPacket::getRtpPayload()
66 {
67 return m_pobjRtpPayload;
68 }
69
formPacket(IN RtpBuffer * pobjRtpPktBuf)70 eRtp_Bool RtpPacket::formPacket(IN RtpBuffer* pobjRtpPktBuf)
71 {
72 RtpDt_UInt32 uiRtpUtlBufLen = RTP_ZERO;
73 RtpDt_UChar* pcRtpBuf = pobjRtpPktBuf->getBuffer();
74
75 // fixed header
76 eRtp_Bool bPackRes = m_objRtpHeader.formHeader(pobjRtpPktBuf);
77 if (bPackRes != eRTP_TRUE)
78 {
79 RTP_TRACE_WARNING("formPacket Failed", RTP_ZERO, RTP_ZERO);
80 return bPackRes;
81 }
82
83 RtpDt_UInt32 uiRtpBufPos = pobjRtpPktBuf->getLength();
84 pcRtpBuf = pcRtpBuf + uiRtpBufPos;
85
86 // extension header
87 if (m_pobjExt != nullptr)
88 {
89 const RtpDt_UChar* pRtpUtlBuf = m_pobjExt->getBuffer();
90 uiRtpUtlBufLen = m_pobjExt->getLength();
91 memcpy(pcRtpBuf, pRtpUtlBuf, uiRtpUtlBufLen);
92 pcRtpBuf += uiRtpUtlBufLen;
93 uiRtpBufPos += uiRtpUtlBufLen;
94 }
95
96 // rtp packet
97 if (m_pobjRtpPayload != nullptr)
98 {
99 const RtpDt_UChar* pRtpUtlBuf = m_pobjRtpPayload->getBuffer();
100 uiRtpUtlBufLen = m_pobjRtpPayload->getLength();
101 memcpy(pcRtpBuf, pRtpUtlBuf, uiRtpUtlBufLen);
102 uiRtpBufPos += uiRtpUtlBufLen;
103 #ifdef ENABLE_PADDING
104 // calculate pad Len
105 pcRtpBuf += uiRtpUtlBufLen;
106 RtpDt_UInt32 uiPadLen = uiRtpUtlBufLen % RTP_WORD_SIZE;
107 if (uiPadLen != RTP_ZERO)
108 {
109 m_ucPadLen = RTP_WORD_SIZE - uiPadLen;
110 }
111
112 // padding
113 if (m_ucPadLen > RTP_ZERO)
114 {
115 RtpDt_UChar ucTmpPadLen = m_ucPadLen - RTP_ONE;
116 memset(pcRtpBuf, RTP_ZERO, m_ucPadLen);
117 // pad length
118 *(reinterpret_cast<RtpDt_UChar*>(pcRtpBuf + ucTmpPadLen)) = m_ucPadLen;
119 uiRtpBufPos += m_ucPadLen;
120 }
121 #endif
122 }
123
124 // set raw buffer length
125 pobjRtpPktBuf->setLength(uiRtpBufPos);
126
127 return eRTP_TRUE;
128 }
129
decodePacket(IN RtpBuffer * pobjRtpPktBuf)130 eRtp_Bool RtpPacket::decodePacket(IN RtpBuffer* pobjRtpPktBuf)
131 {
132 RtpDt_UInt32 uiRtpBufPos = RTP_ZERO;
133 RtpDt_UInt32 uiRtpUtlBufLen = RTP_ZERO;
134 RtpDt_UChar* pcRtpBuf = pobjRtpPktBuf->getBuffer();
135
136 uiRtpUtlBufLen = pobjRtpPktBuf->getLength();
137
138 // decode fixed header
139 m_objRtpHeader.decodeHeader(pobjRtpPktBuf, uiRtpBufPos);
140 pcRtpBuf = pcRtpBuf + uiRtpBufPos;
141
142 // Packet Validation
143 // RTP version check
144 if (m_objRtpHeader.getVersion() != RTP_VERSION_NUM)
145 {
146 return eRTP_FAILURE;
147 }
148
149 // extension header
150 if (m_objRtpHeader.getExtension())
151 {
152 m_pobjExt = new RtpBuffer();
153
154 // Get XHdr type and length
155 RtpDt_UInt32 uiByte4Data = RtpOsUtil::Ntohl(*(reinterpret_cast<RtpDt_UInt32*>(pcRtpBuf)));
156 RtpDt_UInt16 uXHdrLen =
157 (RtpDt_UInt16)(uiByte4Data & RTP_HEX_16_BIT_MAX); // add header size
158
159 uXHdrLen += 1; // add a word for header type info
160 uXHdrLen *= RTP_WORD_SIZE; // convert word to byte
161
162 if ((uXHdrLen <= 0) || ((uiRtpBufPos + uXHdrLen) > uiRtpUtlBufLen))
163 {
164 RTP_TRACE_ERROR("[decodePacket] Invalid Header Extension len[%d]", uXHdrLen, 0);
165 return eRTP_FAILURE;
166 }
167
168 RtpDt_UChar* pRtpExtData = new RtpDt_UChar[uXHdrLen];
169
170 memcpy(pRtpExtData, pcRtpBuf, uXHdrLen);
171 m_pobjExt->setBufferInfo(uXHdrLen, pRtpExtData);
172
173 pcRtpBuf = pcRtpBuf + uXHdrLen;
174 uiRtpBufPos = uiRtpBufPos + uXHdrLen;
175 }
176
177 // rtp payload
178 if (uiRtpUtlBufLen > uiRtpBufPos)
179 uiRtpUtlBufLen -= uiRtpBufPos;
180 else
181 uiRtpUtlBufLen = 0;
182
183 RtpDt_UChar ucPadBit = RTP_ZERO;
184 ucPadBit = m_objRtpHeader.getPadding();
185
186 if (ucPadBit > RTP_ZERO)
187 {
188 RtpDt_UChar ucPadLen = RTP_ZERO;
189 RtpDt_UInt32 uiPadLenPos = uiRtpUtlBufLen;
190
191 uiPadLenPos = uiPadLenPos - RTP_ONE;
192 ucPadLen = *(reinterpret_cast<RtpDt_UChar*>(pcRtpBuf + uiPadLenPos));
193 if (ucPadLen == RTP_ZERO)
194 {
195 return eRTP_FAILURE;
196 }
197 if (uiRtpUtlBufLen > ucPadLen)
198 uiRtpUtlBufLen -= ucPadLen;
199 else
200 uiRtpUtlBufLen = 0;
201 }
202
203 m_pobjRtpPayload = new RtpBuffer();
204 if (m_pobjRtpPayload == nullptr)
205 {
206 return eRTP_FAILURE;
207 }
208 RtpDt_UChar* pRtpUtlBuf = nullptr;
209 pRtpUtlBuf = new RtpDt_UChar[uiRtpUtlBufLen];
210 if (pRtpUtlBuf == nullptr)
211 {
212 return eRTP_FAILURE;
213 }
214 memcpy(pRtpUtlBuf, pcRtpBuf, uiRtpUtlBufLen);
215 m_pobjRtpPayload->setBufferInfo(uiRtpUtlBufLen, pRtpUtlBuf);
216
217 return eRTP_SUCCESS;
218 }
219