/****************************************************************************
|
*
|
* Copyright (C) 2000-2001 RealNetworks, Inc. All rights reserved.
|
*
|
* This program is free software. It may be distributed under the terms
|
* in the file LICENSE, found in the top level of the source distribution.
|
*
|
*/
|
|
#include <stdlib.h>
|
#include <stdio.h>
|
#include <string.h>
|
#include <ctype.h>
|
#include "RtspProt.h"
|
|
/**************************************
|
*
|
* RTSP protocol class
|
*
|
**************************************/
|
const char* s_szHeaders[] = {
|
// From s6.2
|
"Accept",
|
"Accept-Encoding",
|
"Accept-Language",
|
"Authorization",
|
"From",
|
"If-Modified-Since",
|
"Range",
|
"Referer",
|
"User-Agent",
|
NULL
|
};
|
|
CRtspProtocol::CRtspProtocol(CRtspProtocolResponse* pResponse) : m_pResponse(pResponse), m_CSeqSend(0), m_CSeqRecv(0)
|
{
|
if (NULL == m_pResponse)
|
{
|
printf("%s: m_pResponse is null pointer! \n", __FUNCTION__);
|
exit(1);
|
}
|
}
|
|
CRtspProtocol::~CRtspProtocol(void)
|
{
|
RequestTagListQueue.clear();
|
}
|
|
int CRtspProtocol::Encoder(const CRtspMsg* pRtspMsg, char* &pDataStr, int &DataLen)
|
{
|
//Check input parameters exception
|
if (NULL == pRtspMsg)
|
{
|
DBGPrint(M_RtspStack, FATAL_LEVEL, "%s: pRtspMsg is null pointer!", __FUNCTION__);
|
return -1;
|
}
|
|
pDataStr = NULL;
|
|
//Check request or response
|
switch (pRtspMsg->GetType() )
|
{
|
case RTSP_TYPE_REQUEST:
|
{
|
//printf("can't be request here\n");
|
CRtspRequestMsg* pReqMsg = (CRtspRequestMsg *)pRtspMsg;
|
CString StrCSeq = pReqMsg->GetHdr("CSeq");
|
if (StrCSeq.IsEmpty() )
|
{
|
char ClipBuf[16+1];
|
snprintf(ClipBuf, 16, "%d", (int)GetNextCseq() );
|
pReqMsg->SetHdr("CSeq", ClipBuf);
|
}
|
|
CPCHAR pVerb = pReqMsg->GetVerbStr();
|
CPCHAR pUrl = pReqMsg->GetUrl();
|
size_t nHdrLen = pReqMsg->GetHdrLen();
|
size_t nBufLen = pReqMsg->GetBufLen();
|
|
// <verb> SP <url> SP "RTSP/1.0" CRLF
|
// <headers> CRLF <buf>
|
size_t len = FUDGE + strlen(pVerb) + 1 + strlen(pUrl)+ 1 + 8 + 2 + nHdrLen + 2 + nBufLen;
|
char* pBuf = new char[len+1];
|
char* p = pBuf;
|
if (NULL == pBuf)
|
{
|
DBGPrint(M_RtspStack, FATAL_LEVEL, "%s: new pBuf failed!", __FUNCTION__);
|
exit(1);
|
}
|
|
p += sprintf(pBuf, "%s %s RTSP/1.0\r\n", pVerb, pUrl);
|
for (int i=0; i<(int)pReqMsg->GetHdrCount(); i++)
|
{
|
CRtspHdr* pHdr = pReqMsg->GetHdr(i);
|
p += sprintf(p, "%s: %s\r\n", (CPCHAR)pHdr->GetKey(), (CPCHAR)pHdr->GetVal() );
|
}
|
p += sprintf(p, "\r\n");
|
if (nBufLen)
|
{
|
memcpy(p, pRtspMsg->GetBuf(), nBufLen);
|
p += nBufLen;
|
}
|
*p = '\0';
|
|
pDataStr = pBuf;
|
}
|
break;
|
|
case RTSP_TYPE_RESPONSE:
|
{
|
CRtspResponseMsg* pRespMsg = (CRtspResponseMsg*)pRtspMsg;
|
UINT32 nCode = pRespMsg->GetStatusCode();
|
CPCHAR pReason = pRespMsg->GetStatusMsg();
|
size_t nHdrLen = pRespMsg->GetHdrLen();
|
size_t nBufLen = pRespMsg->GetBufLen();
|
|
// "RTSP/1.0" SP <code> SP <reason> CRLF
|
// <headers> CRLF
|
// <buf> (or terminating NULL from sprintf() if no buffer)
|
size_t nResponseLen = 8 + 1 + 3 + 1 + strlen(pReason) + 2 + nHdrLen + 2 + nBufLen;
|
if (0 == nBufLen)
|
nResponseLen++;
|
char* pBuf = new char[nResponseLen+1];
|
char* p = pBuf;
|
if (NULL == pBuf)
|
{
|
DBGPrint(M_RtspStack, FATAL_LEVEL, "%s: new pBuf failed!", __FUNCTION__);
|
exit(1);
|
}
|
|
p += sprintf(pBuf, "RTSP/1.0 %d %s\r\n", (int)nCode, pReason);
|
for (int i=0; i<(int)pRespMsg->GetHdrCount(); i++)
|
{
|
CRtspHdr* pHdr = pRespMsg->GetHdr(i);
|
p += sprintf(p, "%s: %s\r\n", (CPCHAR)pHdr->GetKey(), (CPCHAR)pHdr->GetVal() );
|
}
|
p += sprintf(p, "\r\n");
|
if (nBufLen)
|
{
|
memcpy(p, pRespMsg->GetBuf(), nBufLen);
|
p += nBufLen;
|
}
|
*p = '\0';
|
|
pDataStr = pBuf;
|
//printf("%s\n",pBuf);
|
}
|
break;
|
|
default:
|
DBGPrint(M_RtspStack, ERROR_LEVEL, "%s: Invalid rtsp message type<%d>!", __FUNCTION__, pRtspMsg->GetType() );
|
return -1;
|
}
|
|
DataLen = strlen(pDataStr);
|
|
return 0;
|
}
|
|
//srcip srcport belong to client
|
int CRtspProtocol::DecoderAndDrvie(int sockfd, const char* pDataBuf, int DataLen, CRtspMsg* &pRtspMsg, char SrcIP[], UINT16 SrcPort, int &Code, const char* &pNextPacketPos)
|
{
|
pRtspMsg = NULL;
|
Code = 0;
|
pNextPacketPos = NULL;
|
|
//Check input parameters exception
|
if (NULL == pDataBuf)
|
{
|
DBGPrint(M_RtspStack, ERROR_LEVEL, "%s: pDataBuf is null pointer!", __FUNCTION__);
|
Code = 400;
|
return -1;
|
}
|
|
//Init parser state
|
ReadState mState = stCmd;
|
|
char ALine[A_LINE_MAX_LEN+1];
|
char* pPoll = (char*)pDataBuf;
|
int BodyLen = 0;
|
|
while (pPoll - pDataBuf < DataLen)
|
{
|
memset(ALine, 0, sizeof(ALine));
|
//Skip CRLF
|
if (strncmp(pPoll, RTSP_CRLF, strlen(RTSP_CRLF) ) == 0)
|
{
|
pPoll += strlen(RTSP_CRLF);
|
}
|
int len;
|
//Find Next CRLF for getting a line
|
char* pNextLineWithCRLF = strstr(pPoll, RTSP_CRLF);
|
if (NULL == pNextLineWithCRLF)
|
{
|
len = pDataBuf+DataLen-pPoll;
|
}
|
else
|
{
|
len = pNextLineWithCRLF - pPoll;
|
}
|
|
if (len > 0)
|
{
|
if (len > A_LINE_MAX_LEN)
|
{
|
DBGPrint(M_RtspStack, ERROR_LEVEL, "A line too length, len(%d) > %d in \n%s\n", len, A_LINE_MAX_LEN, pPoll);
|
Code = 406;
|
return -1;
|
}
|
strncpy(ALine, pPoll, len);
|
ALine[len] = '\0';
|
|
//Check parser state
|
switch (mState)
|
{
|
case stCmd:
|
if (HandleReadCmd(ALine, pRtspMsg, Code) != 0)
|
{
|
return -1;
|
}
|
pRtspMsg->SetSockFd(sockfd);
|
pRtspMsg->SetRemoteHost(SrcIP, SrcPort);
|
mState = stHdr;
|
break;
|
|
case stHdr:
|
if (HandleReadHdr(ALine, pRtspMsg, Code) != 0)
|
{
|
return -1;
|
}
|
break;
|
|
case stBody:
|
if (HandleReadBody(pPoll, BodyLen, pRtspMsg, Code) != 0)
|
{
|
return -1;
|
}
|
mState = stDispatch;
|
pNextPacketPos = pPoll + BodyLen;
|
break;
|
|
default:
|
//Note: This case should not be happened.
|
DBGPrint(M_RtspStack, ERROR_LEVEL, "No proto read state, mState=%d!", mState);
|
Code = 500;
|
return -1;
|
}
|
}
|
else
|
{
|
//Empty line indicates end of headers. Note: Body may not be present.
|
CString StrBodyLen = pRtspMsg->GetHdr("Content-Length");
|
BodyLen = atoi(StrBodyLen);
|
if (0 == BodyLen)
|
{
|
mState = stDispatch;
|
|
//Skip CRLF
|
while (strncmp(pPoll, RTSP_CRLF, strlen(RTSP_CRLF) ) == 0)
|
{
|
pPoll += strlen(RTSP_CRLF);
|
}
|
pNextPacketPos = pPoll;
|
}
|
else
|
{
|
mState = stBody;
|
}
|
}
|
|
//Parser end and break into next step
|
if (stDispatch == mState)
|
{
|
if (DispatchMessage(pRtspMsg, Code) != 0)
|
{
|
return -1;
|
}
|
|
//Quit while loop
|
break;
|
}
|
|
pPoll = pNextLineWithCRLF;
|
}
|
|
return 0;
|
}
|
|
|
int CRtspProtocol::DecoderAndDrvie(const char* pDataBuf, int DataLen, CRtspMsg* &pRtspMsg, int &Code, char SrcIP[], UINT16 SrcPort)
|
{
|
pRtspMsg = NULL;
|
Code = 0;
|
|
//Check input parameters exception
|
if (NULL == pDataBuf)
|
{
|
Code = 400;
|
return -1;
|
}
|
|
//Init parser state
|
ReadState mState = stCmd;
|
|
char ALine[A_LINE_MAX_LEN+1];
|
char* pPoll = (char*)pDataBuf;
|
int BodyLen = 0;
|
|
/* ¡À¡À??1???BT??????¡ã2¨¦¨¨¡À??¨²GET_PARAMETER¨º¡À¡ê???¨®|??¨¢D¡ã¨¹¡ê?¡ã¨¹?¨¢?2??¨®D/r/n¡ê?¦Ì????a??3?¡ä¨ª¡ê??¦Ì¨ª3¡À¨¤¨¤¡ê?¡ê --yinxiaogui 2014/3/7 13:59:24
|
* "RTSP/1.0 200 OK\r\nCSeq: 6\r\nDate: Fri, Mar 07 2014 12:04:00 GMT\r\nContent-Base: rtsp://" */
|
while (pPoll - pDataBuf < DataLen)
|
{
|
//Skip CRLF
|
if (strncmp(pPoll, RTSP_CRLF, strlen(RTSP_CRLF) ) == 0)
|
{
|
pPoll += strlen(RTSP_CRLF);
|
}
|
int len;
|
//Find Next CRLF for getting a line
|
char* pNextLineWithCRLF = strstr(pPoll, RTSP_CRLF);
|
if (NULL == pNextLineWithCRLF)
|
{
|
len = pDataBuf+DataLen-pPoll;
|
}
|
else
|
{
|
len = pNextLineWithCRLF - pPoll;
|
}
|
|
if (strncmp(pPoll, RTSP_CRLF, strlen(RTSP_CRLF) ) != 0)
|
{
|
if (len > A_LINE_MAX_LEN)
|
{
|
Code = 406;
|
return -1;
|
}
|
strncpy(ALine, pPoll, len);
|
ALine[len] = '\0';
|
|
//Check parser state
|
switch (mState)
|
{
|
case stCmd:
|
if (HandleReadCmd(ALine, pRtspMsg, Code) != 0)
|
{
|
return -1;
|
}
|
pRtspMsg->SetRemoteHost(SrcIP, SrcPort);
|
mState = stHdr;
|
break;
|
|
case stHdr:
|
if (HandleReadHdr(ALine, pRtspMsg, Code) != 0)
|
{
|
return -1;
|
}
|
|
break;
|
|
case stBody:
|
if (HandleReadBody(pPoll, BodyLen, pRtspMsg, Code) != 0)
|
{
|
return -1;
|
}
|
mState = stDispatch;
|
break;
|
|
default:
|
//Note: This case should not be happened.
|
Code = 500;
|
return -1;
|
}
|
}
|
else
|
{
|
CString StrContentType = pRtspMsg->GetHdr("Content-Type");
|
if (/*StrContentType == "text/xml"*/0)
|
{
|
mState = stDispatch;
|
}
|
else //Parse sdp
|
{
|
//Empty line indicates end of headers. Note: Body may not be present.
|
CString StrBodyLen = pRtspMsg->GetHdr("Content-Length");
|
BodyLen = atoi(StrBodyLen);
|
if (0 == BodyLen)
|
{
|
mState = stDispatch;
|
|
//Skip CRLF
|
while (strncmp(pPoll, RTSP_CRLF, strlen(RTSP_CRLF) ) == 0)
|
{
|
pPoll += strlen(RTSP_CRLF);
|
}
|
}
|
else
|
mState = stBody;
|
}
|
}
|
|
//Parser end and break into next step
|
if (stDispatch == mState)
|
{
|
if (DispatchMessage(pRtspMsg, Code) != 0)
|
{
|
return -1;
|
}
|
|
//Quit while loop
|
break;
|
}
|
|
if (NULL == pNextLineWithCRLF)
|
{
|
Code = 412;
|
return -1;
|
}
|
pPoll = pNextLineWithCRLF;
|
}
|
|
return 0;
|
}
|
|
int CRtspProtocol::DecoderAndDrvie(const char* pDataBuf, int DataLen, CRtspMsg* &pRtspMsg, int &Code)
|
{
|
pRtspMsg = NULL;
|
Code = 0;
|
|
//Check input parameters exception
|
if (NULL == pDataBuf)
|
{
|
Code = 400;
|
return -1;
|
}
|
|
//Init parser state
|
ReadState mState = stCmd;
|
|
char ALine[A_LINE_MAX_LEN+1];
|
char* pPoll = (char*)pDataBuf;
|
int BodyLen = 0;
|
|
/* ±±¾©¹«½»BTÏîÄ¿ÎݲÉ豸ÔÚGET_PARAMETERʱ£¬»ØÓ¦ÏÂÁаü£¬°ü½áβûÓÐ/r/n£¬µ¼Ö½âÎö³ö´í£¬ÏµÍ³±ÀÀ£¡£ --yinxiaogui 2014/3/7 13:59:24
|
* "RTSP/1.0 200 OK\r\nCSeq: 6\r\nDate: Fri, Mar 07 2014 12:04:00 GMT\r\nContent-Base: rtsp://" */
|
while (pPoll - pDataBuf < DataLen)
|
{
|
//Skip CRLF
|
if (strncmp(pPoll, RTSP_CRLF, strlen(RTSP_CRLF) ) == 0)
|
{
|
pPoll += strlen(RTSP_CRLF);
|
}
|
int len;
|
//Find Next CRLF for getting a line
|
char* pNextLineWithCRLF = strstr(pPoll, RTSP_CRLF);
|
if (NULL == pNextLineWithCRLF)
|
{
|
len = pDataBuf+DataLen-pPoll;
|
}
|
else
|
{
|
len = pNextLineWithCRLF - pPoll;
|
}
|
|
if (strncmp(pPoll, RTSP_CRLF, strlen(RTSP_CRLF) ) != 0)
|
{
|
if (len > A_LINE_MAX_LEN)
|
{
|
Code = 406;
|
return -1;
|
}
|
strncpy(ALine, pPoll, len);
|
ALine[len] = '\0';
|
|
//Check parser state
|
switch (mState)
|
{
|
case stCmd:
|
if (HandleReadCmd(ALine, pRtspMsg, Code) != 0)
|
{
|
return -1;
|
}
|
mState = stHdr;
|
break;
|
|
case stHdr:
|
if (HandleReadHdr(ALine, pRtspMsg, Code) != 0)
|
{
|
return -1;
|
}
|
break;
|
|
case stBody:
|
if (HandleReadBody(pPoll, BodyLen, pRtspMsg, Code) != 0)
|
{
|
return -1;
|
}
|
mState = stDispatch;
|
break;
|
|
default:
|
//Note: This case should not be happened.
|
Code = 500;
|
return -1;
|
}
|
}
|
else
|
{
|
CString StrContentType = pRtspMsg->GetHdr("Content-Type");
|
if (/*StrContentType == "text/xml"*/0)
|
{
|
mState = stDispatch;
|
}
|
else //Parse sdp
|
{
|
//Empty line indicates end of headers. Note: Body may not be present.
|
CString StrBodyLen = pRtspMsg->GetHdr("Content-Length");
|
BodyLen = atoi(StrBodyLen);
|
if (0 == BodyLen)
|
{
|
mState = stDispatch;
|
|
//Skip CRLF
|
while (strncmp(pPoll, RTSP_CRLF, strlen(RTSP_CRLF) ) == 0)
|
{
|
pPoll += strlen(RTSP_CRLF);
|
}
|
}
|
else
|
{
|
mState = stBody;
|
}
|
}
|
}
|
|
//Parser end and break into next step
|
if (stDispatch == mState)
|
{
|
if (DispatchMessage(pRtspMsg, Code) != 0)
|
{
|
return -1;
|
}
|
|
//Quit while loop
|
break;
|
}
|
|
if (NULL == pNextLineWithCRLF)
|
{
|
Code = 412;
|
return -1;
|
}
|
pPoll = pNextLineWithCRLF;
|
}
|
|
return 0;
|
}
|
|
int CRtspProtocol::HandleReadCmd(char ALine[], CRtspMsg* &pRtspMsg, int &Code)
|
{
|
if ( (0 == strncmp(ALine, "RTSP", 4) ) && (ALine[4] == '/') && isdigit(ALine[5]) && (ALine[6] == '.') && isdigit(ALine[7]) && (ALine[8] == ' ') )
|
{
|
// Response: RTSP/#.# <code> <reason>
|
if (!isdigit(ALine[9]) || !isdigit(ALine[10]) || !isdigit(ALine[11]) || (ALine[12] != ' ') || (ALine[13] == ' ') || (ALine[13] == '\0') )
|
{
|
Code = 406;
|
return -1;
|
}
|
|
pRtspMsg = new CRtspResponseMsg();
|
( (CRtspResponseMsg*)pRtspMsg)->SetStatus(atoi(ALine + 9) );
|
}
|
else
|
{
|
// Request: <verb> <url> RTSP/#.#
|
char* p = ALine;
|
if (*p == ' ')
|
{
|
DBGPrint(M_RtspStack, ERROR_LEVEL, "RTSP protocol error: bad request line to begin in \n%s\n", ALine);
|
Code = 400;
|
return -1;
|
}
|
char* pVerb = p;
|
while (*p && *p != ' ') p++;
|
if (*p != ' ' || *(p+1) == ' ')
|
{
|
DBGPrint(M_RtspStack, ERROR_LEVEL, "RTSP protocol error: bad request line to find verb in \n%s\n", ALine);
|
Code = 400;
|
return -1;
|
}
|
*p++ = '\0';
|
char* pUrl = p;
|
while (*p && *p != ' ') p++;
|
if (*p != ' ' || *(p+1) == ' ')
|
{
|
DBGPrint(M_RtspStack, ERROR_LEVEL, "RTSP protocol error: bad request line to find url in \n%s\n", ALine);
|
Code = 400;
|
return -1;
|
}
|
*p++ = '\0';
|
if (0 != strncmp(p, "RTSP", 4) || p[4] != '/' || !isdigit(p[5]) || p[6] != '.' || !isdigit(p[7]) || p[8] != '\0')
|
{
|
DBGPrint(M_RtspStack, ERROR_LEVEL, "RTSP protocol error: bad request line to find version in \n%s\n", ALine);
|
Code = 400;
|
return -1;
|
}
|
|
pRtspMsg = new CRtspRequestMsg();
|
( (CRtspRequestMsg*)pRtspMsg)->SetVerb(pVerb);
|
( (CRtspRequestMsg*)pRtspMsg)->SetUrl(pUrl);
|
( (CRtspRequestMsg*)pRtspMsg)->ParserUri();
|
}
|
|
return 0;
|
}
|
|
//ÒÆÖ² live555½âÎöÈÏÖ¤ÐÅÏ¢
|
bool CRtspProtocol::handleAuthenticationFailure(CRtspMsg* &pRtspMsg, char *paramsStr)
|
{
|
if (paramsStr == NULL) return false; // There was no "WWW-Authenticate:" header; we can't proceed.
|
|
// Fill in "fCurrentAuthenticator" with the information from the "WWW-Authenticate:" header:
|
//bool realmHasChanged = false; // by default
|
//bool isStale = false; // by default
|
char realm[64] = {0};
|
char nonce[64] = {0};
|
char stale[32] = {0};
|
bool success = true;
|
if (sscanf(paramsStr, "Digest realm=\"%[^\"]\", nonce=\"%[^\"]\", stale=%[a-zA-Z]", realm, nonce, stale) == 3)
|
{
|
pRtspMsg->SetRealmAndNonce(realm, nonce);
|
}
|
else if (sscanf(paramsStr, "Digest realm=\"%[^\"]\", nonce=\"%[^\"]\"", realm, nonce) == 2)
|
{
|
pRtspMsg->SetRealmAndNonce(realm, nonce);
|
}
|
else if (sscanf(paramsStr, "Basic realm=\"%[^\"]\"", realm) == 1)
|
{
|
pRtspMsg->SetRealmAndNonce(realm, NULL);
|
}
|
else
|
{
|
success = false; // bad "WWW-Authenticate:" header
|
}
|
|
return success;
|
}
|
|
int CRtspProtocol::HandleReadHdr(char ALine[], CRtspMsg* &pRtspMsg, int &Code)
|
{
|
char* p = ALine;
|
if (*p == ':')
|
{
|
DBGPrint(M_RtspStack, ERROR_LEVEL, "RTSP protocol error: received header line '%s'", ALine);
|
Code = 456;
|
return -1;
|
}
|
while (*p && *p != ':') p++;
|
if (*p != ':')
|
{
|
DBGPrint(M_RtspStack, ERROR_LEVEL, "RTSP protocol error: received header line '%s'", ALine);
|
Code = 456;
|
return -1;
|
}
|
|
// Break into key and val, skip LWS, and save it
|
*p++ = '\0';
|
while (*p == ' ') p++;
|
if (*p)
|
{
|
pRtspMsg->SetHdr(ALine, p);
|
}
|
|
if (strcmp(ALine, "WWW-Authenticate") == 0)
|
{
|
if (handleAuthenticationFailure(pRtspMsg, p) == false)
|
{
|
printf("%s:%d RTSP Authentication error: received header line '%s'", __FUNCTION__, __LINE__, p);
|
Code = 403;
|
return -1;
|
}
|
}
|
|
return 0;
|
}
|
|
int CRtspProtocol::HandleReadBody(char* pBody, int BodyLen, CRtspMsg* &pRtspMsg, int &Code)
|
{
|
//Check input parameters exception
|
if (NULL == pBody)
|
{
|
DBGPrint(M_RtspStack, ERROR_LEVEL, "%s: pBody is null pointer!", __FUNCTION__);
|
Code = 400;
|
return -1;
|
}
|
|
if (BodyLen > 0)
|
{
|
pRtspMsg->SetBuf( (CPByte)pBody, BodyLen);
|
}
|
|
return 0;
|
}
|
|
int CRtspProtocol::DispatchMessage(CRtspMsg* &pRtspMsg, int &Code)
|
{
|
//Check input parameters exception
|
if (NULL == pRtspMsg)
|
{
|
DBGPrint(M_RtspStack, ERROR_LEVEL, "%s: pRtspMsg is null pointer!", __FUNCTION__);
|
Code = 500;
|
return -1;
|
}
|
|
switch (pRtspMsg->GetType() )
|
{
|
case RTSP_TYPE_REQUEST:
|
{
|
CRtspRequestMsg* pReqMsg = (CRtspRequestMsg*)pRtspMsg;
|
switch (pReqMsg->GetVerb() )
|
{
|
case VERB_DESCRIBE: m_pResponse->OnDescribeRequest(pReqMsg); break;
|
case VERB_ANNOUNCE: m_pResponse->OnAnnounceRequest(pReqMsg); break;
|
case VERB_GETPARAM: m_pResponse->OnGetParamRequest(pReqMsg); break;
|
case VERB_SETPARAM: m_pResponse->OnSetParamRequest(pReqMsg); break;
|
case VERB_OPTIONS: m_pResponse->OnOptionsRequest(pReqMsg); break;
|
case VERB_PAUSE: m_pResponse->OnPauseRequest(pReqMsg); break;
|
case VERB_PLAY: m_pResponse->OnPlayRequest(pReqMsg); break;
|
case VERB_RECORD: m_pResponse->OnRecordRequest(pReqMsg); break;
|
case VERB_REDIRECT: m_pResponse->OnRedirectRequest(pReqMsg); break;
|
case VERB_SETUP: m_pResponse->OnSetupRequest(pReqMsg); break;
|
case VERB_TEARDOWN: m_pResponse->OnTeardownRequest(pReqMsg); break;
|
default:
|
DBGPrint(M_RtspStack, ERROR_LEVEL, "%s: Rtsp Verb<%d> is unknown!", __FUNCTION__, pReqMsg->GetVerb() );
|
Code = 501;
|
return -1;
|
}
|
}
|
break;
|
|
case RTSP_TYPE_RESPONSE:
|
{
|
CRtspResponseMsg* pRespMsg = (CRtspResponseMsg*)pRtspMsg;
|
const UINT32 CSeq = atoi(pRespMsg->GetHdr("CSeq") );
|
MyList<CRtspRequestTag>::iterator ListItr;
|
|
//Walk request tag list
|
for (ListItr = RequestTagListQueue.begin(); ListItr != RequestTagListQueue.end(); ListItr++)
|
{
|
CRtspRequestTag* pReqTag = (*ListItr);
|
if (NULL == pReqTag)
|
{
|
DBGPrint(M_RtspStack, ERROR_LEVEL, "Request tag list get a element: fatal error!");
|
Code = 500;
|
return -1;
|
}
|
else
|
{
|
if (CSeq == pReqTag->m_cseq)
|
{
|
switch (pReqTag->m_verb)
|
{
|
case VERB_DESCRIBE: m_pResponse->OnDescribeResponse(pRespMsg); break;
|
case VERB_ANNOUNCE: m_pResponse->OnAnnounceResponse(pRespMsg); break;
|
case VERB_GETPARAM: m_pResponse->OnGetParamResponse(pRespMsg); break;
|
case VERB_SETPARAM: m_pResponse->OnSetParamResponse(pRespMsg); break;
|
case VERB_OPTIONS: m_pResponse->OnOptionsResponse(pRespMsg); break;
|
case VERB_PAUSE: m_pResponse->OnPauseResponse(pRespMsg); break;
|
case VERB_PLAY: m_pResponse->OnPlayResponse(pRespMsg); break;
|
case VERB_RECORD: m_pResponse->OnRecordResponse(pRespMsg); break;
|
case VERB_REDIRECT: m_pResponse->OnRedirectResponse(pRespMsg); break;
|
case VERB_SETUP: m_pResponse->OnSetupResponse(pRespMsg); break;
|
case VERB_TEARDOWN: m_pResponse->OnTeardownResponse(pRespMsg); break;
|
default:
|
//No implement at present
|
DBGPrint(M_RtspStack, ERROR_LEVEL, "%s: Not implement for RTSP verb<%d>!", __FUNCTION__, pReqTag->m_verb);
|
RequestTagListQueue.remove(pReqTag);
|
delete pReqTag;
|
Code = 501;
|
return -1;
|
}
|
|
RequestTagListQueue.remove(pReqTag);
|
delete pReqTag;
|
break;
|
}
|
}
|
}
|
}
|
break;
|
default:
|
DBGPrint(M_RtspStack, ERROR_LEVEL, "%s: Rtsp message type<%d> is unknown!", __FUNCTION__, pRtspMsg->GetType() );
|
Code = 500;
|
return -1;
|
}
|
|
return 0;
|
}
|