/* * * @APPLE_LICENSE_HEADER_START@ * * Copyright (c) 1999-2008 Apple Inc. All Rights Reserved. * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The 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" #include "StringParser.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), fHasValidTime(false) { 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. //qtss_printf("SourceInfo::SetActiveNTPTimes start=%"_U32BITARG_" end=%"_U32BITARG_"\n",startTimeNTP,endTimeNTP); Bool16 accepted = false; do { if ((startTimeNTP > 0) && (endTimeNTP > 0) && (endTimeNTP < startTimeNTP)) break; // not valid NTP time UInt32 startTimeUnixSecs = 0; UInt32 endTimeUnixSecs = 0; if (startTimeNTP != 0 && IsValidNTPSecs(startTimeNTP)) // allow anything less than 1970 startTimeUnixSecs = NTPSecs_to_UnixSecs(startTimeNTP);// convert to 1970 time if (endTimeNTP != 0 && !IsValidNTPSecs(endTimeNTP)) // don't allow anything less than 1970 break; if (endTimeNTP != 0) // convert to 1970 time endTimeUnixSecs = NTPSecs_to_UnixSecs(endTimeNTP); fStartTimeUnixSecs = startTimeUnixSecs; fEndTimeUnixSecs = endTimeUnixSecs; accepted = true; } while(0); //char buffer[kTimeStrSize]; //qtss_printf("SourceInfo::SetActiveNTPTimes fStartTimeUnixSecs=%"_U32BITARG_" fEndTimeUnixSecs=%"_U32BITARG_"\n",fStartTimeUnixSecs,fEndTimeUnixSecs); //qtss_printf("SourceInfo::SetActiveNTPTimes start time = %s",qtss_ctime(&fStartTimeUnixSecs, buffer, sizeof(buffer)) ); //qtss_printf("SourceInfo::SetActiveNTPTimes end time = %s",qtss_ctime(&fEndTimeUnixSecs, buffer, sizeof(buffer)) ); fHasValidTime = accepted; 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 (false == fHasValidTime) return false; if (unixTimeSecs < 0) //check valid value return false; if (IsPermanentSource()) //check for 0 0 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 } UInt32 SourceInfo::GetDurationSecs() { if (fEndTimeUnixSecs == 0) // unbounded time return (UInt32) ~0; // max time time_t timeNow = OS::UnixTime_Secs(); if (fEndTimeUnixSecs <= timeNow) // the active time has past or duration is 0 so return the minimum duration return (UInt32) 0; if (fStartTimeUnixSecs == 0) // relative duration = from "now" to end time return fEndTimeUnixSecs - timeNow; return fEndTimeUnixSecs - fStartTimeUnixSecs; // this must be a 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; }