EtherAppCli.cc

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2003 Andras Varga; CTIE, Monash University, Australia
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public License
00015  * along with this program; if not, see <http://www.gnu.org/licenses/>.
00016 */
00017 
00018 #include <stdio.h>
00019 #include <string.h>
00020 #include <math.h>
00021 #include "EtherAppCli.h"
00022 #include "Ieee802Ctrl_m.h"
00023 #include "EtherApp_m.h"
00024 
00025 
00026 Define_Module (EtherAppCli);
00027 
00028 void EtherAppCli::initialize(int stage)
00029 {
00030     // we can only initialize in the 2nd stage (stage==1), because
00031     // assignment of "auto" MAC addresses takes place in stage 0
00032     if (stage == 1)
00033     {
00034         reqLength = &par("reqLength");
00035         respLength = &par("respLength");
00036         waitTime = &par("waitTime");
00037 
00038         localSAP = ETHERAPP_CLI_SAP;
00039         remoteSAP = ETHERAPP_SRV_SAP;
00040 
00041         seqNum = 0;
00042         WATCH(seqNum);
00043 
00044         // statistics
00045         packetsSent = packetsReceived = 0;
00046         eedVector.setName("end-to-end delay");
00047         eedStats.setName("end-to-end delay");
00048         WATCH(packetsSent);
00049         WATCH(packetsReceived);
00050 
00051         destMACAddress = resolveDestMACAddress();
00052 
00053         // if no dest address given, nothing to do
00054         if (destMACAddress.isUnspecified())
00055             return;
00056 
00057         bool registerSAP = par("registerSAP");
00058         if (registerSAP)
00059             registerDSAP(localSAP);
00060 
00061         cMessage *timermsg = new cMessage("generateNextPacket");
00062         simtime_t d = par("startTime").doubleValue();
00063         scheduleAt(simTime()+d, timermsg);
00064     }
00065 }
00066 
00067 MACAddress EtherAppCli::resolveDestMACAddress()
00068 {
00069     MACAddress destMACAddress;
00070     const char *destAddress = par("destAddress");
00071     if (destAddress[0])
00072     {
00073         // try as mac address first, then as a module
00074         if (!destMACAddress.tryParse(destAddress))
00075         {
00076             cModule *destStation = simulation.getModuleByPath(destAddress);
00077             if (!destStation)
00078                 error("cannot resolve MAC address '%s': not a 12-hex-digit MAC address or a valid module path name", destAddress);
00079             cModule *destMAC = destStation->getSubmodule("mac");
00080             if (!destMAC)
00081                 error("module '%s' has no 'mac' submodule", destAddress);
00082             destMACAddress.setAddress(destMAC->par("address"));
00083         }
00084     }
00085     return destMACAddress;
00086 }
00087 
00088 void EtherAppCli::handleMessage(cMessage *msg)
00089 {
00090     if (msg->isSelfMessage())
00091     {
00092         sendPacket();
00093         simtime_t d = waitTime->doubleValue();
00094         scheduleAt(simTime()+d, msg);
00095     }
00096     else
00097     {
00098         receivePacket(msg);
00099     }
00100 }
00101 
00102 void EtherAppCli::registerDSAP(int dsap)
00103 {
00104     EV << getFullPath() << " registering DSAP " << dsap << "\n";
00105 
00106     Ieee802Ctrl *etherctrl = new Ieee802Ctrl();
00107     etherctrl->setDsap(dsap);
00108     cMessage *msg = new cMessage("register_DSAP", IEEE802CTRL_REGISTER_DSAP);
00109     msg->setControlInfo(etherctrl);
00110 
00111     send(msg, "out");
00112 }
00113 
00114 void EtherAppCli::sendPacket()
00115 {
00116     seqNum++;
00117 
00118     char msgname[30];
00119     sprintf(msgname, "req-%d-%ld", getId(), seqNum);
00120     EV << "Generating packet `" << msgname << "'\n";
00121 
00122     EtherAppReq *datapacket = new EtherAppReq(msgname, IEEE802CTRL_DATA);
00123 
00124     datapacket->setRequestId(seqNum);
00125 
00126     long len = reqLength->longValue();
00127     datapacket->setByteLength(len);
00128 
00129     long respLen = respLength->longValue();
00130     datapacket->setResponseBytes(respLen);
00131 
00132     Ieee802Ctrl *etherctrl = new Ieee802Ctrl();
00133     etherctrl->setSsap(localSAP);
00134     etherctrl->setDsap(remoteSAP);
00135     etherctrl->setDest(destMACAddress);
00136     datapacket->setControlInfo(etherctrl);
00137 
00138     send(datapacket, "out");
00139     packetsSent++;
00140 }
00141 
00142 void EtherAppCli::receivePacket(cMessage *msg)
00143 {
00144     EV << "Received packet `" << msg->getName() << "'\n";
00145 
00146     packetsReceived++;
00147     simtime_t lastEED = simTime() - msg->getCreationTime();
00148     eedVector.record(lastEED);
00149     eedStats.collect(lastEED);
00150 
00151     delete msg;
00152 }
00153 
00154 void EtherAppCli::finish()
00155 {
00156     recordScalar("packets sent", packetsSent);
00157     recordScalar("packets rcvd", packetsReceived);
00158     recordScalar("end-to-end delay mean", eedStats.getMean());
00159     recordScalar("end-to-end delay stddev", eedStats.getStddev());
00160     recordScalar("end-to-end delay min", eedStats.getMin());
00161     recordScalar("end-to-end delay max", eedStats.getMax());
00162 }
00163