RtpSession.cxx
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:26k
- /* ====================================================================
- * The Vovida Software License, Version 1.0
- *
- * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The names "VOCAL", "Vovida Open Communication Application Library",
- * and "Vovida Open Communication Application Library (VOCAL)" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact vocal@vovida.org.
- *
- * 4. Products derived from this software may not be called "VOCAL", nor
- * may "VOCAL" appear in their name, without prior written
- * permission of Vovida Networks, Inc.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
- * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
- * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
- * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * ====================================================================
- *
- * This software consists of voluntary contributions made by Vovida
- * Networks, Inc. and many individuals on behalf of Vovida Networks,
- * Inc. For more information on Vovida Networks, Inc., please see
- * <http://www.vovida.org/>.
- *
- */
- static const char* const RtpSession_cxx_Version =
- "$Id: RtpSession.cxx,v 1.53 2001/05/07 19:12:50 kle Exp $";
- #include <iostream>
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <sys/socket.h>
- #include <sys/types.h>
- #include "vtypes.h"
- #include "cpLog.h"
- #include "vsock.hxx"
- #include "rtpTypes.h"
- #include "Rtp.hxx"
- #include "Rtcp.hxx"
- #include "RtpSession.hxx"
- /* ----------------------------------------------------------------- */
- /* --- rtp session Constructor ------------------------------------- */
- /* ----------------------------------------------------------------- */
- RtpSession::RtpSession (const char* remoteHost, int remotePort, int localPort,
- int rtcpRemotePort, int rtcpLocalPort, int portRange,
- RtpPayloadType apiPayloadType,
- RtpPayloadType networkPayloadType, int jitterNew)
- {
- constructRtpSession (remoteHost, remotePort, localPort, rtcpRemotePort,
- rtcpLocalPort, portRange, apiPayloadType,
- networkPayloadType, jitterNew);
- }
- RtpSession::RtpSession (const char* remoteHost, int remotePort, int localPort,
- int rtcpRemotePort, int rtcpLocalPort,
- RtpPayloadType apiPayloadType,
- RtpPayloadType networkPayloadType, int jitterNew)
- {
- constructRtpSession (remoteHost, remotePort, localPort, rtcpRemotePort,
- rtcpLocalPort, 0, apiPayloadType,
- networkPayloadType, jitterNew);
- }
- void RtpSession::constructRtpSession (const char* remoteHost,
- int remotePort, int localPort,
- int rtcpRemotePort, int rtcpLocalPort,
- int portRange, RtpPayloadType apiPayloadType,
- RtpPayloadType networkPayloadType,
- int jitterNew)
- {
- recv = NULL; tran = NULL;
- rtcpTran = NULL, rtcpRecv = NULL;
- if (localPort != 0)
- {
- if (portRange != 0)
- recv = new RtpReceiver (localPort, localPort + portRange,
- apiPayloadType, networkPayloadType,
- jitterNew);
- else
- recv = new RtpReceiver (localPort, apiPayloadType,
- networkPayloadType, jitterNew);
- }
- if (remotePort != 0)
- {
- if (portRange != 0)
- tran = new RtpTransmitter (remoteHost, remotePort,
- remotePort + portRange, apiPayloadType,
- networkPayloadType, recv);
- else
- tran = new RtpTransmitter (remoteHost, remotePort, apiPayloadType,
- networkPayloadType, recv);
- }
- if (rtcpLocalPort != 0)
- {
- if (portRange != 0)
- rtcpRecv = new RtcpReceiver (rtcpLocalPort,
- rtcpLocalPort + portRange);
- else
- rtcpRecv = new RtcpReceiver (rtcpLocalPort);
- }
- if (rtcpRemotePort != 0)
- {
- if (portRange != 0)
- rtcpTran = new RtcpTransmitter (remoteHost, rtcpRemotePort,
- rtcpRemotePort + portRange, rtcpRecv);
- else
- rtcpTran = new RtcpTransmitter (remoteHost,
- rtcpRemotePort, rtcpRecv);
- }
- // update interlinks
- if (rtcpTran && tran) rtcpTran->setRTPtran (tran);
- if (rtcpTran && recv) rtcpTran->setRTPrecv (recv);
- if (rtcpTran && rtcpRecv) rtcpTran->setRTCPrecv (rtcpRecv);
- if (rtcpRecv && recv) recv->setRTCPrecv(rtcpRecv);
- // SDES infromation for transmitter
- if (rtcpTran && tran)
- {
- char dummy[2] = "";
- rtcpTran->setSdesCname();
- rtcpTran->setSdesName(dummy);
- rtcpTran->setSdesEmail(dummy);
- rtcpTran->setSdesPhone(dummy);
- rtcpTran->setSdesLoc(dummy);
- rtcpTran->setSdesTool(dummy);
- rtcpTran->setSdesNote(dummy);
- }
- // session states
- // Currently the states are for RTP stack only, not for RTCP
- if (tran && recv)
- {
- sessionState = rtp_session_sendrecv;
- recv->getUdpStack()->setMode(sendrecv);
- }
- else if (tran && !recv)
- {
- sessionState = rtp_session_sendonly;
- tran->getUdpStack()->setMode(sendonly);
- }
- else if (recv && !tran)
- {
- sessionState = rtp_session_recvonly;
- recv->getUdpStack()->setMode(recvonly);
- }
- else
- {
- cpLog (LOG_DEBUG_STACK, "Session undefined");
- sessionState = rtp_session_undefined;
- }
- if (tran) cpLog (LOG_DEBUG_STACK, "RTP Tran Port: %d",
- tran->getUdpStack()->getDestinationPort());
- if (recv) cpLog (LOG_DEBUG_STACK, "RTP Recv Port: %d", recv->getPort());
- if (rtcpTran) cpLog (LOG_DEBUG_STACK, "RTCP Tran Port: %d",
- rtcpTran->getUdpStack()->getDestinationPort());
- if (rtcpRecv) cpLog (LOG_DEBUG_STACK, "RTCP Recv Port: %d",
- rtcpRecv->getPort());
- }
- RtpSession::~RtpSession ()
- {
- if( rtcpTran )
- {
- delete rtcpTran;
- rtcpTran = NULL;
- }
- if( rtcpRecv )
- {
- delete rtcpRecv;
- rtcpRecv = NULL;
- }
- if( tran )
- {
- delete tran;
- tran = NULL;
- }
- if( recv )
- {
- delete recv;
- recv = NULL;
- }
- }
- int
- RtpSession::reserveRtpPort(int localMin, int localMax)
- {
- int port = 0;
- if ( recv == 0 )
- {
- try
- {
- //let RtpReceiver() automatically generate a port number
- recv = new RtpReceiver(localMin, localMax);
- port = recv->getPort();
- }
- catch ( UdpStackExceptionPortsInUse& exception )
- {
- if ( localMin == localMax )
- cpLog( LOG_ERR, "port %d is not available", localMin );
- else
- cpLog( LOG_ERR, "No ports between %d and %d are available", localMin, localMax);
- recv = 0;
- }
- }
- else
- {
- port = recv->getPort();
- }
- return port;
- }
- int
- RtpSession::releaseRtpPort()
- {
- int port = 0;
- if ( recv != 0 )
- {
- port = recv->getPort();
- delete recv;
- recv = 0;
- }
- return port;
- }
- int
- RtpSession::reserveRtcpPort(int rtcpLocalPort, int portRange)
- {
- int port = 0;
- if ( rtcpRecv == 0 )
- {
- try
- {
- if (rtcpLocalPort != 0)
- {
- if (portRange != 0)
- rtcpRecv = new RtcpReceiver (rtcpLocalPort,
- rtcpLocalPort + portRange);
- else
- rtcpRecv = new RtcpReceiver (rtcpLocalPort);
- }
- port = rtcpRecv->getPort();
- }
- catch ( UdpStackExceptionPortsInUse& exception )
- {
- if ( portRange == 0 )
- cpLog( LOG_ERR, "port %d is not available", rtcpLocalPort );
- else
- cpLog( LOG_ERR, "no ports between %d and %d are available", rtcpLocalPort, rtcpLocalPort + portRange );
- rtcpRecv = 0;
- }
- }
- else
- {
- port = rtcpRecv->getPort();
- }
- return port;
- }
- int
- RtpSession::releaseRtcpPort()
- {
- int port = 0;
- if ( rtcpRecv != 0 )
- {
- port = rtcpRecv->getPort();
- delete rtcpRecv;
- rtcpRecv = 0;
- }
- return port;
- }
- /* --- Send and Receive RTP Functions ------------------------------ */
- void RtpSession::setNetworkFormat (RtpPayloadType type, int no_samples, int packetSize)
- {
- if (tran) tran->setNetworkFormat (type, no_samples, packetSize);
- if (recv) recv->setNetworkFormat (type, no_samples, packetSize);
- }
- void RtpSession::setApiFormat (RtpPayloadType type, int no_samples, int packetSize)
- {
- if (tran) tran->setApiFormat (type, no_samples, packetSize);
- if (recv) recv->setApiFormat (type, no_samples, packetSize);
- }
- void RtpSession::setNetworkPktSize (int no_samples)
- {
- setNetworkPktSampleSize (no_samples);
- }
- void RtpSession::setNetworkPktSampleSize (int no_samples)
- {
- if (tran) tran->setNetworkPktSize (no_samples);
- if (recv) recv->setNetworkPktSize (no_samples);
- }
- void RtpSession::setApiPktSize (int no_samples)
- {
- setApiPktSampleSize (no_samples);
- }
- void RtpSession::setApiPktSampleSize (int no_samples)
- {
- if (tran) tran->setApiPktSize (no_samples);
- if (recv) recv->setApiPktSize (no_samples);
- }
- int RtpSession::getNetworkPktSampleSize ()
- {
- if (tran)
- return tran->getNetworkPktSampleSize ();
- else
- return 0;
- }
- int RtpSession::getApiPktSampleSize ()
- {
- if (recv)
- return recv->getApiPktSampleSize();
- else
- return 0;
- }
- // If there are multiple dests, the return will be the total
- // of all dests. - ?
- int RtpSession::getPacketSent ()
- {
- if (tran)
- return tran->getPacketSent ();
- else
- return 0;
- }
- // If there are multiple dests, the return will be the total
- // of all dests. - ?
- int RtpSession::getByteSent ()
- {
- if (tran)
- return tran->getPayloadSent ();
- else
- return 0;
- }
- // If there are multiple srcs, the return will be the total
- // of all srcs. - ?
- int RtpSession::getPacketReceived ()
- {
- if (recv)
- return recv->getPacketReceived ();
- else
- return 0;
- }
- // If there are multiple srcs, the return will be the total
- // of all srcs. - ?
- int RtpSession::getByteReceived ()
- {
- if (recv)
- return recv->getPayloadReceived ();
- else
- return 0;
- }
- // If there are multiple srcs, this func returns the packect lost
- // for all the srcs
- int RtpSession::getPacketLost ()
- {
- if (rtcpTran)
- {
- if (rtcpRecv)
- {
- int lost = 0;
- for (int i = 0; i < (rtcpRecv->getTranInfoCount()); i++)
- {
- lost += rtcpTran->calcLostCount(rtcpRecv->getTranInfoList(i));
- }
- return lost;
- }
- }
- return 0;
- }
- // If there are multiple srcs, this func returns the jitter
- // calculation results accumulated by all srcs
- int RtpSession::getJitter ()
- {
- if (recv)
- {
- return (recv->getJitter() >> 4);
- }
- return 0;
- }
- // If there are multiple srcs, what this func returns
- // is not clear - ?
- int RtpSession::getLatency ()
- {
- if (rtcpRecv)
- {
- return (rtcpRecv->getAvgOneWayDelay());
- // return (rtcpRecv->getAvgRoundTripDelay());
- }
- return 0;
- }
- void RtpSession::setSessionState (RtpSessionState state)
- {
- switch (state)
- {
- case (rtp_session_inactive):
- if (recv) recv->getUdpStack()->setMode(inactive);
- else if (tran) tran->getUdpStack()->setMode(inactive);
- sessionState = state;
- break;
- case (rtp_session_sendonly):
- if (recv) recv->getUdpStack()->setMode(sendonly);
- else if (tran) tran->getUdpStack()->setMode(sendonly);
- sessionState = state;
- break;
- case (rtp_session_recvonly):
- if (recv) recv->getUdpStack()->setMode(recvonly);
- else if (tran) tran->getUdpStack()->setMode(recvonly);
- sessionState = state;
- break;
- case (rtp_session_sendrecv):
- if (recv) recv->getUdpStack()->setMode(sendrecv);
- else if (tran) tran->getUdpStack()->setMode(sendrecv);
- sessionState = state;
- break;
- case (rtp_session_undefined):
- sessionState = state;
- break;
- default:
- cpLog (LOG_ERR, "Unknown state: %d", (int)state);
- assert (0);
- }
- if (recv) recv->emptyNetwork();
- }
- RtpSessionState RtpSession::getSessionState ()
- {
- return sessionState;
- }
- int
- RtpSession::setReceiver ( int localPort, int rtcpLocalPort, int portRange,
- RtpPayloadType apiFormat,
- RtpPayloadType networkFormat,
- int jitterNew /* = 5 */)
- {
- if ( !(sessionState == rtp_session_sendrecv
- || sessionState == rtp_session_recvonly) )
- {
- cpLog(LOG_ERR, "wrong state of RTP stack.");
- return -1;
- }
- if (localPort != 0)
- {
- if (portRange != 0)
- {
- if (recv)
- {
- assert (recv->getUdpStack());
- recv->getUdpStack()->setLocal(localPort, localPort + portRange);
- }
- else if (tran)
- {
- assert (tran->getUdpStack());
- tran->getUdpStack()->setLocal(localPort, localPort + portRange);
- recv = new RtpReceiver(tran->getUdpStack(), apiFormat,
- networkFormat, jitterNew);
- }
- else
- recv = new RtpReceiver (localPort, localPort + portRange,
- apiFormat, networkFormat,
- jitterNew);
- }
- else
- if (recv)
- {
- assert (recv->getUdpStack());
- recv->getUdpStack()->setLocal(localPort, localPort + portRange);
- }
- else if (tran)
- {
- assert (tran->getUdpStack());
- tran->getUdpStack()->setLocal(localPort, localPort + portRange);
- recv = new RtpReceiver(tran->getUdpStack(), apiFormat,
- networkFormat, jitterNew);
- }
- else
- recv = new RtpReceiver (localPort, apiFormat,
- networkFormat, jitterNew);
- }
- if (rtcpLocalPort != 0)
- {
- if (portRange != 0)
- if (rtcpRecv)
- {
- assert (rtcpRecv->getUdpStack());
- rtcpRecv->getUdpStack()->setLocal(rtcpLocalPort,
- rtcpLocalPort + portRange);
- }
- else if (rtcpTran)
- {
- assert (rtcpTran->getUdpStack());
- rtcpTran->getUdpStack()->setLocal(rtcpLocalPort,
- rtcpLocalPort + portRange);
- rtcpRecv = new RtcpReceiver(rtcpTran->getUdpStack());
- }
- else
- rtcpRecv = new RtcpReceiver (rtcpLocalPort,
- rtcpLocalPort + portRange);
- else
- if (rtcpRecv)
- {
- assert(rtcpRecv->getUdpStack());
- rtcpRecv->getUdpStack()->setLocal(rtcpLocalPort);
- }
- else if (rtcpTran)
- {
- assert(rtcpTran->getUdpStack());
- rtcpTran->getUdpStack()->setLocal(rtcpLocalPort);
- rtcpRecv = new RtcpReceiver(rtcpTran->getUdpStack());
- }
- else
- rtcpRecv = new RtcpReceiver (rtcpLocalPort);
- }
- // update interlinks
- if (rtcpTran && recv) rtcpTran->setRTPrecv (recv);
- if (rtcpTran && rtcpRecv) rtcpTran->setRTCPrecv (rtcpRecv);
- if (rtcpRecv && recv) recv->setRTCPrecv(rtcpRecv);
- if (recv) cpLog (LOG_DEBUG_STACK, "RTP Recv Port: %d", recv->getPort());
- if (rtcpRecv) cpLog (LOG_DEBUG_STACK, "RTCP Recv Port: %d",
- rtcpRecv->getPort());
- return 0;
- }
- int
- RtpSession::setTransmiter ( const char* remoteHost, int remotePort,
- int rtcpRemotePort,
- RtpPayloadType apiFormat,
- RtpPayloadType networkFormat )
- {
- if ( !(sessionState == rtp_session_sendrecv
- || sessionState == rtp_session_sendonly) )
- {
- cpLog(LOG_ERR, "wrong state of RTP stack.");
- return -1;
- }
- if (remotePort != 0)
- {
- if (tran)
- {
- tran->getUdpStack()->setDestination(remoteHost, remotePort);
- NetworkAddress netAddress;
- if ( remoteHost )
- {
- netAddress.setPort(remotePort);
- netAddress.setHostName(remoteHost);
- }
- tran->setRemoteAddr(netAddress);
- }
- else
- tran = new RtpTransmitter ( remoteHost, remotePort, apiFormat,
- networkFormat, recv);
- }
- if (rtcpRemotePort != 0)
- {
- if (rtcpTran)
- {
- rtcpTran->getUdpStack()->setDestination( remoteHost,
- rtcpRemotePort);
- NetworkAddress netAddress1;
- if ( remoteHost )
- {
- netAddress1.setPort(rtcpRemotePort);
- netAddress1.setHostName(remoteHost);
- }
- rtcpTran->setRemoteAddr(netAddress1);
- }
- else
- rtcpTran = new RtcpTransmitter ( remoteHost,
- rtcpRemotePort, rtcpRecv);
- }
- // update interlinks
- if (rtcpTran && tran) rtcpTran->setRTPtran (tran);
- if (rtcpTran && recv) rtcpTran->setRTPrecv (recv);
- if (rtcpTran && rtcpRecv) rtcpTran->setRTCPrecv (rtcpRecv);
- // SDES infromation for transmitter
- if (rtcpTran && tran)
- {
- char dummy[2]= "";
- rtcpTran->setSdesCname();
- rtcpTran->setSdesEmail(dummy);
- rtcpTran->setSdesPhone(dummy);
- rtcpTran->setSdesLoc(dummy);
- rtcpTran->setSdesTool(dummy);
- rtcpTran->setSdesNote(dummy);
- }
- if (tran) cpLog (LOG_DEBUG_STACK, "RTP Tran Port: %d",
- tran->getUdpStack()->getDestinationPort());
- if (rtcpTran) cpLog (LOG_DEBUG_STACK, "RTCP Tran Port: %d",
- rtcpTran->getUdpStack()->getDestinationPort());
- return 0;
- }
- /* --- Send and Receive RTP Functions ------------------------------ */
- RtpPacket* RtpSession::createPacket (int npadSize, int csrcCount)
- {
- assert (tran);
- if (npadSize != 0)
- cpLog(LOG_DEBUG, "Nonzero npadSize not supported");
- return tran->createPacket(npadSize, csrcCount);
- }
- RtpSeqNumber RtpSession::getPrevSequence ()
- {
- assert (tran);
- return tran->getPrevSequence ();
- }
- RtpTime RtpSession::getPrevRtpTime ()
- {
- assert (tran);
- return tran->getPrevRtpTime();
- }
- void RtpSession::setMarkerOnce()
- {
- if( tran )
- {
- tran->setMarkerOnce();
- }
- }
- int RtpSession::transmit (RtpPacket* p)
- {
- if ( !( sessionState == rtp_session_sendrecv
- || sessionState == rtp_session_sendonly ) )
- {
- sessionError = session_wrongState;
- cpLog (LOG_ERR, "RTP stack can't transmit. Wrong state");
- return -1;
- }
- assert (tran);
- sessionError = session_success;
- return tran->transmit(p);
- }
- int RtpSession::transmitRaw (char* inbuffer, int len)
- {
- if ( !( sessionState == rtp_session_sendrecv
- || sessionState == rtp_session_sendonly ) )
- {
- sessionError = session_wrongState;
- cpLog (LOG_ERR, "RTP stack can't transmit. Wrong state");
- return -1;
- }
- assert (tran);
- sessionError = session_success;
- return tran->transmitRaw(inbuffer, len);
- }
- int RtpSession::transmitEvent( int event )
- {
- if ( !( sessionState == rtp_session_sendrecv
- || sessionState == rtp_session_sendonly ) )
- {
- sessionError = session_wrongState;
- cpLog (LOG_ERR, "RTP stack can't transmit event. Wrong state");
- return -1;
- }
- cpLog( LOG_DEBUG_STACK,"Sending DTMF event %d in RTP stream", event );
- assert (tran);
- sessionError = session_success;
- RtpPacket* eventPacket = createPacket(0, 0);
- eventPacket->setPayloadType( rtpPayloadDTMF_RFC2833 );
- eventPacket->setPayloadUsage( sizeof( RtpEventDTMFRFC2833 ) );
- RtpEventDTMFRFC2833* eventPayload = reinterpret_cast<RtpEventDTMFRFC2833*>
- ( eventPacket->getPayloadLoc() );
- // reset event payload
- eventPayload->event = event;
- eventPayload->volume = 0x0A;
- eventPayload->reserved = 0;
- eventPayload->edge = 0;
- eventPayload->duration = 0x00A0;
- // send onedge packet
- tran->transmit( eventPacket, true );
- // send on packet
- eventPayload->edge = 1;
- tran->transmit( eventPacket, true );
- // send offedge packet
- eventPacket->setPayloadUsage( 0 );
- tran->transmit( eventPacket, true );
- if( eventPacket )
- delete eventPacket; eventPacket = NULL;
- return 0;
- }
- RtpPacket* RtpSession::receive ()
- {
- if ( !( sessionState == rtp_session_sendrecv
- || sessionState == rtp_session_recvonly ) )
- {
- if (recv) recv->receive();
- sessionError = session_wrongState;
- cpLog (LOG_ERR, "RTP stack can't receive. Wrong state");
- return NULL;
- }
- assert (recv);
- sessionError = session_success;
- return recv->receive();
- }
- RtpPacket* RtpSession::getPacket()
- {
- if ( !( sessionState == rtp_session_sendrecv
- || sessionState == rtp_session_recvonly ) )
- {
- if (recv) recv->getPacket();
- sessionError = session_wrongState;
- cpLog (LOG_ERR, "RTP stack can't receive. Wrong state");
- return NULL;
- }
- assert (recv);
- sessionError = session_success;
- return recv->getPacket();
- }
- /* --- Send and Receive RTCP Functions ----------------------------- */
- void RtpSession::processRTCP ()
- {
- if (rtcpTran)
- {
- if (checkIntervalRTCP()) transmitRTCP();
- }
- if (rtcpRecv)
- {
- receiveRTCP();
- }
- return ;
- }
- int RtpSession::transmitRTCP ()
- {
- if ( !( sessionState == rtp_session_sendrecv
- || sessionState == rtp_session_sendonly ) )
- {
- sessionError = session_wrongState;
- cpLog (LOG_ERR, "RTCP stack can't transmit. Wrong state");
- return -1;
- }
- assert (rtcpTran);
- // generate compound packet
- RtcpPacket* p = new RtcpPacket();
- // load with report packet
- rtcpTran->addSR(p);
- // load with SDES information
- // currently only sender sends SDES, recv only receiver doesn't
- if (tran) rtcpTran->addSDES(p);
- // transmit packet
- int ret = rtcpTran->transmit(p);
- if (p) delete p;
- return ret;
- }
- int RtpSession::transmitRTCPBYE ()
- {
- assert (rtcpTran);
- // generate compound packet
- RtcpPacket* p = new RtcpPacket();
- // load with report packet
- rtcpTran->addSR(p);
- // load with SDES CNAME
- if (tran) rtcpTran->addSDES(p, rtcpSdesCname);
- // load with BYE packet
- if (tran)
- {
- char reason[] = "Program Ended.";
- rtcpTran->addBYE(p, reason);
- }
- // transmit packet
- int ret = rtcpTran->transmit(p);
- if (p) delete p;
- return ret;
- }
- int RtpSession::receiveRTCP ()
- {
- if ( !( sessionState == rtp_session_sendrecv
- || sessionState == rtp_session_recvonly ) )
- {
- RtcpPacket* p1 = rtcpRecv->getPacket();
- if (p1) delete p1;
- sessionError = session_wrongState;
- cpLog (LOG_ERR, "RTCP stack can't receive. Wrong state");
- return -1;
- }
- assert (rtcpRecv);
- // generate compound packet
- RtcpPacket* p = rtcpRecv->getPacket();
- if (p == NULL) return -1;
- int ret = 0;
- // read compound packet
- if (rtcpRecv->readRTCP(p) == 1)
- {
- ret = 1;
- }
- if (p) delete p;
- return ret;
- }
- int RtpSession::checkIntervalRTCP ()
- {
- assert (rtcpTran);
- return rtcpTran->checkInterval();
- }
- /* --- DTMF Callback functions ------------------------------------- */
- void RtpSession::setDTMFInterface( DTMFInterface* t )
- {
- if ( !recv )
- cpLog(LOG_ERR, "RTP receiver not set, can't set DTMF Interface");
- else
- recv->setDTMFInterface( t );
- }
- void RtpSession::unsetDTMFInterface( DTMFInterface* t )
- {
- if ( !recv )
- cpLog(LOG_ERR, "RTP receiver not set, can't unset DTMF Interface");
- else
- recv->unsetDTMFInterface( t );
- }