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

流媒体/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 $1,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 RtpSession_cxx_Version =
  51.     "$Id: RtpSession.cxx,v 1.53 2001/05/07 19:12:50 kle Exp $";
  52. #include <iostream>
  53. #include <stdlib.h>
  54. #include <stdio.h>
  55. #include <unistd.h>
  56. #include <sys/socket.h>
  57. #include <sys/types.h>
  58. #include "vtypes.h"
  59. #include "cpLog.h"
  60. #include "vsock.hxx"
  61. #include "rtpTypes.h"
  62. #include "Rtp.hxx"
  63. #include "Rtcp.hxx"
  64. #include "RtpSession.hxx"
  65. /* ----------------------------------------------------------------- */
  66. /* --- rtp session Constructor ------------------------------------- */
  67. /* ----------------------------------------------------------------- */
  68. RtpSession::RtpSession (const char* remoteHost, int remotePort, int localPort,
  69.                         int rtcpRemotePort, int rtcpLocalPort, int portRange,
  70.                         RtpPayloadType apiPayloadType,
  71.                         RtpPayloadType networkPayloadType, int jitterNew)
  72. {
  73.     constructRtpSession (remoteHost, remotePort, localPort, rtcpRemotePort,
  74.                          rtcpLocalPort, portRange, apiPayloadType,
  75.                          networkPayloadType, jitterNew);
  76. }
  77. RtpSession::RtpSession (const char* remoteHost, int remotePort, int localPort,
  78.                         int rtcpRemotePort, int rtcpLocalPort,
  79.                         RtpPayloadType apiPayloadType,
  80.                         RtpPayloadType networkPayloadType, int jitterNew)
  81. {
  82.     constructRtpSession (remoteHost, remotePort, localPort, rtcpRemotePort,
  83.                          rtcpLocalPort, 0, apiPayloadType,
  84.                          networkPayloadType, jitterNew);
  85. }
  86. void RtpSession::constructRtpSession (const char* remoteHost,
  87.                                       int remotePort, int localPort,
  88.                                       int rtcpRemotePort, int rtcpLocalPort,
  89.                                       int portRange, RtpPayloadType apiPayloadType,
  90.                                       RtpPayloadType networkPayloadType,
  91.                                       int jitterNew)
  92. {
  93.     recv = NULL; tran = NULL;
  94.     rtcpTran = NULL, rtcpRecv = NULL;
  95.     if (localPort != 0)
  96.     {
  97.         if (portRange != 0)
  98.             recv = new RtpReceiver (localPort, localPort + portRange,
  99.                                     apiPayloadType, networkPayloadType,
  100.                                     jitterNew);
  101.         else
  102.             recv = new RtpReceiver (localPort, apiPayloadType,
  103.                                     networkPayloadType, jitterNew);
  104.     }
  105.     if (remotePort != 0)
  106.     {
  107.         if (portRange != 0)
  108.             tran = new RtpTransmitter (remoteHost, remotePort,
  109.                                        remotePort + portRange, apiPayloadType,
  110.                                        networkPayloadType, recv);
  111.         else
  112.             tran = new RtpTransmitter (remoteHost, remotePort, apiPayloadType,
  113.                                        networkPayloadType, recv);
  114.     }
  115.     if (rtcpLocalPort != 0)
  116.     {
  117.         if (portRange != 0)
  118.             rtcpRecv = new RtcpReceiver (rtcpLocalPort,
  119.                                          rtcpLocalPort + portRange);
  120.         else
  121.             rtcpRecv = new RtcpReceiver (rtcpLocalPort);
  122.     }
  123.     if (rtcpRemotePort != 0)
  124.     {
  125.         if (portRange != 0)
  126.             rtcpTran = new RtcpTransmitter (remoteHost, rtcpRemotePort,
  127.                                             rtcpRemotePort + portRange, rtcpRecv);
  128.         else
  129.             rtcpTran = new RtcpTransmitter (remoteHost,
  130.                                             rtcpRemotePort, rtcpRecv);
  131.     }
  132.     // update interlinks
  133.     if (rtcpTran && tran) rtcpTran->setRTPtran (tran);
  134.     if (rtcpTran && recv) rtcpTran->setRTPrecv (recv);
  135.     if (rtcpTran && rtcpRecv) rtcpTran->setRTCPrecv (rtcpRecv);
  136.     if (rtcpRecv && recv) recv->setRTCPrecv(rtcpRecv);
  137.     // SDES infromation for transmitter
  138.     if (rtcpTran && tran)
  139.     {
  140.         char dummy[2] = "";
  141.         rtcpTran->setSdesCname();
  142.         rtcpTran->setSdesName(dummy);
  143.         rtcpTran->setSdesEmail(dummy);
  144.         rtcpTran->setSdesPhone(dummy);
  145.         rtcpTran->setSdesLoc(dummy);
  146.         rtcpTran->setSdesTool(dummy);
  147.         rtcpTran->setSdesNote(dummy);
  148.     }
  149.     // session states
  150.     // Currently the states are for RTP stack only, not for RTCP
  151.     if (tran && recv)
  152.     {
  153.         sessionState = rtp_session_sendrecv;
  154.         recv->getUdpStack()->setMode(sendrecv);
  155.     }
  156.     else if (tran && !recv)
  157.     {
  158.         sessionState = rtp_session_sendonly;
  159.         tran->getUdpStack()->setMode(sendonly);
  160.     }
  161.     else if (recv && !tran)
  162.     {
  163.         sessionState = rtp_session_recvonly;
  164.         recv->getUdpStack()->setMode(recvonly);
  165.     }
  166.     else
  167.     {
  168.         cpLog (LOG_DEBUG_STACK, "Session undefined");
  169.         sessionState = rtp_session_undefined;
  170.     }
  171.     if (tran) cpLog (LOG_DEBUG_STACK, "RTP Tran Port: %d",
  172.                          tran->getUdpStack()->getDestinationPort());
  173.     if (recv) cpLog (LOG_DEBUG_STACK, "RTP Recv Port: %d", recv->getPort());
  174.     if (rtcpTran) cpLog (LOG_DEBUG_STACK, "RTCP Tran Port: %d",
  175.                              rtcpTran->getUdpStack()->getDestinationPort());
  176.     if (rtcpRecv) cpLog (LOG_DEBUG_STACK, "RTCP Recv Port: %d",
  177.                              rtcpRecv->getPort());
  178. }
  179. RtpSession::~RtpSession ()
  180. {
  181.     if( rtcpTran )
  182.     {
  183.         delete rtcpTran;
  184.         rtcpTran = NULL;
  185.     }
  186.     if( rtcpRecv )
  187.     {
  188.         delete rtcpRecv;
  189.         rtcpRecv = NULL;
  190.     }
  191.     if( tran )
  192.     {
  193.         delete tran;
  194.         tran = NULL;
  195.     }
  196.     if( recv )
  197.     {
  198.         delete recv;
  199.         recv = NULL;
  200.     }
  201. }
  202. int
  203. RtpSession::reserveRtpPort(int localMin, int localMax)
  204. {
  205.     int port = 0;
  206.     if ( recv == 0 )
  207.     {
  208.         try
  209.         {
  210.             //let RtpReceiver() automatically generate a port number
  211.             recv = new RtpReceiver(localMin, localMax);
  212.             port = recv->getPort();
  213.         }
  214.         catch ( UdpStackExceptionPortsInUse& exception )
  215.         {
  216.             if ( localMin == localMax )
  217.                 cpLog( LOG_ERR, "port %d is not available", localMin );
  218.             else
  219.                 cpLog( LOG_ERR, "No ports between %d and %d are available", localMin, localMax);
  220.             recv = 0;
  221.         }
  222.     }
  223.     else
  224.     {
  225.         port = recv->getPort();
  226.     }
  227.     return port;
  228. }
  229. int
  230. RtpSession::releaseRtpPort()
  231. {
  232.     int port = 0;
  233.     if ( recv != 0 )
  234.     {
  235.         port = recv->getPort();
  236.         delete recv;
  237.         recv = 0;
  238.     }
  239.     return port;
  240. }
  241. int
  242. RtpSession::reserveRtcpPort(int rtcpLocalPort, int portRange)
  243. {
  244.     int port = 0;
  245.     if ( rtcpRecv == 0 )
  246.     {
  247.         try
  248.         {
  249.             if (rtcpLocalPort != 0)
  250.             {
  251.                 if (portRange != 0)
  252.                     rtcpRecv = new RtcpReceiver (rtcpLocalPort,
  253.                                                  rtcpLocalPort + portRange);
  254.                 else
  255.                     rtcpRecv = new RtcpReceiver (rtcpLocalPort);
  256.             }
  257.             port = rtcpRecv->getPort();
  258.         }
  259.         catch ( UdpStackExceptionPortsInUse& exception )
  260.         {
  261.             if ( portRange == 0 )
  262.                 cpLog( LOG_ERR, "port %d is not available", rtcpLocalPort );
  263.             else
  264.                 cpLog( LOG_ERR, "no ports between %d and %d are available", rtcpLocalPort, rtcpLocalPort + portRange );
  265.             rtcpRecv = 0;
  266.         }
  267.     }
  268.     else
  269.     {
  270.         port = rtcpRecv->getPort();
  271.     }
  272.     return port;
  273. }
  274. int
  275. RtpSession::releaseRtcpPort()
  276. {
  277.     int port = 0;
  278.     if ( rtcpRecv != 0 )
  279.     {
  280.         port = rtcpRecv->getPort();
  281.         delete rtcpRecv;
  282.         rtcpRecv = 0;
  283.     }
  284.     return port;
  285. }
  286. /* --- Send and Receive RTP Functions ------------------------------ */
  287. void RtpSession::setNetworkFormat (RtpPayloadType type, int no_samples, int packetSize)
  288. {
  289.     if (tran) tran->setNetworkFormat (type, no_samples, packetSize);
  290.     if (recv) recv->setNetworkFormat (type, no_samples, packetSize);
  291. }
  292. void RtpSession::setApiFormat (RtpPayloadType type, int no_samples, int packetSize)
  293. {
  294.     if (tran) tran->setApiFormat (type, no_samples, packetSize);
  295.     if (recv) recv->setApiFormat (type, no_samples, packetSize);
  296. }
  297. void RtpSession::setNetworkPktSize (int no_samples)
  298. {
  299.     setNetworkPktSampleSize (no_samples);
  300. }
  301. void RtpSession::setNetworkPktSampleSize (int no_samples)
  302. {
  303.     if (tran) tran->setNetworkPktSize (no_samples);
  304.     if (recv) recv->setNetworkPktSize (no_samples);
  305. }
  306. void RtpSession::setApiPktSize (int no_samples)
  307. {
  308.     setApiPktSampleSize (no_samples);
  309. }
  310. void RtpSession::setApiPktSampleSize (int no_samples)
  311. {
  312.     if (tran) tran->setApiPktSize (no_samples);
  313.     if (recv) recv->setApiPktSize (no_samples);
  314. }
  315. int RtpSession::getNetworkPktSampleSize ()
  316. {
  317.     if (tran)
  318.         return tran->getNetworkPktSampleSize ();
  319.     else
  320.         return 0;
  321. }
  322. int RtpSession::getApiPktSampleSize ()
  323. {
  324.     if (recv)
  325.         return recv->getApiPktSampleSize();
  326.     else
  327.         return 0;
  328. }
  329. // If there are multiple dests, the return will be the total
  330. // of all dests. - ?
  331. int RtpSession::getPacketSent ()
  332. {
  333.     if (tran)
  334.         return tran->getPacketSent ();
  335.     else
  336.         return 0;
  337. }
  338. // If there are multiple dests, the return will be the total
  339. // of all dests. - ?
  340. int RtpSession::getByteSent ()
  341. {
  342.     if (tran)
  343.         return tran->getPayloadSent ();
  344.     else
  345.         return 0;
  346. }
  347. // If there are multiple srcs, the return will be the total
  348. // of all srcs. - ?
  349. int RtpSession::getPacketReceived ()
  350. {
  351.     if (recv)
  352.         return recv->getPacketReceived ();
  353.     else
  354.         return 0;
  355. }
  356. // If there are multiple srcs, the return will be the total
  357. // of all srcs. - ?
  358. int RtpSession::getByteReceived ()
  359. {
  360.     if (recv)
  361.         return recv->getPayloadReceived ();
  362.     else
  363.         return 0;
  364. }
  365. // If there are multiple srcs, this func returns the packect lost
  366. // for all the srcs
  367. int RtpSession::getPacketLost ()
  368. {
  369.     if (rtcpTran)
  370.     {
  371.         if (rtcpRecv)
  372.         {
  373.             int lost = 0;
  374.             for (int i = 0; i < (rtcpRecv->getTranInfoCount()); i++)
  375.             {
  376.                 lost += rtcpTran->calcLostCount(rtcpRecv->getTranInfoList(i));
  377.             }
  378.             return lost;
  379.         }
  380.     }
  381.     return 0;
  382. }
  383. // If there are multiple srcs, this func returns the jitter
  384. // calculation results accumulated by all srcs
  385. int RtpSession::getJitter ()
  386. {
  387.     if (recv)
  388.     {
  389.         return (recv->getJitter() >> 4);
  390.     }
  391.     return 0;
  392. }
  393. // If there are multiple srcs, what this func returns
  394. // is not clear - ?
  395. int RtpSession::getLatency ()
  396. {
  397.     if (rtcpRecv)
  398.     {
  399.         return (rtcpRecv->getAvgOneWayDelay());
  400.         //        return (rtcpRecv->getAvgRoundTripDelay());
  401.     }
  402.     return 0;
  403. }
  404. void RtpSession::setSessionState (RtpSessionState state)
  405. {
  406.     switch (state)
  407.     {
  408.         case (rtp_session_inactive):
  409.                     if (recv) recv->getUdpStack()->setMode(inactive);
  410.             else if (tran) tran->getUdpStack()->setMode(inactive);
  411.         sessionState = state;
  412.         break;
  413.         case (rtp_session_sendonly):
  414.                     if (recv) recv->getUdpStack()->setMode(sendonly);
  415.             else if (tran) tran->getUdpStack()->setMode(sendonly);
  416.         sessionState = state;
  417.         break;
  418.         case (rtp_session_recvonly):
  419.                     if (recv) recv->getUdpStack()->setMode(recvonly);
  420.             else if (tran) tran->getUdpStack()->setMode(recvonly);
  421.         sessionState = state;
  422.         break;
  423.         case (rtp_session_sendrecv):
  424.                     if (recv) recv->getUdpStack()->setMode(sendrecv);
  425.             else if (tran) tran->getUdpStack()->setMode(sendrecv);
  426.         sessionState = state;
  427.         break;
  428.         case (rtp_session_undefined):
  429.                     sessionState = state;
  430.         break;
  431.         default:
  432.         cpLog (LOG_ERR, "Unknown state: %d", (int)state);
  433.         assert (0);
  434.     }
  435.     if (recv) recv->emptyNetwork();
  436. }
  437. RtpSessionState RtpSession::getSessionState ()
  438. {
  439.     return sessionState;
  440. }
  441. int
  442. RtpSession::setReceiver ( int localPort, int rtcpLocalPort, int portRange,
  443.                           RtpPayloadType apiFormat,
  444.                           RtpPayloadType networkFormat,
  445.                           int jitterNew /* = 5 */)
  446. {
  447.     if ( !(sessionState == rtp_session_sendrecv
  448.             || sessionState == rtp_session_recvonly) )
  449.     {
  450.         cpLog(LOG_ERR, "wrong state of RTP stack.");
  451.         return -1;
  452.     }
  453.     if (localPort != 0)
  454.     {
  455.         if (portRange != 0)
  456.         {
  457.             if (recv)
  458.             {
  459.                 assert (recv->getUdpStack());
  460.                 recv->getUdpStack()->setLocal(localPort, localPort + portRange);
  461.             }
  462.             else if (tran)
  463.             {
  464.                 assert (tran->getUdpStack());
  465.                 tran->getUdpStack()->setLocal(localPort, localPort + portRange);
  466.                 recv = new RtpReceiver(tran->getUdpStack(), apiFormat,
  467.                                        networkFormat, jitterNew);
  468.             }
  469.             else
  470.                 recv = new RtpReceiver (localPort, localPort + portRange,
  471.                                         apiFormat, networkFormat,
  472.                                         jitterNew);
  473.         }
  474.         else
  475.             if (recv)
  476.             {
  477.                 assert (recv->getUdpStack());
  478.                 recv->getUdpStack()->setLocal(localPort, localPort + portRange);
  479.             }
  480.             else if (tran)
  481.             {
  482.                 assert (tran->getUdpStack());
  483.                 tran->getUdpStack()->setLocal(localPort, localPort + portRange);
  484.                 recv = new RtpReceiver(tran->getUdpStack(), apiFormat,
  485.                                        networkFormat, jitterNew);
  486.             }
  487.             else
  488.                 recv = new RtpReceiver (localPort, apiFormat,
  489.                                         networkFormat, jitterNew);
  490.     }
  491.     if (rtcpLocalPort != 0)
  492.     {
  493.         if (portRange != 0)
  494.             if (rtcpRecv)
  495.             {
  496.                 assert (rtcpRecv->getUdpStack());
  497.                 rtcpRecv->getUdpStack()->setLocal(rtcpLocalPort,
  498.                                                   rtcpLocalPort + portRange);
  499.             }
  500.             else if (rtcpTran)
  501.             {
  502.                 assert (rtcpTran->getUdpStack());
  503.                 rtcpTran->getUdpStack()->setLocal(rtcpLocalPort,
  504.                                                   rtcpLocalPort + portRange);
  505.                 rtcpRecv = new RtcpReceiver(rtcpTran->getUdpStack());
  506.             }
  507.             else
  508.                 rtcpRecv = new RtcpReceiver (rtcpLocalPort,
  509.                                              rtcpLocalPort + portRange);
  510.         else
  511.             if (rtcpRecv)
  512.             {
  513.                 assert(rtcpRecv->getUdpStack());
  514.                 rtcpRecv->getUdpStack()->setLocal(rtcpLocalPort);
  515.             }
  516.             else if (rtcpTran)
  517.             {
  518.                 assert(rtcpTran->getUdpStack());
  519.                 rtcpTran->getUdpStack()->setLocal(rtcpLocalPort);
  520.                 rtcpRecv = new RtcpReceiver(rtcpTran->getUdpStack());
  521.             }
  522.             else
  523.                 rtcpRecv = new RtcpReceiver (rtcpLocalPort);
  524.     }
  525.     // update interlinks
  526.     if (rtcpTran && recv) rtcpTran->setRTPrecv (recv);
  527.     if (rtcpTran && rtcpRecv) rtcpTran->setRTCPrecv (rtcpRecv);
  528.     if (rtcpRecv && recv) recv->setRTCPrecv(rtcpRecv);
  529.     if (recv) cpLog (LOG_DEBUG_STACK, "RTP Recv Port: %d", recv->getPort());
  530.     if (rtcpRecv) cpLog (LOG_DEBUG_STACK, "RTCP Recv Port: %d",
  531.                              rtcpRecv->getPort());
  532.     return 0;
  533. }
  534. int
  535. RtpSession::setTransmiter ( const char* remoteHost, int remotePort,
  536.                             int rtcpRemotePort,
  537.                             RtpPayloadType apiFormat,
  538.                             RtpPayloadType networkFormat )
  539. {
  540.     if ( !(sessionState == rtp_session_sendrecv
  541.             || sessionState == rtp_session_sendonly) )
  542.     {
  543.         cpLog(LOG_ERR, "wrong state of RTP stack.");
  544.         return -1;
  545.     }
  546.     if (remotePort != 0)
  547.     {
  548.         if (tran)
  549.         {
  550.             tran->getUdpStack()->setDestination(remoteHost, remotePort);
  551.             NetworkAddress netAddress;
  552.             if ( remoteHost )
  553.             {
  554.                 netAddress.setPort(remotePort);
  555.                 netAddress.setHostName(remoteHost);
  556.             }
  557.             tran->setRemoteAddr(netAddress);
  558.         }
  559.         else
  560.             tran = new RtpTransmitter ( remoteHost, remotePort, apiFormat,
  561.                                         networkFormat, recv);
  562.     }
  563.     if (rtcpRemotePort != 0)
  564.     {
  565.         if (rtcpTran)
  566.         {
  567.             rtcpTran->getUdpStack()->setDestination( remoteHost,
  568.                     rtcpRemotePort);
  569.             NetworkAddress netAddress1;
  570.             if ( remoteHost )
  571.             {
  572.                 netAddress1.setPort(rtcpRemotePort);
  573.                 netAddress1.setHostName(remoteHost);
  574.             }
  575.             rtcpTran->setRemoteAddr(netAddress1);
  576.         }
  577.         else
  578.             rtcpTran = new RtcpTransmitter ( remoteHost,
  579.                                              rtcpRemotePort, rtcpRecv);
  580.     }
  581.     // update interlinks
  582.     if (rtcpTran && tran) rtcpTran->setRTPtran (tran);
  583.     if (rtcpTran && recv) rtcpTran->setRTPrecv (recv);
  584.     if (rtcpTran && rtcpRecv) rtcpTran->setRTCPrecv (rtcpRecv);
  585.     // SDES infromation for transmitter
  586.     if (rtcpTran && tran)
  587.     {
  588.         char dummy[2]= "";
  589.         rtcpTran->setSdesCname();
  590.         rtcpTran->setSdesEmail(dummy);
  591.         rtcpTran->setSdesPhone(dummy);
  592.         rtcpTran->setSdesLoc(dummy);
  593.         rtcpTran->setSdesTool(dummy);
  594.         rtcpTran->setSdesNote(dummy);
  595.     }
  596.     if (tran) cpLog (LOG_DEBUG_STACK, "RTP Tran Port: %d",
  597.                          tran->getUdpStack()->getDestinationPort());
  598.     if (rtcpTran) cpLog (LOG_DEBUG_STACK, "RTCP Tran Port: %d",
  599.                              rtcpTran->getUdpStack()->getDestinationPort());
  600.     return 0;
  601. }
  602. /* --- Send and Receive RTP Functions ------------------------------ */
  603. RtpPacket* RtpSession::createPacket (int npadSize, int csrcCount)
  604. {
  605.     assert (tran);
  606.     if (npadSize != 0)
  607.         cpLog(LOG_DEBUG, "Nonzero npadSize not supported");
  608.     return tran->createPacket(npadSize, csrcCount);
  609. }
  610. RtpSeqNumber RtpSession::getPrevSequence ()
  611. {
  612.     assert (tran);
  613.     return tran->getPrevSequence ();
  614. }
  615. RtpTime RtpSession::getPrevRtpTime ()
  616. {
  617.     assert (tran);
  618.     return tran->getPrevRtpTime();
  619. }
  620. void RtpSession::setMarkerOnce()
  621. {
  622.     if( tran )
  623.     {
  624.         tran->setMarkerOnce();
  625.     }
  626. }
  627. int RtpSession::transmit (RtpPacket* p)
  628. {
  629.     if ( !( sessionState == rtp_session_sendrecv
  630.             || sessionState == rtp_session_sendonly ) )
  631.     {
  632.         sessionError = session_wrongState;
  633.         cpLog (LOG_ERR, "RTP stack can't transmit. Wrong state");
  634.         return -1;
  635.     }
  636.     assert (tran);
  637.     sessionError = session_success;
  638.     return tran->transmit(p);
  639. }
  640. int RtpSession::transmitRaw (char* inbuffer, int len)
  641. {
  642.     if ( !( sessionState == rtp_session_sendrecv
  643.             || sessionState == rtp_session_sendonly ) )
  644.     {
  645.         sessionError = session_wrongState;
  646.         cpLog (LOG_ERR, "RTP stack can't transmit. Wrong state");
  647.         return -1;
  648.     }
  649.     assert (tran);
  650.     sessionError = session_success;
  651.     return tran->transmitRaw(inbuffer, len);
  652. }
  653. int RtpSession::transmitEvent( int event )
  654. {
  655.     if ( !( sessionState == rtp_session_sendrecv
  656.             || sessionState == rtp_session_sendonly ) )
  657.     {
  658.         sessionError = session_wrongState;
  659.         cpLog (LOG_ERR, "RTP stack can't transmit event. Wrong state");
  660.         return -1;
  661.     }
  662.     cpLog( LOG_DEBUG_STACK,"Sending DTMF event %d in RTP stream", event );
  663.     assert (tran);
  664.     sessionError = session_success;
  665.     RtpPacket* eventPacket = createPacket(0, 0);
  666.     eventPacket->setPayloadType( rtpPayloadDTMF_RFC2833 );
  667.     eventPacket->setPayloadUsage( sizeof( RtpEventDTMFRFC2833 ) );
  668.     RtpEventDTMFRFC2833* eventPayload = reinterpret_cast<RtpEventDTMFRFC2833*>
  669.                                         ( eventPacket->getPayloadLoc() );
  670.     // reset event payload
  671.     eventPayload->event = event; 
  672.     eventPayload->volume = 0x0A;
  673.     eventPayload->reserved = 0;
  674.     eventPayload->edge = 0;
  675.     eventPayload->duration = 0x00A0;
  676.     // send onedge packet
  677.     tran->transmit( eventPacket, true );
  678.     // send on packet
  679.     eventPayload->edge = 1;
  680.     tran->transmit( eventPacket, true );
  681.     // send offedge packet
  682.     eventPacket->setPayloadUsage( 0 );
  683.     tran->transmit( eventPacket, true );
  684.     if( eventPacket )
  685.         delete eventPacket; eventPacket = NULL;
  686.     return 0;
  687. }
  688. RtpPacket* RtpSession::receive ()
  689. {
  690.     if ( !( sessionState == rtp_session_sendrecv
  691.             || sessionState == rtp_session_recvonly ) )
  692.     {
  693.         if (recv) recv->receive();
  694.         sessionError = session_wrongState;
  695.         cpLog (LOG_ERR, "RTP stack can't receive. Wrong state");
  696.         return NULL;
  697.     }
  698.     assert (recv);
  699.     sessionError = session_success;
  700.     return recv->receive();
  701. }
  702. RtpPacket* RtpSession::getPacket()
  703. {
  704.     if ( !( sessionState == rtp_session_sendrecv
  705.             || sessionState == rtp_session_recvonly ) )
  706.     {
  707.         if (recv) recv->getPacket();
  708.         sessionError = session_wrongState;
  709.         cpLog (LOG_ERR, "RTP stack can't receive. Wrong state");
  710.         return NULL;
  711.     }
  712.     assert (recv);
  713.     sessionError = session_success;
  714.     return recv->getPacket();
  715. }
  716. /* --- Send and Receive RTCP Functions ----------------------------- */
  717. void RtpSession::processRTCP ()
  718. {
  719.     if (rtcpTran)
  720.     {
  721.         if (checkIntervalRTCP()) transmitRTCP();
  722.     }
  723.     if (rtcpRecv)
  724.     {
  725.         receiveRTCP();
  726.     }
  727.     return ;
  728. }
  729. int RtpSession::transmitRTCP ()
  730. {
  731.     if ( !( sessionState == rtp_session_sendrecv
  732.             || sessionState == rtp_session_sendonly ) )
  733.     {
  734.         sessionError = session_wrongState;
  735.         cpLog (LOG_ERR, "RTCP stack can't transmit. Wrong state");
  736.         return -1;
  737.     }
  738.     assert (rtcpTran);
  739.     // generate compound packet
  740.     RtcpPacket* p = new RtcpPacket();
  741.     // load with report packet
  742.     rtcpTran->addSR(p);
  743.     // load with SDES information
  744.     // currently only sender sends SDES, recv only receiver doesn't
  745.     if (tran) rtcpTran->addSDES(p);
  746.     // transmit packet
  747.     int ret = rtcpTran->transmit(p);
  748.     if (p) delete p;
  749.     return ret;
  750. }
  751. int RtpSession::transmitRTCPBYE ()
  752. {
  753.     assert (rtcpTran);
  754.     // generate compound packet
  755.     RtcpPacket* p = new RtcpPacket();
  756.     // load with report packet
  757.     rtcpTran->addSR(p);
  758.     // load with SDES CNAME
  759.     if (tran) rtcpTran->addSDES(p, rtcpSdesCname);
  760.     // load with BYE packet
  761.     if (tran)
  762.     {
  763.         char reason[] = "Program Ended.";
  764.         rtcpTran->addBYE(p, reason);
  765.     }
  766.     // transmit packet
  767.     int ret = rtcpTran->transmit(p);
  768.     if (p) delete p;
  769.     return ret;
  770. }
  771. int RtpSession::receiveRTCP ()
  772. {
  773.     if ( !( sessionState == rtp_session_sendrecv
  774.             || sessionState == rtp_session_recvonly ) )
  775.     {
  776.         RtcpPacket* p1 = rtcpRecv->getPacket();
  777.         if (p1) delete p1;
  778.         sessionError = session_wrongState;
  779.         cpLog (LOG_ERR, "RTCP stack can't receive. Wrong state");
  780.         return -1;
  781.     }
  782.     assert (rtcpRecv);
  783.     // generate compound packet
  784.     RtcpPacket* p = rtcpRecv->getPacket();
  785.     if (p == NULL) return -1;
  786.     int ret = 0;
  787.     // read compound packet
  788.     if (rtcpRecv->readRTCP(p) == 1)
  789.     {
  790.        ret = 1;
  791.     }
  792.     if (p) delete p;
  793.     return ret;
  794. }
  795. int RtpSession::checkIntervalRTCP ()
  796. {
  797.     assert (rtcpTran);
  798.     return rtcpTran->checkInterval();
  799. }
  800. /* --- DTMF Callback functions ------------------------------------- */
  801. void RtpSession::setDTMFInterface( DTMFInterface* t )
  802. {
  803.     if ( !recv )
  804.         cpLog(LOG_ERR, "RTP receiver not set, can't set DTMF Interface");
  805.     else
  806.         recv->setDTMFInterface( t );
  807. }
  808. void RtpSession::unsetDTMFInterface( DTMFInterface* t )
  809. {
  810.     if ( !recv )
  811.         cpLog(LOG_ERR, "RTP receiver not set, can't unset DTMF Interface");
  812.     else
  813.         recv->unsetDTMFInterface( t );
  814. }