I3Session.cc

Go to the documentation of this file.
00001 // Copyright (C) 2006 Institut fuer Telematik, Universitaet Karlsruhe (TH)
00002 //
00003 // This program is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU General Public License
00005 // as published by the Free Software Foundation; either version 2
00006 // of the License, or (at your option) any later version.
00007 //
00008 // This program is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 // GNU General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this program; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00016 //
00017 
00024 #include "I3BaseApp.h"
00025 #include "I3SessionMessage_m.h"
00026 
00027 using namespace std;
00028 
00029 #define DONT_REMOVE         0
00030 #define REMOVE_AT_ONCE      1
00031 #define WAIT_STATIC         2
00032 #define WAIT_CONFIRMATION   3
00033 
00034 #define TYPE_CHANGE_SESSION 0
00035 #define TYPE_REMOVE_TRIGGER 1
00036 
00037 enum Stats {
00038     STAT_CHANGE,
00039     STAT_RX,
00040     STAT_WRONG,
00041     NUM_STATS
00042 };
00043 
00044 class I3SessionServer : public I3BaseApp
00045 {
00046 public:
00047     int numExchanged;
00048 
00049     I3Identifier myIdentifier;
00050     I3Identifier clientIdentifier;
00051 
00052     void initializeI3();
00053     void deliver(I3Trigger &trigger, I3IdentifierStack &stack, cPacket *msg);
00054     void finish();
00055 };
00056 
00057 Define_Module(I3SessionServer);
00058 
00059 void I3SessionServer::initializeI3()
00060 {
00061     numExchanged = 0;
00062     clientIdentifier.createFromHash("Client");
00063     myIdentifier.createFromHash("Server");
00064     insertTrigger(myIdentifier);
00065 }
00066 
00067 void I3SessionServer::deliver(I3Trigger &trigger, I3IdentifierStack &stack, cPacket *msg)
00068 {
00069     SessionMsg *smsg = check_and_cast<SessionMsg*>(msg);
00070     smsg->setValue(smsg->getValue() + 1);
00071     numExchanged++;
00072     sendPacket(clientIdentifier, smsg);
00073 }
00074 
00075 void I3SessionServer::finish() {
00076     recordScalar("Server packets exchanged", numExchanged);
00077 }
00078 
00079 
00080 
00081 
00082 
00083 
00084 class I3SessionClient : public I3BaseApp
00085 {
00086 public:
00087     cStdDev myStats[NUM_STATS];
00088 
00089     int numForeignPackets;
00090     int numSessions;
00091     int numExchanged;
00092     bool holdsSession;
00093     double actualValue;
00094     I3Identifier clientIdentifier;
00095     I3Identifier serverIdentifier;
00096     I3Identifier poolIdentifier;
00097 
00098     void initializeApp(int stage);
00099     virtual void initializeI3();
00100     void deliver(I3Trigger &trigger, I3IdentifierStack &stack, cPacket *msg);
00101     void handleTimerEvent(cMessage *msg);
00102     void finish();
00103 };
00104 
00105 Define_Module(I3SessionClient);
00106 
00107 
00108 void I3SessionClient::initializeApp(int stage)
00109 {
00110     holdsSession = false;
00111     numForeignPackets = 0;
00112     numSessions = 0;
00113     numExchanged = 0;
00114     WATCH(numForeignPackets);
00115     clientIdentifier.createFromHash("Client");
00116     serverIdentifier.createFromHash("Server");
00117 }
00118 
00119 void I3SessionClient::initializeI3() {
00120     poolIdentifier.createFromHash("Pool");
00121     poolIdentifier.createRandomSuffix();
00122     insertTrigger(poolIdentifier);
00123 }
00124 
00125 void I3SessionClient::deliver(I3Trigger &trigger, I3IdentifierStack &stack, cPacket *msg)
00126 {
00127     SessionMsg *smsg = check_and_cast<SessionMsg*>(msg);
00128 
00129     if (smsg->getType() == PAYLOAD) {
00130         if (holdsSession) {
00131             //std::cout << "Got value " << smsg->getValue() << ", resending..." << endl;
00132             numExchanged++;
00133             actualValue = smsg->getValue();
00134             sendPacket(serverIdentifier, msg);
00135         } else {
00136             numForeignPackets++;
00137             //std::cout << "Foreign packet at " << nodeIPAddress << endl;
00138             delete msg;
00139         }
00140 
00141     } else if (smsg->getType() == CHANGE_SESSION) {
00142 
00143         //cout << "Insert new trigger" << nodeIPAddress << endl;
00144         /* resume session */
00145         insertTrigger(clientIdentifier, int(par("sessionMobilityType")) != DONT_REMOVE); // renew only if type != DONT_REMOVE
00146         holdsSession = true;
00147 
00148         SessionMsg *newMsg = new SessionMsg();
00149         newMsg->setType(PAYLOAD);
00150         newMsg->setValue(smsg->getValue());
00151         sendPacket(serverIdentifier, newMsg);
00152 
00153         if (int(par("sessionMobilityType")) == WAIT_CONFIRMATION) {
00154             // send confirmation
00155             SessionMsg *newMsg = new SessionMsg();
00156             newMsg->setType(TRIGGER_CONFIRMATION);
00157             newMsg->setValue(0);
00158             newMsg->setSource(poolIdentifier);
00159             sendPacket(smsg->getSource(), newMsg);
00160         }
00161         delete smsg;
00162 
00163         cMessage *msg = new cMessage();
00164         msg->setKind(TYPE_CHANGE_SESSION);
00165         scheduleAt(simTime() + int(par("sessionTime")), msg);
00166         numSessions++;
00167 
00168         getParentModule()->bubble("Got session!");
00169 
00170     } else if (smsg->getType() == TRIGGER_CONFIRMATION) { // only for WAIT_CONFIRMATION
00171         removeTrigger(clientIdentifier);
00172         getParentModule()->bubble("Got confirmation for erase.");
00173         delete smsg;
00174 
00175     } else {
00176         // ??
00177         delete smsg;
00178     }
00179 }
00180 
00181 void I3SessionClient::finish() {
00182     recordScalar("Client packets received", numExchanged);
00183     recordScalar("Client wrong received  ", numForeignPackets);
00184     recordScalar("Client session changed ", numSessions);
00185 
00186 }
00187 
00188 void I3SessionClient::handleTimerEvent(cMessage *msg) {
00189     if (msg->getKind() == TYPE_CHANGE_SESSION) {
00190         myStats[STAT_CHANGE].collect(simTime());
00191         switch (int(par("sessionMobilityType"))) {
00192         case DONT_REMOVE:
00193         case WAIT_CONFIRMATION:
00194             break;
00195         case REMOVE_AT_ONCE:
00196             removeTrigger(clientIdentifier);
00197             break;
00198         case WAIT_STATIC:
00199             cMessage *msg = new cMessage();
00200             msg->setKind(TYPE_REMOVE_TRIGGER);
00201             scheduleAt(simTime() + int(par("sessionMobilityWait")), msg);
00202             break;
00203         }
00204         holdsSession = false;
00205 
00206         /* cede session */
00207         I3Identifier sessionId;
00208 
00209         sessionId.createFromHash("Pool");
00210         sessionId.createRandomSuffix();
00211 
00212         SessionMsg *newMsg = new SessionMsg();
00213         newMsg->setType(CHANGE_SESSION);
00214         newMsg->setValue(actualValue);
00215         newMsg->setSource(poolIdentifier);
00216         sendPacket(sessionId, newMsg);
00217 
00218         getParentModule()->bubble("Ceding session...");
00219         delete msg;
00220 
00221     } else if (msg->getKind() == TYPE_REMOVE_TRIGGER) { // for WAIT_STATIC only
00222         getParentModule()->bubble("Timer ticked for erase.");
00223         removeTrigger(clientIdentifier);
00224         //cout << "Delete old trigger " << nodeIPAddress << endl;
00225         delete msg;
00226     }
00227 }
00228 
00229 
00230 
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 class I3SessionClientStarter : public I3SessionClient
00239 {
00240 public:
00241     void initializeI3();
00242 };
00243 
00244 Define_Module(I3SessionClientStarter);
00245 
00246 void I3SessionClientStarter::initializeI3() {
00247     I3SessionClient::initializeI3();
00248 
00249     /* start session */
00250     insertTrigger(clientIdentifier, int(par("sessionMobilityType")) != DONT_REMOVE); // renew only if type != DONT_REMOVE
00251     holdsSession = true;
00252 
00253     SessionMsg *newMsg = new SessionMsg();
00254     newMsg->setType(PAYLOAD);
00255     newMsg->setValue(0);
00256     sendPacket(serverIdentifier, newMsg);
00257 
00258     cMessage *msg = new cMessage();
00259     msg->setKind(TYPE_CHANGE_SESSION);
00260 
00261     std::cout << "Started starts" << endl;
00262     scheduleAt(simTime() + int(par("sessionTime")), msg);
00263 }
Generated on Wed May 26 16:21:14 2010 for OverSim by  doxygen 1.6.3