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