#include <RTCP.h>
Public Member Functions | |
RTCP () | |
Protected Member Functions | |
virtual void | initialize () |
virtual | ~RTCP () |
virtual void | handleMessage (cMessage *msg) |
virtual void | handleMessageFromRTP (cMessage *msg) |
virtual void | handleMessageFromUDP (cMessage *msg) |
virtual void | handleSelfMessage (cMessage *msg) |
virtual void | initializeRTCP (RTPInnerPacket *rinp) |
virtual void | senderModuleInitialized (RTPInnerPacket *rinp) |
virtual void | dataOut (RTPInnerPacket *packet) |
virtual void | dataIn (RTPInnerPacket *rinp) |
virtual void | leaveSession (RTPInnerPacket *rinp) |
virtual void | connectRet () |
virtual void | readRet (cPacket *sifpIn) |
virtual void | createSocket () |
virtual void | chooseSSRC () |
virtual void | scheduleInterval () |
virtual void | createPacket () |
virtual void | processOutgoingRTPPacket (RTPPacket *packet) |
virtual void | processIncomingRTPPacket (RTPPacket *packet, IPAddress address, int port) |
virtual void | processIncomingRTCPPacket (RTCPCompoundPacket *packet, IPAddress address, int port) |
virtual RTPParticipantInfo * | findParticipantInfo (uint32 ssrc) |
virtual void | calculateAveragePacketSize (int size) |
Protected Attributes | |
int | _mtu |
int | _bandwidth |
int | _rtcpPercentage |
IPAddress | _destinationAddress |
int | _port |
bool | _ssrcChosen |
bool | _leaveSession |
RTPSenderInfo * | _senderInfo |
cArray * | _participantInfos |
int | _socketFdIn |
int | _socketFdOut |
int | _packetsCalculated |
double | _averagePacketSize |
cOutVector * | _rtcpIntervalOutVector |
The class RTCP is responsible for creating, receiving and processing of rtcp packets. It also keeps track of this and other rtp end systems.
Definition at line 37 of file RTCP.h.
RTCP::RTCP | ( | ) |
Definition at line 35 of file RTCP.cc.
{ _participantInfos = NULL; }
RTCP::~RTCP | ( | ) | [protected, virtual] |
Definition at line 55 of file RTCP.cc.
{ delete _participantInfos; }
void RTCP::calculateAveragePacketSize | ( | int | size | ) | [protected, virtual] |
Recalculates the average size of an RTCPCompoundPacket when one of this size has been sent or received.
Definition at line 532 of file RTCP.cc.
Referenced by createPacket(), and processIncomingRTCPPacket().
{ // add size of ip and udp header to given size before calculating _averagePacketSize = ((double)(_packetsCalculated) * _averagePacketSize + (double)(size + 20 + 8)) / (double)(++_packetsCalculated); }
void RTCP::chooseSSRC | ( | ) | [protected, virtual] |
Chooses the ssrc identifier for this end system.
Definition at line 247 of file RTCP.cc.
Referenced by handleSelfMessage().
{ uint32 ssrc = 0; bool ssrcConflict = false; do { ssrc = intrand(0x7fffffff); ssrcConflict = findParticipantInfo(ssrc) != NULL; } while (ssrcConflict); ev << "chooseSSRC" << ssrc; _senderInfo->setSSRC(ssrc); _participantInfos->add(_senderInfo); _ssrcChosen = true; }
void RTCP::connectRet | ( | ) | [protected, virtual] |
Called when the socket layer has finished a connect.
Definition at line 186 of file RTCP.cc.
Referenced by createSocket().
{ // schedule first rtcp packet double intervalLength = 2.5 * (dblrand() + 0.5); cMessage *reminderMessage = new cMessage("Interval"); scheduleAt(simTime() + intervalLength, reminderMessage); }
void RTCP::createPacket | ( | ) | [protected, virtual] |
Creates and sends an RTCPCompoundPacket.
Definition at line 262 of file RTCP.cc.
Referenced by handleSelfMessage().
{ // first packet in an rtcp compound packet must // be a sender or receiver report RTCPReceiverReportPacket *reportPacket; // if this rtcp end system is a sender (see SenderInformation::isSender() for // details) insert a sender report if (_senderInfo->isSender()) { RTCPSenderReportPacket *senderReportPacket = new RTCPSenderReportPacket("SenderReportPacket"); senderReportPacket->setSenderReport(_senderInfo->senderReport(simTime())); reportPacket = senderReportPacket; } else reportPacket = new RTCPReceiverReportPacket("ReceiverReportPacket"); reportPacket->setSSRC(_senderInfo->getSSRC()); // insert receiver reports for packets from other sources for (int i = 0; i < _participantInfos->size(); i++) { if (_participantInfos->exist(i)) { RTPParticipantInfo *participantInfo = (RTPParticipantInfo *)(_participantInfos->get(i)); if (participantInfo->getSSRC() != _senderInfo->getSSRC()) { ReceptionReport *report = ((RTPReceiverInfo *)participantInfo)->receptionReport(simTime()); if (report != NULL) { reportPacket->addReceptionReport(report); } } participantInfo->nextInterval(simTime()); if (participantInfo->toBeDeleted(simTime())) { _participantInfos->remove(participantInfo); delete participantInfo; // perhaps inform the profile } } } // insert source description items (at least common name) RTCPSDESPacket *sdesPacket = new RTCPSDESPacket("SDESPacket"); SDESChunk *chunk = _senderInfo->getSDESChunk(); sdesPacket->addSDESChunk(chunk); RTCPCompoundPacket *compoundPacket = new RTCPCompoundPacket("RTCPCompoundPacket"); compoundPacket->addRTCPPacket(reportPacket); compoundPacket->addRTCPPacket(sdesPacket); // create rtcp app/bye packets if needed if (_leaveSession) { RTCPByePacket *byePacket = new RTCPByePacket("ByePacket"); byePacket->setSSRC(_senderInfo->getSSRC()); compoundPacket->addRTCPPacket(byePacket); } calculateAveragePacketSize(compoundPacket->getByteLength()); cPacket *msg = new cPacket("RTCPCompoundPacket"); msg->encapsulate(compoundPacket); msg->setKind(UDP_C_DATA); UDPControlInfo *ctrl = new UDPControlInfo(); ctrl->setSockId(_socketFdOut); ctrl->setDestAddr(_destinationAddress); ctrl->setDestPort(_port); msg->setControlInfo(ctrl); send(msg, "udpOut"); if (_leaveSession) { RTPInnerPacket *rinp = new RTPInnerPacket("sessionLeft()"); rinp->sessionLeft(); send(rinp, "rtpOut"); } }
void RTCP::createSocket | ( | ) | [protected, virtual] |
Request a server socket from the socket layer.
Definition at line 201 of file RTCP.cc.
Referenced by initializeRTCP().
{ // TODO UDPAppBase should be ported to use UDPSocket sometime, but for now // we just manage the UDP socket by hand... if (_socketFdIn == -1) { _socketFdIn = UDPSocket::generateSocketId(); UDPControlInfo *ctrl = new UDPControlInfo(); IPAddress ipaddr(_destinationAddress); if (ipaddr.isMulticast()) { ctrl->setSrcAddr(IPAddress(_destinationAddress)); ctrl->setSrcPort(_port); } else { ctrl->setSrcPort(_port); ctrl->setSockId(_socketFdOut); } ctrl->setSockId((int)_socketFdIn); cMessage *msg = new cMessage("UDP_C_BIND", UDP_C_BIND); msg->setControlInfo(ctrl); send(msg,"udpOut"); connectRet(); } }
void RTCP::dataIn | ( | RTPInnerPacket * | rinp | ) | [protected, virtual] |
Stores information about an outgoing rtp data packet.
Definition at line 172 of file RTCP.cc.
Referenced by handleMessageFromRTP().
{ RTPPacket *rtpPacket = check_and_cast<RTPPacket *>(rinp->decapsulate()); //rtpPacket->dump(); processIncomingRTPPacket(rtpPacket, rinp->getAddress(), rinp->getPort()); }
void RTCP::dataOut | ( | RTPInnerPacket * | packet | ) | [protected, virtual] |
Stores information about an outgoing rtp data packet.
Definition at line 165 of file RTCP.cc.
Referenced by handleMessageFromRTP().
{ RTPPacket *rtpPacket = check_and_cast<RTPPacket *>(packet->decapsulate()); processOutgoingRTPPacket(rtpPacket); }
RTPParticipantInfo * RTCP::findParticipantInfo | ( | uint32 | ssrc | ) | [protected, virtual] |
Returns the RTPParticipantInfo object used for storing information about the rtp end system with this ssrc identifier. Returns NULL if this end system is unknown.
Definition at line 519 of file RTCP.cc.
Referenced by chooseSSRC(), processIncomingRTCPPacket(), and processIncomingRTPPacket().
{ char *ssrcString = RTPParticipantInfo::ssrcToName(ssrc); int participantIndex = _participantInfos->find(ssrcString); if (participantIndex != -1) { return (RTPParticipantInfo *)(_participantInfos->get(participantIndex)); } else { return NULL; } }
void RTCP::handleMessage | ( | cMessage * | msg | ) | [protected, virtual] |
Message handling. Dispatches messages by arrival gate.
Definition at line 60 of file RTCP.cc.
{ // first distinguish incoming messages by arrival gate if (msg->getArrivalGateId() == findGate("rtpIn")) { handleMessageFromRTP(msg); } else if (msg->getArrivalGateId() == findGate("udpIn")) { handleMessageFromUDP(msg); } else { handleSelfMessage(msg); } delete msg; }
void RTCP::handleMessageFromRTP | ( | cMessage * | msg | ) | [protected, virtual] |
Handles messages from the rtp module.
Definition at line 81 of file RTCP.cc.
Referenced by handleMessage().
{ // from the rtp module all messages are of type RTPInnerPacket RTPInnerPacket *rinp = check_and_cast<RTPInnerPacket *>(msg); // distinguish by type if (rinp->getType() == RTPInnerPacket::RTP_INP_INITIALIZE_RTCP) { initializeRTCP(rinp); } else if (rinp->getType() == RTPInnerPacket::RTP_INP_SENDER_MODULE_INITIALIZED) { senderModuleInitialized(rinp); } else if (rinp->getType() == RTPInnerPacket::RTP_INP_DATA_OUT) { dataOut(rinp); } else if (rinp->getType() == RTPInnerPacket::RTP_INP_DATA_IN) { dataIn(rinp); } else if (rinp->getType() == RTPInnerPacket::RTP_INP_LEAVE_SESSION) { leaveSession(rinp); } else { error("unknown RTPInnerPacket type"); } }
void RTCP::handleMessageFromUDP | ( | cMessage * | msg | ) | [protected, virtual] |
Handles messages coming from the socket layer.
Definition at line 109 of file RTCP.cc.
Referenced by handleMessage().
void RTCP::handleSelfMessage | ( | cMessage * | msg | ) | [protected, virtual] |
Handles self messages.
Definition at line 116 of file RTCP.cc.
Referenced by handleMessage().
{ // it's time to create an rtcp packet if (!_ssrcChosen) { chooseSSRC(); RTPInnerPacket *rinp1 = new RTPInnerPacket("rtcpInitialized()"); rinp1->rtcpInitialized(_senderInfo->getSSRC()); send(rinp1, "rtpOut"); } createPacket(); if (!_leaveSession) { scheduleInterval(); } }
void RTCP::initialize | ( | ) | [protected, virtual] |
Initializes variables.
Definition at line 40 of file RTCP.cc.
{ // initialize variables _ssrcChosen = false; _leaveSession = false; _socketFdIn = -1; _socketFdOut = -1; _packetsCalculated = 0; _averagePacketSize = 0.0; _participantInfos = new cArray("ParticipantInfos"); }
void RTCP::initializeRTCP | ( | RTPInnerPacket * | rinp | ) | [protected, virtual] |
Initializes the rtcp module when the session is started.
Definition at line 137 of file RTCP.cc.
Referenced by handleMessageFromRTP().
{ _mtu = rinp->getMTU(); _bandwidth = rinp->getBandwidth(); _rtcpPercentage = rinp->getRtcpPercentage(); _destinationAddress = rinp->getAddress(); _port = rinp->getPort(); _senderInfo = new RTPSenderInfo(); SDESItem *sdesItem = new SDESItem(SDESItem::SDES_CNAME, rinp->getCommonName()); _senderInfo->addSDESItem(sdesItem); // create server socket for receiving rtcp packets createSocket(); }
void RTCP::leaveSession | ( | RTPInnerPacket * | rinp | ) | [protected, virtual] |
Makes the rtcp module send an RTCPByePacket in the next RTCPCompoundPacket to tell other participants in the rtp session that this end system leaves.
Definition at line 180 of file RTCP.cc.
Referenced by handleMessageFromRTP().
{ _leaveSession = true; }
void RTCP::processIncomingRTCPPacket | ( | RTCPCompoundPacket * | packet, | |
IPAddress | address, | |||
int | port | |||
) | [protected, virtual] |
Extracts information of a received RTCPCompoundPacket.
Definition at line 371 of file RTCP.cc.
Referenced by readRet().
{ calculateAveragePacketSize(packet->getByteLength()); cArray *rtcpPackets = packet->getRtcpPackets(); simtime_t arrivalTime = packet->getArrivalTime(); delete packet; for (int i = 0; i < rtcpPackets->size(); i++) { if (rtcpPackets->exist(i)) { // remove the rtcp packet from the rtcp compound packet RTCPPacket *rtcpPacket = (RTCPPacket *)(rtcpPackets->remove(i)); if (rtcpPacket->getPacketType() == RTCPPacket::RTCP_PT_SR) { RTCPSenderReportPacket *rtcpSenderReportPacket = (RTCPSenderReportPacket *)rtcpPacket; uint32 ssrc = rtcpSenderReportPacket->getSSRC(); RTPParticipantInfo *participantInfo = findParticipantInfo(ssrc); if (participantInfo == NULL) { participantInfo = new RTPReceiverInfo(ssrc); participantInfo->setAddress(address); participantInfo->setRTCPPort(port); _participantInfos->add(participantInfo); } else { if (participantInfo->getAddress() == address) { if (participantInfo->getRTCPPort() == PORT_UNDEF) { participantInfo->setRTCPPort(port); } else { // check for ssrc conflict } } else { // check for ssrc conflict } } participantInfo->processSenderReport(rtcpSenderReportPacket->getSenderReport(), simTime()); cArray *receptionReports = rtcpSenderReportPacket->getReceptionReports(); for (int j = 0; j < receptionReports->size(); j++) { if (receptionReports->exist(j)) { ReceptionReport *receptionReport = (ReceptionReport *)(receptionReports->remove(j)); if (_senderInfo) { if (receptionReport->getSSRC() == _senderInfo->getSSRC()) { _senderInfo->processReceptionReport(receptionReport, simTime()); } } else //cancelAndDelete(receptionReport); delete receptionReport; } } delete receptionReports; } else if (rtcpPacket->getPacketType() == RTCPPacket::RTCP_PT_RR) { RTCPReceiverReportPacket *rtcpReceiverReportPacket = (RTCPReceiverReportPacket *)rtcpPacket; uint32 ssrc = rtcpReceiverReportPacket->getSSRC(); RTPParticipantInfo *participantInfo = findParticipantInfo(ssrc); if (participantInfo == NULL) { participantInfo = new RTPReceiverInfo(ssrc); participantInfo->setAddress(address); participantInfo->setRTCPPort(port); _participantInfos->add(participantInfo); } else { if (participantInfo->getAddress() == address) { if (participantInfo->getRTCPPort() == PORT_UNDEF) { participantInfo->setRTCPPort(port); } else { // check for ssrc conflict } } else { // check for ssrc conflict } } cArray *receptionReports = rtcpReceiverReportPacket->getReceptionReports(); for (int j = 0; j < receptionReports->size(); j++) { if (receptionReports->exist(j)) { ReceptionReport *receptionReport = (ReceptionReport *)(receptionReports->remove(j)); if (_senderInfo) { if (receptionReport->getSSRC() == _senderInfo->getSSRC()) { _senderInfo->processReceptionReport(receptionReport, simTime()); } } else //cancelAndDelete(receptionReport); delete receptionReport; } } delete receptionReports; } else if (rtcpPacket->getPacketType() == RTCPPacket::RTCP_PT_SDES) { RTCPSDESPacket *rtcpSDESPacket = (RTCPSDESPacket *)rtcpPacket; cArray *sdesChunks = rtcpSDESPacket->getSdesChunks(); for (int j = 0; j < sdesChunks->size(); j++) { if (sdesChunks->exist(j)) { // remove the sdes chunk from the cArray of sdes chunks SDESChunk *sdesChunk = (SDESChunk *)(sdesChunks->remove(j)); // this is needed to avoid seg faults //sdesChunk->setOwner(this); uint32 ssrc = sdesChunk->getSSRC(); RTPParticipantInfo *participantInfo = findParticipantInfo(ssrc); if (participantInfo == NULL) { participantInfo = new RTPReceiverInfo(ssrc); participantInfo->setAddress(address); participantInfo->setRTCPPort(port); _participantInfos->add(participantInfo); } else { // check for ssrc conflict } participantInfo->processSDESChunk(sdesChunk, arrivalTime); } } delete sdesChunks; } else if (rtcpPacket->getPacketType() == RTCPPacket::RTCP_PT_BYE) { RTCPByePacket *rtcpByePacket = (RTCPByePacket *)rtcpPacket; uint32 ssrc = rtcpByePacket->getSSRC(); RTPParticipantInfo *participantInfo = findParticipantInfo(ssrc); if (participantInfo != NULL && participantInfo != _senderInfo) { _participantInfos->remove(participantInfo); delete participantInfo; // perhaps it would be useful to inform // the profile to remove the corresponding // receiver module } } else { // app rtcp packets } delete rtcpPacket; } } delete rtcpPackets; }
void RTCP::processIncomingRTPPacket | ( | RTPPacket * | packet, | |
IPAddress | address, | |||
int | port | |||
) | [protected, virtual] |
Extracts information of a received RTPPacket.
Definition at line 345 of file RTCP.cc.
Referenced by dataIn().
{ uint32 ssrc = packet->getSSRC(); RTPParticipantInfo *participantInfo = findParticipantInfo(ssrc); if (participantInfo == NULL) { participantInfo = new RTPParticipantInfo(ssrc); participantInfo->setAddress(address); participantInfo->setRTPPort(port); _participantInfos->add(participantInfo); } else { // check for ssrc conflict if (participantInfo->getAddress() != address) { // we have an address conflict } if (participantInfo->getRTPPort() == PORT_UNDEF) { participantInfo->setRTPPort(port); } else if (participantInfo->getRTPPort() != port) { // we have an rtp port conflict } } participantInfo->processRTPPacket(packet, getId(), packet->getArrivalTime()); }
void RTCP::processOutgoingRTPPacket | ( | RTPPacket * | packet | ) | [protected, virtual] |
Extracts information of a sent RTPPacket.
Definition at line 339 of file RTCP.cc.
Referenced by dataOut().
{ _senderInfo->processRTPPacket(packet, getId(), simTime()); }
void RTCP::readRet | ( | cPacket * | sifpIn | ) | [protected, virtual] |
Called when this rtcp module receives data from the socket layer.
Definition at line 195 of file RTCP.cc.
Referenced by handleMessageFromUDP().
{ RTCPCompoundPacket *packet = (RTCPCompoundPacket *)(sifpIn->decapsulate()); processIncomingRTCPPacket(packet, IPAddress(_destinationAddress), _port); }
void RTCP::scheduleInterval | ( | ) | [protected, virtual] |
Calculates the length of the next rtcp interval an issues a self message to remind itself.
Definition at line 228 of file RTCP.cc.
Referenced by handleSelfMessage().
{ simtime_t intervalLength = _averagePacketSize * (simtime_t)(_participantInfos->size()) / (simtime_t)(_bandwidth * _rtcpPercentage * (_senderInfo->isSender() ? 1.0 : 0.75) / 100.0); // interval length must be at least 5 seconds if (intervalLength < 5.0) intervalLength = 5.0; // to avoid rtcp packet bursts multiply calculated interval length // with a random number between 0.5 and 1.5 intervalLength = intervalLength * (0.5 + dblrand()); intervalLength /= (double) (2.71828-1.5); // [RFC 3550] , by Ahmed ayadi cMessage *reminderMessage = new cMessage("Interval"); scheduleAt(simTime() + intervalLength, reminderMessage); }
void RTCP::senderModuleInitialized | ( | RTPInnerPacket * | rinp | ) | [protected, virtual] |
Stores information about the new transmission.
Definition at line 156 of file RTCP.cc.
Referenced by handleMessageFromRTP().
{ _senderInfo->setStartTime(simTime()); _senderInfo->setClockRate(rinp->getClockRate()); _senderInfo->setTimeStampBase(rinp->getTimeStampBase()); _senderInfo->setSequenceNumberBase(rinp->getSequenceNumberBase()); }
double RTCP::_averagePacketSize [protected] |
The average size of an RTCPCompoundPacket.
Definition at line 175 of file RTCP.h.
Referenced by calculateAveragePacketSize(), initialize(), and scheduleInterval().
int RTCP::_bandwidth [protected] |
The bandwidth for this rtp session.
Definition at line 118 of file RTCP.h.
Referenced by initializeRTCP(), and scheduleInterval().
IPAddress RTCP::_destinationAddress [protected] |
The destination address.
Definition at line 128 of file RTCP.h.
Referenced by createPacket(), createSocket(), initializeRTCP(), and readRet().
bool RTCP::_leaveSession [protected] |
True when this end system is about to leave the session.
Definition at line 143 of file RTCP.h.
Referenced by createPacket(), handleSelfMessage(), initialize(), and leaveSession().
int RTCP::_mtu [protected] |
The maximum size an RTCPCompundPacket can have.
Definition at line 113 of file RTCP.h.
Referenced by initializeRTCP().
int RTCP::_packetsCalculated [protected] |
The number of packets this rtcp module has calculated.
Definition at line 170 of file RTCP.h.
Referenced by calculateAveragePacketSize(), and initialize().
cArray* RTCP::_participantInfos [protected] |
Information about all known rtp end system participating in this rtp session.
Definition at line 154 of file RTCP.h.
Referenced by chooseSSRC(), createPacket(), findParticipantInfo(), initialize(), processIncomingRTCPPacket(), processIncomingRTPPacket(), RTCP(), scheduleInterval(), and ~RTCP().
int RTCP::_port [protected] |
The rtcp port.
Definition at line 133 of file RTCP.h.
Referenced by createPacket(), createSocket(), initializeRTCP(), and readRet().
cOutVector* RTCP::_rtcpIntervalOutVector [protected] |
int RTCP::_rtcpPercentage [protected] |
The percentage of bandwidth for rtcp.
Definition at line 123 of file RTCP.h.
Referenced by initializeRTCP(), and scheduleInterval().
RTPSenderInfo* RTCP::_senderInfo [protected] |
The RTPSenderInfo about this end system.
Definition at line 148 of file RTCP.h.
Referenced by chooseSSRC(), createPacket(), handleSelfMessage(), initializeRTCP(), processIncomingRTCPPacket(), processOutgoingRTPPacket(), scheduleInterval(), and senderModuleInitialized().
int RTCP::_socketFdIn [protected] |
The server socket for receiving rtcp packets.
Definition at line 159 of file RTCP.h.
Referenced by createSocket(), and initialize().
int RTCP::_socketFdOut [protected] |
The client socket for sending rtcp packets.
Definition at line 164 of file RTCP.h.
Referenced by createPacket(), createSocket(), and initialize().
bool RTCP::_ssrcChosen [protected] |
True when this end system has chosen its ssrc identifier.
Definition at line 138 of file RTCP.h.
Referenced by chooseSSRC(), handleSelfMessage(), and initialize().