SensorApplLayer.cc

00001 /***************************************************************************
00002  * file:        SensorApplLayer.h
00003  *
00004  * author:      Amre El-Hoiydi, Jerome Rousselot, Ramon Serna Oliver
00005  *
00006  * copyright:   (C) 2007-2008 CSEM
00007  *
00008  *              This program is free software; you can redistribute it
00009  *              and/or modify it under the terms of the GNU General Public
00010  *              License as published by the Free Software Foundation; either
00011  *              version 2 of the License, or (at your option) any later
00012  *              version.
00013  *              For further information see file COPYING
00014  *              in the top level directory
00015  ***************************************************************************
00016  * part of:     framework implementation developed by tkn
00017  * description: Generate periodic traffic addressed to a sink
00018  **************************************************************************/
00019 
00020 #include "SensorApplLayer.h"
00021 //#include <sstream>
00022 #include <BaseNetwLayer.h>
00023 #include <AddressingInterface.h>
00024 
00025 Define_Module(SensorApplLayer);
00026 
00035 void SensorApplLayer::initialize(int stage) {
00036     BaseLayer::initialize(stage);
00037   if (stage == 0) {
00038 
00039     debugEV<< "in initialize() stage 0...";
00040     debug = par("debug");
00041     stats = par("stats");
00042     trace = par("trace");
00043     nbPackets = par("nbPackets");
00044     trafficParam = par("trafficParam");
00045     initializationTime = par("initializationTime");
00046     broadcastPackets = par("broadcastPackets");
00047     headerLength = par("headerLength");
00048     // application configuration
00049     const char *traffic = par("trafficType");
00050     destAddr = par("destAddr");
00051     nbPacketsSent = 0;
00052     nbPacketsReceived = 0;
00053     firstPacketGeneration = -1;
00054     lastPacketReception = -2;
00055 
00056     initializeDistribution(traffic);
00057 
00058     delayTimer = new cMessage("appDelay", SEND_DATA_TIMER);
00059     // Blackboard stuff:
00060     hostID = getParentModule()->getId();
00061 
00062     // get pointer to the world module
00063 
00064     world = FindModule<BaseWorldUtility*>::findGlobalModule();
00065 
00066   } else if (stage == 1) {
00067     debugEV << "in initialize() stage 1...";
00068     // Application address configuration: equals to host address
00069 
00070     cModule *netw = FindModule<BaseNetwLayer*>::findSubModule(findHost());
00071     if(!netw) {
00072       netw = findHost()->getSubmodule("netw");
00073       if(!netw) {
00074         opp_error("Could not find network layer module. This means "
00075               "either no network layer module is present or the "
00076               "used network layer module does not subclass from "
00077               "BaseNetworkLayer.");
00078       }
00079     }
00080     AddressingInterface* addrScheme = FindModule<AddressingInterface*>
00081 													::findSubModule(findHost());
00082     if(addrScheme) {
00083       myAppAddr = addrScheme->myNetwAddr(netw);
00084     } else {
00085       myAppAddr = netw->getId();
00086     }
00087     sentPackets = 0;
00088     catPacket = world->getCategory(&packet);
00089 
00090     // first packet generation time is always chosen uniformly
00091     // to avoid systematic collisions
00092     if(nbPackets> 0)
00093     scheduleAt(simTime() +uniform(initializationTime, initializationTime + trafficParam), delayTimer);
00094 
00095     if (stats) {
00096       latenciesRaw.setName("rawLatencies");
00097       latenciesRaw.setUnit("s");
00098       latency.setName("latency");
00099     }
00100   }
00101 }
00102 
00103 cStdDev& SensorApplLayer::hostsLatency(int hostAddress)
00104 {
00105     if(latencies.count(hostAddress) == 0) {
00106       std::ostringstream oss;
00107       oss << hostAddress;
00108       cStdDev aLatency(oss.str().c_str());
00109       latencies.insert(pair<int, cStdDev>(hostAddress, aLatency));
00110     }
00111 
00112     return latencies[hostAddress];
00113 }
00114 
00115 void SensorApplLayer::initializeDistribution(const char* traffic) {
00116   if (!strcmp(traffic, "periodic")) {
00117     trafficType = PERIODIC;
00118   } else if (!strcmp(traffic, "uniform")) {
00119     trafficType = UNIFORM;
00120   } else if (!strcmp(traffic, "exponential")) {
00121     trafficType = EXPONENTIAL;
00122   } else {
00123     trafficType = UNKNOWN;
00124     EV << "Error! Unknown traffic type: " << traffic << endl;
00125   }
00126 }
00127 
00128 void SensorApplLayer::scheduleNextPacket() {
00129   if (nbPackets > sentPackets && trafficType != 0) { // We must generate packets
00130 
00131     simtime_t waitTime = -1;
00132 
00133     switch (trafficType) {
00134     case PERIODIC:
00135       waitTime = trafficParam;
00136       debugEV<< "Periodic traffic, waitTime=" << waitTime << endl;
00137       break;
00138       case UNIFORM:
00139       waitTime = uniform(0, trafficParam);
00140       debugEV << "Uniform traffic, waitTime=" << waitTime << endl;
00141       break;
00142       case EXPONENTIAL:
00143       waitTime = exponential(trafficParam);
00144       debugEV << "Exponential traffic, waitTime=" << waitTime << endl;
00145       break;
00146       case UNKNOWN:
00147       default:
00148       EV <<
00149       "Cannot generate requested traffic type (unimplemented or unknown)."
00150       << endl;
00151 
00152     }
00153     debugEV << "Start timer for a new packet in " << waitTime << " seconds." <<
00154     endl;
00155     scheduleAt(simTime() + waitTime, delayTimer);
00156     debugEV << "...timer rescheduled." << endl;
00157   } else {
00158     debugEV << "All packets sent.\n";
00159   }
00160 }
00161 
00165 void SensorApplLayer::handleLowerMsg(cMessage * msg) {
00166   ApplPkt *m;
00167 
00168   switch (msg->getKind()) {
00169   case DATA_MESSAGE:
00170     m = static_cast<ApplPkt *> (msg);
00171     nbPacketsReceived++;
00172     packet.setPacketSent(false);
00173     packet.setNbPacketsSent(0);
00174     packet.setNbPacketsReceived(1);
00175     packet.setHost(myAppAddr);
00176     world->publishBBItem(catPacket, &packet, hostID);
00177     if (stats) {
00178       simtime_t theLatency = m->getArrivalTime() - m->getCreationTime();
00179       if(trace) {
00180         hostsLatency(m->getSrcAddr()).collect(theLatency);
00181         latenciesRaw.record(theLatency.dbl());
00182       }
00183       latency.collect(theLatency);
00184       if (firstPacketGeneration < 0)
00185         firstPacketGeneration = m->getCreationTime();
00186       lastPacketReception = m->getArrivalTime();
00187       if(trace) {
00188         debugEV<< "Received a data packet from host[" << m->getSrcAddr()
00189         << "], latency=" << theLatency
00190         << ", collected " << hostsLatency(m->getSrcAddr()).
00191         getCount() << "mean is now: " << hostsLatency(m->getSrcAddr()).
00192         getMean() << endl;
00193       } else {
00194           debugEV<< "Received a data packet from host[" << m->getSrcAddr()
00195           << "], latency=" << theLatency << endl;
00196       }
00197     }
00198     delete msg;
00199 
00200     //  sendReply(m);
00201     break;
00202     default:
00203     EV << "Error! got packet with unknown kind: " << msg->getKind() << endl;
00204     delete msg;
00205   }
00206 }
00207 
00216 void SensorApplLayer::handleSelfMsg(cMessage * msg) {
00217   switch (msg->getKind()) {
00218   case SEND_DATA_TIMER:
00219     sendData();
00220     //delete msg;
00221     break;
00222   default:
00223     EV<< "Unkown selfmessage! -> delete, kind: " << msg->getKind() << endl;
00224     delete msg;
00225   }
00226 }
00227 
00228 void SensorApplLayer::handleLowerControl(cMessage * msg) {
00229   delete msg;
00230 }
00231 
00236 void SensorApplLayer::sendData() {
00237   ApplPkt *pkt = new ApplPkt("Data", DATA_MESSAGE);
00238 
00239   if(broadcastPackets) {
00240     pkt->setDestAddr(L3BROADCAST);
00241   } else {
00242     pkt->setDestAddr(destAddr);
00243   }
00244   pkt->setSrcAddr(myAppAddr);
00245   pkt->setByteLength(headerLength);
00246   // set the control info to tell the network layer the layer 3 address
00247   pkt->setControlInfo(new NetwControlInfo(pkt->getDestAddr()));
00248   debugEV<< "Sending data packet!\n";
00249   sendDown(pkt);
00250   nbPacketsSent++;
00251   packet.setPacketSent(true);
00252   packet.setNbPacketsSent(1);
00253   packet.setNbPacketsReceived(0);
00254   packet.setHost(myAppAddr);
00255   world->publishBBItem(catPacket, &packet, hostID);
00256   sentPackets++;
00257   scheduleNextPacket();
00258 }
00259 
00260 void SensorApplLayer::finish() {
00261   if (stats) {
00262     if (trace) {
00263       // output logs to scalar file
00264       for (map<int, cStdDev>::iterator it = latencies.begin(); it
00265           != latencies.end(); ++it) {
00266         char dispstring[12];
00267         cStdDev aLatency = it->second;
00268         sprintf(dispstring, "latency%d", it->first);
00269         //dispstring
00270         recordScalar(dispstring, aLatency.getMean(), "s");
00271         aLatency.record();
00272       }
00273     }
00274     recordScalar("activity duration", lastPacketReception
00275         - firstPacketGeneration, "s");
00276     recordScalar("firstPacketGeneration", firstPacketGeneration, "s");
00277     recordScalar("lastPacketReception", lastPacketReception, "s");
00278     recordScalar("nbPacketsSent", nbPacketsSent);
00279     recordScalar("nbPacketsReceived", nbPacketsReceived);
00280     latency.record();
00281   }
00282   BaseModule::finish();
00283 }
00284 
00285 SensorApplLayer::~SensorApplLayer() {
00286   cancelAndDelete(delayTimer);
00287 }