Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00023 #include "IPAddress.h"
00024 #include "UDPSocket.h"
00025 #include "UDPControlInfo_m.h"
00026
00027 #include "RTCP.h"
00028 #include "RTPInnerPacket.h"
00029 #include "RTPParticipantInfo.h"
00030 #include "RTPSenderInfo.h"
00031 #include "RTPReceiverInfo.h"
00032
00033 Define_Module(RTCP);
00034
00035 RTCP::RTCP()
00036 {
00037 _participantInfos = NULL;
00038 }
00039
00040 void RTCP::initialize()
00041 {
00042
00043
00044 _ssrcChosen = false;
00045 _leaveSession = false;
00046 _socketFdIn = -1;
00047 _socketFdOut = -1;
00048
00049 _packetsCalculated = 0;
00050 _averagePacketSize = 0.0;
00051
00052 _participantInfos = new cArray("ParticipantInfos");
00053 }
00054
00055 RTCP::~RTCP()
00056 {
00057 delete _participantInfos;
00058 }
00059
00060 void RTCP::handleMessage(cMessage *msg)
00061 {
00062
00063
00064 if (msg->getArrivalGateId() == findGate("rtpIn")) {
00065 handleMessageFromRTP(msg);
00066 }
00067 else if (msg->getArrivalGateId() == findGate("udpIn")) {
00068 handleMessageFromUDP(msg);
00069 }
00070 else {
00071 handleSelfMessage(msg);
00072 }
00073
00074 delete msg;
00075 }
00076
00077
00078
00079
00080
00081 void RTCP::handleMessageFromRTP(cMessage *msg)
00082 {
00083
00084
00085 RTPInnerPacket *rinp = check_and_cast<RTPInnerPacket *>(msg);
00086
00087
00088 if (rinp->getType() == RTPInnerPacket::RTP_INP_INITIALIZE_RTCP) {
00089 initializeRTCP(rinp);
00090 }
00091 else if (rinp->getType() == RTPInnerPacket::RTP_INP_SENDER_MODULE_INITIALIZED) {
00092 senderModuleInitialized(rinp);
00093 }
00094 else if (rinp->getType() == RTPInnerPacket::RTP_INP_DATA_OUT) {
00095 dataOut(rinp);
00096 }
00097 else if (rinp->getType() == RTPInnerPacket::RTP_INP_DATA_IN) {
00098 dataIn(rinp);
00099 }
00100 else if (rinp->getType() == RTPInnerPacket::RTP_INP_LEAVE_SESSION) {
00101 leaveSession(rinp);
00102 }
00103 else {
00104 error("unknown RTPInnerPacket type");
00105 }
00106 }
00107
00108
00109 void RTCP::handleMessageFromUDP(cMessage *msg)
00110 {
00111
00112 readRet(PK(msg));
00113 }
00114
00115
00116 void RTCP::handleSelfMessage(cMessage *msg)
00117 {
00118
00119 if (!_ssrcChosen) {
00120 chooseSSRC();
00121 RTPInnerPacket *rinp1 = new RTPInnerPacket("rtcpInitialized()");
00122 rinp1->rtcpInitialized(_senderInfo->getSSRC());
00123 send(rinp1, "rtpOut");
00124 }
00125
00126 createPacket();
00127
00128 if (!_leaveSession) {
00129 scheduleInterval();
00130 }
00131 }
00132
00133
00134
00135
00136
00137 void RTCP::initializeRTCP(RTPInnerPacket *rinp)
00138 {
00139 _mtu = rinp->getMTU();
00140 _bandwidth = rinp->getBandwidth();
00141 _rtcpPercentage = rinp->getRtcpPercentage();
00142 _destinationAddress = rinp->getAddress();
00143 _port = rinp->getPort();
00144
00145 _senderInfo = new RTPSenderInfo();
00146
00147 SDESItem *sdesItem = new SDESItem(SDESItem::SDES_CNAME, rinp->getCommonName());
00148 _senderInfo->addSDESItem(sdesItem);
00149
00150
00151
00152 createSocket();
00153 }
00154
00155
00156 void RTCP::senderModuleInitialized(RTPInnerPacket *rinp)
00157 {
00158 _senderInfo->setStartTime(simTime());
00159 _senderInfo->setClockRate(rinp->getClockRate());
00160 _senderInfo->setTimeStampBase(rinp->getTimeStampBase());
00161 _senderInfo->setSequenceNumberBase(rinp->getSequenceNumberBase());
00162 }
00163
00164
00165 void RTCP::dataOut(RTPInnerPacket *packet)
00166 {
00167 RTPPacket *rtpPacket = check_and_cast<RTPPacket *>(packet->decapsulate());
00168 processOutgoingRTPPacket(rtpPacket);
00169 }
00170
00171
00172 void RTCP::dataIn(RTPInnerPacket *rinp)
00173 {
00174 RTPPacket *rtpPacket = check_and_cast<RTPPacket *>(rinp->decapsulate());
00175
00176 processIncomingRTPPacket(rtpPacket, rinp->getAddress(), rinp->getPort());
00177 }
00178
00179
00180 void RTCP::leaveSession(RTPInnerPacket *rinp)
00181 {
00182 _leaveSession = true;
00183 }
00184
00185
00186 void RTCP::connectRet()
00187 {
00188
00189 double intervalLength = 2.5 * (dblrand() + 0.5);
00190 cMessage *reminderMessage = new cMessage("Interval");
00191 scheduleAt(simTime() + intervalLength, reminderMessage);
00192 }
00193
00194
00195 void RTCP::readRet(cPacket *sifpIn)
00196 {
00197 RTCPCompoundPacket *packet = (RTCPCompoundPacket *)(sifpIn->decapsulate());
00198 processIncomingRTCPPacket(packet, IPAddress(_destinationAddress), _port);
00199 }
00200
00201 void RTCP::createSocket()
00202 {
00203
00204
00205 if (_socketFdIn == -1) {
00206 _socketFdIn = UDPSocket::generateSocketId();
00207 UDPControlInfo *ctrl = new UDPControlInfo();
00208 IPAddress ipaddr(_destinationAddress);
00209
00210 if (ipaddr.isMulticast()) {
00211 ctrl->setSrcAddr(IPAddress(_destinationAddress));
00212 ctrl->setSrcPort(_port);
00213 }
00214 else {
00215 ctrl->setSrcPort(_port);
00216 ctrl->setSockId(_socketFdOut);
00217 }
00218 ctrl->setSockId((int)_socketFdIn);
00219 cMessage *msg = new cMessage("UDP_C_BIND", UDP_C_BIND);
00220 msg->setControlInfo(ctrl);
00221 send(msg,"udpOut");
00222
00223 connectRet();
00224 }
00225 }
00226
00227
00228 void RTCP::scheduleInterval(){
00229
00230 simtime_t intervalLength = _averagePacketSize * (simtime_t)(_participantInfos->size()) / (simtime_t)(_bandwidth * _rtcpPercentage * (_senderInfo->isSender() ? 1.0 : 0.75) / 100.0);
00231
00232
00233 if (intervalLength < 5.0)
00234 intervalLength = 5.0;
00235
00236
00237
00238 intervalLength = intervalLength * (0.5 + dblrand());
00239
00240 intervalLength /= (double) (2.71828-1.5);
00241
00242 cMessage *reminderMessage = new cMessage("Interval");
00243 scheduleAt(simTime() + intervalLength, reminderMessage);
00244 }
00245
00246
00247 void RTCP::chooseSSRC(){
00248
00249 uint32 ssrc = 0;
00250 bool ssrcConflict = false;
00251 do {
00252 ssrc = intrand(0x7fffffff);
00253 ssrcConflict = findParticipantInfo(ssrc) != NULL;
00254 } while (ssrcConflict);
00255 ev << "chooseSSRC" << ssrc;
00256 _senderInfo->setSSRC(ssrc);
00257 _participantInfos->add(_senderInfo);
00258 _ssrcChosen = true;
00259 }
00260
00261
00262 void RTCP::createPacket()
00263 {
00264
00265
00266 RTCPReceiverReportPacket *reportPacket;
00267
00268
00269
00270 if (_senderInfo->isSender()) {
00271 RTCPSenderReportPacket *senderReportPacket = new RTCPSenderReportPacket("SenderReportPacket");
00272 senderReportPacket->setSenderReport(_senderInfo->senderReport(simTime()));
00273 reportPacket = senderReportPacket;
00274 }
00275 else
00276 reportPacket = new RTCPReceiverReportPacket("ReceiverReportPacket");
00277 reportPacket->setSSRC(_senderInfo->getSSRC());
00278
00279
00280
00281 for (int i = 0; i < _participantInfos->size(); i++) {
00282
00283 if (_participantInfos->exist(i)) {
00284 RTPParticipantInfo *participantInfo = (RTPParticipantInfo *)(_participantInfos->get(i));
00285 if (participantInfo->getSSRC() != _senderInfo->getSSRC()) {
00286 ReceptionReport *report = ((RTPReceiverInfo *)participantInfo)->receptionReport(simTime());
00287 if (report != NULL) {
00288 reportPacket->addReceptionReport(report);
00289 }
00290 }
00291 participantInfo->nextInterval(simTime());
00292
00293 if (participantInfo->toBeDeleted(simTime())) {
00294 _participantInfos->remove(participantInfo);
00295 delete participantInfo;
00296
00297 }
00298 }
00299 }
00300
00301 RTCPSDESPacket *sdesPacket = new RTCPSDESPacket("SDESPacket");
00302
00303 SDESChunk *chunk = _senderInfo->getSDESChunk();
00304 sdesPacket->addSDESChunk(chunk);
00305
00306 RTCPCompoundPacket *compoundPacket = new RTCPCompoundPacket("RTCPCompoundPacket");
00307
00308 compoundPacket->addRTCPPacket(reportPacket);
00309 compoundPacket->addRTCPPacket(sdesPacket);
00310
00311
00312 if (_leaveSession) {
00313 RTCPByePacket *byePacket = new RTCPByePacket("ByePacket");
00314 byePacket->setSSRC(_senderInfo->getSSRC());
00315 compoundPacket->addRTCPPacket(byePacket);
00316 }
00317
00318 calculateAveragePacketSize(compoundPacket->getByteLength());
00319
00320 cPacket *msg = new cPacket("RTCPCompoundPacket");
00321 msg->encapsulate(compoundPacket);
00322 msg->setKind(UDP_C_DATA);
00323 UDPControlInfo *ctrl = new UDPControlInfo();
00324 ctrl->setSockId(_socketFdOut);
00325 ctrl->setDestAddr(_destinationAddress);
00326 ctrl->setDestPort(_port);
00327 msg->setControlInfo(ctrl);
00328
00329 send(msg, "udpOut");
00330
00331 if (_leaveSession) {
00332 RTPInnerPacket *rinp = new RTPInnerPacket("sessionLeft()");
00333 rinp->sessionLeft();
00334 send(rinp, "rtpOut");
00335 }
00336 }
00337
00338
00339 void RTCP::processOutgoingRTPPacket(RTPPacket *packet)
00340 {
00341 _senderInfo->processRTPPacket(packet, getId(), simTime());
00342 }
00343
00344
00345 void RTCP::processIncomingRTPPacket(RTPPacket *packet, IPAddress address, int port)
00346 {
00347 uint32 ssrc = packet->getSSRC();
00348 RTPParticipantInfo *participantInfo = findParticipantInfo(ssrc);
00349 if (participantInfo == NULL) {
00350 participantInfo = new RTPParticipantInfo(ssrc);
00351 participantInfo->setAddress(address);
00352 participantInfo->setRTPPort(port);
00353 _participantInfos->add(participantInfo);
00354 }
00355 else {
00356
00357 if (participantInfo->getAddress() != address) {
00358
00359 }
00360 if (participantInfo->getRTPPort() == PORT_UNDEF) {
00361 participantInfo->setRTPPort(port);
00362 }
00363 else if (participantInfo->getRTPPort() != port) {
00364
00365 }
00366 }
00367 participantInfo->processRTPPacket(packet, getId(), packet->getArrivalTime());
00368 }
00369
00370
00371 void RTCP::processIncomingRTCPPacket(RTCPCompoundPacket *packet, IPAddress address, int port)
00372 {
00373 calculateAveragePacketSize(packet->getByteLength());
00374 cArray *rtcpPackets = packet->getRtcpPackets();
00375
00376 simtime_t arrivalTime = packet->getArrivalTime();
00377 delete packet;
00378
00379 for (int i = 0; i < rtcpPackets->size(); i++) {
00380 if (rtcpPackets->exist(i)) {
00381
00382 RTCPPacket *rtcpPacket = (RTCPPacket *)(rtcpPackets->remove(i));
00383 if (rtcpPacket->getPacketType() == RTCPPacket::RTCP_PT_SR) {
00384 RTCPSenderReportPacket *rtcpSenderReportPacket = (RTCPSenderReportPacket *)rtcpPacket;
00385 uint32 ssrc = rtcpSenderReportPacket->getSSRC();
00386 RTPParticipantInfo *participantInfo = findParticipantInfo(ssrc);
00387
00388 if (participantInfo == NULL) {
00389 participantInfo = new RTPReceiverInfo(ssrc);
00390 participantInfo->setAddress(address);
00391 participantInfo->setRTCPPort(port);
00392 _participantInfos->add(participantInfo);
00393 }
00394 else {
00395 if (participantInfo->getAddress() == address) {
00396 if (participantInfo->getRTCPPort() == PORT_UNDEF) {
00397 participantInfo->setRTCPPort(port);
00398 }
00399 else {
00400
00401 }
00402 }
00403 else {
00404
00405 }
00406 }
00407 participantInfo->processSenderReport(rtcpSenderReportPacket->getSenderReport(), simTime());
00408
00409 cArray *receptionReports = rtcpSenderReportPacket->getReceptionReports();
00410 for (int j = 0; j < receptionReports->size(); j++) {
00411 if (receptionReports->exist(j)) {
00412 ReceptionReport *receptionReport = (ReceptionReport *)(receptionReports->remove(j));
00413 if (_senderInfo) {
00414 if (receptionReport->getSSRC() == _senderInfo->getSSRC()) {
00415 _senderInfo->processReceptionReport(receptionReport, simTime());
00416 }
00417 }
00418 else
00419
00420 delete receptionReport;
00421 }
00422 }
00423 delete receptionReports;
00424
00425 }
00426 else if (rtcpPacket->getPacketType() == RTCPPacket::RTCP_PT_RR) {
00427 RTCPReceiverReportPacket *rtcpReceiverReportPacket = (RTCPReceiverReportPacket *)rtcpPacket;
00428 uint32 ssrc = rtcpReceiverReportPacket->getSSRC();
00429 RTPParticipantInfo *participantInfo = findParticipantInfo(ssrc);
00430 if (participantInfo == NULL) {
00431 participantInfo = new RTPReceiverInfo(ssrc);
00432 participantInfo->setAddress(address);
00433 participantInfo->setRTCPPort(port);
00434 _participantInfos->add(participantInfo);
00435 }
00436 else {
00437 if (participantInfo->getAddress() == address) {
00438 if (participantInfo->getRTCPPort() == PORT_UNDEF) {
00439 participantInfo->setRTCPPort(port);
00440 }
00441 else {
00442
00443 }
00444 }
00445 else {
00446
00447 }
00448 }
00449
00450 cArray *receptionReports = rtcpReceiverReportPacket->getReceptionReports();
00451 for (int j = 0; j < receptionReports->size(); j++) {
00452 if (receptionReports->exist(j)) {
00453 ReceptionReport *receptionReport = (ReceptionReport *)(receptionReports->remove(j));
00454 if (_senderInfo) {
00455
00456 if (receptionReport->getSSRC() == _senderInfo->getSSRC()) {
00457 _senderInfo->processReceptionReport(receptionReport, simTime());
00458 }
00459 }
00460
00461 else
00462
00463 delete receptionReport;
00464 }
00465 }
00466 delete receptionReports;
00467 }
00468 else if (rtcpPacket->getPacketType() == RTCPPacket::RTCP_PT_SDES) {
00469 RTCPSDESPacket *rtcpSDESPacket = (RTCPSDESPacket *)rtcpPacket;
00470 cArray *sdesChunks = rtcpSDESPacket->getSdesChunks();
00471
00472 for (int j = 0; j < sdesChunks->size(); j++) {
00473 if (sdesChunks->exist(j)) {
00474
00475 SDESChunk *sdesChunk = (SDESChunk *)(sdesChunks->remove(j));
00476
00477
00478 uint32 ssrc = sdesChunk->getSSRC();
00479 RTPParticipantInfo *participantInfo = findParticipantInfo(ssrc);
00480 if (participantInfo == NULL) {
00481 participantInfo = new RTPReceiverInfo(ssrc);
00482 participantInfo->setAddress(address);
00483 participantInfo->setRTCPPort(port);
00484 _participantInfos->add(participantInfo);
00485 }
00486 else {
00487
00488 }
00489 participantInfo->processSDESChunk(sdesChunk, arrivalTime);
00490 }
00491 }
00492 delete sdesChunks;
00493
00494 }
00495 else if (rtcpPacket->getPacketType() == RTCPPacket::RTCP_PT_BYE) {
00496 RTCPByePacket *rtcpByePacket = (RTCPByePacket *)rtcpPacket;
00497 uint32 ssrc = rtcpByePacket->getSSRC();
00498 RTPParticipantInfo *participantInfo = findParticipantInfo(ssrc);
00499
00500 if (participantInfo != NULL && participantInfo != _senderInfo) {
00501 _participantInfos->remove(participantInfo);
00502
00503 delete participantInfo;
00504
00505
00506
00507 }
00508 }
00509 else {
00510
00511 }
00512 delete rtcpPacket;
00513 }
00514 }
00515 delete rtcpPackets;
00516 }
00517
00518
00519 RTPParticipantInfo *RTCP::findParticipantInfo(uint32 ssrc)
00520 {
00521 char *ssrcString = RTPParticipantInfo::ssrcToName(ssrc);
00522 int participantIndex = _participantInfos->find(ssrcString);
00523 if (participantIndex != -1) {
00524 return (RTPParticipantInfo *)(_participantInfos->get(participantIndex));
00525 }
00526 else {
00527 return NULL;
00528 }
00529 }
00530
00531
00532 void RTCP::calculateAveragePacketSize(int size)
00533 {
00534
00535 _averagePacketSize = ((double)(_packetsCalculated) * _averagePacketSize + (double)(size + 20 + 8)) / (double)(++_packetsCalculated);
00536 }