00001 // 00002 // Copyright (C) 2009 Institut fuer Telematik, Universitaet Karlsruhe (TH) 00003 // 00004 // This program is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU 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 General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this program; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 // 00018 00023 #include <string> 00024 00025 #include "UnderlayConfigurator.h" 00026 #include "GlobalStatistics.h" 00027 00028 #include "MyMessage_m.h" 00029 00030 #include "MyApplication.h" 00031 00032 Define_Module(MyApplication); 00033 00034 // initializeApp() is called when the module is being created. 00035 // Use this function instead of the constructor for initializing variables. 00036 void MyApplication::initializeApp(int stage) 00037 { 00038 // initializeApp will be called twice, each with a different stage. 00039 // stage can be either MIN_STAGE_APP (this module is being created), 00040 // or MAX_STAGE_APP (all modules were created). 00041 // We only care about MIN_STAGE_APP here. 00042 00043 if (stage != MIN_STAGE_APP) return; 00044 00045 // copy the module parameter values to our own variables 00046 sendPeriod = par("sendPeriod"); 00047 numToSend = par("numToSend"); 00048 largestKey = par("largestKey"); 00049 00050 // initialize our statistics variables 00051 numSent = 0; 00052 numReceived = 0; 00053 00054 // tell the GUI to display our variables 00055 WATCH(numSent); 00056 WATCH(numReceived); 00057 00058 // start our timer! 00059 timerMsg = new cMessage("MyApplication Timer"); 00060 scheduleAt(simTime() + sendPeriod, timerMsg); 00061 00062 bindToPort(2000); 00063 } 00064 00065 00066 // finish is called when the module is being destroyed 00067 void MyApplication::finishApp() 00068 { 00069 // finish() is usually used to save the module's statistics. 00070 // We'll use globalStatistics->addStdDev(), which will calculate min, max, mean and deviation values. 00071 // The first parameter is a name for the value, you can use any name you like (use a name you can find quickly!). 00072 // In the end, the simulator will mix together all values, from all nodes, with the same name. 00073 00074 globalStatistics->addStdDev("MyApplication: Sent packets", numSent); 00075 globalStatistics->addStdDev("MyApplication: Received packets", numReceived); 00076 } 00077 00078 00079 // handleTimerEvent is called when a timer event triggers 00080 void MyApplication::handleTimerEvent(cMessage* msg) 00081 { 00082 // is this our timer? 00083 if (msg == timerMsg) { 00084 // reschedule our message 00085 scheduleAt(simTime() + sendPeriod, timerMsg); 00086 00087 // if the simulator is still busy creating the network, 00088 // let's wait a bit longer 00089 if (underlayConfigurator->isInInitPhase()) return; 00090 00091 for (int i = 0; i < numToSend; i++) { 00092 00093 // let's create a random key 00094 OverlayKey randomKey(intuniform(1, largestKey)); 00095 00096 MyMessage *myMessage; // the message we'll send 00097 myMessage = new MyMessage(); 00098 myMessage->setType(MYMSG_PING); // set the message type to PING 00099 myMessage->setSenderAddress(thisNode); // set the sender address to our own 00100 myMessage->setByteLength(100); // set the message length to 100 bytes 00101 00102 numSent++; // update statistics 00103 00104 EV << thisNode.getAddress() << ": Sending packet to " 00105 << randomKey << "!" << std::endl; 00106 00107 callRoute(randomKey, myMessage); // send it to the overlay 00108 } 00109 } else { 00110 // unknown message types are discarded 00111 delete msg; 00112 } 00113 } 00114 00115 // deliver() is called when we receive a message from the overlay. 00116 // Unknown packets can be safely deleted here. 00117 void MyApplication::deliver(OverlayKey& key, cMessage* msg) 00118 { 00119 // we are only expecting messages of type MyMessage, throw away any other 00120 MyMessage *myMsg = dynamic_cast<MyMessage*>(msg); 00121 if (myMsg == NULL) { 00122 delete msg; // type unknown! 00123 return; 00124 } 00125 00126 // are we a PING? send a PONG! 00127 if (myMsg->getType() == MYMSG_PING) { 00128 myMsg->setType(MYMSG_PONG); // change type 00129 00130 EV << thisNode.getAddress() << ": Got packet from " 00131 << myMsg->getSenderAddress() << ", sending back!" 00132 << std::endl; 00133 00134 // send it back to its owner 00135 sendMessageToUDP(myMsg->getSenderAddress(), myMsg); 00136 } else { 00137 // only handle PING messages 00138 delete msg; 00139 } 00140 } 00141 00142 // handleUDPMessage() is called when we receive a message from UDP. 00143 // Unknown packets can be safely deleted here. 00144 void MyApplication::handleUDPMessage(cMessage* msg) 00145 { 00146 // we are only expecting messages of type MyMessage 00147 MyMessage *myMsg = dynamic_cast<MyMessage*>(msg); 00148 00149 if (myMsg && myMsg->getType() == MYMSG_PONG) { 00150 EV << thisNode.getAddress() << ": Got reply!" << std::endl; 00151 numReceived++; 00152 } 00153 00154 // Message isn't needed any more -> delete it 00155 delete msg; 00156 }