|
INET Framework for OMNeT++/OMNEST
|
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