/* * * @APPLE_LICENSE_HEADER_START@ * * Copyright (c) 1999-2001 Apple Computer, Inc. All Rights Reserved. The * contents of this file constitute Original Code as defined in and are * subject to the Apple Public Source License Version 1.2 (the 'License'). * You may not use this file except in compliance with the License. Please * obtain a copy of the License at http://www.apple.com/publicsource and * read it before using this file. * * This Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please * see the License for the specific language governing rights and * limitations under the License. * * * @APPLE_LICENSE_HEADER_END@ * */ /* File: SourceInfo.cpp Contains: Implements object defined in .h file. */ #include "SourceInfo.h" #include "SocketUtils.h" #include "SDPSourceInfo.h" #include "OSMemory.h" SourceInfo::SourceInfo(const SourceInfo& copy) : fStreamArray(NULL), fNumStreams(copy.fNumStreams), fOutputArray(NULL), fNumOutputs(copy.fNumOutputs), fTimeSet(copy.fTimeSet),fStartTimeUnixSecs(copy.fStartTimeUnixSecs), fEndTimeUnixSecs(copy.fEndTimeUnixSecs), fSessionControlType(copy.fSessionControlType) { if(copy.fStreamArray != NULL && fNumStreams != 0) { fStreamArray = NEW StreamInfo[fNumStreams]; for (UInt32 index=0; index < fNumStreams; index++) fStreamArray[index].Copy(copy.fStreamArray[index]); } if(copy.fOutputArray != NULL && fNumOutputs != 0) { fOutputArray = NEW OutputInfo[fNumOutputs]; for (UInt32 index2=0; index2 < fNumOutputs; index2++) fOutputArray[index2].Copy(copy.fOutputArray[index2]); } } SourceInfo::~SourceInfo() { if(fStreamArray != NULL) delete [] fStreamArray; if(fOutputArray != NULL) delete [] fOutputArray; } Bool16 SourceInfo::IsReflectable() { if (fStreamArray == NULL) return false; if (fNumStreams == 0) return false; //each stream's info must meet certain criteria for (UInt32 x = 0; x < fNumStreams; x++) { if (fStreamArray[x].fIsTCP) continue; if ((!this->IsReflectableIPAddr(fStreamArray[x].fDestIPAddr)) || (fStreamArray[x].fTimeToLive == 0)) return false; } return true; } Bool16 SourceInfo::IsReflectableIPAddr(UInt32 inIPAddr) { if (SocketUtils::IsMulticastIPAddr(inIPAddr) || SocketUtils::IsLocalIPAddr(inIPAddr)) return true; return false; } Bool16 SourceInfo::HasTCPStreams() { //each stream's info must meet certain criteria for (UInt32 x = 0; x < fNumStreams; x++) { if (fStreamArray[x].fIsTCP) return true; } return false; } Bool16 SourceInfo::HasIncomingBroacast() { //each stream's info must meet certain criteria for (UInt32 x = 0; x < fNumStreams; x++) { if (fStreamArray[x].fSetupToReceive) return true; } return false; } SourceInfo::StreamInfo* SourceInfo::GetStreamInfo(UInt32 inIndex) { Assert(inIndex < fNumStreams); if (fStreamArray == NULL) return NULL; if (inIndex < fNumStreams) return &fStreamArray[inIndex]; else return NULL; } SourceInfo::StreamInfo* SourceInfo::GetStreamInfoByTrackID(UInt32 inTrackID) { if (fStreamArray == NULL) return NULL; for (UInt32 x = 0; x < fNumStreams; x++) { if (fStreamArray[x].fTrackID == inTrackID) return &fStreamArray[x]; } return NULL; } SourceInfo::OutputInfo* SourceInfo::GetOutputInfo(UInt32 inIndex) { Assert(inIndex < fNumOutputs); if (fOutputArray == NULL) return NULL; if (inIndex < fNumOutputs) return &fOutputArray[inIndex]; else return NULL; } UInt32 SourceInfo::GetNumNewOutputs() { UInt32 theNumNewOutputs = 0; for (UInt32 x = 0; x < fNumOutputs; x++) { if (!fOutputArray[x].fAlreadySetup) theNumNewOutputs++; } return theNumNewOutputs; } Bool16 SourceInfo::SetActiveNTPTimes(UInt32 startTimeNTP,UInt32 endTimeNTP) { // right now only handles earliest start and latest end time. //printf("SourceInfo::SetActiveNTPTimes start=%lu end=%lu\n",startTimeNTP,endTimeNTP); Bool16 accepted = false; if (startTimeNTP <= endTimeNTP || endTimeNTP == 0) do { if (startTimeNTP != 0 && !IsValidNTPSecs(startTimeNTP)) break; // not valid NTP time if (endTimeNTP != 0 && !IsValidNTPSecs(endTimeNTP)) break; // not valid NTP time time_t startTimeUnixSecs = 0; time_t endTimeUnixSecs = 0; if (startTimeNTP != 0) startTimeUnixSecs = NTPSecs_to_UnixSecs(startTimeNTP); if (endTimeNTP != 0) endTimeUnixSecs =NTPSecs_to_UnixSecs(endTimeNTP); if (!fTimeSet) { fTimeSet = true; fStartTimeUnixSecs = startTimeUnixSecs; fEndTimeUnixSecs = endTimeUnixSecs; } else { if (startTimeUnixSecs < fStartTimeUnixSecs || 0 == startTimeUnixSecs ) fStartTimeUnixSecs = startTimeUnixSecs; if (endTimeUnixSecs > fEndTimeUnixSecs || 0 == endTimeUnixSecs) fEndTimeUnixSecs = endTimeUnixSecs; } //printf("SourceInfo::SetActiveNTPTimes fStartTimeUnixSecs=%lu fEndTimeUnixSecs=%lu\n",fStartTimeUnixSecs,fEndTimeUnixSecs); //printf("SourceInfo::SetActiveNTPTimes\n"); //printf("SourceInfo::SetActiveNTPTimes start time = %s",ctime(&fStartTimeUnixSecs) ); //printf("SourceInfo::SetActiveNTPTimes end time = %s",ctime(&fEndTimeUnixSecs) ); accepted = true; } while(0); return accepted; } Bool16 SourceInfo::IsActiveTime(time_t unixTimeSecs) { // order of tests are important here // we do it this way because of the special case time value of 0 for end time // start - 0 = unbounded // 0 - 0 = permanent if (unixTimeSecs < 0) //check valid value return false; if (IsPermanentSource()) //check for all times accepted return true; if (unixTimeSecs < fStartTimeUnixSecs) return false; //too early if (fEndTimeUnixSecs == 0) return true;// accept any time after start if (unixTimeSecs > fEndTimeUnixSecs) return false; // too late return true; // ok start <= time <= end } time_t SourceInfo::GetDurationSecs() { if (fEndTimeUnixSecs == 0) // unbounded time return 0; time_t timeNow = OS::UnixTime_Secs(); if (fEndTimeUnixSecs <= timeNow) // the active time has past or duration is 0 so return the minimum duration return 1; if (fStartTimeUnixSecs == 0) // relative duration = from "now" to end time return fEndTimeUnixSecs - timeNow; return fEndTimeUnixSecs - fStartTimeUnixSecs; // this must be an duration because of test for endtime above } Bool16 SourceInfo::Equal(SourceInfo* inInfo) { // Check to make sure the # of streams matches up if (this->GetNumStreams() != inInfo->GetNumStreams()) return false; // Check the src & dest addr, and port of each stream. for (UInt32 x = 0; x < this->GetNumStreams(); x++) { if (GetStreamInfo(x)->fDestIPAddr != inInfo->GetStreamInfo(x)->fDestIPAddr) return false; if (GetStreamInfo(x)->fSrcIPAddr != inInfo->GetStreamInfo(x)->fSrcIPAddr) return false; // If either one of the comparators is 0 (the "wildcard" port), then we know at this point // they are equivalent if ((GetStreamInfo(x)->fPort == 0) || (inInfo->GetStreamInfo(x)->fPort == 0)) return true; // Neither one is the wildcard port, so they must be the same if (GetStreamInfo(x)->fPort != inInfo->GetStreamInfo(x)->fPort) return false; } return true; } void SourceInfo::StreamInfo::Copy(const StreamInfo& copy) { fSrcIPAddr = copy.fSrcIPAddr; fDestIPAddr = copy.fDestIPAddr; fPort = copy.fPort; fTimeToLive = copy.fTimeToLive; fPayloadType = copy.fPayloadType; if ((copy.fPayloadName).Ptr != NULL) fPayloadName.Set((copy.fPayloadName).GetAsCString(), (copy.fPayloadName).Len); fTrackID = copy.fTrackID; fBufferDelay = copy.fBufferDelay; fIsTCP = copy.fIsTCP; fSetupToReceive = copy.fSetupToReceive; fTimeScale = copy.fTimeScale; } SourceInfo::StreamInfo::~StreamInfo() { if (fPayloadName.Ptr != NULL) delete fPayloadName.Ptr; fPayloadName.Len = 0; } void SourceInfo::OutputInfo::Copy(const OutputInfo& copy) { fDestAddr = copy.fDestAddr; fLocalAddr = copy.fLocalAddr; fTimeToLive = copy.fTimeToLive; fNumPorts = copy.fNumPorts; if(fNumPorts != 0) { fPortArray = NEW UInt16[fNumPorts]; ::memcpy(fPortArray, copy.fPortArray, fNumPorts * sizeof(UInt16)); } fBasePort = copy.fBasePort; fAlreadySetup = copy.fAlreadySetup; } SourceInfo::OutputInfo::~OutputInfo() { if (fPortArray != NULL) delete [] fPortArray; } Bool16 SourceInfo::OutputInfo::Equal(const OutputInfo& info) { if ((fDestAddr == info.fDestAddr) && (fLocalAddr == info.fLocalAddr) && (fTimeToLive == info.fTimeToLive)) { if ((fBasePort != 0) && (fBasePort == info.fBasePort)) return true; else if ((fNumPorts == 0) || ((fNumPorts == info.fNumPorts) && (fPortArray[0] == info.fPortArray[0]))) return true; } return false; }