| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  This file is a part of JRTPLIB | 
					
						
							|  |  |  |  Copyright (c) 1999-2017 Jori Liesenborgs | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  Contact: jori.liesenborgs@gmail.com | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  This library was developed at the Expertise Centre for Digital Media | 
					
						
							|  |  |  |  (http://www.edm.uhasselt.be), a research center of the Hasselt University
 | 
					
						
							|  |  |  |  (http://www.uhasselt.be). The library is based upon work done for
 | 
					
						
							|  |  |  |  my thesis at the School for Knowledge Technology (Belgium/The Netherlands). | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  Permission is hereby granted, free of charge, to any person obtaining a | 
					
						
							|  |  |  |  copy of this software and associated documentation files (the "Software"), | 
					
						
							|  |  |  |  to deal in the Software without restriction, including without limitation | 
					
						
							|  |  |  |  the rights to use, copy, modify, merge, publish, distribute, sublicense, | 
					
						
							|  |  |  |  and/or sell copies of the Software, and to permit persons to whom the | 
					
						
							|  |  |  |  Software is furnished to do so, subject to the following conditions: | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  The above copyright notice and this permission notice shall be included | 
					
						
							|  |  |  |  in all copies or substantial portions of the Software. | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | 
					
						
							|  |  |  |  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
					
						
							|  |  |  |  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL | 
					
						
							|  |  |  |  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 
					
						
							|  |  |  |  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | 
					
						
							|  |  |  |  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | 
					
						
							|  |  |  |  IN THE SOFTWARE. | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "rtpsources.h"
 | 
					
						
							|  |  |  | #include "rtperrors.h"
 | 
					
						
							|  |  |  | #include "rtprawpacket.h"
 | 
					
						
							|  |  |  | #include "rtpinternalsourcedata.h"
 | 
					
						
							|  |  |  | #include "rtptimeutilities.h"
 | 
					
						
							|  |  |  | #include "rtpdefines.h"
 | 
					
						
							|  |  |  | #include "rtcpcompoundpacket.h"
 | 
					
						
							|  |  |  | #include "rtcppacket.h"
 | 
					
						
							|  |  |  | #include "rtcpapppacket.h"
 | 
					
						
							|  |  |  | #include "rtcpbyepacket.h"
 | 
					
						
							|  |  |  | #include "rtcpsdespacket.h"
 | 
					
						
							|  |  |  | #include "rtcpsrpacket.h"
 | 
					
						
							|  |  |  | #include "rtcprrpacket.h"
 | 
					
						
							|  |  |  | #include "rtptransmitter.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace qrtplib | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:54:23 +01:00
										 |  |  | RTPSources::RTPSources() | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     totalcount = 0; | 
					
						
							|  |  |  |     sendercount = 0; | 
					
						
							|  |  |  |     activecount = 0; | 
					
						
							|  |  |  |     owndata = 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RTPSources::~RTPSources() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     Clear(); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RTPSources::Clear() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     ClearSourceList(); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RTPSources::ClearSourceList() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     sourcelist.GotoFirstElement(); | 
					
						
							|  |  |  |     while (sourcelist.HasCurrentElement()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         RTPInternalSourceData *sourcedata; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         sourcedata = sourcelist.GetCurrentElement(); | 
					
						
							|  |  |  |         delete sourcedata; | 
					
						
							|  |  |  |         sourcelist.GotoNextElement(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     sourcelist.Clear(); | 
					
						
							|  |  |  |     owndata = 0; | 
					
						
							|  |  |  |     totalcount = 0; | 
					
						
							|  |  |  |     sendercount = 0; | 
					
						
							|  |  |  |     activecount = 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int RTPSources::CreateOwnSSRC(uint32_t ssrc) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (owndata != 0) | 
					
						
							|  |  |  |         return ERR_RTP_SOURCES_ALREADYHAVEOWNSSRC; | 
					
						
							|  |  |  |     if (GotEntry(ssrc)) | 
					
						
							|  |  |  |         return ERR_RTP_SOURCES_SSRCEXISTS; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int status; | 
					
						
							|  |  |  |     bool created; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     status = ObtainSourceDataInstance(ssrc, &owndata, &created); | 
					
						
							|  |  |  |     if (status < 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         owndata = 0; // just to make sure
 | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     owndata->SetOwnSSRC(); | 
					
						
							|  |  |  |     owndata->SetRTPDataAddress(0); | 
					
						
							|  |  |  |     owndata->SetRTCPDataAddress(0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // we've created a validated ssrc, so we should increase activecount
 | 
					
						
							|  |  |  |     activecount++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     OnNewSource(owndata); | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int RTPSources::DeleteOwnSSRC() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (owndata == 0) | 
					
						
							|  |  |  |         return ERR_RTP_SOURCES_DONTHAVEOWNSSRC; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     uint32_t ssrc = owndata->GetSSRC(); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     sourcelist.GotoElement(ssrc); | 
					
						
							|  |  |  |     sourcelist.DeleteCurrentElement(); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     totalcount--; | 
					
						
							|  |  |  |     if (owndata->IsSender()) | 
					
						
							|  |  |  |         sendercount--; | 
					
						
							|  |  |  |     if (owndata->IsActive()) | 
					
						
							|  |  |  |         activecount--; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     OnRemoveSource(owndata); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     delete owndata; | 
					
						
							|  |  |  |     owndata = 0; | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RTPSources::SentRTPPacket() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (owndata == 0) | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     bool prevsender = owndata->IsSender(); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     owndata->SentRTPPacket(); | 
					
						
							|  |  |  |     if (!prevsender && owndata->IsSender()) | 
					
						
							|  |  |  |         sendercount++; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | int RTPSources::ProcessRawPacket(RTPRawPacket *rawpack, RTPTransmitter *rtptrans, bool acceptownpackets) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     RTPTransmitter *transmitters[1]; | 
					
						
							|  |  |  |     int num; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     transmitters[0] = rtptrans; | 
					
						
							|  |  |  |     if (rtptrans == 0) | 
					
						
							|  |  |  |         num = 0; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         num = 1; | 
					
						
							|  |  |  |     return ProcessRawPacket(rawpack, transmitters, num, acceptownpackets); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | int RTPSources::ProcessRawPacket(RTPRawPacket *rawpack, RTPTransmitter *rtptrans[], int numtrans, bool acceptownpackets) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     int status; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (rawpack->IsRTP()) // RTP packet
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         RTPPacket *rtppack; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // First, we'll see if the packet can be parsed
 | 
					
						
							|  |  |  |         rtppack = new RTPPacket(*rawpack); | 
					
						
							|  |  |  |         if (rtppack == 0) | 
					
						
							|  |  |  |             return ERR_RTP_OUTOFMEM; | 
					
						
							|  |  |  |         if ((status = rtppack->GetCreationError()) < 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (status == ERR_RTP_PACKET_INVALIDPACKET) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 delete rtppack; | 
					
						
							|  |  |  |                 rtppack = 0; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 delete rtppack; | 
					
						
							|  |  |  |                 return status; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Check if the packet was valid
 | 
					
						
							|  |  |  |         if (rtppack != 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             bool stored = false; | 
					
						
							|  |  |  |             bool ownpacket = false; | 
					
						
							|  |  |  |             int i; | 
					
						
							| 
									
										
										
										
											2018-03-05 01:17:19 +01:00
										 |  |  |             const RTPAddress& senderaddress = rawpack->GetSenderAddress(); | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             for (i = 0; !ownpacket && i < numtrans; i++) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (rtptrans[i]->ComesFromThisTransmitter(senderaddress)) | 
					
						
							|  |  |  |                     ownpacket = true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Check if the packet is our own.
 | 
					
						
							|  |  |  |             if (ownpacket) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 // Now it depends on the user's preference
 | 
					
						
							|  |  |  |                 // what to do with this packet:
 | 
					
						
							|  |  |  |                 if (acceptownpackets) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     // sender addres for own packets has to be NULL!
 | 
					
						
							|  |  |  |                     if ((status = ProcessRTPPacket(rtppack, rawpack->GetReceiveTime(), 0, &stored)) < 0) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         if (!stored) | 
					
						
							|  |  |  |                             delete rtppack; | 
					
						
							|  |  |  |                         return status; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2018-03-05 01:17:19 +01:00
										 |  |  |                 if ((status = ProcessRTPPacket(rtppack, rawpack->GetReceiveTime(), &senderaddress, &stored)) < 0) | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |                 { | 
					
						
							|  |  |  |                     if (!stored) | 
					
						
							|  |  |  |                         delete rtppack; | 
					
						
							|  |  |  |                     return status; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (!stored) | 
					
						
							|  |  |  |                 delete rtppack; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else // RTCP packet
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         RTCPCompoundPacket rtcpcomppack(*rawpack); | 
					
						
							|  |  |  |         bool valid = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ((status = rtcpcomppack.GetCreationError()) < 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (status != ERR_RTP_RTCPCOMPOUND_INVALIDPACKET) | 
					
						
							|  |  |  |                 return status; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             valid = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (valid) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             bool ownpacket = false; | 
					
						
							|  |  |  |             int i; | 
					
						
							| 
									
										
										
										
											2018-03-05 01:17:19 +01:00
										 |  |  |             const RTPAddress& senderaddress = rawpack->GetSenderAddress(); | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             for (i = 0; !ownpacket && i < numtrans; i++) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (rtptrans[i]->ComesFromThisTransmitter(senderaddress)) | 
					
						
							|  |  |  |                     ownpacket = true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // First check if it's a packet of this session.
 | 
					
						
							|  |  |  |             if (ownpacket) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (acceptownpackets) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     // sender address for own packets has to be NULL
 | 
					
						
							|  |  |  |                     status = ProcessRTCPCompoundPacket(&rtcpcomppack, rawpack->GetReceiveTime(), 0); | 
					
						
							|  |  |  |                     if (status < 0) | 
					
						
							|  |  |  |                         return status; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else // not our own packet
 | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2018-03-05 01:17:19 +01:00
										 |  |  |                 status = ProcessRTCPCompoundPacket(&rtcpcomppack, rawpack->GetReceiveTime(), &rawpack->GetSenderAddress()); | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |                 if (status < 0) | 
					
						
							|  |  |  |                     return status; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | int RTPSources::ProcessRTPPacket(RTPPacket *rtppack, const RTPTime &receivetime, const RTPAddress *senderaddress, bool *stored) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     uint32_t ssrc; | 
					
						
							|  |  |  |     RTPInternalSourceData *srcdat; | 
					
						
							|  |  |  |     int status; | 
					
						
							|  |  |  |     bool created; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     OnRTPPacket(rtppack, receivetime, senderaddress); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     *stored = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ssrc = rtppack->GetSSRC(); | 
					
						
							|  |  |  |     if ((status = ObtainSourceDataInstance(ssrc, &srcdat, &created)) < 0) | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (created) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ((status = srcdat->SetRTPDataAddress(senderaddress)) < 0) | 
					
						
							|  |  |  |             return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else // got a previously existing source
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (CheckCollision(srcdat, senderaddress, true)) | 
					
						
							|  |  |  |             return 0; // ignore packet on collision
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool prevsender = srcdat->IsSender(); | 
					
						
							|  |  |  |     bool prevactive = srcdat->IsActive(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     uint32_t CSRCs[RTP_MAXCSRCS]; | 
					
						
							|  |  |  |     int numCSRCs = rtppack->GetCSRCCount(); | 
					
						
							|  |  |  |     if (numCSRCs > RTP_MAXCSRCS) // shouldn't happen, but better to check than go out of bounds
 | 
					
						
							|  |  |  |         numCSRCs = RTP_MAXCSRCS; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (int i = 0; i < numCSRCs; i++) | 
					
						
							|  |  |  |         CSRCs[i] = rtppack->GetCSRC(i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // The packet comes from a valid source, we can process it further now
 | 
					
						
							|  |  |  |     // The following function should delete rtppack itself if something goes
 | 
					
						
							|  |  |  |     // wrong
 | 
					
						
							|  |  |  |     if ((status = srcdat->ProcessRTPPacket(rtppack, receivetime, stored, this)) < 0) | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // NOTE: we cannot use 'rtppack' anymore since it may have been deleted in
 | 
					
						
							|  |  |  |     //       OnValidatedRTPPacket
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!prevsender && srcdat->IsSender()) | 
					
						
							|  |  |  |         sendercount++; | 
					
						
							|  |  |  |     if (!prevactive && srcdat->IsActive()) | 
					
						
							|  |  |  |         activecount++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (created) | 
					
						
							|  |  |  |         OnNewSource(srcdat); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (srcdat->IsValidated()) // process the CSRCs
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         RTPInternalSourceData *csrcdat; | 
					
						
							|  |  |  |         bool createdcsrc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         int num = numCSRCs; | 
					
						
							|  |  |  |         int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (i = 0; i < num; i++) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if ((status = ObtainSourceDataInstance(CSRCs[i], &csrcdat, &createdcsrc)) < 0) | 
					
						
							|  |  |  |                 return status; | 
					
						
							|  |  |  |             if (createdcsrc) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 csrcdat->SetCSRC(); | 
					
						
							|  |  |  |                 if (csrcdat->IsActive()) | 
					
						
							|  |  |  |                     activecount++; | 
					
						
							|  |  |  |                 OnNewSource(csrcdat); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else // already found an entry, possibly because of RTCP data
 | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (!CheckCollision(csrcdat, senderaddress, true)) | 
					
						
							|  |  |  |                     csrcdat->SetCSRC(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | int RTPSources::ProcessRTCPCompoundPacket(RTCPCompoundPacket *rtcpcomppack, const RTPTime &receivetime, const RTPAddress *senderaddress) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     RTCPPacket *rtcppack; | 
					
						
							|  |  |  |     int status; | 
					
						
							|  |  |  |     bool gotownssrc = ((owndata == 0) ? false : true); | 
					
						
							|  |  |  |     uint32_t ownssrc = ((owndata != 0) ? owndata->GetSSRC() : 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     OnRTCPCompoundPacket(rtcpcomppack, receivetime, senderaddress); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     rtcpcomppack->GotoFirstPacket(); | 
					
						
							|  |  |  |     while ((rtcppack = rtcpcomppack->GetNextPacket()) != 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (rtcppack->IsKnownFormat()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             switch (rtcppack->GetPacketType()) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |             case RTCPPacket::SR: | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 RTCPSRPacket *p = (RTCPSRPacket *) rtcppack; | 
					
						
							|  |  |  |                 uint32_t senderssrc = p->GetSenderSSRC(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 status = ProcessRTCPSenderInfo(senderssrc, p->GetNTPTimestamp(), p->GetRTPTimestamp(), p->GetSenderPacketCount(), p->GetSenderOctetCount(), receivetime, | 
					
						
							|  |  |  |                         senderaddress); | 
					
						
							|  |  |  |                 if (status < 0) | 
					
						
							|  |  |  |                     return status; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 bool gotinfo = false; | 
					
						
							|  |  |  |                 if (gotownssrc) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     int i; | 
					
						
							|  |  |  |                     int num = p->GetReceptionReportCount(); | 
					
						
							|  |  |  |                     for (i = 0; i < num; i++) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         if (p->GetSSRC(i) == ownssrc) // data is meant for us
 | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             gotinfo = true; | 
					
						
							|  |  |  |                             status = ProcessRTCPReportBlock(senderssrc, p->GetFractionLost(i), p->GetLostPacketCount(i), p->GetExtendedHighestSequenceNumber(i), p->GetJitter(i), | 
					
						
							|  |  |  |                                     p->GetLSR(i), p->GetDLSR(i), receivetime, senderaddress); | 
					
						
							|  |  |  |                             if (status < 0) | 
					
						
							|  |  |  |                                 return status; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (!gotinfo) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     status = UpdateReceiveTime(senderssrc, receivetime, senderaddress); | 
					
						
							|  |  |  |                     if (status < 0) | 
					
						
							|  |  |  |                         return status; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case RTCPPacket::RR: | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 RTCPRRPacket *p = (RTCPRRPacket *) rtcppack; | 
					
						
							|  |  |  |                 uint32_t senderssrc = p->GetSenderSSRC(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 bool gotinfo = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (gotownssrc) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     int i; | 
					
						
							|  |  |  |                     int num = p->GetReceptionReportCount(); | 
					
						
							|  |  |  |                     for (i = 0; i < num; i++) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         if (p->GetSSRC(i) == ownssrc) | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             gotinfo = true; | 
					
						
							|  |  |  |                             status = ProcessRTCPReportBlock(senderssrc, p->GetFractionLost(i), p->GetLostPacketCount(i), p->GetExtendedHighestSequenceNumber(i), p->GetJitter(i), | 
					
						
							|  |  |  |                                     p->GetLSR(i), p->GetDLSR(i), receivetime, senderaddress); | 
					
						
							|  |  |  |                             if (status < 0) | 
					
						
							|  |  |  |                                 return status; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (!gotinfo) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     status = UpdateReceiveTime(senderssrc, receivetime, senderaddress); | 
					
						
							|  |  |  |                     if (status < 0) | 
					
						
							|  |  |  |                         return status; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case RTCPPacket::SDES: | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 RTCPSDESPacket *p = (RTCPSDESPacket *) rtcppack; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (p->GotoFirstChunk()) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     do | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         uint32_t sdesssrc = p->GetChunkSSRC(); | 
					
						
							|  |  |  |                         bool updated = false; | 
					
						
							|  |  |  |                         if (p->GotoFirstItem()) | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             do | 
					
						
							|  |  |  |                             { | 
					
						
							|  |  |  |                                 RTCPSDESPacket::ItemType t; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                                 if ((t = p->GetItemType()) != RTCPSDESPacket::PRIV) | 
					
						
							|  |  |  |                                 { | 
					
						
							|  |  |  |                                     updated = true; | 
					
						
							|  |  |  |                                     status = ProcessSDESNormalItem(sdesssrc, t, p->GetItemLength(), p->GetItemData(), receivetime, senderaddress); | 
					
						
							|  |  |  |                                     if (status < 0) | 
					
						
							|  |  |  |                                         return status; | 
					
						
							|  |  |  |                                 } | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | #ifdef RTP_SUPPORT_SDESPRIV
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |                                 else | 
					
						
							|  |  |  |                                 { | 
					
						
							|  |  |  |                                     updated = true; | 
					
						
							|  |  |  |                                     status = ProcessSDESPrivateItem(sdesssrc, p->GetPRIVPrefixLength(), p->GetPRIVPrefixData(), p->GetPRIVValueLength(), p->GetPRIVValueData(), | 
					
						
							|  |  |  |                                             receivetime, senderaddress); | 
					
						
							|  |  |  |                                     if (status < 0) | 
					
						
							|  |  |  |                                         return status; | 
					
						
							|  |  |  |                                 } | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | #endif // RTP_SUPPORT_SDESPRIV
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |                             } while (p->GotoNextItem()); | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         if (!updated) | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             status = UpdateReceiveTime(sdesssrc, receivetime, senderaddress); | 
					
						
							|  |  |  |                             if (status < 0) | 
					
						
							|  |  |  |                                 return status; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } while (p->GotoNextChunk()); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case RTCPPacket::BYE: | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 RTCPBYEPacket *p = (RTCPBYEPacket *) rtcppack; | 
					
						
							|  |  |  |                 int i; | 
					
						
							|  |  |  |                 int num = p->GetSSRCCount(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 for (i = 0; i < num; i++) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     uint32_t byessrc = p->GetSSRC(i); | 
					
						
							|  |  |  |                     status = ProcessBYE(byessrc, p->GetReasonLength(), p->GetReasonData(), receivetime, senderaddress); | 
					
						
							|  |  |  |                     if (status < 0) | 
					
						
							|  |  |  |                         return status; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case RTCPPacket::APP: | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 RTCPAPPPacket *p = (RTCPAPPPacket *) rtcppack; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 OnAPPPacket(p, receivetime, senderaddress); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case RTCPPacket::Unknown: | 
					
						
							|  |  |  |             default: | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 OnUnknownPacketType(rtcppack, receivetime, senderaddress); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             OnUnknownPacketFormat(rtcppack, receivetime, senderaddress); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool RTPSources::GotoFirstSource() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     sourcelist.GotoFirstElement(); | 
					
						
							|  |  |  |     if (sourcelist.HasCurrentElement()) | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool RTPSources::GotoNextSource() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     sourcelist.GotoNextElement(); | 
					
						
							|  |  |  |     if (sourcelist.HasCurrentElement()) | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool RTPSources::GotoPreviousSource() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     sourcelist.GotoPreviousElement(); | 
					
						
							|  |  |  |     if (sourcelist.HasCurrentElement()) | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool RTPSources::GotoFirstSourceWithData() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     bool found = false; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     sourcelist.GotoFirstElement(); | 
					
						
							|  |  |  |     while (!found && sourcelist.HasCurrentElement()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         RTPInternalSourceData *srcdat; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |         srcdat = sourcelist.GetCurrentElement(); | 
					
						
							|  |  |  |         if (srcdat->HasData()) | 
					
						
							|  |  |  |             found = true; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             sourcelist.GotoNextElement(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     return found; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool RTPSources::GotoNextSourceWithData() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     bool found = false; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     sourcelist.GotoNextElement(); | 
					
						
							|  |  |  |     while (!found && sourcelist.HasCurrentElement()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         RTPInternalSourceData *srcdat; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |         srcdat = sourcelist.GetCurrentElement(); | 
					
						
							|  |  |  |         if (srcdat->HasData()) | 
					
						
							|  |  |  |             found = true; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             sourcelist.GotoNextElement(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     return found; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool RTPSources::GotoPreviousSourceWithData() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     bool found = false; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     sourcelist.GotoPreviousElement(); | 
					
						
							|  |  |  |     while (!found && sourcelist.HasCurrentElement()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         RTPInternalSourceData *srcdat; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |         srcdat = sourcelist.GetCurrentElement(); | 
					
						
							|  |  |  |         if (srcdat->HasData()) | 
					
						
							|  |  |  |             found = true; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             sourcelist.GotoPreviousElement(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     return found; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RTPSourceData *RTPSources::GetCurrentSourceInfo() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (!sourcelist.HasCurrentElement()) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     return sourcelist.GetCurrentElement(); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RTPSourceData *RTPSources::GetSourceInfo(uint32_t ssrc) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (sourcelist.GotoElement(ssrc) < 0) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     if (!sourcelist.HasCurrentElement()) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     return sourcelist.GetCurrentElement(); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool RTPSources::GotEntry(uint32_t ssrc) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     return sourcelist.HasElement(ssrc); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RTPPacket *RTPSources::GetNextPacket() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (!sourcelist.HasCurrentElement()) | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     RTPInternalSourceData *srcdat = sourcelist.GetCurrentElement(); | 
					
						
							|  |  |  |     RTPPacket *pack = srcdat->GetNextPacket(); | 
					
						
							|  |  |  |     return pack; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | int RTPSources::ProcessRTCPSenderInfo(uint32_t ssrc, const RTPNTPTime &ntptime, uint32_t rtptime, uint32_t packetcount, uint32_t octetcount, const RTPTime &receivetime, | 
					
						
							|  |  |  |         const RTPAddress *senderaddress) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     RTPInternalSourceData *srcdat; | 
					
						
							|  |  |  |     bool created; | 
					
						
							|  |  |  |     int status; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     status = GetRTCPSourceData(ssrc, senderaddress, &srcdat, &created); | 
					
						
							|  |  |  |     if (status < 0) | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     if (srcdat == 0) | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     srcdat->ProcessSenderInfo(ntptime, rtptime, packetcount, octetcount, receivetime); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     // Call the callback
 | 
					
						
							|  |  |  |     if (created) | 
					
						
							|  |  |  |         OnNewSource(srcdat); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     OnRTCPSenderReport(srcdat); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | int RTPSources::ProcessRTCPReportBlock(uint32_t ssrc, uint8_t fractionlost, int32_t lostpackets, uint32_t exthighseqnr, uint32_t jitter, uint32_t lsr, uint32_t dlsr, | 
					
						
							|  |  |  |         const RTPTime &receivetime, const RTPAddress *senderaddress) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     RTPInternalSourceData *srcdat; | 
					
						
							|  |  |  |     bool created; | 
					
						
							|  |  |  |     int status; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     status = GetRTCPSourceData(ssrc, senderaddress, &srcdat, &created); | 
					
						
							|  |  |  |     if (status < 0) | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     if (srcdat == 0) | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     srcdat->ProcessReportBlock(fractionlost, lostpackets, exthighseqnr, jitter, lsr, dlsr, receivetime); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     // Call the callback
 | 
					
						
							|  |  |  |     if (created) | 
					
						
							|  |  |  |         OnNewSource(srcdat); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     OnRTCPReceiverReport(srcdat); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  | int RTPSources::ProcessSDESNormalItem(uint32_t ssrc, RTCPSDESPacket::ItemType t, std::size_t itemlength, const void *itemdata, const RTPTime &receivetime, | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |         const RTPAddress *senderaddress) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     RTPInternalSourceData *srcdat; | 
					
						
							|  |  |  |     bool created, cnamecollis; | 
					
						
							|  |  |  |     int status; | 
					
						
							|  |  |  |     uint8_t sdesid; | 
					
						
							|  |  |  |     bool prevactive; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (t) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     case RTCPSDESPacket::CNAME: | 
					
						
							|  |  |  |         sdesid = RTCP_SDES_ID_CNAME; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case RTCPSDESPacket::NAME: | 
					
						
							|  |  |  |         sdesid = RTCP_SDES_ID_NAME; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case RTCPSDESPacket::EMAIL: | 
					
						
							|  |  |  |         sdesid = RTCP_SDES_ID_EMAIL; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case RTCPSDESPacket::PHONE: | 
					
						
							|  |  |  |         sdesid = RTCP_SDES_ID_PHONE; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case RTCPSDESPacket::LOC: | 
					
						
							|  |  |  |         sdesid = RTCP_SDES_ID_LOCATION; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case RTCPSDESPacket::TOOL: | 
					
						
							|  |  |  |         sdesid = RTCP_SDES_ID_TOOL; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case RTCPSDESPacket::NOTE: | 
					
						
							|  |  |  |         sdesid = RTCP_SDES_ID_NOTE; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         return ERR_RTP_SOURCES_ILLEGALSDESTYPE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     status = GetRTCPSourceData(ssrc, senderaddress, &srcdat, &created); | 
					
						
							|  |  |  |     if (status < 0) | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     if (srcdat == 0) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     prevactive = srcdat->IsActive(); | 
					
						
							|  |  |  |     status = srcdat->ProcessSDESItem(sdesid, (const uint8_t *) itemdata, itemlength, receivetime, &cnamecollis); | 
					
						
							|  |  |  |     if (!prevactive && srcdat->IsActive()) | 
					
						
							|  |  |  |         activecount++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Call the callback
 | 
					
						
							|  |  |  |     if (created) | 
					
						
							|  |  |  |         OnNewSource(srcdat); | 
					
						
							|  |  |  |     if (cnamecollis) | 
					
						
							|  |  |  |         OnCNAMECollision(srcdat, senderaddress, (const uint8_t *) itemdata, itemlength); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (status >= 0) | 
					
						
							|  |  |  |         OnRTCPSDESItem(srcdat, t, itemdata, itemlength); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return status; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef RTP_SUPPORT_SDESPRIV
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  | int RTPSources::ProcessSDESPrivateItem(uint32_t ssrc, std::size_t prefixlen, const void *prefixdata, std::size_t valuelen, const void *valuedata, const RTPTime &receivetime, | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |         const RTPAddress *senderaddress) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     RTPInternalSourceData *srcdat; | 
					
						
							|  |  |  |     bool created; | 
					
						
							|  |  |  |     int status; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     status = GetRTCPSourceData(ssrc, senderaddress, &srcdat, &created); | 
					
						
							|  |  |  |     if (status < 0) | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     if (srcdat == 0) | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     status = srcdat->ProcessPrivateSDESItem((const uint8_t *) prefixdata, prefixlen, (const uint8_t *) valuedata, valuelen, receivetime); | 
					
						
							|  |  |  |     // Call the callback
 | 
					
						
							|  |  |  |     if (created) | 
					
						
							|  |  |  |         OnNewSource(srcdat); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (status >= 0) | 
					
						
							|  |  |  |         OnRTCPSDESPrivateItem(srcdat, prefixdata, prefixlen, valuedata, valuelen); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     return status; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | #endif //RTP_SUPPORT_SDESPRIV
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  | int RTPSources::ProcessBYE(uint32_t ssrc, std::size_t reasonlength, const void *reasondata, const RTPTime &receivetime, const RTPAddress *senderaddress) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     RTPInternalSourceData *srcdat; | 
					
						
							|  |  |  |     bool created; | 
					
						
							|  |  |  |     int status; | 
					
						
							|  |  |  |     bool prevactive; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     status = GetRTCPSourceData(ssrc, senderaddress, &srcdat, &created); | 
					
						
							|  |  |  |     if (status < 0) | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     if (srcdat == 0) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // we'll ignore BYE packets for our own ssrc
 | 
					
						
							|  |  |  |     if (srcdat == owndata) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     prevactive = srcdat->IsActive(); | 
					
						
							|  |  |  |     srcdat->ProcessBYEPacket((const uint8_t *) reasondata, reasonlength, receivetime); | 
					
						
							|  |  |  |     if (prevactive && !srcdat->IsActive()) | 
					
						
							|  |  |  |         activecount--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Call the callback
 | 
					
						
							|  |  |  |     if (created) | 
					
						
							|  |  |  |         OnNewSource(srcdat); | 
					
						
							|  |  |  |     OnBYEPacket(srcdat); | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | int RTPSources::ObtainSourceDataInstance(uint32_t ssrc, RTPInternalSourceData **srcdat, bool *created) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     RTPInternalSourceData *srcdat2; | 
					
						
							|  |  |  |     int status; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (sourcelist.GotoElement(ssrc) < 0) // No entry for this source
 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:36:24 +01:00
										 |  |  |         srcdat2 = new RTPInternalSourceData(ssrc); | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |         if (srcdat2 == 0) | 
					
						
							|  |  |  |             return ERR_RTP_OUTOFMEM; | 
					
						
							|  |  |  |         if ((status = sourcelist.AddElement(ssrc, srcdat2)) < 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             delete srcdat2; | 
					
						
							|  |  |  |             return status; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         *srcdat = srcdat2; | 
					
						
							|  |  |  |         *created = true; | 
					
						
							|  |  |  |         totalcount++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         *srcdat = sourcelist.GetCurrentElement(); | 
					
						
							|  |  |  |         *created = false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | int RTPSources::GetRTCPSourceData(uint32_t ssrc, const RTPAddress *senderaddress, RTPInternalSourceData **srcdat2, bool *newsource) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     int status; | 
					
						
							|  |  |  |     bool created; | 
					
						
							|  |  |  |     RTPInternalSourceData *srcdat; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     *srcdat2 = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((status = ObtainSourceDataInstance(ssrc, &srcdat, &created)) < 0) | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (created) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ((status = srcdat->SetRTCPDataAddress(senderaddress)) < 0) | 
					
						
							|  |  |  |             return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else // got a previously existing source
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (CheckCollision(srcdat, senderaddress, false)) | 
					
						
							|  |  |  |             return 0; // ignore packet on collision
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     *srcdat2 = srcdat; | 
					
						
							|  |  |  |     *newsource = created; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | int RTPSources::UpdateReceiveTime(uint32_t ssrc, const RTPTime &receivetime, const RTPAddress *senderaddress) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     RTPInternalSourceData *srcdat; | 
					
						
							|  |  |  |     bool created; | 
					
						
							|  |  |  |     int status; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     status = GetRTCPSourceData(ssrc, senderaddress, &srcdat, &created); | 
					
						
							|  |  |  |     if (status < 0) | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     if (srcdat == 0) | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     // We got valid SSRC info
 | 
					
						
							|  |  |  |     srcdat->UpdateMessageTime(receivetime); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     // Call the callback
 | 
					
						
							|  |  |  |     if (created) | 
					
						
							|  |  |  |         OnNewSource(srcdat); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | void RTPSources::Timeout(const RTPTime &curtime, const RTPTime &timeoutdelay) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     int newtotalcount = 0; | 
					
						
							|  |  |  |     int newsendercount = 0; | 
					
						
							|  |  |  |     int newactivecount = 0; | 
					
						
							|  |  |  |     RTPTime checktime = curtime; | 
					
						
							|  |  |  |     checktime -= timeoutdelay; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sourcelist.GotoFirstElement(); | 
					
						
							|  |  |  |     while (sourcelist.HasCurrentElement()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         RTPInternalSourceData *srcdat = sourcelist.GetCurrentElement(); | 
					
						
							|  |  |  |         RTPTime lastmsgtime = srcdat->INF_GetLastMessageTime(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // we don't want to time out ourselves
 | 
					
						
							|  |  |  |         if ((srcdat != owndata) && (lastmsgtime < checktime)) // timeout
 | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             totalcount--; | 
					
						
							|  |  |  |             if (srcdat->IsSender()) | 
					
						
							|  |  |  |                 sendercount--; | 
					
						
							|  |  |  |             if (srcdat->IsActive()) | 
					
						
							|  |  |  |                 activecount--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             sourcelist.DeleteCurrentElement(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             OnTimeout(srcdat); | 
					
						
							|  |  |  |             OnRemoveSource(srcdat); | 
					
						
							|  |  |  |             delete srcdat; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             newtotalcount++; | 
					
						
							|  |  |  |             if (srcdat->IsSender()) | 
					
						
							|  |  |  |                 newsendercount++; | 
					
						
							|  |  |  |             if (srcdat->IsActive()) | 
					
						
							|  |  |  |                 newactivecount++; | 
					
						
							|  |  |  |             sourcelist.GotoNextElement(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     totalcount = newtotalcount; // just to play it safe
 | 
					
						
							|  |  |  |     sendercount = newsendercount; | 
					
						
							|  |  |  |     activecount = newactivecount; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | void RTPSources::SenderTimeout(const RTPTime &curtime, const RTPTime &timeoutdelay) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     int newtotalcount = 0; | 
					
						
							|  |  |  |     int newsendercount = 0; | 
					
						
							|  |  |  |     int newactivecount = 0; | 
					
						
							|  |  |  |     RTPTime checktime = curtime; | 
					
						
							|  |  |  |     checktime -= timeoutdelay; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sourcelist.GotoFirstElement(); | 
					
						
							|  |  |  |     while (sourcelist.HasCurrentElement()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         RTPInternalSourceData *srcdat = sourcelist.GetCurrentElement(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         newtotalcount++; | 
					
						
							|  |  |  |         if (srcdat->IsActive()) | 
					
						
							|  |  |  |             newactivecount++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (srcdat->IsSender()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             RTPTime lastrtppacktime = srcdat->INF_GetLastRTPPacketTime(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (lastrtppacktime < checktime) // timeout
 | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 srcdat->ClearSenderFlag(); | 
					
						
							|  |  |  |                 sendercount--; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 newsendercount++; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         sourcelist.GotoNextElement(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     totalcount = newtotalcount; // just to play it safe
 | 
					
						
							|  |  |  |     sendercount = newsendercount; | 
					
						
							|  |  |  |     activecount = newactivecount; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | void RTPSources::BYETimeout(const RTPTime &curtime, const RTPTime &timeoutdelay) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     int newtotalcount = 0; | 
					
						
							|  |  |  |     int newsendercount = 0; | 
					
						
							|  |  |  |     int newactivecount = 0; | 
					
						
							|  |  |  |     RTPTime checktime = curtime; | 
					
						
							|  |  |  |     checktime -= timeoutdelay; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sourcelist.GotoFirstElement(); | 
					
						
							|  |  |  |     while (sourcelist.HasCurrentElement()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         RTPInternalSourceData *srcdat = sourcelist.GetCurrentElement(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (srcdat->ReceivedBYE()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             RTPTime byetime = srcdat->GetBYETime(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if ((srcdat != owndata) && (checktime > byetime)) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 totalcount--; | 
					
						
							|  |  |  |                 if (srcdat->IsSender()) | 
					
						
							|  |  |  |                     sendercount--; | 
					
						
							|  |  |  |                 if (srcdat->IsActive()) | 
					
						
							|  |  |  |                     activecount--; | 
					
						
							|  |  |  |                 sourcelist.DeleteCurrentElement(); | 
					
						
							|  |  |  |                 OnBYETimeout(srcdat); | 
					
						
							|  |  |  |                 OnRemoveSource(srcdat); | 
					
						
							|  |  |  |                 delete srcdat; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 newtotalcount++; | 
					
						
							|  |  |  |                 if (srcdat->IsSender()) | 
					
						
							|  |  |  |                     newsendercount++; | 
					
						
							|  |  |  |                 if (srcdat->IsActive()) | 
					
						
							|  |  |  |                     newactivecount++; | 
					
						
							|  |  |  |                 sourcelist.GotoNextElement(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             newtotalcount++; | 
					
						
							|  |  |  |             if (srcdat->IsSender()) | 
					
						
							|  |  |  |                 newsendercount++; | 
					
						
							|  |  |  |             if (srcdat->IsActive()) | 
					
						
							|  |  |  |                 newactivecount++; | 
					
						
							|  |  |  |             sourcelist.GotoNextElement(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     totalcount = newtotalcount; // just to play it safe
 | 
					
						
							|  |  |  |     sendercount = newsendercount; | 
					
						
							|  |  |  |     activecount = newactivecount; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | void RTPSources::NoteTimeout(const RTPTime &curtime, const RTPTime &timeoutdelay) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     int newtotalcount = 0; | 
					
						
							|  |  |  |     int newsendercount = 0; | 
					
						
							|  |  |  |     int newactivecount = 0; | 
					
						
							|  |  |  |     RTPTime checktime = curtime; | 
					
						
							|  |  |  |     checktime -= timeoutdelay; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sourcelist.GotoFirstElement(); | 
					
						
							|  |  |  |     while (sourcelist.HasCurrentElement()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         RTPInternalSourceData *srcdat = sourcelist.GetCurrentElement(); | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |         std::size_t notelen; | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         srcdat->SDES_GetNote(¬elen); | 
					
						
							|  |  |  |         if (notelen != 0) // Note has been set
 | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             RTPTime notetime = srcdat->INF_GetLastSDESNoteTime(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (checktime > notetime) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 srcdat->ClearNote(); | 
					
						
							|  |  |  |                 OnNoteTimeout(srcdat); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         newtotalcount++; | 
					
						
							|  |  |  |         if (srcdat->IsSender()) | 
					
						
							|  |  |  |             newsendercount++; | 
					
						
							|  |  |  |         if (srcdat->IsActive()) | 
					
						
							|  |  |  |             newactivecount++; | 
					
						
							|  |  |  |         sourcelist.GotoNextElement(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     totalcount = newtotalcount; // just to play it safe
 | 
					
						
							|  |  |  |     sendercount = newsendercount; | 
					
						
							|  |  |  |     activecount = newactivecount; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | void RTPSources::MultipleTimeouts(const RTPTime &curtime, const RTPTime &sendertimeout, const RTPTime &byetimeout, const RTPTime &generaltimeout, const RTPTime ¬etimeout) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     int newtotalcount = 0; | 
					
						
							|  |  |  |     int newsendercount = 0; | 
					
						
							|  |  |  |     int newactivecount = 0; | 
					
						
							|  |  |  |     RTPTime senderchecktime = curtime; | 
					
						
							|  |  |  |     RTPTime byechecktime = curtime; | 
					
						
							|  |  |  |     RTPTime generaltchecktime = curtime; | 
					
						
							|  |  |  |     RTPTime notechecktime = curtime; | 
					
						
							|  |  |  |     senderchecktime -= sendertimeout; | 
					
						
							|  |  |  |     byechecktime -= byetimeout; | 
					
						
							|  |  |  |     generaltchecktime -= generaltimeout; | 
					
						
							|  |  |  |     notechecktime -= notetimeout; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sourcelist.GotoFirstElement(); | 
					
						
							|  |  |  |     while (sourcelist.HasCurrentElement()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         RTPInternalSourceData *srcdat = sourcelist.GetCurrentElement(); | 
					
						
							|  |  |  |         bool deleted, issender, isactive; | 
					
						
							|  |  |  |         bool byetimeout, normaltimeout, notetimeout; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |         std::size_t notelen; | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         issender = srcdat->IsSender(); | 
					
						
							|  |  |  |         isactive = srcdat->IsActive(); | 
					
						
							|  |  |  |         deleted = false; | 
					
						
							|  |  |  |         byetimeout = false; | 
					
						
							|  |  |  |         normaltimeout = false; | 
					
						
							|  |  |  |         notetimeout = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         srcdat->SDES_GetNote(¬elen); | 
					
						
							|  |  |  |         if (notelen != 0) // Note has been set
 | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             RTPTime notetime = srcdat->INF_GetLastSDESNoteTime(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (notechecktime > notetime) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 notetimeout = true; | 
					
						
							|  |  |  |                 srcdat->ClearNote(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (srcdat->ReceivedBYE()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             RTPTime byetime = srcdat->GetBYETime(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if ((srcdat != owndata) && (byechecktime > byetime)) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 sourcelist.DeleteCurrentElement(); | 
					
						
							|  |  |  |                 deleted = true; | 
					
						
							|  |  |  |                 byetimeout = true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!deleted) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             RTPTime lastmsgtime = srcdat->INF_GetLastMessageTime(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if ((srcdat != owndata) && (lastmsgtime < generaltchecktime)) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 sourcelist.DeleteCurrentElement(); | 
					
						
							|  |  |  |                 deleted = true; | 
					
						
							|  |  |  |                 normaltimeout = true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!deleted) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             newtotalcount++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (issender) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 RTPTime lastrtppacktime = srcdat->INF_GetLastRTPPacketTime(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (lastrtppacktime < senderchecktime) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     srcdat->ClearSenderFlag(); | 
					
						
							|  |  |  |                     sendercount--; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                     newsendercount++; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (isactive) | 
					
						
							|  |  |  |                 newactivecount++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (notetimeout) | 
					
						
							|  |  |  |                 OnNoteTimeout(srcdat); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             sourcelist.GotoNextElement(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else // deleted entry
 | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (issender) | 
					
						
							|  |  |  |                 sendercount--; | 
					
						
							|  |  |  |             if (isactive) | 
					
						
							|  |  |  |                 activecount--; | 
					
						
							|  |  |  |             totalcount--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (byetimeout) | 
					
						
							|  |  |  |                 OnBYETimeout(srcdat); | 
					
						
							|  |  |  |             if (normaltimeout) | 
					
						
							|  |  |  |                 OnTimeout(srcdat); | 
					
						
							|  |  |  |             OnRemoveSource(srcdat); | 
					
						
							|  |  |  |             delete srcdat; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     totalcount = newtotalcount; // just to play it safe
 | 
					
						
							|  |  |  |     sendercount = newsendercount; | 
					
						
							|  |  |  |     activecount = newactivecount; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | bool RTPSources::CheckCollision(RTPInternalSourceData *srcdat, const RTPAddress *senderaddress, bool isrtp) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     bool isset, otherisset; | 
					
						
							|  |  |  |     const RTPAddress *addr, *otheraddr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (isrtp) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         isset = srcdat->IsRTPAddressSet(); | 
					
						
							|  |  |  |         addr = srcdat->GetRTPDataAddress(); | 
					
						
							|  |  |  |         otherisset = srcdat->IsRTCPAddressSet(); | 
					
						
							|  |  |  |         otheraddr = srcdat->GetRTCPDataAddress(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         isset = srcdat->IsRTCPAddressSet(); | 
					
						
							|  |  |  |         addr = srcdat->GetRTCPDataAddress(); | 
					
						
							|  |  |  |         otherisset = srcdat->IsRTPAddressSet(); | 
					
						
							|  |  |  |         otheraddr = srcdat->GetRTPDataAddress(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!isset) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (otherisset) // got other address, can check if it comes from same host
 | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (otheraddr == 0) // other came from our own session
 | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (senderaddress != 0) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     OnSSRCCollision(srcdat, senderaddress, isrtp); | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // Ok, store it
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (isrtp) | 
					
						
							|  |  |  |                     srcdat->SetRTPDataAddress(senderaddress); | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                     srcdat->SetRTCPDataAddress(senderaddress); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (!otheraddr->IsFromSameHost(senderaddress)) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     OnSSRCCollision(srcdat, senderaddress, isrtp); | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // Ok, comes from same host, store the address
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (isrtp) | 
					
						
							|  |  |  |                     srcdat->SetRTPDataAddress(senderaddress); | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                     srcdat->SetRTCPDataAddress(senderaddress); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else // no other address, store this one
 | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (isrtp) | 
					
						
							|  |  |  |                 srcdat->SetRTPDataAddress(senderaddress); | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 srcdat->SetRTCPDataAddress(senderaddress); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else // already got an address
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (addr == 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (senderaddress != 0) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 OnSSRCCollision(srcdat, senderaddress, isrtp); | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (!addr->IsSameAddress(senderaddress)) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 OnSSRCCollision(srcdat, senderaddress, isrtp); | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // end namespace
 | 
					
						
							|  |  |  | 
 |