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 <RtpReceiverInfo.h>
18 #include <RtpStackUtil.h>
19 #include <RtpTrace.h>
20 #include <string.h>
21 
RtpReceiverInfo()22 RtpReceiverInfo::RtpReceiverInfo() :
23         m_uiSsrc(RTP_ZERO),
24         m_bSender(eRTP_FALSE),
25         m_uiTotalRcvdRtpPkts(RTP_ZERO),
26         m_uiTotalRcvdRtpOcts(RTP_ZERO),
27         m_pobjIpAddr(nullptr),
28         m_usPort(RTP_ZERO),
29         m_bIsCsrcFlag(eRTP_FALSE),
30         m_prevRtpTimestamp(RTP_ZERO),
31         m_stPreSrTimestamp(RTP_ZERO),
32         m_stLastSrNtpTimestamp(RTP_ZERO),
33         m_bIsFirstRtp(eRTP_TRUE)
34 
35 {
36     // m_stPrevNtpTimestamp
37     m_stPrevNtpTimestamp.m_uiNtpHigh32Bits = RTP_ZERO;
38     m_stPrevNtpTimestamp.m_uiNtpLow32Bits = RTP_ZERO;
39     // m_stRtpSource
40     memset(&m_stRtpSource, RTP_ZERO, sizeof(tRTP_SOURCE));
41     m_stRtpSource.uiProbation = RTP_MIN_SEQUENTIAL;
42     m_stRtpSource.uiTransit = RTP_MIN_SEQUENTIAL;
43 }
44 
~RtpReceiverInfo()45 RtpReceiverInfo::~RtpReceiverInfo()
46 {
47     if (m_pobjIpAddr != nullptr)
48     {
49         delete m_pobjIpAddr;
50         m_pobjIpAddr = nullptr;
51     }
52 }
53 
getCsrcFlag()54 eRtp_Bool RtpReceiverInfo::getCsrcFlag()
55 {
56     return m_bIsCsrcFlag;
57 }
58 
setCsrcFlag(IN eRtp_Bool bIsCsrcFlag)59 RtpDt_Void RtpReceiverInfo::setCsrcFlag(IN eRtp_Bool bIsCsrcFlag)
60 {
61     m_bIsCsrcFlag = bIsCsrcFlag;
62 }
63 
findLostRtpPkts()64 RtpDt_UInt32 RtpReceiverInfo::findLostRtpPkts()
65 {
66     RtpDt_UInt32 uiExtendedMax =
67             (m_stRtpSource.uiCycles << RTP_BYTE2_BIT_SIZE) + m_stRtpSource.usMaxSeq;
68     RtpDt_UInt32 uiExpected = (uiExtendedMax - m_stRtpSource.uiBaseSeq) + RTP_ONE;
69 
70     // The number of packets received includes any that are late or duplicated, and hence may
71     // be greater than the number expected, so the cumulative number of packets lost may be negative
72     RtpDt_Int32 uiLostRtpPkts = uiExpected - m_stRtpSource.uiReceived;
73 
74     // Restrict cumulative lost number to 24-bits
75     if (uiLostRtpPkts > RTP_HEX_24_BIT_MAX)
76         uiLostRtpPkts = RTP_HEX_24_BIT_MAX;
77     else if (uiLostRtpPkts < (RtpDt_Int32)RTP_HEX_24_BIT_MIN)
78         uiLostRtpPkts = RTP_HEX_24_BIT_MIN;
79     return uiLostRtpPkts;
80 }  // findLostRtpPkts
81 
getExtSeqNum()82 RtpDt_UInt32 RtpReceiverInfo::getExtSeqNum()
83 {
84     RtpDt_UInt32 uiExtSeqNum = (m_stRtpSource.uiCycles << RTP_BYTE2_BIT_SIZE);
85     uiExtSeqNum = uiExtSeqNum | m_stRtpSource.usMaxSeq;
86     return uiExtSeqNum;
87 }  // getExtSeqNum
88 
calcJitter(IN RtpDt_UInt32 uiRcvRtpTs,IN RtpDt_UInt32 uiSamplingRate)89 RtpDt_Void RtpReceiverInfo::calcJitter(IN RtpDt_UInt32 uiRcvRtpTs, IN RtpDt_UInt32 uiSamplingRate)
90 {
91     tRTP_NTP_TIME stCurNtpTimestamp;
92 
93     // get current NTP Timestamp
94     RtpOsUtil::GetNtpTime(stCurNtpTimestamp);
95     RtpDt_UInt32 uiCurRtpTimestamp = RtpStackUtil::calcRtpTimestamp(
96             m_prevRtpTimestamp, &stCurNtpTimestamp, &m_stPrevNtpTimestamp, uiSamplingRate);
97     // calculate arrival
98     RtpDt_UInt32 uiArrival = uiCurRtpTimestamp;
99     RtpDt_Int32 iTransit = uiArrival - uiRcvRtpTs;
100     RtpDt_Int32 iDifference = iTransit - m_stRtpSource.uiTransit;
101     m_stRtpSource.uiTransit = iTransit;
102     if (iDifference < RTP_ZERO)
103     {
104         iDifference = -iDifference;
105     }
106 
107     /*m_stRtpSource.uiJitter += iDifference -
108                                 ((m_stRtpSource.uiJitter + RTP_EIGHT) >> RTP_FOUR);*/
109     // Alternate division logic as per RFC 3550 sec A.8
110     if (m_bIsFirstRtp == eRTP_TRUE)
111     {
112         m_stRtpSource.uiJitter = RTP_ZERO;
113         m_bIsFirstRtp = eRTP_FALSE;
114     }
115     else
116     {
117         m_stRtpSource.uiJitter += (1. / 16.) * ((RtpDt_Double)iDifference - m_stRtpSource.uiJitter);
118     }
119 
120     m_stPrevNtpTimestamp = stCurNtpTimestamp;
121     m_prevRtpTimestamp = uiCurRtpTimestamp;
122     return;
123 }  // calcJitter
124 
fractionLost()125 RtpDt_UInt16 RtpReceiverInfo::fractionLost()
126 {
127     RtpDt_UInt32 uiExtendedMax =
128             (m_stRtpSource.uiCycles << RTP_BYTE2_BIT_SIZE) + m_stRtpSource.usMaxSeq;
129     RtpDt_UInt32 uiExpected = (uiExtendedMax - m_stRtpSource.uiBaseSeq) + RTP_ONE;
130     RtpDt_UInt32 iExpIntvl = uiExpected - m_stRtpSource.uiExpectedPrior;
131 
132     m_stRtpSource.uiExpectedPrior = uiExpected;
133     RtpDt_UInt32 uiRcvdIntvl = m_stRtpSource.uiReceived - m_stRtpSource.uiReceivedPrior;
134     m_stRtpSource.uiReceivedPrior = m_stRtpSource.uiReceived;
135 
136     RtpDt_Int32 iLostIntvl = iExpIntvl - uiRcvdIntvl;
137     RtpDt_UInt16 ucFraction = RTP_ZERO;
138 
139     if ((iExpIntvl == RTP_ZERO) || (iLostIntvl <= RTP_ZERO))
140     {
141         ucFraction = RTP_ZERO;
142     }
143     else
144     {
145         ucFraction = (iLostIntvl << RTP_BYTE_BIT_SIZE) / iExpIntvl;
146     }
147     return ucFraction;
148 }  // fractionLost
149 
initSeq(IN RtpDt_UInt16 usSeq)150 RtpDt_Void RtpReceiverInfo::initSeq(IN RtpDt_UInt16 usSeq)
151 {
152     m_stRtpSource.uiBaseSeq = usSeq;
153     m_stRtpSource.usMaxSeq = usSeq;
154     m_stRtpSource.uiBadSeq = RTP_SEQ_MOD + RTP_ONE; /* so seq == bad_seq is false */
155     m_stRtpSource.uiCycles = RTP_ZERO;
156     m_stRtpSource.uiReceived = RTP_ZERO;
157     m_stRtpSource.uiReceivedPrior = RTP_ZERO;
158     m_stRtpSource.uiExpectedPrior = RTP_ZERO;
159     /* other initialization */
160 }  // initSeq
161 
updateSeq(IN RtpDt_UInt16 usSeq)162 RtpDt_UInt32 RtpReceiverInfo::updateSeq(IN RtpDt_UInt16 usSeq)
163 {
164     RtpDt_UInt16 usDelta = usSeq - m_stRtpSource.usMaxSeq;
165 
166     /*
167      * Source is not valid until RTP_MIN_SEQUENTIAL packets with
168      * sequential sequence numbers have been received.
169      */
170     if (m_stRtpSource.uiProbation)
171     {
172         /* packet is in sequence */
173         if (usSeq == m_stRtpSource.usMaxSeq + RTP_ONE)
174         {
175             m_stRtpSource.uiProbation--;
176             m_stRtpSource.usMaxSeq = usSeq;
177             if (m_stRtpSource.uiProbation == RTP_ZERO)
178             {
179                 initSeq(usSeq);
180                 m_stRtpSource.uiReceived++;
181                 return RTP_ONE;
182             }
183         }
184         else
185         {
186             m_stRtpSource.uiProbation = RTP_MIN_SEQUENTIAL - RTP_ONE;
187             m_stRtpSource.usMaxSeq = usSeq;
188         }
189         return RTP_ZERO;
190     }
191     else if (usDelta < RTP_MAX_DROPOUT)
192     {
193         /* in order, with permissible gap */
194         if (usSeq < m_stRtpSource.usMaxSeq)
195         {
196             /*
197              * Sequence number wrapped - count another 64K cycle.
198              */
199             m_stRtpSource.uiCycles += RTP_ONE;
200         }
201         m_stRtpSource.usMaxSeq = usSeq;
202     }
203     else if (usDelta <= RTP_SEQ_MOD - RTP_MAX_MISORDER)
204     {
205         /* the sequence number made a very large jump */
206         if (usSeq == m_stRtpSource.uiBadSeq)
207         {
208             /*
209              * Two sequential packets -- assume that the other side
210              * restarted without telling us so just re-sync
211              * (i.e., pretend this was the first packet).
212              */
213             initSeq(usSeq);
214         }
215         else
216         {
217             m_stRtpSource.uiBadSeq = (usSeq + RTP_ONE) & (RTP_SEQ_MOD - RTP_ONE);
218             return RTP_ZERO;
219         }
220     }
221     else
222     {
223         /* duplicate or reordered packet */
224     }
225     m_stRtpSource.uiReceived++;
226     return RTP_ONE;
227 }  // updateSeq
228 
getSsrc()229 RtpDt_UInt32 RtpReceiverInfo::getSsrc()
230 {
231     return m_uiSsrc;
232 }
233 
setSsrc(IN RtpDt_UInt32 uiSsrc)234 RtpDt_Void RtpReceiverInfo::setSsrc(IN RtpDt_UInt32 uiSsrc)
235 {
236     m_uiSsrc = uiSsrc;
237 }
238 
isSender()239 eRtp_Bool RtpReceiverInfo::isSender()
240 {
241     return m_bSender;
242 }
243 
setSenderFlag(IN eRtp_Bool bSender)244 RtpDt_Void RtpReceiverInfo::setSenderFlag(IN eRtp_Bool bSender)
245 {
246     m_bSender = bSender;
247 }
248 
getTotalRcvdRtpPkts()249 RtpDt_UInt32 RtpReceiverInfo::getTotalRcvdRtpPkts()
250 {
251     return m_uiTotalRcvdRtpPkts;
252 }
253 
incrTotalRcvdRtpPkts()254 RtpDt_Void RtpReceiverInfo::incrTotalRcvdRtpPkts()
255 {
256     m_uiTotalRcvdRtpPkts += RTP_ONE;
257 }
258 
incrTotalRcvdRtpOcts(IN RtpDt_UInt32 uiRcvdOcts)259 RtpDt_Void RtpReceiverInfo::incrTotalRcvdRtpOcts(IN RtpDt_UInt32 uiRcvdOcts)
260 {
261     m_uiTotalRcvdRtpOcts += uiRcvdOcts;
262 }
263 
getIpAddr()264 RtpBuffer* RtpReceiverInfo::getIpAddr()
265 {
266     return m_pobjIpAddr;
267 }
268 
setIpAddr(IN RtpBuffer * pobjIpAddr)269 eRTP_STATUS_CODE RtpReceiverInfo::setIpAddr(IN RtpBuffer* pobjIpAddr)
270 {
271     RtpDt_UChar* pBuffer = pobjIpAddr->getBuffer();
272     RtpDt_UInt32 uiLength = pobjIpAddr->getLength();
273     m_pobjIpAddr = new RtpBuffer(uiLength, pBuffer);
274     if (m_pobjIpAddr == nullptr)
275     {
276         RTP_TRACE_ERROR("[Memory Error] new returned NULL.", RTP_ZERO, RTP_ZERO);
277         return RTP_MEMORY_FAIL;
278     }
279     return RTP_SUCCESS;
280 }
281 
getPort()282 RtpDt_UInt16 RtpReceiverInfo::getPort()
283 {
284     return m_usPort;
285 }
286 
setPort(IN RtpDt_UInt16 usPort)287 RtpDt_Void RtpReceiverInfo::setPort(IN RtpDt_UInt16 usPort)
288 {
289     m_usPort = usPort;
290 }
291 
setpreSrTimestamp(IN tRTP_NTP_TIME * pstNtpTs)292 RtpDt_Void RtpReceiverInfo::setpreSrTimestamp(IN tRTP_NTP_TIME* pstNtpTs)
293 {
294     m_stPreSrTimestamp = RtpStackUtil::getMidFourOctets(pstNtpTs);
295 }
296 
setLastSrNtpTimestamp(IN tRTP_NTP_TIME * pstNtpTs)297 RtpDt_Void RtpReceiverInfo::setLastSrNtpTimestamp(IN tRTP_NTP_TIME* pstNtpTs)
298 {
299     m_stLastSrNtpTimestamp = RtpStackUtil::getMidFourOctets(pstNtpTs);
300 }
301 
setprevRtpTimestamp(IN RtpDt_UInt32 pstRtpTs)302 RtpDt_Void RtpReceiverInfo::setprevRtpTimestamp(IN RtpDt_UInt32 pstRtpTs)
303 {
304     m_prevRtpTimestamp = pstRtpTs;
305 }
306 
setprevNtpTimestamp(IN tRTP_NTP_TIME * pstNtpTs)307 RtpDt_Void RtpReceiverInfo::setprevNtpTimestamp(IN tRTP_NTP_TIME* pstNtpTs)
308 {
309     m_stPrevNtpTimestamp.m_uiNtpHigh32Bits = pstNtpTs->m_uiNtpHigh32Bits;
310     m_stPrevNtpTimestamp.m_uiNtpLow32Bits = pstNtpTs->m_uiNtpLow32Bits;
311 }
312 
delaySinceLastSR()313 RtpDt_UInt32 RtpReceiverInfo::delaySinceLastSR()
314 {
315     tRTP_NTP_TIME stCurNtpTimestamp = {RTP_ZERO, RTP_ZERO};
316     RtpDt_UInt32 dDifference = RTP_ZERO;
317 
318     if (m_stLastSrNtpTimestamp == RTP_ZERO)
319     {
320         return RTP_ZERO;
321     }
322     RtpOsUtil::GetNtpTime(stCurNtpTimestamp);
323     stCurNtpTimestamp.m_uiNtpHigh32Bits = RtpStackUtil::getMidFourOctets(&stCurNtpTimestamp);
324     dDifference = stCurNtpTimestamp.m_uiNtpHigh32Bits - m_stLastSrNtpTimestamp;
325     return dDifference;
326 }  // delaySinceLastSR
327 
populateReportBlock(IN RtcpReportBlock * pobjRepBlk)328 eRTP_STATUS_CODE RtpReceiverInfo::populateReportBlock(IN RtcpReportBlock* pobjRepBlk)
329 {
330     // ssrc
331     pobjRepBlk->setSsrc(m_uiSsrc);
332     // jitter
333     RtpDt_UInt32 uiJitter = (RtpDt_UInt32)m_stRtpSource.uiJitter;
334     pobjRepBlk->setJitter(uiJitter);
335     // uiJitter = uiJitter >> RTP_FOUR; // as per second logic
336 
337     // fraction lost
338     pobjRepBlk->setFracLost((RtpDt_UChar)fractionLost());
339     // cumulative number of packets lost
340     pobjRepBlk->setCumNumPktLost(findLostRtpPkts());
341     // extensible highest sequence number
342     pobjRepBlk->setExtHighSeqRcv(getExtSeqNum());
343 
344     // Last SR timestamp
345     RtpDt_UInt32 uiLSR = m_stPreSrTimestamp;
346     pobjRepBlk->setLastSR(uiLSR);
347     // delay since last sr
348     pobjRepBlk->setDelayLastSR(delaySinceLastSR());
349 
350     return RTP_SUCCESS;
351 }  // populateReportBlock
352