RTP.cc

Go to the documentation of this file.
00001 /***************************************************************************
00002                           RTP.cc  -  description
00003                              -------------------
00004     (C) 2007 Ahmed Ayadi  <ahmed.ayadi@sophia.inria.fr>
00005     (C) 2001 Matthias Oppitz <Matthias.Oppitz@gmx.de>
00006 
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00022 #include "IPAddress.h"
00023 #include "UDPSocket.h"
00024 #include "UDPControlInfo_m.h"
00025 
00026 #include "RTP.h"
00027 #include "RTPInterfacePacket.h"
00028 #include "RTPInnerPacket.h"
00029 #include "RTPProfile.h"
00030 
00031 #include "RTPSenderControlMessage_m.h"
00032 #include "RTPSenderStatusMessage_m.h"
00033 
00034 Define_Module(RTP);
00035 
00036 
00037 //
00038 // methods inherited from cSimpleModule
00039 //
00040 
00041 void RTP::initialize()
00042 {
00043     _socketFdIn = -1;//UDPSocket::generateSocketId();
00044     _socketFdOut = -1;
00045     _leaveSession = false;
00046 }
00047 
00048 
00049 void RTP::handleMessage(cMessage *msg)
00050 {
00051     if (msg->getArrivalGateId() == findGate("appIn")) {
00052         handleMessageFromApp(msg);
00053     }
00054     else if (msg->getArrivalGateId() == findGate("profileIn")) {
00055         handleMessageFromProfile(msg);
00056     }
00057     else if (msg->getArrivalGateId() == findGate("rtcpIn")) {
00058         handleMessageFromRTCP(msg);
00059     }
00060     else if (msg->getArrivalGateId() == findGate("udpIn")) {
00061         handleMessagefromUDP(msg);
00062     }
00063     else {
00064         error("Message from unknown gate");
00065     }
00066 }
00067 
00068 
00069 //
00070 // handle messages from different gates
00071 //
00072 
00073 void RTP::handleMessageFromApp(cMessage *msg)
00074 {
00075     RTPInterfacePacket *rifp = check_and_cast<RTPInterfacePacket *>(msg);
00076     if (rifp->getType() == RTPInterfacePacket::RTP_IFP_ENTER_SESSION) {
00077         enterSession(rifp);
00078     }
00079     else if (rifp->getType() == RTPInterfacePacket::RTP_IFP_CREATE_SENDER_MODULE) {
00080         createSenderModule(rifp);
00081     }
00082     else if (rifp->getType() == RTPInterfacePacket::RTP_IFP_DELETE_SENDER_MODULE) {
00083         deleteSenderModule(rifp);
00084     }
00085     else if (rifp->getType() == RTPInterfacePacket::RTP_IFP_SENDER_CONTROL) {
00086         senderModuleControl(rifp);
00087     }
00088     else if (rifp->getType() == RTPInterfacePacket::RTP_IFP_LEAVE_SESSION) {
00089         leaveSession(rifp);
00090     }
00091     else {
00092         error("unknown RTPInterfacePacket type from application");
00093     }
00094 }
00095 
00096 
00097 void RTP::handleMessageFromProfile(cMessage *msg)
00098 {
00099     RTPInnerPacket *rinp = check_and_cast<RTPInnerPacket *>(msg);
00100     if (rinp->getType() == RTPInnerPacket::RTP_INP_PROFILE_INITIALIZED) {
00101         profileInitialized(rinp);
00102     }
00103     else if (rinp->getType() == RTPInnerPacket::RTP_INP_SENDER_MODULE_CREATED) {
00104         senderModuleCreated(rinp);
00105     }
00106     else if (rinp->getType() == RTPInnerPacket::RTP_INP_SENDER_MODULE_DELETED) {
00107         senderModuleDeleted(rinp);
00108     }
00109     else if (rinp->getType() == RTPInnerPacket::RTP_INP_SENDER_MODULE_INITIALIZED) {
00110         senderModuleInitialized(rinp);
00111     }
00112     else if (rinp->getType() == RTPInnerPacket::RTP_INP_SENDER_MODULE_STATUS) {
00113         senderModuleStatus(rinp);
00114     }
00115     else if (rinp->getType() == RTPInnerPacket::RTP_INP_DATA_OUT) {
00116         dataOut(rinp);
00117     }
00118     else {
00119         delete msg;
00120     }
00121     ev << "handleMessageFromProfile(cMessage *msg) Exit"<<endl;
00122 }
00123 
00124 
00125 void RTP::handleMessageFromRTCP(cMessage *msg)
00126 {
00127     RTPInnerPacket *rinp = check_and_cast<RTPInnerPacket *>(msg);
00128     if (rinp->getType() == RTPInnerPacket::RTP_INP_RTCP_INITIALIZED) {
00129         rtcpInitialized(rinp);
00130     }
00131     else if (rinp->getType() == RTPInnerPacket::RTP_INP_SESSION_LEFT) {
00132         sessionLeft(rinp);
00133     }
00134     else {
00135         error("Unknown RTPInnerPacket type %d from rtcp", rinp->getType());
00136     }
00137 }
00138 
00139 void RTP::handleMessagefromUDP(cMessage *msg)
00140 {
00141     readRet(msg);
00142 }
00143 
00144 
00145 //
00146 // methods for different messages
00147 //
00148 
00149 void RTP::enterSession(RTPInterfacePacket *rifp)
00150 {
00151     _profileName = rifp->getProfileName();
00152     _commonName = rifp->getCommonName();
00153     _bandwidth = rifp->getBandwidth();
00154     _destinationAddress = rifp->getDestinationAddress();
00155 
00156     _port = rifp->getPort();
00157     if (_port % 2 != 0) {
00158         _port = _port - 1;
00159     }
00160 
00161     _mtu = resolveMTU();
00162 
00163     createProfile();
00164     initializeProfile();
00165     delete rifp;
00166 }
00167 
00168 
00169 void RTP::leaveSession(RTPInterfacePacket *rifp)
00170 {
00171     cModule *profileModule = gate("profileOut")->getNextGate()->getOwnerModule();
00172     profileModule->deleteModule();
00173     _leaveSession = true;
00174     RTPInnerPacket *rinp = new RTPInnerPacket("leaveSession()");
00175     rinp->leaveSession();
00176     send(rinp,"rtcpOut");
00177 
00178     delete rifp;
00179 }
00180 
00181 
00182 void RTP::createSenderModule(RTPInterfacePacket *rifp)
00183 {
00184     RTPInnerPacket *rinp = new RTPInnerPacket("createSenderModule()");
00185     ev << rifp->getSSRC()<<endl;
00186     rinp->createSenderModule(rifp->getSSRC(), rifp->getPayloadType(), rifp->getFileName());
00187     send(rinp, "profileOut");
00188 
00189     delete rifp;
00190 }
00191 
00192 
00193 void RTP::deleteSenderModule(RTPInterfacePacket *rifp)
00194 {
00195     RTPInnerPacket *rinp = new RTPInnerPacket("deleteSenderModule()");
00196     rinp->deleteSenderModule(rifp->getSSRC());
00197     send(rinp, "profileOut");
00198 
00199     delete rifp;
00200 }
00201 
00202 
00203 void RTP::senderModuleControl(RTPInterfacePacket *rifp)
00204 {
00205     RTPInnerPacket *rinp = new RTPInnerPacket("senderModuleControl()");
00206     rinp->senderModuleControl(rinp->getSSRC(), (RTPSenderControlMessage *)(rifp->decapsulate()));
00207     send(rinp, "profileOut");
00208 
00209     delete rifp;
00210 }
00211 
00212 
00213 void RTP::profileInitialized(RTPInnerPacket *rinp)
00214 {
00215     _rtcpPercentage = rinp->getRtcpPercentage();
00216     if (_port == PORT_UNDEF) {
00217         _port = rinp->getPort();
00218         if (_port % 2 != 0) {
00219             _port = _port - 1;
00220         }
00221     }
00222 
00223     delete rinp;
00224 
00225     createSocket();
00226 }
00227 
00228 
00229 void RTP::senderModuleCreated(RTPInnerPacket *rinp)
00230 {
00231     RTPInterfacePacket *rifp = new RTPInterfacePacket("senderModuleCreated()");
00232     rifp->senderModuleCreated(rinp->getSSRC());
00233     send(rifp, "appOut");
00234 
00235     delete rinp;
00236 }
00237 
00238 
00239 void RTP::senderModuleDeleted(RTPInnerPacket *rinp)
00240 {
00241     RTPInterfacePacket *rifp = new RTPInterfacePacket("senderModuleDeleted()");
00242     rifp->senderModuleDeleted(rinp->getSSRC());
00243     send(rifp, "appOut");
00244 
00245     // perhaps we should send a message to rtcp module
00246     delete rinp;
00247 }
00248 
00249 
00250 void RTP::senderModuleInitialized(RTPInnerPacket *rinp)
00251 {
00252     send(rinp, "rtcpOut");
00253 }
00254 
00255 
00256 void RTP::senderModuleStatus(RTPInnerPacket *rinp)
00257 {
00258     RTPInterfacePacket *rifp = new RTPInterfacePacket("senderModuleStatus()");
00259     rifp->senderModuleStatus(rinp->getSSRC(), (RTPSenderStatusMessage *)(rinp->decapsulate()));
00260     send(rifp, "appOut");
00261 
00262     delete rinp;
00263 }
00264 
00265 
00266 void RTP::dataOut(RTPInnerPacket *rinp)
00267 {
00268     RTPPacket *msg = check_and_cast<RTPPacket *>(rinp->decapsulate());
00269 
00270     // send message to UDP, with the appropriate control info attached
00271     msg->setKind(UDP_C_DATA);
00272 
00273     UDPControlInfo *ctrl = new UDPControlInfo();
00274     ctrl->setDestAddr(_destinationAddress);
00275     ctrl->setDestPort(_port);
00276     msg->setControlInfo(ctrl);
00277 
00278 //     ev << "Sending packet: ";msg->dump();
00279     send(msg, "udpOut");
00280 
00281     // RTCP module must be informed about sent rtp data packet
00282 
00283     RTPInnerPacket *rinpOut = new RTPInnerPacket(*rinp);
00284     rinpOut->encapsulate(new RTPPacket(*msg));
00285     send(rinpOut, "rtcpOut");
00286 
00287     delete rinp;
00288 }
00289 
00290 
00291 void RTP::rtcpInitialized(RTPInnerPacket *rinp)
00292 {
00293     RTPInterfacePacket *rifp = new RTPInterfacePacket("sessionEntered()");
00294     rifp->sessionEntered(rinp->getSSRC());
00295     send(rifp, "appOut");
00296 
00297     delete rinp;
00298 }
00299 
00300 
00301 void RTP::sessionLeft(RTPInnerPacket *rinp)
00302 {
00303     RTPInterfacePacket *rifp = new RTPInterfacePacket("sessionLeft()");
00304     rifp->sessionLeft();
00305     send(rifp, "appOut");
00306 
00307     delete rinp;
00308 }
00309 
00310 
00311 void RTP::socketRet()
00312 {
00313 }
00314 
00315 
00316 void RTP::connectRet()
00317 {
00318     initializeRTCP();
00319 }
00320 
00321 
00322 void RTP::readRet(cMessage *sifp)
00323 {
00324     if ( ! _leaveSession)
00325     {
00326          RTPPacket *msg = check_and_cast<RTPPacket *>(sifp);
00327 
00328          msg->dump();
00329          RTPInnerPacket *rinp1 = new RTPInnerPacket("dataIn1()");
00330          rinp1->dataIn(new RTPPacket(*msg), IPAddress(_destinationAddress), _port);
00331 
00332          RTPInnerPacket *rinp2 = new RTPInnerPacket(*rinp1);
00333          send(rinp2, "rtcpOut");
00334          //delete rinp2;
00335          send(rinp1, "profileOut");
00336          //delete rinp1;
00337     }
00338 
00339     delete sifp;
00340 }
00341 
00342 
00343 int RTP::resolveMTU()
00344 {
00345     // this is not what it should be
00346     // do something like mtu path discovery
00347     // for the simulation we can use this example value
00348     // it's 1500 bytes (ethernet) minus ip
00349     // and udp headers
00350     return 1500 - 20 - 8;
00351 }
00352 
00353 
00354 void RTP::createProfile()
00355 {
00356     cModuleType *moduleType = cModuleType::find(_profileName);
00357     if (moduleType == NULL)
00358         error("Profile type `%s' not found", _profileName);
00359 
00360     RTPProfile *profile = check_and_cast<RTPProfile *>(moduleType->create("Profile", this));
00361     profile->finalizeParameters();
00362 
00363     profile->setGateSize("payloadReceiverOut", 30);
00364     profile->setGateSize("payloadReceiverIn", 30);
00365 
00366     this->gate("profileOut")->connectTo(profile->gate("rtpIn"));
00367     profile->gate("rtpOut")->connectTo(this->gate("profileIn"));
00368 
00369     profile->callInitialize();
00370     profile->scheduleStart(simTime());
00371 }
00372 
00373 
00374 void RTP::createSocket()
00375 {
00376     // TODO UDPAppBase should be ported to use UDPSocket sometime, but for now
00377     // we just manage the UDP socket by hand...
00378     if (_socketFdIn == -1) {
00379         _socketFdIn = UDPSocket::generateSocketId();
00380 
00381         UDPControlInfo *ctrl = new UDPControlInfo();
00382 
00383         IPAddress ipaddr(_destinationAddress);
00384 
00385         if (ipaddr.isMulticast()) {
00386             ctrl->setSrcAddr(IPAddress(_destinationAddress));
00387             ctrl->setSrcPort(_port);
00388         }
00389         else {
00390              ctrl->setSrcPort(_port);
00391              ctrl->setSockId(_socketFdOut);
00392         }
00393         ctrl->setSockId((int)_socketFdIn);
00394         cMessage *msg = new cMessage("UDP_C_BIND", UDP_C_BIND);
00395         msg->setControlInfo(ctrl);
00396         send(msg,"udpOut");
00397 
00398         connectRet();
00399     }
00400 }
00401 
00402 void RTP::initializeProfile()
00403 {
00404     RTPInnerPacket *rinp = new RTPInnerPacket("initializeProfile()");
00405     rinp->initializeProfile(_mtu);
00406     send(rinp, "profileOut");
00407 }
00408 
00409 
00410 void RTP::initializeRTCP()
00411 {
00412     RTPInnerPacket *rinp = new RTPInnerPacket("initializeRTCP()");
00413     int rtcpPort = _port + 1;
00414     rinp->initializeRTCP(opp_strdup(_commonName), _mtu, _bandwidth, _rtcpPercentage, _destinationAddress, rtcpPort);
00415     send(rinp, "rtcpOut");
00416 }
00417 
00418