Add even more of the source
This should be about everything needed to build so far?
This commit is contained in:
parent
af3619d4fa
commit
849723c9cf
547 changed files with 149239 additions and 0 deletions
463
Server.tproj/RTPSessionInterface.cpp
Normal file
463
Server.tproj/RTPSessionInterface.cpp
Normal file
|
@ -0,0 +1,463 @@
|
|||
/*
|
||||
*
|
||||
* @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: RTPSessionInterface.h
|
||||
|
||||
Contains: Implementation of object defined in .h
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "RTPSessionInterface.h"
|
||||
#include "QTSServerInterface.h"
|
||||
#include "RTSPRequestInterface.h"
|
||||
#include "QTSS.h"
|
||||
#include "OS.h"
|
||||
#include "RTPStream.h"
|
||||
#include "md5.h"
|
||||
#include "md5digest.h"
|
||||
#include "base64.h"
|
||||
|
||||
unsigned int RTPSessionInterface::sRTPSessionIDCounter = 0;
|
||||
|
||||
|
||||
QTSSAttrInfoDict::AttrInfo RTPSessionInterface::sAttributes[] =
|
||||
{ /*fields: fAttrName, fFuncPtr, fAttrDataType, fAttrPermission */
|
||||
/* 0 */ { "qtssCliSesStreamObjects", NULL, qtssAttrDataTypeQTSS_Object, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 1 */ { "qtssCliSesCreateTimeInMsec", NULL, qtssAttrDataTypeTimeVal, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 2 */ { "qtssCliSesFirstPlayTimeInMsec", NULL, qtssAttrDataTypeTimeVal, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 3 */ { "qtssCliSesPlayTimeInMsec", NULL, qtssAttrDataTypeTimeVal, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 4 */ { "qtssCliSesAdjustedPlayTimeInMsec", NULL, qtssAttrDataTypeTimeVal, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 5 */ { "qtssCliSesRTPBytesSent", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 6 */ { "qtssCliSesRTPPacketsSent", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 7 */ { "qtssCliSesState", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 8 */ { "qtssCliSesPresentationURL", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 9 */ { "qtssCliSesFirstUserAgent", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 10 */ { "qtssCliStrMovieDurationInSecs", NULL, qtssAttrDataTypeFloat64, qtssAttrModeRead | qtssAttrModePreempSafe | qtssAttrModeWrite },
|
||||
/* 11 */ { "qtssCliStrMovieSizeInBytes", NULL, qtssAttrDataTypeUInt64, qtssAttrModeRead | qtssAttrModePreempSafe | qtssAttrModeWrite },
|
||||
/* 12 */ { "qtssCliSesMovieAverageBitRate", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModePreempSafe | qtssAttrModeWrite },
|
||||
/* 13 */ { "qtssCliSesLastRTSPSession", NULL, qtssAttrDataTypeQTSS_Object, qtssAttrModeRead | qtssAttrModePreempSafe } ,
|
||||
/* 14 */ { "qtssCliSesFullURL", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe } ,
|
||||
/* 15 */ { "qtssCliSesHostName", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
|
||||
/* 16 */ { "qtssCliRTSPSessRemoteAddrStr", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 17 */ { "qtssCliRTSPSessLocalDNS", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 18 */ { "qtssCliRTSPSessLocalAddrStr", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 19 */ { "qtssCliRTSPSesUserName", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 20 */ { "qtssCliRTSPSesUserPassword", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 21 */ { "qtssCliRTSPSesURLRealm", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 22 */ { "qtssCliRTSPReqRealStatusCode", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 23 */ { "qtssCliTeardownReason", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModePreempSafe | qtssAttrModeWrite },
|
||||
/* 24 */ { "qtssCliSesReqQueryString", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 25 */ { "qtssCliRTSPReqRespMsg", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
|
||||
/* 26 */ { "qtssCliSesCurrentBitRate", CurrentBitRate, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 27 */ { "qtssCliSesPacketLossPercent", PacketLossPercent, qtssAttrDataTypeFloat32, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 28 */ { "qtssCliSesTimeConnectedinMsec", TimeConnected, qtssAttrDataTypeSInt64, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 29 */ { "qtssCliSesCounterID", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 30 */ { "qtssCliSesRTSPSessionID", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 31 */ { "qtssCliSesFramesSkipped", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModeWrite | qtssAttrModePreempSafe },
|
||||
/* 32 */ { "qtssCliSesTimeoutMsec", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModeWrite | qtssAttrModePreempSafe },
|
||||
/* 33 */ { "qtssCliSesOverBufferEnabled", NULL, qtssAttrDataTypeBool16, qtssAttrModeRead | qtssAttrModeWrite | qtssAttrModePreempSafe },
|
||||
/* 34 */ { "qtssCliSesRTCPPacketsRecv", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 35 */ { "qtssCliSesRTCPBytesRecv", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 36 */ { "qtssCliSesStartedThinning", NULL, qtssAttrDataTypeBool16, qtssAttrModeRead | qtssAttrModeWrite | qtssAttrModePreempSafe },
|
||||
/* 37 */ { "qtssCliSes3GPPObject", NULL, qtssAttrDataTypeQTSS_Object, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 38 */ { "qtssCliSessLastRTSPBandwidth", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModePreempSafe },
|
||||
/* 39 */ { "qtssCliSessIs3GPPSession", NULL, qtssAttrDataTypeBool16, qtssAttrModeRead | qtssAttrModePreempSafe }
|
||||
|
||||
|
||||
};
|
||||
|
||||
void RTPSessionInterface::Initialize()
|
||||
{
|
||||
for (UInt32 x = 0; x < qtssCliSesNumParams; x++)
|
||||
QTSSDictionaryMap::GetMap(QTSSDictionaryMap::kClientSessionDictIndex)->
|
||||
SetAttribute(x, sAttributes[x].fAttrName, sAttributes[x].fFuncPtr,
|
||||
sAttributes[x].fAttrDataType, sAttributes[x].fAttrPermission);
|
||||
}
|
||||
|
||||
RTPSessionInterface::RTPSessionInterface()
|
||||
: QTSSDictionary(QTSSDictionaryMap::GetMap(QTSSDictionaryMap::kClientSessionDictIndex), NULL),
|
||||
Task(),
|
||||
fLastQualityCheckTime(0),
|
||||
fLastQualityCheckMediaTime(0),
|
||||
fStartedThinning(false),
|
||||
fIsFirstPlay(true),
|
||||
fAllTracksInterleaved(true), // assume true until proven false!
|
||||
fFirstPlayTime(0),
|
||||
fPlayTime(0),
|
||||
fAdjustedPlayTime(0),
|
||||
fNTPPlayTime(0),
|
||||
fNextSendPacketsTime(0),
|
||||
fSessionQualityLevel(0),
|
||||
fState(qtssPausedState),
|
||||
fPlayFlags(0),
|
||||
fLastBitRateBytes(0),
|
||||
fLastBitRateUpdateTime(0),
|
||||
fMovieCurrentBitRate(0),
|
||||
fRTSPSession(NULL),
|
||||
fLastRTSPReqRealStatusCode(200),
|
||||
fTimeoutTask(NULL, QTSServerInterface::GetServer()->GetPrefs()->GetRTPTimeoutInSecs() * 1000),
|
||||
fNumQualityLevels(0),
|
||||
fBytesSent(0),
|
||||
fPacketsSent(0),
|
||||
fPacketLossPercent(0.0),
|
||||
fTimeConnected(0),
|
||||
fTotalRTCPPacketsRecv(0),
|
||||
fTotalRTCPBytesRecv(0),
|
||||
fMovieDuration(0),
|
||||
fMovieSizeInBytes(0),
|
||||
fMovieAverageBitRate(0),
|
||||
fTeardownReason(0),
|
||||
fUniqueID(0),
|
||||
fTracker(QTSServerInterface::GetServer()->GetPrefs()->IsSlowStartEnabled()),
|
||||
fOverbufferWindow(QTSServerInterface::GetServer()->GetPrefs()->GetSendIntervalInMsec(),kUInt32_Max, QTSServerInterface::GetServer()->GetPrefs()->GetMaxSendAheadTimeInSecs(),
|
||||
QTSServerInterface::GetServer()->GetPrefs()->GetOverbufferRate()),
|
||||
fAuthScheme(QTSServerInterface::GetServer()->GetPrefs()->GetAuthScheme()),
|
||||
fAuthQop(RTSPSessionInterface::kNoQop),
|
||||
fAuthNonceCount(0),
|
||||
fFramesSkipped(0),
|
||||
fRTPSession3GPP(QTSServerInterface::GetServer()->GetPrefs()->Get3GPPEnabled() ),
|
||||
fRTPSession3GPPPtr(&fRTPSession3GPP),
|
||||
fLastRTSPBandwidthHeaderBits(0),
|
||||
fIs3GPPSession(false)
|
||||
{
|
||||
//don't actually setup the fTimeoutTask until the session has been bound!
|
||||
//(we don't want to get timeouts before the session gets bound)
|
||||
|
||||
fTimeoutTask.SetTask(this);
|
||||
fTimeout = QTSServerInterface::GetServer()->GetPrefs()->GetRTPTimeoutInSecs() * 1000;
|
||||
fUniqueID = (UInt32)atomic_add(&sRTPSessionIDCounter, 1);
|
||||
|
||||
// fQualityUpdate is a counter the starting value is the unique ID so every session starts at a different position
|
||||
fQualityUpdate = fUniqueID;
|
||||
|
||||
//mark the session create time
|
||||
fSessionCreateTime = OS::Milliseconds();
|
||||
|
||||
// Setup all dictionary attribute values
|
||||
|
||||
// Make sure the dictionary knows about our preallocated memory for the RTP stream array
|
||||
this->SetEmptyVal(qtssCliSesFirstUserAgent, &fUserAgentBuffer[0], kUserAgentBufSize);
|
||||
this->SetEmptyVal(qtssCliSesStreamObjects, &fStreamBuffer[0], kStreamBufSize);
|
||||
this->SetEmptyVal(qtssCliSesPresentationURL, &fPresentationURL[0], kPresentationURLSize);
|
||||
this->SetEmptyVal(qtssCliSesFullURL, &fFullRequestURL[0], kRequestHostNameBufferSize);
|
||||
this->SetEmptyVal(qtssCliSesHostName, &fRequestHostName[0], kFullRequestURLBufferSize);
|
||||
|
||||
this->SetVal(qtssCliSesCreateTimeInMsec, &fSessionCreateTime, sizeof(fSessionCreateTime));
|
||||
this->SetVal(qtssCliSesFirstPlayTimeInMsec, &fFirstPlayTime, sizeof(fFirstPlayTime));
|
||||
this->SetVal(qtssCliSesPlayTimeInMsec, &fPlayTime, sizeof(fPlayTime));
|
||||
this->SetVal(qtssCliSesAdjustedPlayTimeInMsec, &fAdjustedPlayTime, sizeof(fAdjustedPlayTime));
|
||||
this->SetVal(qtssCliSesRTPBytesSent, &fBytesSent, sizeof(fBytesSent));
|
||||
this->SetVal(qtssCliSesRTPPacketsSent, &fPacketsSent, sizeof(fPacketsSent));
|
||||
this->SetVal(qtssCliSesState, &fState, sizeof(fState));
|
||||
this->SetVal(qtssCliSesMovieDurationInSecs, &fMovieDuration, sizeof(fMovieDuration));
|
||||
this->SetVal(qtssCliSesMovieSizeInBytes, &fMovieSizeInBytes, sizeof(fMovieSizeInBytes));
|
||||
this->SetVal(qtssCliSesLastRTSPSession, &fRTSPSession, sizeof(fRTSPSession));
|
||||
this->SetVal(qtssCliSesMovieAverageBitRate, &fMovieAverageBitRate, sizeof(fMovieAverageBitRate));
|
||||
this->SetEmptyVal(qtssCliRTSPSessRemoteAddrStr, &fRTSPSessRemoteAddrStr[0], kIPAddrStrBufSize );
|
||||
this->SetEmptyVal(qtssCliRTSPSessLocalDNS, &fRTSPSessLocalDNS[0], kLocalDNSBufSize);
|
||||
this->SetEmptyVal(qtssCliRTSPSessLocalAddrStr, &fRTSPSessLocalAddrStr[0], kIPAddrStrBufSize);
|
||||
|
||||
this->SetEmptyVal(qtssCliRTSPSesUserName, &fUserNameBuf[0],RTSPSessionInterface::kMaxUserNameLen);
|
||||
this->SetEmptyVal(qtssCliRTSPSesUserPassword, &fUserPasswordBuf[0], RTSPSessionInterface::kMaxUserPasswordLen);
|
||||
this->SetEmptyVal(qtssCliRTSPSesURLRealm, &fUserRealmBuf[0], RTSPSessionInterface::kMaxUserRealmLen);
|
||||
|
||||
this->SetVal(qtssCliRTSPReqRealStatusCode, &fLastRTSPReqRealStatusCode, sizeof(fLastRTSPReqRealStatusCode));
|
||||
|
||||
this->SetVal(qtssCliTeardownReason, &fTeardownReason, sizeof(fTeardownReason));
|
||||
// this->SetVal(qtssCliSesCurrentBitRate, &fMovieCurrentBitRate, sizeof(fMovieCurrentBitRate));
|
||||
this->SetVal(qtssCliSesCounterID, &fUniqueID, sizeof(fUniqueID));
|
||||
this->SetEmptyVal(qtssCliSesRTSPSessionID, &fRTSPSessionIDBuf[0], QTSS_MAX_SESSION_ID_LENGTH + 4);
|
||||
this->SetVal(qtssCliSesFramesSkipped, &fFramesSkipped, sizeof(fFramesSkipped));
|
||||
this->SetVal(qtssCliSesRTCPPacketsRecv, &fTotalRTCPPacketsRecv, sizeof(fTotalRTCPPacketsRecv));
|
||||
this->SetVal(qtssCliSesRTCPBytesRecv, &fTotalRTCPBytesRecv, sizeof(fTotalRTCPBytesRecv));
|
||||
|
||||
this->SetVal(qtssCliSesTimeoutMsec, &fTimeout, sizeof(fTimeout));
|
||||
|
||||
this->SetVal(qtssCliSesOverBufferEnabled, this->GetOverbufferWindow()->OverbufferingEnabledPtr(), sizeof(Bool16));
|
||||
this->SetVal(qtssCliSesStartedThinning, &fStartedThinning, sizeof(Bool16));
|
||||
this->SetVal(qtssCliSes3GPPObject, &fRTPSession3GPPPtr, sizeof(fRTPSession3GPPPtr));
|
||||
|
||||
this->SetVal(qtssCliSessLastRTSPBandwidth, &fLastRTSPBandwidthHeaderBits, sizeof(fLastRTSPBandwidthHeaderBits));
|
||||
this->SetVal(qtssCliSessIs3GPPSession, &fIs3GPPSession, sizeof(fIs3GPPSession));
|
||||
|
||||
|
||||
}
|
||||
|
||||
void RTPSessionInterface::SetValueComplete(UInt32 inAttrIndex, QTSSDictionaryMap* inMap,
|
||||
UInt32 inValueIndex, void* inNewValue, UInt32 inNewValueLen)
|
||||
{
|
||||
if (inAttrIndex == qtssCliSesTimeoutMsec)
|
||||
{
|
||||
Assert(inNewValueLen == sizeof(UInt32));
|
||||
UInt32 newTimeOut = *((UInt32 *) inNewValue);
|
||||
fTimeoutTask.SetTimeout((SInt64) newTimeOut);
|
||||
}
|
||||
}
|
||||
|
||||
void RTPSessionInterface::UpdateRTSPSession(RTSPSessionInterface* inNewRTSPSession)
|
||||
{
|
||||
if (inNewRTSPSession != fRTSPSession)
|
||||
{
|
||||
// If there was an old session, let it know that we are done
|
||||
if (fRTSPSession != NULL)
|
||||
fRTSPSession->DecrementObjectHolderCount();
|
||||
|
||||
// Increment this count to prevent the RTSP session from being deleted
|
||||
fRTSPSession = inNewRTSPSession;
|
||||
fRTSPSession->IncrementObjectHolderCount();
|
||||
}
|
||||
}
|
||||
|
||||
char* RTPSessionInterface::GetSRBuffer(UInt32 inSRLen)
|
||||
{
|
||||
if (fSRBuffer.Len < inSRLen)
|
||||
{
|
||||
delete [] fSRBuffer.Ptr;
|
||||
fSRBuffer.Set(NEW char[2*inSRLen], 2*inSRLen);
|
||||
}
|
||||
return fSRBuffer.Ptr;
|
||||
}
|
||||
|
||||
QTSS_Error RTPSessionInterface::DoSessionSetupResponse(RTSPRequestInterface* inRequest)
|
||||
{
|
||||
// This function appends a session header to the SETUP response, and
|
||||
// checks to see if it is a 304 Not Modified. If it is, it sends the entire
|
||||
// response and returns an error
|
||||
if ( QTSServerInterface::GetServer()->GetPrefs()->GetRTSPTimeoutInSecs() > 0 ) // adv the timeout
|
||||
inRequest->AppendSessionHeaderWithTimeout( this->GetValue(qtssCliSesRTSPSessionID), QTSServerInterface::GetServer()->GetPrefs()->GetRTSPTimeoutAsString() );
|
||||
else
|
||||
inRequest->AppendSessionHeaderWithTimeout( this->GetValue(qtssCliSesRTSPSessionID), NULL ); // no timeout in resp.
|
||||
|
||||
if (inRequest->GetStatus() == qtssRedirectNotModified)
|
||||
{
|
||||
(void)inRequest->SendHeader();
|
||||
return QTSS_RequestFailed;
|
||||
}
|
||||
return QTSS_NoErr;
|
||||
}
|
||||
|
||||
void RTPSessionInterface::UpdateBitRateInternal(const SInt64& curTime)
|
||||
{
|
||||
if (fState == qtssPausedState)
|
||||
{ fMovieCurrentBitRate = 0;
|
||||
fLastBitRateUpdateTime = curTime;
|
||||
fLastBitRateBytes = fBytesSent;
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 bitsInInterval = (fBytesSent - fLastBitRateBytes) * 8;
|
||||
SInt64 updateTime = (curTime - fLastBitRateUpdateTime) / 1000;
|
||||
if (updateTime > 0) // leave Bit Rate the same if updateTime is 0 also don't divide by 0.
|
||||
fMovieCurrentBitRate = (UInt32) (bitsInInterval / updateTime);
|
||||
fTracker.UpdateAckTimeout(bitsInInterval, curTime - fLastBitRateUpdateTime);
|
||||
fLastBitRateBytes = fBytesSent;
|
||||
fLastBitRateUpdateTime = curTime;
|
||||
}
|
||||
//qtss_printf("fMovieCurrentBitRate=%"_U32BITARG_"\n",fMovieCurrentBitRate);
|
||||
//qtss_printf("Cur bandwidth: %d. Cur ack timeout: %d.\n",fTracker.GetCurrentBandwidthInBps(), fTracker.RecommendedClientAckTimeout());
|
||||
}
|
||||
|
||||
void* RTPSessionInterface::TimeConnected(QTSSDictionary* inSession, UInt32* outLen)
|
||||
{
|
||||
RTPSessionInterface* theSession = (RTPSessionInterface*)inSession;
|
||||
theSession->fTimeConnected = (OS::Milliseconds() - theSession->GetSessionCreateTime());
|
||||
|
||||
// Return the result
|
||||
*outLen = sizeof(theSession->fTimeConnected);
|
||||
return &theSession->fTimeConnected;
|
||||
}
|
||||
|
||||
void* RTPSessionInterface::CurrentBitRate(QTSSDictionary* inSession, UInt32* outLen)
|
||||
{
|
||||
RTPSessionInterface* theSession = (RTPSessionInterface*)inSession;
|
||||
theSession->UpdateBitRateInternal(OS::Milliseconds());
|
||||
|
||||
// Return the result
|
||||
*outLen = sizeof(theSession->fMovieCurrentBitRate);
|
||||
return &theSession->fMovieCurrentBitRate;
|
||||
}
|
||||
|
||||
|
||||
void* RTPSessionInterface::PacketLossPercent(QTSSDictionary* inSession, UInt32* outLen)
|
||||
{
|
||||
RTPSessionInterface* theSession = (RTPSessionInterface*)inSession;
|
||||
RTPStream* theStream = NULL;
|
||||
UInt32 theLen = sizeof(theStream);
|
||||
|
||||
SInt64 packetsLost = 0;
|
||||
SInt64 packetsSent = 0;
|
||||
|
||||
for (int x = 0; theSession->GetValue(qtssCliSesStreamObjects, x, (void*)&theStream, &theLen) == QTSS_NoErr; x++)
|
||||
{
|
||||
if (theStream != NULL )
|
||||
{
|
||||
UInt32 streamCurPacketsLost = 0;
|
||||
theLen = sizeof(UInt32);
|
||||
(void) theStream->GetValue(qtssRTPStrCurPacketsLostInRTCPInterval,0, &streamCurPacketsLost, &theLen);
|
||||
//qtss_printf("stream = %d streamCurPacketsLost = %"_U32BITARG_" \n",x, streamCurPacketsLost);
|
||||
|
||||
UInt32 streamCurPackets = 0;
|
||||
theLen = sizeof(UInt32);
|
||||
(void) theStream->GetValue(qtssRTPStrPacketCountInRTCPInterval,0, &streamCurPackets, &theLen);
|
||||
//qtss_printf("stream = %d streamCurPackets = %"_U32BITARG_" \n",x, streamCurPackets);
|
||||
|
||||
packetsSent += (SInt64) streamCurPackets;
|
||||
packetsLost += (SInt64) streamCurPacketsLost;
|
||||
//qtss_printf("stream calculated loss = %f \n",x, (Float32) streamCurPacketsLost / (Float32) streamCurPackets);
|
||||
|
||||
}
|
||||
|
||||
theStream = NULL;
|
||||
theLen = sizeof(UInt32);
|
||||
}
|
||||
|
||||
//Assert(packetsLost <= packetsSent);
|
||||
if (packetsSent > 0)
|
||||
{ if (packetsLost <= packetsSent)
|
||||
theSession->fPacketLossPercent =(Float32) (( ((Float32) packetsLost / (Float32) packetsSent) * 100.0) );
|
||||
else
|
||||
theSession->fPacketLossPercent = 100.0;
|
||||
}
|
||||
else
|
||||
theSession->fPacketLossPercent = 0.0;
|
||||
//qtss_printf("Session loss percent packetsLost = %qd packetsSent= %qd theSession->fPacketLossPercent=%f\n",packetsLost,packetsSent,theSession->fPacketLossPercent);
|
||||
// Return the result
|
||||
*outLen = sizeof(theSession->fPacketLossPercent);
|
||||
return &theSession->fPacketLossPercent;
|
||||
}
|
||||
|
||||
void RTPSessionInterface::CreateDigestAuthenticationNonce() {
|
||||
|
||||
// Calculate nonce: MD5 of sessionid:timestamp
|
||||
SInt64 curTime = OS::Milliseconds();
|
||||
char* curTimeStr = NEW char[128];
|
||||
qtss_sprintf(curTimeStr, "%"_64BITARG_"d", curTime);
|
||||
|
||||
// Delete old nonce before creating a new one
|
||||
if(fAuthNonce.Ptr != NULL)
|
||||
delete [] fAuthNonce.Ptr;
|
||||
|
||||
MD5_CTX ctxt;
|
||||
unsigned char nonceStr[16];
|
||||
unsigned char colon[] = ":";
|
||||
MD5_Init(&ctxt);
|
||||
StrPtrLen* sesID = this->GetValue(qtssCliSesRTSPSessionID);
|
||||
MD5_Update(&ctxt, (unsigned char *)sesID->Ptr, sesID->Len);
|
||||
MD5_Update(&ctxt, (unsigned char *)colon, 1);
|
||||
MD5_Update(&ctxt, (unsigned char *)curTimeStr, ::strlen(curTimeStr));
|
||||
MD5_Final(nonceStr, &ctxt);
|
||||
HashToString(nonceStr, &fAuthNonce);
|
||||
|
||||
delete [] curTimeStr; // No longer required once nonce is created
|
||||
|
||||
// Set the nonce count value to zero
|
||||
// as a new nonce has been created
|
||||
fAuthNonceCount = 0;
|
||||
|
||||
}
|
||||
|
||||
void RTPSessionInterface::SetChallengeParams(QTSS_AuthScheme scheme, UInt32 qop, Bool16 newNonce, Bool16 createOpaque)
|
||||
{
|
||||
// Set challenge params
|
||||
// Set authentication scheme
|
||||
fAuthScheme = scheme;
|
||||
|
||||
if(fAuthScheme == qtssAuthDigest) {
|
||||
// Set Quality of Protection
|
||||
// auth-int (Authentication with integrity) not supported yet
|
||||
fAuthQop = qop;
|
||||
|
||||
if(newNonce || (fAuthNonce.Ptr == NULL))
|
||||
this->CreateDigestAuthenticationNonce();
|
||||
|
||||
if(createOpaque) {
|
||||
// Generate a random UInt32 and convert it to a string
|
||||
// The base64 encoded form of the string is made the opaque value
|
||||
SInt64 theMicroseconds = OS::Microseconds();
|
||||
::srand((unsigned int)theMicroseconds);
|
||||
UInt32 randomNum = ::rand();
|
||||
char* randomNumStr = NEW char[128];
|
||||
qtss_sprintf(randomNumStr, "%"_U32BITARG_"", randomNum);
|
||||
int len = ::strlen(randomNumStr);
|
||||
fAuthOpaque.Len = Base64encode_len(len);
|
||||
char *opaqueStr = NEW char[fAuthOpaque.Len];
|
||||
(void) Base64encode(opaqueStr, randomNumStr,len);
|
||||
delete [] randomNumStr; // Don't need this anymore
|
||||
if(fAuthOpaque.Ptr != NULL) // Delete existing pointer before assigning new
|
||||
delete [] fAuthOpaque.Ptr; // one
|
||||
fAuthOpaque.Ptr = opaqueStr;
|
||||
}
|
||||
else {
|
||||
if(fAuthOpaque.Ptr != NULL)
|
||||
delete [] fAuthOpaque.Ptr;
|
||||
fAuthOpaque.Len = 0;
|
||||
}
|
||||
// Increase the Nonce Count by one
|
||||
// This number is a count of the next request the server
|
||||
// expects with this nonce. (Implies that the server
|
||||
// has already received nonce count - 1 requests that
|
||||
// sent authorization with this nonce
|
||||
fAuthNonceCount ++;
|
||||
}
|
||||
}
|
||||
|
||||
void RTPSessionInterface::UpdateDigestAuthChallengeParams(Bool16 newNonce, Bool16 createOpaque, UInt32 qop) {
|
||||
if(newNonce || (fAuthNonce.Ptr == NULL))
|
||||
this->CreateDigestAuthenticationNonce();
|
||||
|
||||
|
||||
if(createOpaque) {
|
||||
// Generate a random UInt32 and convert it to a string
|
||||
// The base64 encoded form of the string is made the opaque value
|
||||
SInt64 theMicroseconds = OS::Microseconds();
|
||||
::srand((unsigned int)theMicroseconds);
|
||||
UInt32 randomNum = ::rand();
|
||||
char* randomNumStr = NEW char[128];
|
||||
qtss_sprintf(randomNumStr, "%"_U32BITARG_"", randomNum);
|
||||
int len = ::strlen(randomNumStr);
|
||||
fAuthOpaque.Len = Base64encode_len(len);
|
||||
char *opaqueStr = NEW char[fAuthOpaque.Len];
|
||||
(void) Base64encode(opaqueStr, randomNumStr,len);
|
||||
delete [] randomNumStr; // Don't need this anymore
|
||||
if(fAuthOpaque.Ptr != NULL) // Delete existing pointer before assigning new
|
||||
delete [] fAuthOpaque.Ptr; // one
|
||||
fAuthOpaque.Ptr = opaqueStr;
|
||||
fAuthOpaque.Len = ::strlen(opaqueStr);
|
||||
}
|
||||
else {
|
||||
if(fAuthOpaque.Ptr != NULL)
|
||||
delete [] fAuthOpaque.Ptr;
|
||||
fAuthOpaque.Len = 0;
|
||||
}
|
||||
fAuthNonceCount ++;
|
||||
|
||||
fAuthQop = qop;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue