1 /*
2 
3   This file is a part of JRTPLIB
4   Copyright (c) 1999-2017 Jori Liesenborgs
5 
6   Contact: jori.liesenborgs@gmail.com
7 
8   This library was developed at the Expertise Centre for Digital Media
9   (http://www.edm.uhasselt.be), a research center of the Hasselt University
10   (http://www.uhasselt.be). The library is based upon work done for
11   my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
12 
13   Permission is hereby granted, free of charge, to any person obtaining a
14   copy of this software and associated documentation files (the "Software"),
15   to deal in the Software without restriction, including without limitation
16   the rights to use, copy, modify, merge, publish, distribute, sublicense,
17   and/or sell copies of the Software, and to permit persons to whom the
18   Software is furnished to do so, subject to the following conditions:
19 
20   The above copyright notice and this permission notice shall be included
21   in all copies or substantial portions of the Software.
22 
23   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
26   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
29   IN THE SOFTWARE.
30 
31 */
32 
33 #include "rtpsourcedata.h"
34 #include "rtpdefines.h"
35 #include "rtpaddress.h"
36 #include "rtpmemorymanager.h"
37 #ifdef RTP_SUPPORT_NETINET_IN
38 	#include <netinet/in.h>
39 #endif // RTP_SUPPORT_NETINET_IN
40 
41 #ifdef RTPDEBUG
42 	#include <iostream>
43 	#include <string>
44 #endif // RTPDEBUG
45 
46 #include "rtpdebug.h"
47 
48 #define ACCEPTPACKETCODE									\
49 		*accept = true;									\
50 												\
51 		sentdata = true;								\
52 		packetsreceived++;								\
53 		numnewpackets++;								\
54 												\
55 		if (pack->GetExtendedSequenceNumber() == 0)					\
56 		{										\
57 			baseseqnr = 0x0000FFFF;							\
58 			numcycles = 0x00010000;							\
59 		}										\
60 		else										\
61 			baseseqnr = pack->GetExtendedSequenceNumber() - 1;			\
62 												\
63 		exthighseqnr = baseseqnr + 1;							\
64 		prevpacktime = receivetime;							\
65 		prevexthighseqnr = baseseqnr;							\
66 		savedextseqnr = baseseqnr;							\
67 												\
68 		pack->SetExtendedSequenceNumber(exthighseqnr);					\
69 												\
70 		prevtimestamp = pack->GetTimestamp();						\
71 		lastmsgtime = prevpacktime;							\
72 		if (!ownpacket) /* for own packet, this value is set on an outgoing packet */	\
73 			lastrtptime = prevpacktime;
74 
75 namespace jrtplib
76 {
77 
ProcessPacket(RTPPacket * pack,const RTPTime & receivetime,double tsunit,bool ownpacket,bool * accept,bool applyprobation,bool * onprobation)78 void RTPSourceStats::ProcessPacket(RTPPacket *pack,const RTPTime &receivetime,double tsunit,
79                                    bool ownpacket,bool *accept,bool applyprobation,bool *onprobation)
80 {
81 	JRTPLIB_UNUSED(applyprobation); // possibly unused
82 
83 	// Note that the sequence number in the RTP packet is still just the
84 	// 16 bit number contained in the RTP header
85 
86 	*onprobation = false;
87 
88 	if (!sentdata) // no valid packets received yet
89 	{
90 #ifdef RTP_SUPPORT_PROBATION
91 		if (applyprobation)
92 		{
93 			bool acceptpack = false;
94 
95 			if (probation)
96 			{
97 				uint16_t pseq;
98 				uint32_t pseq2;
99 
100 				pseq = prevseqnr;
101 				pseq++;
102 				pseq2 = (uint32_t)pseq;
103 				if (pseq2 == pack->GetExtendedSequenceNumber()) // ok, its the next expected packet
104 				{
105 					prevseqnr = (uint16_t)pack->GetExtendedSequenceNumber();
106 					probation--;
107 					if (probation == 0) // probation over
108 						acceptpack = true;
109 					else
110 						*onprobation = true;
111 				}
112 				else // not next packet
113 				{
114 					probation = RTP_PROBATIONCOUNT;
115 					prevseqnr = (uint16_t)pack->GetExtendedSequenceNumber();
116 					*onprobation = true;
117 				}
118 			}
119 			else // first packet received with this SSRC ID, start probation
120 			{
121 				probation = RTP_PROBATIONCOUNT;
122 				prevseqnr = (uint16_t)pack->GetExtendedSequenceNumber();
123 				*onprobation = true;
124 			}
125 
126 			if (acceptpack)
127 			{
128 				ACCEPTPACKETCODE
129 			}
130 			else
131 			{
132 				*accept = false;
133 				lastmsgtime = receivetime;
134 			}
135 		}
136 		else // No probation
137 		{
138 			ACCEPTPACKETCODE
139 		}
140 #else // No compiled-in probation support
141 
142 		ACCEPTPACKETCODE
143 
144 #endif // RTP_SUPPORT_PROBATION
145 	}
146 	else // already got packets
147 	{
148 		uint16_t maxseq16;
149 		uint32_t extseqnr;
150 
151 		// Adjust max extended sequence number and set extende seq nr of packet
152 
153 		*accept = true;
154 		packetsreceived++;
155 		numnewpackets++;
156 
157 		maxseq16 = (uint16_t)(exthighseqnr&0x0000FFFF);
158 		if (pack->GetExtendedSequenceNumber() >= maxseq16)
159 		{
160 			extseqnr = numcycles+pack->GetExtendedSequenceNumber();
161 			exthighseqnr = extseqnr;
162 		}
163 		else
164 		{
165 			uint16_t dif1,dif2;
166 
167 			dif1 = ((uint16_t)pack->GetExtendedSequenceNumber());
168 			dif1 -= maxseq16;
169 			dif2 = maxseq16;
170 			dif2 -= ((uint16_t)pack->GetExtendedSequenceNumber());
171 			if (dif1 < dif2)
172 			{
173 				numcycles += 0x00010000;
174 				extseqnr = numcycles+pack->GetExtendedSequenceNumber();
175 				exthighseqnr = extseqnr;
176 			}
177 			else
178 				extseqnr = numcycles+pack->GetExtendedSequenceNumber();
179 		}
180 
181 		pack->SetExtendedSequenceNumber(extseqnr);
182 
183 		// Calculate jitter
184 
185 		if (tsunit > 0)
186 		{
187 #if 0
188 			RTPTime curtime = receivetime;
189 			double diffts1,diffts2,diff;
190 
191 			curtime -= prevpacktime;
192 			diffts1 = curtime.GetDouble()/tsunit;
193 			diffts2 = (double)pack->GetTimestamp() - (double)prevtimestamp;
194 			diff = diffts1 - diffts2;
195 			if (diff < 0)
196 				diff = -diff;
197 			diff -= djitter;
198 			diff /= 16.0;
199 			djitter += diff;
200 			jitter = (uint32_t)djitter;
201 #else
202 RTPTime curtime = receivetime;
203 double diffts1,diffts2,diff;
204 uint32_t curts = pack->GetTimestamp();
205 
206 curtime -= prevpacktime;
207 diffts1 = curtime.GetDouble()/tsunit;
208 
209 if (curts > prevtimestamp)
210 {
211 	uint32_t unsigneddiff = curts - prevtimestamp;
212 
213 	if (unsigneddiff < 0x10000000) // okay, curts realy is larger than prevtimestamp
214 		diffts2 = (double)unsigneddiff;
215 	else
216 	{
217 		// wraparound occurred and curts is actually smaller than prevtimestamp
218 
219 		unsigneddiff = -unsigneddiff; // to get the actual difference (in absolute value)
220 		diffts2 = -((double)unsigneddiff);
221 	}
222 }
223 else if (curts < prevtimestamp)
224 {
225 	uint32_t unsigneddiff = prevtimestamp - curts;
226 
227 	if (unsigneddiff < 0x10000000) // okay, curts really is smaller than prevtimestamp
228 		diffts2 = -((double)unsigneddiff); // negative since we actually need curts-prevtimestamp
229 	else
230 	{
231 		// wraparound occurred and curts is actually larger than prevtimestamp
232 
233 		unsigneddiff = -unsigneddiff; // to get the actual difference (in absolute value)
234 		diffts2 = (double)unsigneddiff;
235 	}
236 }
237 else
238 	diffts2 = 0;
239 
240 diff = diffts1 - diffts2;
241 if (diff < 0)
242 	diff = -diff;
243 diff -= djitter;
244 diff /= 16.0;
245 djitter += diff;
246 jitter = (uint32_t)djitter;
247 #endif
248 		}
249 		else
250 		{
251 			djitter = 0;
252 			jitter = 0;
253 		}
254 
255 		prevpacktime = receivetime;
256 		prevtimestamp = pack->GetTimestamp();
257 		lastmsgtime = prevpacktime;
258 		if (!ownpacket) // for own packet, this value is set on an outgoing packet
259 			lastrtptime = prevpacktime;
260 	}
261 }
262 
RTPSourceData(uint32_t s,RTPMemoryManager * mgr)263 RTPSourceData::RTPSourceData(uint32_t s, RTPMemoryManager *mgr) : RTPMemoryObject(mgr),SDESinf(mgr),byetime(0,0)
264 {
265 	ssrc = s;
266 	issender = false;
267 	iscsrc = false;
268 	timestampunit = -1;
269 	receivedbye = false;
270 	byereason = 0;
271 	byereasonlen = 0;
272 	rtpaddr = 0;
273 	rtcpaddr = 0;
274 	ownssrc = false;
275 	validated = false;
276 	processedinrtcp = false;
277 	isrtpaddrset = false;
278 	isrtcpaddrset = false;
279 }
280 
~RTPSourceData()281 RTPSourceData::~RTPSourceData()
282 {
283 	FlushPackets();
284 	if (byereason)
285 		RTPDeleteByteArray(byereason,GetMemoryManager());
286 	if (rtpaddr)
287 		RTPDelete(rtpaddr,GetMemoryManager());
288 	if (rtcpaddr)
289 		RTPDelete(rtcpaddr,GetMemoryManager());
290 }
291 
INF_GetEstimatedTimestampUnit() const292 double RTPSourceData::INF_GetEstimatedTimestampUnit() const
293 {
294 	if (!SRprevinf.HasInfo())
295 		return -1.0;
296 
297 	RTPTime t1 = RTPTime(SRinf.GetNTPTimestamp());
298 	RTPTime t2 = RTPTime(SRprevinf.GetNTPTimestamp());
299 	if (t1.IsZero() || t2.IsZero()) // one of the times couldn't be calculated
300 		return -1.0;
301 
302 	if (t1 <= t2)
303 		return -1.0;
304 
305 	t1 -= t2; // get the time difference
306 
307 	uint32_t tsdiff = SRinf.GetRTPTimestamp()-SRprevinf.GetRTPTimestamp();
308 
309 	return (t1.GetDouble()/((double)tsdiff));
310 }
311 
INF_GetRoundtripTime() const312 RTPTime RTPSourceData::INF_GetRoundtripTime() const
313 {
314 	if (!RRinf.HasInfo())
315 		return RTPTime(0,0);
316 	if (RRinf.GetDelaySinceLastSR() == 0 && RRinf.GetLastSRTimestamp() == 0)
317 		return RTPTime(0,0);
318 
319 	RTPNTPTime recvtime = RRinf.GetReceiveTime().GetNTPTime();
320 	uint32_t rtt = ((recvtime.GetMSW()&0xFFFF)<<16)|((recvtime.GetLSW()>>16)&0xFFFF);
321 	rtt -= RRinf.GetLastSRTimestamp();
322 	rtt -= RRinf.GetDelaySinceLastSR();
323 
324 	double drtt = (((double)rtt)/65536.0);
325 	return RTPTime(drtt);
326 }
327 
328 #ifdef RTPDEBUG
Dump()329 void RTPSourceData::Dump()
330 {
331 	std::cout << "Source data for SSRC:     " << ssrc << std::endl;
332 	std::cout << "    Active:               " << ((IsActive())?"Yes":"No") << std::endl;
333 	std::cout << "    Sender:               " << ((issender)?"Yes":"No") << std::endl;
334 	std::cout << "    CSRC:                 " << ((iscsrc)?"Yes":"No") << std::endl;
335 	std::cout << "    Received bye:         " << ((receivedbye)?"Yes":"No") << std::endl;
336 	std::cout << "    ProcessedInRTCP:      " << ((processedinrtcp)?"Yes":"No") << std::endl;
337 	std::cout << "    Timestamp unit:       " << timestampunit << std::endl;
338 	std::cout << "    RTP address:          ";
339 	if (!isrtpaddrset)
340 		std::cout << "Not set" << std::endl;
341 	else
342 	{
343 		if (rtpaddr == 0)
344 			std::cout << "Own session" << std::endl;
345 		else
346 			std::cout << rtpaddr->GetAddressString() << std::endl;
347 	}
348 	std::cout << "    RTCP address:         ";
349 	if (!isrtcpaddrset)
350 		std::cout << "Not set" << std::endl;
351 	else
352 	{
353 		if (rtcpaddr == 0)
354 			std::cout << "Own session" << std::endl;
355 		else
356 			std::cout << rtcpaddr->GetAddressString() << std::endl;
357 	}
358 	if (SRinf.HasInfo())
359 	{
360 		if (!SRprevinf.HasInfo())
361 		{
362 			std::cout << "    SR Info:" << std::endl;
363 			std::cout << "        NTP timestamp:    " << SRinf.GetNTPTimestamp().GetMSW() << ":" << SRinf.GetNTPTimestamp().GetLSW() << std::endl;
364 			std::cout << "        RTP timestamp:    " << SRinf.GetRTPTimestamp() << std::endl;
365 			std::cout << "        Packet count:     " << SRinf.GetPacketCount() << std::endl;
366 			std::cout << "        Octet count:      " << SRinf.GetByteCount() << std::endl;
367 			std::cout << "        Receive time:     " << SRinf.GetReceiveTime().GetSeconds() << std::endl;
368 		}
369 		else
370 		{
371 			std::cout << "    SR Info:" << std::endl;
372 			std::cout << "        NTP timestamp:    " << SRinf.GetNTPTimestamp().GetMSW() << ":" << SRinf.GetNTPTimestamp().GetLSW()
373 				  << " (" << SRprevinf.GetNTPTimestamp().GetMSW() << ":" << SRprevinf.GetNTPTimestamp().GetLSW() << ")" << std::endl;
374 			std::cout << "        RTP timestamp:    " << SRinf.GetRTPTimestamp()
375 			          << " (" << SRprevinf.GetRTPTimestamp() << ")" << std::endl;
376 			std::cout << "        Packet count:     " << SRinf.GetPacketCount()
377 			          << " (" << SRprevinf.GetPacketCount() << ")" << std::endl;
378 			std::cout << "        Octet count:      " << SRinf.GetByteCount()
379 			          << " (" << SRprevinf.GetByteCount() <<")" << std::endl;
380 			std::cout << "        Receive time:     " << SRinf.GetReceiveTime().GetSeconds()
381 			          << " (" << SRprevinf.GetReceiveTime().GetSeconds() << ")" << std::endl;
382 		}
383 	}
384 	if (RRinf.HasInfo())
385 	{
386 		if (!RRprevinf.HasInfo())
387 		{
388 			std::cout << "    RR Info:" << std::endl;
389 			std::cout << "        Fraction lost:    " << RRinf.GetFractionLost() << std::endl;
390 			std::cout << "        Packets lost:     " << RRinf.GetPacketsLost() << std::endl;
391 			std::cout << "        Ext.High.Seq:     " << RRinf.GetExtendedHighestSequenceNumber() << std::endl;
392 			std::cout << "        Jitter:           " << RRinf.GetJitter() << std::endl;
393 			std::cout << "        LSR:              " << RRinf.GetLastSRTimestamp() << std::endl;
394 			std::cout << "        DLSR:             " << RRinf.GetDelaySinceLastSR() << std::endl;
395 			std::cout << "        Receive time:     " << RRinf.GetReceiveTime().GetSeconds() << std::endl;
396 		}
397 		else
398 		{
399 			std::cout << "    RR Info:" << std::endl;
400 			std::cout << "        Fraction lost:    " << RRinf.GetFractionLost()
401 				  << " (" << RRprevinf.GetFractionLost() << ")" << std::endl;
402 			std::cout << "        Packets lost:     " << RRinf.GetPacketsLost()
403 			          << " (" << RRprevinf.GetPacketsLost() << ")" << std::endl;
404 			std::cout << "        Ext.High.Seq:     " << RRinf.GetExtendedHighestSequenceNumber()
405 			          << " (" << RRprevinf.GetExtendedHighestSequenceNumber() << ")" << std::endl;
406 			std::cout << "        Jitter:           " << RRinf.GetJitter()
407 			          << " (" << RRprevinf.GetJitter() << ")" << std::endl;
408 			std::cout << "        LSR:              " << RRinf.GetLastSRTimestamp()
409 			          << " (" << RRprevinf.GetLastSRTimestamp() << ")" << std::endl;
410 			std::cout << "        DLSR:             " << RRinf.GetDelaySinceLastSR()
411 			          << " (" << RRprevinf.GetDelaySinceLastSR() << ")" << std::endl;
412 			std::cout << "        Receive time:     " << RRinf.GetReceiveTime().GetSeconds()
413 			          << " (" << RRprevinf.GetReceiveTime().GetSeconds() <<")" << std::endl;
414 		}
415 	}
416 	std::cout << "    Stats:" << std::endl;
417 	std::cout << "        Sent data:        " << ((stats.HasSentData())?"Yes":"No") << std::endl;
418 	std::cout << "        Packets received: " << stats.GetNumPacketsReceived() << std::endl;
419 	std::cout << "        Seq. base:        " << stats.GetBaseSequenceNumber() << std::endl;
420 	std::cout << "        Ext.High.Seq:     " << stats.GetExtendedHighestSequenceNumber() << std::endl;
421 	std::cout << "        Jitter:           " << stats.GetJitter() << std::endl;
422 	std::cout << "        New packets:      " << stats.GetNumPacketsReceivedInInterval() << std::endl;
423 	std::cout << "        Saved seq. nr.:   " << stats.GetSavedExtendedSequenceNumber() << std::endl;
424 	std::cout << "        RTT:              " << INF_GetRoundtripTime().GetDouble() << " seconds" << std::endl;
425 	if (INF_GetEstimatedTimestampUnit() > 0)
426 		std::cout << "        Estimated:        " << (1.0/INF_GetEstimatedTimestampUnit()) << " samples per second" << std::endl;
427 	std::cout << "    SDES Info:" << std::endl;
428 
429 	size_t len;
430 	char str[1024];
431 	uint8_t *val;
432 
433 	if ((val = SDESinf.GetCNAME(&len)) != 0)
434 	{
435 		memcpy(str,val,len);
436 		str[len] = 0;
437 		std::cout << "        CNAME:            " << std::string(str) << std::endl;
438 	}
439 	if ((val = SDESinf.GetName(&len)) != 0)
440 	{
441 		memcpy(str,val,len);
442 		str[len] = 0;
443 		std::cout << "        Name:             " << std::string(str) << std::endl;
444 	}
445 	if ((val = SDESinf.GetEMail(&len)) != 0)
446 	{
447 		memcpy(str,val,len);
448 		str[len] = 0;
449 		std::cout << "        EMail:            " << std::string(str) << std::endl;
450 	}
451 	if ((val = SDESinf.GetPhone(&len)) != 0)
452 	{
453 		memcpy(str,val,len);
454 		str[len] = 0;
455 		std::cout << "        phone:            " << std::string(str) << std::endl;
456 	}
457 	if ((val = SDESinf.GetLocation(&len)) != 0)
458 	{
459 		memcpy(str,val,len);
460 		str[len] = 0;
461 		std::cout << "        Location:         " << std::string(str) << std::endl;
462 	}
463 	if ((val = SDESinf.GetTool(&len)) != 0)
464 	{
465 		memcpy(str,val,len);
466 		str[len] = 0;
467 		std::cout << "        Tool:             " << std::string(str) << std::endl;
468 	}
469 	if ((val = SDESinf.GetNote(&len)) != 0)
470 	{
471 		memcpy(str,val,len);
472 		str[len] = 0;
473 		std::cout << "        Note:             " << std::string(str) << std::endl;
474 	}
475 #ifdef RTP_SUPPORT_SDESPRIV
476 	SDESinf.GotoFirstPrivateValue();
477 	uint8_t *pref;
478 	size_t preflen;
479 	while (SDESinf.GetNextPrivateValue(&pref,&preflen,&val,&len))
480 	{
481 		char prefstr[1024];
482 		memcpy(prefstr,pref,preflen);
483 		memcpy(str,val,len);
484 		prefstr[preflen] = 0;
485 		str[len] = 0;
486 		std::cout << "        Private:          " << std::string(prefstr) << ":" << std::string(str) << std::endl;
487 	}
488 #endif // RTP_SUPPORT_SDESPRIV
489 	if (byereason)
490 	{
491 		memcpy(str,byereason,byereasonlen);
492 		str[byereasonlen] = 0;
493 		std::cout << "    BYE Reason:           " << std::string(str) << std::endl;
494 	}
495 }
496 
497 #endif // RTPDEBUG
498 
499 } // end namespace
500 
501 
502