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 <RtcpXrPacket.h>
18 #include <RtpTrace.h>
19 #include <RtpSession.h>
20 
RtcpXrPacket()21 RtcpXrPacket::RtcpXrPacket() :
22         m_reportBlk(nullptr)
23 {
24 }
25 
~RtcpXrPacket()26 RtcpXrPacket::~RtcpXrPacket()
27 {
28     if (m_reportBlk)
29     {
30         delete (m_reportBlk);
31         m_reportBlk = nullptr;
32     }
33 }
34 
getRtcpHdrInfo()35 RtcpHeader* RtcpXrPacket::getRtcpHdrInfo()
36 {
37     return &m_objRtcpHdr;
38 }
39 
setRtcpHdrInfo(RtcpHeader & header)40 RtpDt_Void RtcpXrPacket::setRtcpHdrInfo(RtcpHeader& header)
41 {
42     m_objRtcpHdr = header;
43 }
44 
getReportBlk()45 RtpBuffer* RtcpXrPacket::getReportBlk()
46 {
47     return m_reportBlk;
48 }
49 
setReportBlk(IN RtpBuffer * reportBlk)50 RtpDt_Void RtcpXrPacket::setReportBlk(IN RtpBuffer* reportBlk)
51 {
52     m_reportBlk = reportBlk;
53 }
54 
decodeRtcpXrPacket(IN RtpDt_UChar * pucRtcpXrBuf,IN RtpDt_UInt16 usRtcpXrLen,IN RtpDt_UChar ucPktType)55 eRTP_STATUS_CODE RtcpXrPacket::decodeRtcpXrPacket(
56         IN RtpDt_UChar* pucRtcpXrBuf, IN RtpDt_UInt16 usRtcpXrLen, IN RtpDt_UChar ucPktType)
57 {
58     (RtpDt_Void) pucRtcpXrBuf;
59     (RtpDt_Void) usRtcpXrLen;
60     (RtpDt_Void) ucPktType;
61     RTP_TRACE_WARNING("decodeRtcpXrPacket not implemented.", RTP_ZERO, RTP_ZERO);
62 
63     /* TODO: Currently, there is no requirement to handle XR packets. Returning success to avoid
64     RTCP decoding issues. */
65     return RTP_SUCCESS;
66 }
67 
formRtcpXrPacket(OUT RtpBuffer * pobjRtcpPktBuf)68 eRTP_STATUS_CODE RtcpXrPacket::formRtcpXrPacket(OUT RtpBuffer* pobjRtcpPktBuf)
69 {
70     RtpDt_UInt32 uiXrPktPos = pobjRtcpPktBuf->getLength();
71     RtpDt_UInt32 uiCurPos = pobjRtcpPktBuf->getLength();
72     RtpDt_UChar* pucBuffer = pobjRtcpPktBuf->getBuffer();
73 
74     if (!pucBuffer)
75     {
76         RTP_TRACE_ERROR("formXrPacket with null buffer", RTP_ZERO, RTP_ZERO);
77         return RTP_FAILURE;
78     }
79 
80     uiCurPos = uiCurPos + RTCP_FIXED_HDR_LEN;
81     pucBuffer = pucBuffer + uiCurPos;
82 
83     // set the report block buffer
84     RtpBuffer* pReportBlk = this->getReportBlk();
85     memcpy(pucBuffer, pReportBlk->getBuffer(), pReportBlk->getLength());
86 
87     uiCurPos = uiCurPos + pReportBlk->getLength();
88 
89     // padding
90     RtpDt_UInt32 uiXrPktLen = uiCurPos - uiXrPktPos;
91 #ifdef ENABLE_PADDING
92     RtpDt_UInt32 uiPadLen = RTP_ZERO;
93     uiPadLen = uiXrPktLen % RTP_WORD_SIZE;
94     if (uiPadLen > RTP_ZERO)
95     {
96         uiPadLen = RTP_WORD_SIZE - uiPadLen;
97         uiXrPktLen = uiXrPktLen + uiPadLen;
98         uiCurPos = uiCurPos + uiPadLen;
99         pucBuffer = pucBuffer + pReportBlk->getLength();
100         memset(pucBuffer, RTP_ZERO, uiPadLen);
101 
102         pucBuffer = pucBuffer + uiPadLen;
103         pucBuffer = pucBuffer - RTP_ONE;
104         *(reinterpret_cast<RtpDt_UChar*>(pucBuffer)) = (RtpDt_UChar)uiPadLen;
105 
106         // set pad bit in header
107         m_objRtcpHdr.setPadding();
108         // set length in header
109         m_objRtcpHdr.setLength(uiXrPktLen);
110     }
111     else
112 #endif
113     {
114         // set length in header
115         m_objRtcpHdr.setLength(uiXrPktLen);
116     }
117 
118     pobjRtcpPktBuf->setLength(uiXrPktPos);
119     m_objRtcpHdr.formRtcpHeader(pobjRtcpPktBuf);
120 
121     // set the current position of the RTCP compound packet
122     pobjRtcpPktBuf->setLength(uiCurPos);
123 
124     return RTP_SUCCESS;
125 }
126