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