rtspbase.cpp
Upload User: zhongxx05
Upload Date: 2007-06-06
Package Size: 33641k
Code Size: 17k
Category:

Symbian

Development Platform:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "hxcom.h"
  36. #include "hxtypes.h"
  37. #include "hxstring.h"
  38. #include "hxslist.h"
  39. #include "hxengin.h"
  40. #include "ihxpckts.h"
  41. #include "chxpckts.h"
  42. #include "safestring.h"
  43. //#include "rtmlpars.h"
  44. #include "mimehead.h"
  45. #include "mimescan.h"
  46. #include "timerep.h"
  47. #include "rtspmsg.h"
  48. #include "rtsppars.h"
  49. #include "rtspmdsc.h"
  50. #include "basepkt.h"
  51. #include "servrsnd.h"
  52. #include "rtspbase.h"
  53. #include "dbcs.h" // for HXIsEqual
  54. #include "hxheap.h"
  55. #ifdef _DEBUG
  56. #undef HX_THIS_FILE
  57. static const char HX_THIS_FILE[] = __FILE__;
  58. #endif
  59. // XXXHP: NEED TO MODIFY THE SAME STRUCTURE AT DLLMAIN.CPP!!!
  60. struct RTSPError
  61. {
  62.     const char* pErrNo;
  63.     const char* pErrMsg;
  64. };
  65. //
  66. // XXXBAB - turn this into a dictionary
  67. //
  68. // XXXHP: NEED TO REGENERATE ON WIN16 EVERYTIME THIS ARRAY
  69. //   IS MODIFIED!!!
  70. #ifdef _WIN16
  71. extern RTSPError* RTSPErrorTable;
  72. #else
  73. static const RTSPError RTSPErrorTable[] =
  74. {
  75.     { "100", "Continue" },
  76.     { "200", "OK" },
  77.     { "201", "Created" },
  78.     { "250", "Low On Storage Space" },
  79.     { "300", "Multiple Choices" },
  80.     { "301", "Moved Permanently" },
  81.     { "302", "Moved Temporarily" },
  82.     { "303", "See Other" },
  83.     { "304", "Not Modified" },
  84.     { "305", "Use Proxy" },
  85.     { "400", "Bad Request" },
  86.     { "401", "Unauthorized" },
  87.     { "402", "Payment Required" },
  88.     { "403", "Forbidden" },
  89.     { "404", "Not Found" },
  90.     { "405", "Method Not Allowed" },
  91.     { "406", "Not Acceptable" },
  92.     { "407", "Proxy Authentication Required" },
  93.     { "408", "Request Time-out" },
  94.     { "409", "Conflict" },
  95.     { "410", "Gone" },
  96.     { "411", "Length Required" },
  97.     { "412", "Precondition Failed" },
  98.     { "413", "Request Entity Too Large" },
  99.     { "414", "Request-URI Too Large" },
  100.     { "415", "Unsupported Media Type" },
  101.     { "451", "Parameter Not Understood" },
  102.     { "452", "Conference Not Found" },
  103.     { "453", "Not Enough Bandwidth" },
  104.     { "454", "Session Not Found" },
  105.     { "455", "Method Not Valid In This State" },
  106.     { "456", "Header Field Not Valid For Resource" },
  107.     { "457", "Invalid Range" },
  108.     { "458", "Parameter Is Read-Only" },
  109.     { "459", "Aggregate Operation Not Allowed" },
  110.     { "460", "Only Aggregate Operation Allowed" },
  111.     { "461", "Unsupported Transport" },
  112.     { "462", "Destination Unreachable" },
  113.     { "500", "Internal Server Error" },
  114.     { "501", "Not Implemented" },
  115.     { "502", "Bad Gateway" },
  116.     { "503", "Service Unavailable" },
  117.     { "504", "Gateway Time-out" },
  118.     { "505", "RTSP Version not supported" },
  119.     { "551", "Option not supported" }
  120. };
  121. #endif
  122. const RTSPRequireOptions RTSPBaseProtocol::RTSPRequireOptionsTable
  123.     [RTSPBaseProtocol::m_NumRTSPRequireOptions] =
  124.     {
  125.         {"com.real.retain-entity-for-setup", "DESCRIBE", 8},
  126.         {"com.real.load-test-password-enabled", "OPTIONS", 7}
  127.     };
  128. const RTSPAcceptEncodingOptions RTSPBaseProtocol::RTSPAcceptEncodingOptionsTable
  129.     [RTSPBaseProtocol::m_NumRTSPAcceptEncodingOptions] =
  130.     {
  131.         {"mei", "DESCRIBE", 8},
  132.         {"mei", "SETUP", 5}
  133.     };
  134. /*
  135.  * RTSPBaseProtocol methods
  136.  */
  137. RTSPBaseProtocol::RTSPBaseProtocol():
  138.     m_pContext(NULL),
  139.     m_pCommonClassFactory(NULL),
  140.     m_pSocket(0),
  141.     m_pFastSocket(0),
  142.     m_uControlBytesSent(0),
  143.     m_pControlBuffer(0)
  144. {
  145. }
  146. RTSPBaseProtocol::~RTSPBaseProtocol()
  147. {
  148.     clearMessages();
  149.     HX_RELEASE(m_pControlBuffer);
  150.     HX_RELEASE(m_pCommonClassFactory);
  151.     HX_RELEASE(m_pContext);
  152. }
  153. HX_RESULT
  154. RTSPBaseProtocol::enqueueMessage(RTSPMessage* pMsg)
  155. {
  156.     m_msgQueue.AddTail(pMsg);
  157.     return HXR_OK;
  158. }
  159. RTSPMessage*
  160. RTSPBaseProtocol::dequeueMessage(UINT32 seqNo)
  161. {
  162.     LISTPOSITION pos = m_msgQueue.GetHeadPosition();
  163.     while(pos)
  164.     {
  165.         RTSPMessage* pMsg = (RTSPMessage*)m_msgQueue.GetAt(pos);
  166.         if(pMsg->seqNo() == seqNo)
  167.         {
  168.             (void)m_msgQueue.RemoveAt(pos);
  169.             return pMsg;
  170.         }
  171.         (void)m_msgQueue.GetNext(pos);
  172.     }
  173.     return 0;
  174. }
  175. void
  176. RTSPBaseProtocol::clearMessages()
  177. {
  178.     LISTPOSITION pos = m_msgQueue.GetHeadPosition();
  179.     while(pos)
  180.     {
  181.         RTSPMessage* pMsg = (RTSPMessage*)m_msgQueue.GetNext(pos);
  182.         delete pMsg;
  183.     }
  184. }
  185. const char*
  186. RTSPBaseProtocol::getErrorText(const char* pErrNo)
  187. {
  188.     int tabSize = sizeof(RTSPErrorTable) / sizeof(RTSPErrorTable[0]);
  189.     for (int i = 0; i < tabSize; ++i)
  190.     {
  191.         if (strcmp(pErrNo, RTSPErrorTable[i].pErrNo) == 0)
  192.         {
  193.             return RTSPErrorTable[i].pErrMsg;
  194.         }
  195.     }
  196.     return "";
  197. }
  198. HX_RESULT
  199. RTSPBaseProtocol::sendRequest(RTSPRequestMessage* pMsg,
  200.     const char* pContent, const char* pMimeType, UINT32 seqNo)
  201. {
  202.     if(pContent)
  203.     {
  204.         char tmpBuf[32];
  205.         pMsg->addHeader("Content-type", pMimeType);
  206.         SafeSprintf(tmpBuf, 32,"%d", strlen(pContent)); 
  207.         pMsg->addHeader("Content-length", tmpBuf);
  208.         pMsg->setContent(pContent);
  209.     }
  210.     return sendRequest(pMsg, seqNo);
  211. }
  212. HX_RESULT
  213. RTSPBaseProtocol::sendRequest(RTSPRequestMessage* pMsg, UINT32 seqNo)
  214. {
  215.     // set sequence number
  216.     char seqBuf[32]; 
  217.     SafeSprintf(seqBuf, 32, "%ld", seqNo); 
  218.     pMsg->addHeader("CSeq", seqBuf, TRUE); // add to head of list
  219.     pMsg->setSeqNo(seqNo);
  220.     enqueueMessage(pMsg);
  221.     CHXString msgStr = pMsg->asString();
  222.     CHXBuffer* pBuffer = new CHXBuffer;
  223.     pBuffer->AddRef();
  224.     pBuffer->Set((BYTE*)(const char*)msgStr, msgStr.GetLength());
  225.     HX_RESULT rc = sendControlMessage(pBuffer);
  226.     handleSendEvent(pMsg);
  227.     pBuffer->Release();
  228.     return HXR_OK;
  229. }
  230. void
  231. RTSPBaseProtocol::handleDebug(IHXBuffer* pMsgBuf, BOOL bInbound)
  232. {
  233.     // Only implemented by subclasses in server modules
  234. }
  235. void
  236. RTSPBaseProtocol::handleTiming(IHXBuffer* pMsgBuf, BOOL bInbound)
  237. {
  238.     // Only implemented by subclasses in server modules
  239. }
  240. void 
  241. RTSPBaseProtocol::handleSendEvent(RTSPRequestMessage* pMsg)
  242. {
  243.     // Only implemented by subclasses in server modules
  244. }
  245. RTSPResponseMessage*
  246. RTSPBaseProtocol::makeResponseMessage(UINT32 seqNo, const char* pErrNo)
  247. {
  248.     RTSPResponseMessage* pMsg = new RTSPResponseMessage;
  249.     // set sequence number
  250.     char seqBuf[32]; 
  251.     SafeSprintf(seqBuf,32,"%ld", seqNo);
  252.     pMsg->addHeader("CSeq", seqBuf, TRUE); // add to head of list
  253.     pMsg->setSeqNo(seqNo);
  254.     pMsg->setErrorCode(pErrNo);
  255.     pMsg->setErrorMsg(getErrorText(pErrNo));
  256.     UTCTimeRep utcNow;
  257.     pMsg->addHeader("Date", utcNow.asRFC1123String());
  258.     return pMsg;
  259. }
  260. HX_RESULT
  261. RTSPBaseProtocol::sendResponse(UINT32 seqNo, const char* pErrNo)
  262. {
  263.     RTSPResponseMessage* pMsg = makeResponseMessage(seqNo, pErrNo);
  264.     HX_RESULT err = sendResponse(pMsg);
  265.     delete pMsg;
  266.     return err;
  267. }
  268. HX_RESULT
  269. RTSPBaseProtocol::sendResponse(
  270.     RTSPResponseMessage* pMsg, const char* pContent, const char* pMimeType)
  271. {
  272.     if (pContent != NULL)
  273.     {
  274.         char tmpBuf[32]; 
  275.         pMsg->addHeader("Content-type", pMimeType);
  276.         SafeSprintf(tmpBuf,32, "%d", strlen(pContent));  // only for strings 
  277.         pMsg->addHeader("Content-length", tmpBuf);
  278.         pMsg->setContent(pContent);
  279.     }
  280.     CHXString msgStr = pMsg->asString();
  281.     CHXBuffer* pBuffer = new CHXBuffer;
  282.     pBuffer->AddRef();
  283.     pBuffer->Set((BYTE*)(const char*)msgStr, msgStr.GetLength());
  284.     sendControlMessage(pBuffer);
  285.     handleSendEvent(pMsg);
  286.     pBuffer->Release();
  287.     return HXR_OK;
  288. }
  289. void 
  290. RTSPBaseProtocol::handleSendEvent(RTSPResponseMessage* pMsg)
  291. {
  292.     // Only implmented by subclasses in server modules
  293. }
  294. void
  295. RTSPBaseProtocol::addRFC822Headers(RTSPMessage* pMsg,
  296.    IHXValues* pRFC822Headers)
  297. {
  298.     HX_RESULT         res;
  299.     MIMEHeader*       pMimeHeader;
  300.     const char*       pName = NULL;
  301.     IHXBuffer*       pValue = NULL;
  302.     IHXKeyValueList* pKeyedHdrs;
  303.     if (!pRFC822Headers)
  304.     {
  305. return;
  306.     }
  307.     // Find out if the IHXValues supports IHXKeyValueList
  308.     // XXX showell - eventually, we should just make all callers
  309.     // give us an IHXKeyValueList, since it's more efficient,
  310.     // and so we don't overwrite duplicate headers.
  311.     res = pRFC822Headers->QueryInterface(IID_IHXKeyValueList, 
  312.  (void**) &pKeyedHdrs);
  313.     if (res == HXR_OK)
  314.     {
  315. IHXKeyValueListIter* pListIter = NULL;
  316. pKeyedHdrs->GetIter(pListIter);
  317. HX_ASSERT(pListIter);
  318. while (pListIter->GetNextPair(pName, pValue) == HXR_OK)
  319. {
  320.     pMimeHeader = new MIMEHeader(pName);
  321.     pMimeHeader->addHeaderValue((char*)pValue->GetBuffer());
  322.     pMsg->addHeader(pMimeHeader);
  323.     HX_RELEASE(pValue);
  324. }
  325. HX_RELEASE(pListIter);
  326.     }
  327.     else
  328.     {
  329. res = pRFC822Headers->GetFirstPropertyCString(pName, pValue);
  330. while (res == HXR_OK)
  331. {
  332.     pMimeHeader = new MIMEHeader(pName);
  333.     pMimeHeader->addHeaderValue((char*)pValue->GetBuffer());
  334.     pMsg->addHeader(pMimeHeader);
  335.     pValue->Release();
  336.     res = pRFC822Headers->GetNextPropertyCString(pName, pValue);
  337. }
  338.     }
  339.     HX_RELEASE(pKeyedHdrs);
  340. }
  341. void
  342. RTSPBaseProtocol::getRFC822Headers(RTSPMessage* pMsg,
  343.     REF(IHXValues*) pRFC822Headers)
  344. {
  345.     MIMEHeader* pHeader = NULL;
  346.     IUnknown* pUnknown = NULL;
  347.     IHXKeyValueList* pList = NULL;
  348.     pRFC822Headers = NULL;
  349.     if (!m_pCommonClassFactory)
  350.     {
  351. goto cleanup;
  352.     }
  353.     if (HXR_OK != m_pCommonClassFactory->CreateInstance(CLSID_IHXKeyValueList,
  354. (void**) &pUnknown))
  355.     {
  356. goto cleanup;
  357.     }
  358.     if (HXR_OK != pUnknown->QueryInterface(IID_IHXKeyValueList, 
  359.    (void**) &pList))
  360.     {
  361. goto cleanup;
  362.     }
  363.     pHeader = pMsg->getFirstHeader();
  364.     while (pHeader)
  365.     {
  366. MIMEHeaderValue* pHeaderValue;
  367. /*
  368.  * XXX...There is way too much memcpy() going on here
  369.  */
  370. pHeaderValue = pHeader->getFirstHeaderValue();
  371. CHXString HeaderString;
  372. while (pHeaderValue)
  373. {
  374.     CHXString TempString;
  375.     pHeaderValue->asString(TempString);
  376.     HeaderString += TempString;
  377.     pHeaderValue = pHeader->getNextHeaderValue();
  378.     if (pHeaderValue)
  379.     {
  380. HeaderString += ", ";
  381.     }
  382. }
  383. IHXBuffer *pBuffer = NULL;
  384. CHXBuffer::FromCharArray((const char*) HeaderString, &pBuffer);
  385. pList->AddKeyValue(pHeader->name(), pBuffer);
  386. HX_RELEASE(pBuffer);
  387. pHeader = pMsg->getNextHeader();
  388.     }
  389.     // XXX showell - Yet another item for rnvalues cleanup phase II.  We should
  390.     // just change this function so its callers don't expect IHXValues, since
  391.     // the IHXKeyValueList interface is better for header data.
  392.     if (HXR_OK != pList->QueryInterface(IID_IHXValues,
  393. (void**) &pRFC822Headers))
  394.     {
  395. pRFC822Headers = NULL;
  396.     }
  397. cleanup:
  398.     HX_RELEASE(pList);
  399.     HX_RELEASE(pUnknown);
  400. }
  401. HX_RESULT
  402. RTSPBaseProtocol::sendControlMessage(IHXBuffer* pBuffer)
  403. {
  404.     HX_RESULT hxr = HXR_OK;
  405.     handleDebug(pBuffer, FALSE);
  406.     handleTiming(pBuffer, FALSE);
  407.     if (!m_pSocket)
  408.     {
  409.         m_pControlBuffer = pBuffer;
  410.         m_pControlBuffer->AddRef();
  411.         hxr = reopenSocket();
  412.     }
  413.     else
  414.     {
  415.         m_uControlBytesSent += pBuffer->GetSize();
  416.         if (m_pFastSocket)
  417.         {
  418.             hxr = m_pFastSocket->BufferedWrite(pBuffer);
  419.             m_pFastSocket->FlushWrite();
  420.         }
  421.         else
  422.         {
  423.             hxr = m_pSocket->Write(pBuffer);
  424.         }
  425.     }
  426.     return hxr;
  427. }
  428. HX_RESULT
  429. RTSPBaseProtocol::handleACK(IHXPacketResend* pPacketResend,
  430.     RTSPResendBuffer* pResendBuffer,
  431.     UINT16 uStreamNumber,
  432.     UINT16* pAckList,
  433.     UINT32 uAckListCount,
  434.     UINT16* pNakList,
  435.     UINT32 uNakListCount,
  436.     BOOL bIgnoreACK)
  437. {
  438.     if (!pResendBuffer)
  439.     {
  440. return HXR_UNEXPECTED;
  441.     }
  442.     /*
  443.      * ACKs and NAKs only have meaning for resend buffers
  444.      *
  445.      * NOTE: keep the ACKing/NAKing in order by starting at the back of
  446.      *       the lists
  447.      */
  448.         
  449.     INT32 i;
  450.     
  451.     if (!bIgnoreACK)
  452.     {
  453. for (i = uAckListCount - 1; i >= 0; i--)
  454. {
  455.     pResendBuffer->Remove(pAckList[i]);
  456. }
  457.     }
  458.     
  459.     if (uNakListCount)
  460.     {
  461. //XXXGH...must be BasePacket
  462. BasePacket** ppPacket = new BasePacket*[uNakListCount + 1];
  463. /*
  464.  * Only allow 10 packets to be resent
  465.  */
  466. UINT16 j = 0;
  467. for (i = uNakListCount - 1; i >= 0 && j < 10; i--)
  468. {
  469.     BasePacket* pPacket;
  470.     pPacket = pResendBuffer->Find(pNakList[i], TRUE);
  471.     if (pPacket)
  472.     {
  473. ppPacket[j++] = pPacket;
  474. pPacket->AddRef();
  475.     }
  476. }
  477. ppPacket[j] = 0;
  478. //XXX..will the BasePacket have the stream number in it?
  479. pPacketResend->OnPacket(uStreamNumber, ppPacket);
  480. BasePacket* pReleasePacket = NULL;
  481. BasePacket** ppReleasePacket = ppPacket;
  482. for (; (pReleasePacket = *ppReleasePacket); ppReleasePacket++)
  483. {
  484.     HX_RELEASE(pReleasePacket);
  485. }     
  486. HX_VECTOR_DELETE(ppPacket);
  487.     }
  488.     return HXR_OK;
  489. }
  490. /*
  491.  *  The grammer in RFC2326, I think, is wrong....But in any case, there is no 
  492.  *  gurantee seq_no and rtptime are present in RTP-Info.
  493.  */
  494. RTPInfoEnum
  495. RTSPBaseProtocol::parseRTPInfoHeader(
  496.     MIMEHeaderValue* pSeqValue, UINT16& streamID, UINT16& seqNum,
  497.     UINT32& ulTimestamp, const char*& pControl)
  498. {
  499.     BOOL bFoundSeqNo = FALSE;
  500.     BOOL bFoundRTPTime = FALSE;
  501.     MIMEParameter* pParam = pSeqValue->getFirstParameter();
  502.     while (pParam != NULL)
  503.     {
  504. if(pParam->m_attribute == "url")
  505. {
  506.     // Note: We don't currently do anything with the first section
  507.     // of the "url" attribute (the actual player-requested URL). If
  508.     // we ever do, please note that all ';' characters were escaped 
  509.     // by the server when this message was created, because ';' has
  510.     // special meaning as a delimiter in this message. Remember to
  511.     // unescape all instances of "%3b" to ";" before using the URL.
  512.     const char* pUrl = (const char*) pParam->m_value;
  513.     const char* pEq  = strrchr(pUrl, '=');
  514.     if (pEq != NULL)
  515.     {
  516. streamID = (UINT16)strtol(pEq + 1, 0, 10);
  517.     }
  518.     // take the control string...
  519.     pControl = pUrl;
  520. }
  521. else if(pParam->m_attribute == "seq")
  522. {
  523.     bFoundSeqNo = TRUE;
  524.     seqNum = (UINT16)strtol((const char*)pParam->m_value,0,10);
  525. }
  526. else if(pParam->m_attribute == "rtptime")
  527. {
  528.     bFoundRTPTime = TRUE;
  529.     ulTimestamp = (UINT32)strtoul((const char*)pParam->m_value, 0, 10);
  530. }
  531. pParam = pSeqValue->getNextParameter();
  532.     }
  533.     if (bFoundSeqNo)
  534.     {
  535. if (bFoundRTPTime)
  536. {
  537.     return RTPINFO_SEQ_RTPTIME;
  538. }
  539. return RTPINFO_SEQ;
  540.     }
  541.     if (bFoundRTPTime)
  542.     {
  543. return RTPINFO_RTPTIME;
  544.     }
  545.     return RTPINFO_EMPTY;
  546. }
  547. BOOL 
  548. RTSPBaseProtocol::isRequired(RTSPMessage* pRTSPMessageToSearch, 
  549.      UINT32 ulOptionToFind)
  550. {
  551.     BOOL bRetainState = FALSE;
  552.     MIMEHeader* pMIMEHeaderRequire;
  553.     pMIMEHeaderRequire = pRTSPMessageToSearch->getHeader("Require");
  554.     // If a require header was found
  555.     if (pMIMEHeaderRequire != NULL)
  556.     {
  557. MIMEHeaderValue* pMIMEHeaderValueRequire =
  558.     pMIMEHeaderRequire->getFirstHeaderValue();
  559. while (pMIMEHeaderValueRequire != NULL)
  560. {
  561.     if (!strcasecmp(RTSPRequireOptionsTable[ulOptionToFind].pcharOption,
  562.                             pMIMEHeaderValueRequire->value()))
  563.     {
  564. bRetainState = TRUE;
  565.     }
  566.     pMIMEHeaderValueRequire = pMIMEHeaderRequire->getNextHeaderValue();
  567. }
  568.     }
  569.     return bRetainState;
  570. }