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