📄 rtspprotocol.cpp
字号:
{
spIHXObjectConfigurationAuthenticator =
(
spIUnknownAuthenticator
);
spIHXObjectConfigurationAuthenticator->SetContext
(
pIUnknownContext
);
m_spIHXClientAuthConversationAuthenticator =
(
spIUnknownAuthenticator
);
}
}
if
(
m_spIHXClientAuthConversationAuthenticator.IsValid()
&&
!m_spIHXClientAuthConversationAuthenticator->IsDone()
)
{
HX_ASSERT(m_pRequest);
if (m_pRequest)
{
m_pRequest->SetResponseHeaders
(
pIHXValuesHeaders
);
HX_RESULTRet =
(
m_spIHXClientAuthConversationAuthenticator->MakeResponse
(
this,
m_pRequest
)
);
}
else
{
// Auth Failed!
m_spIHXClientAuthConversationAuthenticator->Authenticated(FALSE);
mOwner->ReportError(HXR_NOT_AUTHORIZED);
}
// Flow continues in ResponseReady()
}
else
{
// Auth Failed!
if (m_spIHXClientAuthConversationAuthenticator.IsValid())
{
m_spIHXClientAuthConversationAuthenticator->Authenticated(FALSE);
}
mOwner->ReportError(HXR_NOT_AUTHORIZED);
}
HX_RELEASE(pIUnknownContext);
return HXR_OK;
}
return HXR_OK;
}
STDMETHODIMP
RTSPProtocol::AuthenticationRequestDone(HX_RESULT result,
const char* user,
const char* password)
{
return HXR_NOTIMPL;
}
#endif /* HELIX_FEATURE_AUTHENTICATION */
// XXXGo - IPTV_HACK
void
RTSPProtocol::hackCookie(IHXBuffer* pCookie)
{
HX_ASSERT(m_bUseRTP);
// XXXGo - Interop Hack
// IP/TV send a spec incomplient cookie...take care of it for now while
// we get them to fix it.
// we will assume Set-Cookie has just NAME=VALUE paris.
IHXBuffer* pBuffer = new CHXBuffer();
pBuffer->AddRef();
pBuffer->Set((const BYTE*)pCookie->GetBuffer(),
strlen((const char*)pCookie->GetBuffer()) +1);
IHXBuffer* pBuf = NULL;
char* pcOneCookie = (char*)pBuffer->GetBuffer();
char* pc = pcOneCookie;
char* pcKey = NULL;
// go thorough each ';'
for (;;)
{
pc = strchr(pc, ';');
if (pc)
{
pBuf = new CHXBuffer();
pBuf->AddRef();
*pc = NULL;
pBuf->Set((const BYTE*)pcOneCookie, strlen(pcOneCookie) + 1);
mOwner->SetCookie(pBuf);
HX_RELEASE(pBuf);
pcOneCookie = ++pc;
}
else
{
// just set it
pBuf = new CHXBuffer();
pBuf->AddRef();
pBuf->Set((const BYTE*)pcOneCookie, strlen(pcOneCookie) + 1);
mOwner->SetCookie(pBuf);
HX_RELEASE(pBuf);
break;
}
}
}
HX_RESULT
RTSPProtocol::SwitchToUnicast(void)
{
HX_RESULT rc = HXR_FAILED;
IHXBuffer* pBuffer = NULL;
if (mOwner && mOwner->m_pFileHeader)
{
// get a URL from the file header. No URL, no Unicast!
if (HXR_OK == mOwner->m_pFileHeader->GetPropertyCString("UnicastURL", pBuffer) &&
pBuffer)
{
rc = HandleRedirectRequest((const char*)pBuffer->GetBuffer(), 0);
}
HX_RELEASE(pBuffer);
}
return rc;
}
STDMETHODIMP
RTSPProtocol::HandleOptionsResponse(HX_RESULT status,
IHXValues* pHeader)
{
if (FAILED(status))
{
mOwner->ReportError(status);
return status;
}
else if (HXR_REDIRECTION == status)
{
// expect a redirection message soon!
m_idleState = NULL_STATE;
BOOL bHackCookie = FALSE;
IHXBuffer* pAgent = NULL;
if (pHeader->GetPropertyCString("User-Agent", pAgent) == HXR_OK)
{
if (strncasecmp((const char*)pAgent->GetBuffer(), "Cisco IP/TV",
11) == 0)
{
bHackCookie = TRUE;
}
}
HX_RELEASE(pAgent);
// retrieve cookies from the response header
IHXKeyValueList* pKeyValueList = NULL;
if (HXR_OK == pHeader->QueryInterface(IID_IHXKeyValueList,
(void**)&pKeyValueList))
{
IHXKeyValueListIterOneKey* pListIter = NULL;
IHXBuffer* pCookie = NULL;
pKeyValueList->GetIterOneKey("Set-Cookie",pListIter);
while (pListIter->GetNextString(pCookie) == HXR_OK)
{
// XXXGo - IPTV_HACK
if (bHackCookie)
{
hackCookie(pCookie);
}
else
{
mOwner->SetCookie(pCookie);
}
HX_RELEASE(pCookie);
}
HX_RELEASE(pListIter);
}
HX_RELEASE(pKeyValueList);
return HXR_OK;
}
m_bConnectDone = TRUE;
HX_RESULT result = HXR_OK;
result = m_pProtocolLib->SendStreamDescriptionRequest
(
mPath,
m_spIHXValuesStoredHeaders
);
return result;
}
STDMETHODIMP
RTSPProtocol::HandleStreamDescriptionResponse(HX_RESULT status,
IHXValues* pFileHeader,
CHXSimpleList* pHeaderList,
IHXValues* pResponseHeaders)
{
HX_RESULT hr = HXR_OK;
if (FAILED(status))
{
if (!pFileHeader || !pHeaderList)
{
/*
* XXX...Need to get proper errors from protocol library
*/
mOwner->ReportError(status);//ConvertHResultToHXError(status));
return (status != (UINT32)HXR_OK) ? status : (UINT32)HXR_FAIL;
}
}
else if (!pFileHeader || !pHeaderList)
{
// Not a severe failure, need to try again.
return m_pProtocolLib->SendStreamDescriptionRequest(mPath,
m_spIHXValuesStoredHeaders);
}
#if defined(HELIX_FEATURE_REVERTER)
// DESCRIBE Succeeded!
//
m_pDataRevert->RevertHeaders(pFileHeader, pHeaderList, pResponseHeaders);
#else
RevertHeadersDone(pFileHeader,
pHeaderList,
pResponseHeaders,
FALSE);
#endif /* HELIX_FEATURE_REVERTER */
return HXR_OK;
}
/*
* IHXPreferredTransportSink methods
*/
STDMETHODIMP
RTSPProtocol::TransportSucceeded(TransportMode /* IN */ prefTransportType,
UINT16 /* IN */ uCloakPort)
{
if (m_bHTTPOnly)
{
return mOwner->TransportSucceeded(HTTPCloakMode, uCloakPort);
}
// we ignore the TCP control channel succeeded message if we are attempting
// Multicast or UDP
else if (mCurrentTransport == prefTransportType)
{
return mOwner->TransportSucceeded(prefTransportType, uCloakPort);
}
else
{
HX_ASSERT(mCurrentTransport == UDPMode || mCurrentTransport == MulticastMode);
}
return HXR_OK;
}
STDMETHODIMP
RTSPProtocol::TransportFailed()
{
return mOwner->TransportFailed();
}
void
RTSPProtocol::RevertHeadersDone(IHXValues* pFileHeader,
CHXSimpleList* pHeaderList,
IHXValues* pResponseHeaders,
BOOL bUseReverter)
{
HX_RESULT status = HXR_OK;
ULONG32 tempLiveStream = 0;
pFileHeader->GetPropertyULONG32("LiveStream", tempLiveStream);
mLiveStream = (tempLiveStream > 0)?TRUE:FALSE;
#if defined(HELIX_FEATURE_REVERTER)
if (bUseReverter && m_pDataRevert)
{
m_pProtocolLib->InitPacketFilter(m_pDataRevert);
}
#endif /* HELIX_FEATURE_REVERTER */
ULONG32 ulFlags = 0;
pFileHeader->GetPropertyULONG32("Flags", ulFlags);
mSaveAsAllowed = ulFlags & HX_SAVE_ENABLED ? TRUE : FALSE;
IHXBuffer* pBuffer = NULL;
if (HXR_OK == pResponseHeaders->GetPropertyCString("StatsMask", pBuffer))
{
mSendStatsMask = atoi((const char*)pBuffer->GetBuffer());
mOwner->SetOption(HX_STATS_MASK, &mSendStatsMask);
}
HX_RELEASE(pBuffer);
if (HXR_OK == pResponseHeaders->GetPropertyCString("StatsInterval", pBuffer))
{
UINT32 ulStatsInterval = 1000* atoi((const char*)pBuffer->GetBuffer());
// ulStatsInterval = 0 to disable the stats
if (ulStatsInterval && ulStatsInterval < MINIMUM_STATS_INTERVAL)
{
ulStatsInterval = MINIMUM_STATS_INTERVAL;
}
mOwner->SetOption(HX_STATS_INTERVAL, &ulStatsInterval);
}
HX_RELEASE(pBuffer);
if (HXR_OK == pResponseHeaders->GetPropertyCString("MaxBandwidth", pBuffer))
{
UINT32 ulMaxBandwidth = atoi((const char*)pBuffer->GetBuffer());
// ulMaxBandwidth = 0 to disable the faststart
mOwner->SetOption(HX_MAX_BANDWIDTH, &ulMaxBandwidth);
}
HX_RELEASE(pBuffer);
if (HXR_OK == pResponseHeaders->GetPropertyCString("TurboPlay", pBuffer))
{
BOOL bTurboPlay = (BOOL)atoi((const char*)pBuffer->GetBuffer());
mOwner->SetOption(HX_TURBO_PLAY, &bTurboPlay);
}
HX_RELEASE(pBuffer);
// UseRTP was set from RTSPClientProtocol::handleDescribeResponse when
// it detected we were not playing a stream from a RealServer.
ULONG32 ulTemp = 0;
if (HXR_OK == pResponseHeaders->GetPropertyULONG32("UseRTP", ulTemp))
{
m_bUseRTP = ulTemp;
}
// retrieve cookies from the response header
IHXKeyValueList* pKeyValueList = NULL;
if (HXR_OK == pResponseHeaders->QueryInterface(IID_IHXKeyValueList,
(void**)&pKeyValueList))
{
IHXKeyValueListIterOneKey* pListIter = NULL;
IHXBuffer* pCookie = NULL;
pKeyValueList->GetIterOneKey("Set-Cookie",pListIter);
while (pListIter->GetNextString(pCookie) == HXR_OK)
{
mOwner->SetCookie(pCookie);
HX_RELEASE(pCookie);
}
HX_RELEASE(pListIter);
}
HX_RELEASE(pKeyValueList);
m_pRequest->SetResponseHeaders(pResponseHeaders);
// notify the source file header is ready
mOwner->FileHeaderReady(pFileHeader);
UINT32 ulNumHeaders = (UINT32) pHeaderList->GetCount();
HX_ASSERT(m_pStreamInfoList->IsEmpty() == TRUE);
if (m_pStreamInfoList->IsEmpty() && ulNumHeaders > 0 &&
ulNumHeaders < m_pStreamInfoList->GetHashTableSize())
{
m_pStreamInfoList->InitHashTable(ulNumHeaders);
}
CHXSimpleList::Iterator i;
for (i = pHeaderList->Begin(); i != pHeaderList->End(); ++i)
{
IHXValues* pHeader = (IHXValues*)(*i);
mOwner->HeaderCallback(pHeader);
if(!m_bIsASMSource)
{
// see if there's an ASMRuleBook in the stream header and set
//flag for QI. only need to get one rulebook to make this TRUE
IHXBuffer* pRuleBook = NULL;
pHeader->GetPropertyCString("ASMRuleBook", pRuleBook);
if(pRuleBook)
{
m_bIsASMSource = TRUE;
pRuleBook->Release();
}
}
/*
* Need to maintain status for the streams
*/
HX_RESULT result;
UINT32 ulStreamNumber = 0;
UINT32 ulClipBandwidth = 0;
IHXBuffer* pMimeType = NULL;
result = pHeader->GetPropertyULONG32("StreamNumber", ulStreamNumber);
if (result != HXR_OK)
{
return;
}
pHeader->GetPropertyCString("MimeType", pMimeType);
pHeader->GetPropertyULONG32("AvgBitRate", ulClipBandwidth);
RTSP_STREAM_INFO* pStreamInfo = new RTSP_STREAM_INFO;
pStreamInfo->m_uStreamNumber = (UINT16)ulStreamNumber;
pStreamInfo->m_ulClipBandwidth = ulClipBandwidth;
#if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
pStreamInfo->m_pStreamStats = create_statistics((UINT16)ulStreamNumber);
if (pStreamInfo->m_pStreamStats)
{
pStreamInfo->m_pStreamStats->m_pClipBandwidth->SetInt(0);
if (pMimeType)
{
pStreamInfo->m_pStreamStats->m_pMimeType->SetStr((char*)pMimeType->GetBuffer());
}
}
#endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
HX_RELEASE(pMimeType);
(*m_pStreamInfoList)[ulStreamNumber] = pStreamInfo;
m_uStreamCount++;
}
mReceivedControl = TRUE;
m_uCurrentStreamCount = m_uStreamCount;
m_idleState = INIT_SOCKETS_STATE;
}
void
RTSPProtocol::SendControlBuffer(IHXBuffer* pBuffer)
{
char* p64Buf = new char[pBuffer->GetSize() * 2 + 4];
BinTo64((const unsigned char*)pBuffer->GetBuffer(),
pBuffer->GetSize(), p64Buf);
m_pProtocolLib->SendSetParameterRequest("DataConvertBuffer", "1",
"base64", p64Buf);
delete[] p64Buf;
}
UINT16
RTSPProtocol::GetRDTFeatureLevel(void)
{
#if defined(HELIX_FEATURE_RDT)
if (m_pProtocolLib)
{
return ((RTSPClientProtocolExt*)m_pProtocolLib)->GetRDTFeatureLevel();
}
else
#endif /* HELIX_FEATURE_RDT */
{
return 0;
}
}
void
RTSPProtocol::LeavePrefetch(void)
{
m_bPrefetch = FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -