Darwin-Streaming-Server/Server.tproj/RTPSessionInterface.cpp
Darren VanBuren 849723c9cf Add even more of the source
This should be about everything needed to build so far?
2017-03-07 17:14:16 -08:00

463 lines
23 KiB
C++

/*
*
* @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;
}