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 <RtcpHeader.h>
18 #include <RtpTrace.h>
19
RtcpHeader()20 RtcpHeader::RtcpHeader() :
21 m_ucVersion(RTP_ZERO),
22 m_ucIsPadding(eRTP_FALSE),
23 m_ucReceptionReportCount(RTP_ZERO),
24 m_ucPacketType(RTP_ZERO),
25 m_usLength(RTP_ZERO),
26 m_uiSsrc(RTP_ZERO)
27 {
28 }
29
~RtcpHeader()30 RtcpHeader::~RtcpHeader() {}
31
setVersion(IN RtpDt_UChar ucVersion)32 eRtp_Bool RtcpHeader::setVersion(IN RtpDt_UChar ucVersion)
33 {
34 if (ucVersion > MAX_RTP_VERSION)
35 {
36 RTP_TRACE_ERROR("Invalid RTP version %d", ucVersion, 0);
37 return eRTP_FALSE;
38 }
39
40 m_ucVersion = ucVersion;
41 return eRTP_TRUE;
42 }
43
getVersion()44 RtpDt_UChar RtcpHeader::getVersion()
45 {
46 return m_ucVersion;
47 }
48
setPadding(eRtp_Bool padding)49 RtpDt_Void RtcpHeader::setPadding(eRtp_Bool padding)
50 {
51 m_ucIsPadding = padding;
52 }
53
getPadding()54 eRtp_Bool RtcpHeader::getPadding()
55 {
56 return m_ucIsPadding;
57 }
58
setReceptionReportCount(IN RtpDt_UChar ucReceptionReportCount)59 eRtp_Bool RtcpHeader::setReceptionReportCount(IN RtpDt_UChar ucReceptionReportCount)
60 {
61 if (ucReceptionReportCount > MAX_RECEPTION_REPORT_COUNT)
62 {
63 RTP_TRACE_ERROR("Invalid Reception Report Count %d", ucReceptionReportCount, 0);
64 return eRTP_FALSE;
65 }
66
67 m_ucReceptionReportCount = ucReceptionReportCount;
68 return eRTP_TRUE;
69 }
70
getReceptionReportCount()71 RtpDt_UChar RtcpHeader::getReceptionReportCount()
72 {
73 return m_ucReceptionReportCount;
74 }
75
setPacketType(IN RtpDt_UChar ucPacketType)76 RtpDt_Void RtcpHeader::setPacketType(IN RtpDt_UChar ucPacketType)
77 {
78 m_ucPacketType = ucPacketType;
79 }
80
getPacketType()81 RtpDt_UChar RtcpHeader::getPacketType()
82 {
83 return m_ucPacketType;
84 }
85
setLength(IN RtpDt_UInt32 usLength)86 RtpDt_Void RtcpHeader::setLength(IN RtpDt_UInt32 usLength)
87 {
88 m_usLength = usLength;
89 }
90
getLength()91 RtpDt_UInt32 RtcpHeader::getLength()
92 {
93 return m_usLength;
94 }
95
setSsrc(IN RtpDt_UInt32 uiSsrc)96 RtpDt_Void RtcpHeader::setSsrc(IN RtpDt_UInt32 uiSsrc)
97 {
98 m_uiSsrc = uiSsrc;
99 }
100
getSsrc()101 RtpDt_UInt32 RtcpHeader::getSsrc()
102 {
103 return m_uiSsrc;
104 }
105
operator ==(const RtcpHeader & objRtcpHeader) const106 bool RtcpHeader::operator==(const RtcpHeader& objRtcpHeader) const
107 {
108 return (m_ucVersion == objRtcpHeader.m_ucVersion &&
109 m_ucIsPadding == objRtcpHeader.m_ucIsPadding &&
110 m_ucReceptionReportCount == objRtcpHeader.m_ucReceptionReportCount &&
111 m_ucPacketType == objRtcpHeader.m_ucPacketType &&
112 m_usLength == objRtcpHeader.m_usLength && m_uiSsrc == objRtcpHeader.m_uiSsrc);
113 }
114
decodeRtcpHeader(IN RtpDt_UChar * pRtcpBuffer,RtpDt_Int32 length)115 eRtp_Bool RtcpHeader::decodeRtcpHeader(IN RtpDt_UChar* pRtcpBuffer, RtpDt_Int32 length)
116 {
117 if (length < RTP_WORD_SIZE)
118 return eRTP_FALSE;
119
120 RtpDt_UInt32 uiTemp4Data = RtpOsUtil::Ntohl(*(reinterpret_cast<RtpDt_UInt32*>(pRtcpBuffer)));
121
122 // Packet Length
123 m_usLength = uiTemp4Data & 0x0000FFFF;
124 m_usLength *= RTP_WORD_SIZE; // Convert length from WORD count to Bytes count
125
126 // Packet Type
127 m_ucPacketType = (uiTemp4Data >> RTP_16) & 0x000000FF;
128
129 // 8-MSB bits of 32-bit data.
130 uiTemp4Data = uiTemp4Data >> RTP_24;
131
132 // version. 2-MSB bits
133 m_ucVersion = (RtpDt_UInt8)(uiTemp4Data >> RTP_SIX) & 0x00000003;
134
135 // padding
136 m_ucIsPadding = ((uiTemp4Data >> RTP_FIVE) & 0x00000001) ? eRTP_TRUE : eRTP_FALSE;
137
138 // RC
139 m_ucReceptionReportCount = RtpDt_UInt8(uiTemp4Data & 0x0000001F);
140
141 // SSRC
142 if (m_usLength)
143 {
144 pRtcpBuffer = pRtcpBuffer + RTP_WORD_SIZE;
145 m_uiSsrc = RtpOsUtil::Ntohl(*(reinterpret_cast<RtpDt_UInt32*>(pRtcpBuffer)));
146 }
147
148 return eRTP_SUCCESS;
149 } // decodeRtcpHeader
150
formRtcpHeader(OUT RtpBuffer * pobjRtcpPktBuf)151 eRtp_Bool RtcpHeader::formRtcpHeader(OUT RtpBuffer* pobjRtcpPktBuf)
152 {
153 // do partial encoding
154 formPartialRtcpHeader(pobjRtcpPktBuf);
155
156 RtpDt_UChar* pcRtcpHdrBuf = pobjRtcpPktBuf->getBuffer();
157 RtpDt_UInt32 uiBufPos = pobjRtcpPktBuf->getLength();
158 pcRtcpHdrBuf = pcRtcpHdrBuf + uiBufPos;
159
160 // ssrc
161 *(reinterpret_cast<RtpDt_UInt32*>(pcRtcpHdrBuf)) = RtpOsUtil::Ntohl(m_uiSsrc);
162
163 uiBufPos = uiBufPos + RTP_WORD_SIZE;
164 pobjRtcpPktBuf->setLength(uiBufPos);
165
166 return eRTP_SUCCESS;
167 } // formRtcpHeader
168
formPartialRtcpHeader(OUT RtpBuffer * pobjRtcpPktBuf)169 eRtp_Bool RtcpHeader::formPartialRtcpHeader(OUT RtpBuffer* pobjRtcpPktBuf)
170 {
171 RtpDt_UInt16 usUtlData = RTP_ZERO;
172 RtpDt_UInt16 usTmpData = RTP_ZERO;
173 RtpDt_UChar* pcRtcpHdrBuf = pobjRtcpPktBuf->getBuffer();
174 RtpDt_UInt32 uiBufPos = pobjRtcpPktBuf->getLength();
175
176 pcRtcpHdrBuf = pcRtcpHdrBuf + uiBufPos;
177
178 // version 2 bits
179 RTP_FORM_HDR_UTL(usUtlData, m_ucVersion, RTP_VER_SHIFT_VAL, usTmpData);
180 // padding 1 bit
181 RTP_FORM_HDR_UTL(usUtlData, m_ucIsPadding, RTP_PAD_SHIFT_VAL, usTmpData);
182 // RC 5 bits
183 RTP_FORM_HDR_UTL(usUtlData, m_ucReceptionReportCount, RTCP_RC_SHIFT_VAL, usTmpData);
184 // PT 8 bits
185 RTP_FORM_HDR_UTL(usUtlData, m_ucPacketType, RTCP_PT_SHIFT_VAL, usTmpData);
186
187 RtpDt_UInt32 uiByte4Data = usTmpData;
188 uiByte4Data = uiByte4Data << RTP_SIXTEEN;
189
190 // convert m_usLength into words - 1
191 m_usLength = m_usLength / RTP_WORD_SIZE;
192 m_usLength = m_usLength - RTP_ONE;
193
194 // length 16 bits
195 uiByte4Data = uiByte4Data | m_usLength;
196
197 *(reinterpret_cast<RtpDt_UInt32*>(pcRtcpHdrBuf)) = RtpOsUtil::Ntohl(uiByte4Data);
198
199 uiBufPos = uiBufPos + RTP_WORD_SIZE;
200 pobjRtcpPktBuf->setLength(uiBufPos);
201
202 return eRTP_SUCCESS;
203
204 } // end formPartialRtcpHeader
205
populateRtcpHeader(IN RtpDt_UChar ucReceptionReportCount,IN RtpDt_UChar ucPacketType,IN RtpDt_UInt32 uiSsrc)206 RtpDt_Void RtcpHeader::populateRtcpHeader(
207 IN RtpDt_UChar ucReceptionReportCount, IN RtpDt_UChar ucPacketType, IN RtpDt_UInt32 uiSsrc)
208 {
209 m_ucVersion = RTP_VERSION_NUM;
210 m_ucReceptionReportCount = ucReceptionReportCount;
211 m_ucPacketType = ucPacketType;
212 m_uiSsrc = uiSsrc;
213 }
214