RtspResponse.cxx
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:9k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /* ====================================================================
  2.  * The Vovida Software License, Version 1.0 
  3.  * 
  4.  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in
  15.  *    the documentation and/or other materials provided with the
  16.  *    distribution.
  17.  * 
  18.  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
  19.  *    and "Vovida Open Communication Application Library (VOCAL)" must
  20.  *    not be used to endorse or promote products derived from this
  21.  *    software without prior written permission. For written
  22.  *    permission, please contact vocal@vovida.org.
  23.  *
  24.  * 4. Products derived from this software may not be called "VOCAL", nor
  25.  *    may "VOCAL" appear in their name, without prior written
  26.  *    permission of Vovida Networks, Inc.
  27.  * 
  28.  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
  29.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
  31.  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
  32.  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
  33.  * IN EXCESS OF 281421,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
  34.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  35.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  36.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  37.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  39.  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  40.  * DAMAGE.
  41.  * 
  42.  * ====================================================================
  43.  * 
  44.  * This software consists of voluntary contributions made by Vovida
  45.  * Networks, Inc. and many individuals on behalf of Vovida Networks,
  46.  * Inc.  For more information on Vovida Networks, Inc., please see
  47.  * <http://www.vovida.org/>.
  48.  *
  49.  */
  50. static const char* const RtspResponse_cxx_Version =
  51.     "$Id: RtspResponse.cxx,v 1.24 2001/05/15 20:26:12 bko Exp $";
  52. #include <string.h>
  53. #include <stdio.h>
  54. #include "cpLog.h"
  55. #include "RtspResponse.hxx"
  56. #include "RtspBadDataException.hxx"
  57. RtspResponse::RtspResponse()
  58.     : RtspMsg(),
  59.       myRtspRequest(0),
  60.       myStatusCodeType(RTSP_NULL_STATUS),
  61.       myStatusCode(0),
  62.       myFileLocation(0)
  63. {
  64. }
  65. RtspResponse::RtspResponse(Sptr< RtspRequest > rtspRequest,
  66.                            RtspStatusCodesType statusCode)
  67.     : RtspMsg(),
  68.       myRtspRequest(rtspRequest),
  69.       myStatusCodeType(statusCode),
  70.       myStatusCode(0),
  71.       myFileLocation(0)
  72. {
  73.     assert(rtspRequest != 0);
  74.     myTransConnPtr = rtspRequest->getTransConnPtr();
  75.     setStatusLine();
  76.     appendCSeqHdr(rtspRequest);
  77.     appendSessionHdr(rtspRequest);
  78. }
  79. RtspResponse::RtspResponse( const RtspResponse& src)
  80.     : RtspMsg(src),
  81.       myRtspRequest(0),
  82.       myStatusCodeType(src.myStatusCodeType),
  83.       myStatusCode(src.myStatusCode),
  84.       myFileLocation(0)
  85. {
  86.     if (src.myRtspRequest != 0)
  87.     {
  88.         myRtspRequest = new RtspRequest();
  89.         *myRtspRequest = *src.myRtspRequest;
  90.     }
  91.     if (src.myFileLocation != 0)
  92.     {
  93.         myFileLocation = new RtspLocationHdr();
  94.         *myFileLocation = *src.myFileLocation;
  95.     }
  96. }
  97. RtspResponse&
  98. RtspResponse::operator= (const RtspResponse& src)
  99. {
  100.     if (&src != this)
  101.     {
  102.         RtspMsg::operator=(src);
  103.         myStatusCodeType = src.myStatusCodeType;
  104.         myStatusCode = src.myStatusCode;
  105.         myRtspRequest = 0;
  106.         myFileLocation = 0;
  107.         if (src.myRtspRequest != 0)
  108.         {
  109.             myRtspRequest = new RtspRequest();
  110.             *myRtspRequest = *src.myRtspRequest;
  111.         }
  112.         if (src.myFileLocation != 0)
  113.         {
  114.             myFileLocation = new RtspLocationHdr();
  115.             *myFileLocation = *src.myFileLocation;
  116.         }
  117.     }
  118.     return (*this);
  119. }
  120. void
  121. RtspResponse::setStatusLine()
  122. {
  123.     char tmpBuf[64];
  124.     u_int32_t len = 0;
  125.     CharData version = RtspUtil::getVersion();
  126.     CharData statusCode = RtspUtil::getStatusCodeInString(myStatusCodeType);
  127.     CharData statusString = RtspUtil::getStatusInString(myStatusCodeType);
  128.     u_int32_t versionLen = version.getLen();
  129.     u_int32_t statusCodeLen = statusCode.getLen();
  130.     u_int32_t statusStringLen = statusString.getLen();
  131.     memcpy(tmpBuf, version.getPtr(), versionLen);
  132.     len = versionLen;
  133.     tmpBuf[len++] = ' ';
  134.     memcpy(tmpBuf + len, statusCode.getPtr(), statusCodeLen);
  135.     len += statusCodeLen;
  136.     tmpBuf[len++] = ' ';
  137.     memcpy(tmpBuf + len, statusString.getPtr(), statusStringLen);
  138.     len += statusStringLen;
  139.     memcpy(tmpBuf + len, "rn", 2);
  140.     len += 2;
  141.     Data statusLine(tmpBuf, len);
  142.     myStartLine = statusLine;
  143. }
  144. void
  145. RtspResponse::appendCSeqHdr(Sptr< RtspRequest > rtspRequest)
  146. {
  147.     if ( (rtspRequest->getCSeq()).length() > 0)
  148.     {
  149.         myHeaders += "CSeq: ";
  150.         myHeaders += rtspRequest->getCSeq();
  151.         myHeaders += "rn";
  152.     }
  153. }
  154. void
  155. RtspResponse::appendSessionHdr(Sptr< RtspRequest > rtspRequest)
  156. {
  157.     if ( (rtspRequest->getSessionId()).length() > 0)
  158.     {
  159.         myHeaders += "Session: ";
  160.         myHeaders += rtspRequest->getSessionId();
  161.         myHeaders += "rn";
  162.     }
  163. }
  164. void
  165. RtspResponse::appendSessionId(u_int32_t sessionId)
  166. {
  167.     char tmpBuf[32];
  168.     sprintf(tmpBuf, "%d", sessionId);
  169.     myHeaders += "Session: ";
  170.     myHeaders += tmpBuf;
  171.     myHeaders += "rn";
  172. }
  173. void
  174. RtspResponse::appendTransportHdr(Sptr< RtspRequest > rtspRequest, 
  175.                                  u_int32_t serverPortA, u_int32_t serverPortB)
  176. {
  177.     Sptr< RtspTransportSpec > spec = rtspRequest->getTransport();
  178.     spec->myServerPortA = serverPortA;
  179.     spec->myServerPortB = serverPortB;
  180.     RtspTransportHdr transportHdr;
  181.     transportHdr.appendTransportSpec(spec);
  182.     myHeaders += transportHdr.encode();
  183. }
  184. void
  185. RtspResponse::appendTransportHdr(Sptr< RtspTransportSpec > spec)
  186. {
  187.     RtspTransportHdr transportHdr;
  188.     transportHdr.appendTransportSpec(spec);
  189.     myHeaders += transportHdr.encode();
  190. }
  191. void
  192. RtspResponse::appendNPTRangeHdr(double startTime, double endTime)
  193. {
  194.    RtspRangeHdr rangeHdr(startTime, endTime);
  195.    myHeaders += rangeHdr.encode();
  196. }
  197. void
  198. RtspResponse::appendLocationHdr(Sptr< RtspLocationHdr > hdr)
  199. {
  200.     myFileLocation = hdr;
  201.     myHeaders += hdr->encode();
  202. }
  203. void
  204. RtspResponse::appendRtpInfoHdr(Sptr< RtspRtpInfoHdr > hdr)
  205. {
  206.     myRtpInfo = hdr;
  207.     myHeaders += hdr->encode();
  208. }
  209. void
  210. RtspResponse::appendConnectionCloseHdr()
  211. {
  212.     myHeaders += "Connection: closern";
  213. }
  214. void
  215. RtspResponse::appendEndOfHeaders()
  216. {
  217.     myHeaders += "rn";
  218. }
  219. void
  220. RtspResponse::appendSdpData( RtspSdp& sdp )
  221. {
  222.     myHasBody = true;
  223.     Data contData = sdp.encode();
  224.     if (contData.length() > 0)
  225.     {
  226.         char tmpBuf[32];
  227.         sprintf(tmpBuf, "%d", contData.length());
  228.         myHeaders += "Content-Type: application/sdprn";
  229.         myHeaders += "Content-Length: ";
  230.         myHeaders += tmpBuf;
  231.         myHeaders += "rnrn";
  232.         myMsgBody = contData;
  233.     }
  234. }
  235. Data
  236. RtspResponse::encode()
  237. {
  238.     if (!myHasBody)
  239.         appendEndOfHeaders();
  240.     Data msg = myStartLine + myHeaders;
  241.     if (myHasBody)
  242.         msg += myMsgBody;
  243.         
  244.     return msg;
  245. }
  246. const u_int32_t
  247. RtspResponse::getStatusCode() throw (RtspBadDataException&)
  248. {
  249.     if (myStatusCode == 0)
  250.     {
  251.         if (myStartLine.length() == 0)
  252.             return myStatusCode;
  253.         CharData strtLine;
  254.         strtLine.set(myStartLine.getDataBuf(), myStartLine.length());
  255.         CharDataParser charParser(&strtLine);
  256.         CharData version;
  257.         u_int32_t len = 8;
  258.         if (charParser.getThruLength(&version, len) == 0)
  259.         {
  260.             throw RtspBadDataException( "Bad RTSP message", __FILE__, __LINE__, 0 );
  261.         }
  262.         //TODO can add check for version here
  263.         charParser.getThruSpaces(NULL);
  264.         u_int32_t statusCodeNum;
  265.         if (charParser.getNextInteger( statusCodeNum ))
  266.         {
  267.             myStatusCode = statusCodeNum;
  268.         }
  269.         else
  270.         {
  271.             cpLog(LOG_ERR, "error read status code number");
  272.         }
  273.     }
  274.     return myStatusCode;
  275. }
  276. /* Local Variables: */
  277. /* c-file-style: "stroustrup" */
  278. /* indent-tabs-mode: nil */
  279. /* c-file-offsets: ((access-label . -) (inclass . ++)) */
  280. /* c-basic-offset: 4 */
  281. /* End: */