RTPProfile.cc

Go to the documentation of this file.
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->getEncapsulatedMsg());
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