|
INET Framework for OMNeT++/OMNEST
|
00001 /*************************************************************************** 00002 RTPProfile.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 <string.h> 00023 #include "RTPProfile.h" 00024 #include "RTPInnerPacket.h" 00025 #include "RTPPayloadSender.h" 00026 #include "RTPPayloadReceiver.h" 00027 #include "RTPParticipantInfo.h" 00028 00029 00030 Define_Module(RTPProfile); 00031 00032 RTPProfile::RTPProfile() 00033 { 00034 _ssrcGates = NULL; 00035 } 00036 00037 void RTPProfile::initialize() 00038 { 00039 ev << "initialize() Enter"<<endl; 00040 _profileName = "Profile"; 00041 _rtcpPercentage = 5; 00042 _preferredPort = PORT_UNDEF; 00043 00044 // how many gates to payload receivers do we have 00045 _maxReceivers = gateSize("payloadReceiverOut"); 00046 _ssrcGates = new cArray("SSRCGates"); 00047 _autoOutputFileNames = par("autoOutputFileNames").boolValue(); 00048 ev << "initialize() Exit"<<endl; 00049 } 00050 00051 RTPProfile::~RTPProfile() 00052 { 00053 delete _ssrcGates; 00054 } 00055 00056 00057 void RTPProfile::handleMessage(cMessage *msg) 00058 { 00059 if (msg->getArrivalGateId() == findGate("rtpIn")) { 00060 handleMessageFromRTP(msg); 00061 } 00062 00063 else if (msg->getArrivalGateId() == findGate("payloadSenderIn")) { 00064 handleMessageFromPayloadSender(msg); 00065 } 00066 00067 else if (msg->getArrivalGateId() >= findGate("payloadReceiverIn") && msg->getArrivalGateId() < findGate("payloadReceiverIn") + _maxReceivers) { 00068 handleMessageFromPayloadReceiver(msg); 00069 } 00070 00071 else { 00072 error("message coming from unknown gate"); 00073 } 00074 00075 } 00076 00077 00078 void RTPProfile::handleMessageFromRTP(cMessage *msg) 00079 { 00080 ev << "handleMessageFromRTP Enter "<<endl; 00081 00082 RTPInnerPacket *rinpIn = check_and_cast<RTPInnerPacket *>(msg); 00083 00084 if (rinpIn->getType() == RTPInnerPacket::RTP_INP_INITIALIZE_PROFILE) { 00085 initializeProfile(rinpIn); 00086 } 00087 else if (rinpIn->getType() == RTPInnerPacket::RTP_INP_CREATE_SENDER_MODULE) { 00088 createSenderModule(rinpIn); 00089 } 00090 else if (rinpIn->getType() == RTPInnerPacket::RTP_INP_DELETE_SENDER_MODULE) { 00091 deleteSenderModule(rinpIn); 00092 } 00093 else if (rinpIn->getType() == RTPInnerPacket::RTP_INP_SENDER_MODULE_CONTROL) { 00094 senderModuleControl(rinpIn); 00095 } 00096 else if (rinpIn->getType() == RTPInnerPacket::RTP_INP_DATA_IN) { 00097 dataIn(rinpIn); 00098 } 00099 else { 00100 error("RTPInnerPacket from RTPModule has wrong type"); 00101 } 00102 00103 ev << "handleMessageFromRTP Exit "<<endl; 00104 } 00105 00106 00107 void RTPProfile::handleMessageFromPayloadSender(cMessage *msg) 00108 { 00109 00110 RTPInnerPacket *rinpIn = check_and_cast<RTPInnerPacket *>(msg); 00111 00112 if (rinpIn->getType() == RTPInnerPacket::RTP_INP_DATA_OUT) { 00113 dataOut(rinpIn); 00114 } 00115 else if (rinpIn->getType() == RTPInnerPacket::RTP_INP_SENDER_MODULE_INITIALIZED) { 00116 senderModuleInitialized(rinpIn); 00117 } 00118 else if (rinpIn->getType() == RTPInnerPacket::RTP_INP_SENDER_MODULE_STATUS) { 00119 senderModuleStatus(rinpIn); 00120 } 00121 else { 00122 error("Profile received RTPInnerPacket from sender module with wrong type"); 00123 } 00124 00125 } 00126 00127 00128 void RTPProfile::handleMessageFromPayloadReceiver(cMessage *msg) 00129 { 00130 // currently payload receiver modules don't send messages 00131 delete msg; 00132 } 00133 00134 00135 void RTPProfile::initializeProfile(RTPInnerPacket *rinp) 00136 { 00137 ev << "initializeProfile Enter"<<endl; 00138 _mtu = rinp->getMTU(); 00139 delete rinp; 00140 RTPInnerPacket *rinpOut = new RTPInnerPacket("profileInitialized()"); 00141 rinpOut->profileInitialized(_rtcpPercentage, _preferredPort); 00142 send(rinpOut, "rtpOut"); 00143 ev << "initializeProfile Exit"<<endl; 00144 } 00145 00146 00147 void RTPProfile::createSenderModule(RTPInnerPacket *rinp) 00148 { 00149 ev << "createSenderModule Enter"<<endl; 00150 int ssrc = rinp->getSSRC(); 00151 int payloadType = rinp->getPayloadType(); 00152 char moduleName[100]; 00153 00154 ev << "ProfileName: " << _profileName << " payloadType: " << payloadType<<endl; 00155 const char *pkgPrefix = "inet.transport.rtp."; //FIXME hardcoded string 00156 sprintf(moduleName, "%sRTP%sPayload%iSender", pkgPrefix, _profileName, payloadType); 00157 00158 cModuleType *moduleType = cModuleType::find(moduleName); 00159 if (moduleType == NULL) 00160 opp_error("RTPProfile: payload sender module '%s' not found", moduleName); 00161 00162 RTPPayloadSender *rtpPayloadSender = (RTPPayloadSender *)(moduleType->create(moduleName, this)); 00163 rtpPayloadSender->finalizeParameters(); 00164 00165 gate("payloadSenderOut")->connectTo(rtpPayloadSender->gate("profileIn")); 00166 rtpPayloadSender->gate("profileOut")->connectTo(gate("payloadSenderIn")); 00167 00168 rtpPayloadSender->initialize(); 00169 rtpPayloadSender->scheduleStart(simTime()); 00170 00171 RTPInnerPacket *rinpOut1 = new RTPInnerPacket("senderModuleCreated()"); 00172 rinpOut1->senderModuleCreated(ssrc); 00173 send(rinpOut1, "rtpOut"); 00174 00175 RTPInnerPacket *rinpOut2 = new RTPInnerPacket("initializeSenderModule()"); 00176 rinpOut2->initializeSenderModule(ssrc, rinp->getFileName(), _mtu); 00177 send(rinpOut2, "payloadSenderOut"); 00178 00179 delete rinp; 00180 ev << "createSenderModule Exit"<<endl; 00181 } 00182 00183 00184 void RTPProfile::deleteSenderModule(RTPInnerPacket *rinpIn) 00185 { 00186 cModule *senderModule = gate("payloadSenderOut")->getNextGate()->getOwnerModule(); 00187 senderModule->deleteModule(); 00188 00189 RTPInnerPacket *rinpOut = new RTPInnerPacket("senderModuleDeleted()"); 00190 rinpOut->senderModuleDeleted(rinpIn->getSSRC()); 00191 delete rinpIn; 00192 00193 send(rinpOut, "rtpOut"); 00194 } 00195 00196 00197 void RTPProfile::senderModuleControl(RTPInnerPacket *rinp) 00198 { 00199 send(rinp, "payloadSenderOut"); 00200 } 00201 00202 00203 void RTPProfile::dataIn(RTPInnerPacket *rinp) 00204 { 00205 ev << "dataIn(RTPInnerPacket *rinp) Enter"<<endl; 00206 processIncomingPacket(rinp); 00207 00208 RTPPacket *packet = check_and_cast<RTPPacket *>(rinp->getEncapsulatedPacket()); 00209 00210 uint32 ssrc = packet->getSSRC(); 00211 00212 SSRCGate *ssrcGate = findSSRCGate(ssrc); 00213 00214 if (!ssrcGate) { 00215 ssrcGate = newSSRCGate(ssrc); 00216 char payloadReceiverName[100]; 00217 const char *pkgPrefix = "inet.transport.rtp."; //FIXME hardcoded string 00218 sprintf(payloadReceiverName, "%sRTP%sPayload%iReceiver", pkgPrefix, _profileName, packet->getPayloadType()); 00219 00220 cModuleType *moduleType = cModuleType::find(payloadReceiverName); 00221 if (moduleType == NULL) 00222 opp_error("Receiver module type %s not found", payloadReceiverName); 00223 00224 else { 00225 RTPPayloadReceiver *receiverModule = (RTPPayloadReceiver *)(moduleType->create(payloadReceiverName, this)); 00226 if (_autoOutputFileNames) { 00227 char outputFileName[100]; 00228 sprintf(outputFileName, "id%i.sim", receiverModule->getId()); 00229 receiverModule->par("outputFileName") = outputFileName; 00230 } 00231 receiverModule->finalizeParameters(); 00232 00233 this->gate(ssrcGate->getGateId())->connectTo(receiverModule->gate("profileIn")); 00234 receiverModule->gate("profileOut")->connectTo(this->gate(ssrcGate->getGateId() - findGate("payloadReceiverOut",0) + findGate("payloadReceiverIn",0))); 00235 00236 receiverModule->callInitialize(0); 00237 receiverModule->scheduleStart(simTime()); 00238 } 00239 } 00240 00241 send(rinp, ssrcGate->getGateId()); 00242 ev << "dataIn(RTPInnerPacket *rinp) Exit"<<endl; 00243 } 00244 00245 00246 void RTPProfile::dataOut(RTPInnerPacket *rinp) 00247 { 00248 processOutgoingPacket(rinp); 00249 send(rinp, "rtpOut"); 00250 } 00251 00252 00253 void RTPProfile::senderModuleInitialized(RTPInnerPacket *rinp) 00254 { 00255 ev << "senderModuleInitialized"<<endl; 00256 send(rinp, "rtpOut"); 00257 } 00258 00259 00260 void RTPProfile::senderModuleStatus(RTPInnerPacket *rinp) 00261 { 00262 ev << "senderModuleStatus"<<endl; 00263 send(rinp, "rtpOut"); 00264 } 00265 00266 00267 void RTPProfile::processIncomingPacket(RTPInnerPacket *rinp) 00268 { 00269 // do nothing with the packet 00270 } 00271 00272 00273 void RTPProfile::processOutgoingPacket(RTPInnerPacket *rinp) 00274 { 00275 // do nothing with the packet 00276 } 00277 00278 00279 RTPProfile::SSRCGate *RTPProfile::findSSRCGate(uint32 ssrc) 00280 { 00281 const char *name = RTPParticipantInfo::ssrcToName(ssrc); 00282 int objectIndex = _ssrcGates->find(name); 00283 if (objectIndex == -1) { 00284 return NULL; 00285 } 00286 else { 00287 cObject *co = (_ssrcGates->get(objectIndex)); 00288 return (SSRCGate *)co; 00289 } 00290 } 00291 00292 00293 RTPProfile::SSRCGate *RTPProfile::newSSRCGate(uint32 ssrc) 00294 { 00295 SSRCGate *ssrcGate = new SSRCGate(ssrc); 00296 bool assigned = false; 00297 int receiverGateId = findGate("payloadReceiverOut",0); 00298 for (int i = receiverGateId; i < receiverGateId + _maxReceivers && !assigned; i++) { 00299 if (!gate(i)->isConnected()) { 00300 ssrcGate->setGateId(i); 00301 assigned = true; 00302 } 00303 } 00304 00305 if (!assigned) 00306 opp_error("Can't manage more senders"); 00307 00308 _ssrcGates->add(ssrcGate); 00309 return ssrcGate; 00310 } 00311 00312