?? router.cc
字號:
// -*- C++ -*-
// Copyright (C) 2003 Leherstuh f黵 Betrieb System/ Verteilte System,
// Universitaet Dortmund
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// Author: Muddassar Farooq
// Informatik III, Universitaet Dortmund
// Germany
//-------------------------------------------------------------
// file: router.cpp
// (part of AntNet Routing Simulation)
//-------------------------------------------------------------
#include <stdio.h>
#include "router.h"
Define_Module( Router );
Router::Router(const char *name, cModule *parentmodule, unsigned stacksize)
:cSimpleModule(name, parentmodule, stacksize)
{
sequenceNumber = 0;
timerID = 0;
packetCount = 0;
linkCost = 1.0; // we are just interested in the connectivity
}
Router::~Router()
{
// please ensure that we delete all packetbuffer entries to
// avoid memory leak
while( !timerQueue.empty())
{
cMessage *temp = (cMessage *) timerQueue.pop();
timerContextInfo *tempContext = (timerContextInfo *) temp->contextPointer();
delete tempContext;
delete temp;
};
while( !commandQueue.empty())
{
cMessage *temp = (cMessage *) commandQueue.pop();
delete temp;
};
pIter iter;
for(iter = destGate.begin(); iter != destGate.end(); ++iter)
{
pairNumber *sPtr = (pairNumber*) *iter;
delete sPtr;
};
delete[] sendNormalQueue; // at the moment no receive queue
delete[] sendPriorityQueue; // just for backward ants
delete[] sendNormalAndForwardAnt;
delete[] sendBackwardAnt;
delete[] msgServiced;
if(logResults)
{
delete[] queueLenPackets;
delete[] queueingTime;
delete[] queueDrops;
delete[] queueDelayPackets;
}
// Different variables that help in processing packets
delete[] numPacketsToSend;
delete[] numPacketsToSendDropped;
}
void Router::initialize()
{
dataRate = par("dataRate"); //in simplenet 10Mb/sec
myAddress = par("address");
cPar queueLength = par("queueSize");
numStations = par("numStations");
int messageLength = (int) par("messageLength");
double txTime = (double) (messageLength * BYTE) / dataRate;
topologyDiscovered = false;
probabilisticRouting = par("probabilisticRouting");
numNodes = par("numStations");
startTime = (double) par("startTime");
endTime = (double) par("endTime");
qWeightFactor = (double) par("qWeightFactor");
debug = true;
logResults = par("logResults");
const char *statModulePath = par("statModulePath");
cModule *tmp1 = simulation.moduleByPath(statModulePath);
sPtr= check_and_cast<statistics *> (tmp1);
WATCH(debug);
fsm.setName("fsm");
timerQueue.setName("timerQueue");
commandQueue.setName("commandQueue");
queueMaxLen = (int) queueLength;
resendAttempts = par("resendAttempts");
timeValues.helloTimeOutValue = par("helloTimeOutValue");
timeValues.topologyUpdatePeriod = par("topologyUpdatePeriod");
timeValues.waitHelloReplyTime = par("waitHelloReplyTime");
tcb.state = INIT_S;
msgServiced = NULL;
startUpMessage = new cMessage("StartUpMessage",START_UP_MESSAGE);
scheduleAt(0.0 , startUpMessage);
}
void Router::handleMessage(cMessage *msg)
{
/** Now we really implement the real routing algorithm. Since we
start with a very simple model, hence our first algorithm
is link State Routing, a variant of OSPF. We represent the
topology of the network in a graph. We will implement
following steps
1. A router first discovers its neighbors and their network addresses
2. Measures the delay cost to each of its neighbors
3. Start normal ant algorithm
**/
// first message a router sends after coming up is to send hello
// message
simtime_t time = simTime();
if( time > startTime && time < endTime) //router down
{
if(dynamic_cast<samplePacket *> (msg) != NULL)
{
samplePacket *dPacket = (samplePacket*) msg;
int destination = dPacket->getDestAddress();
if(destination == myAddress)
{
sPtr->incrTotalBitsUndeliverable();
}
else
{
sPtr->incrTotalBitsLost();
}
delete dPacket;
}
else if(dynamic_cast<Ant *> (msg) != NULL)
{
delete msg;
}
}
else
{
FSM_Switch( fsm )
{
case FSM_Exit(INIT):
// switch to send Hello Packet State
analyzeEvent(msg);
performExitInitActions(msg);
break;
case FSM_Exit(SENT_HELLO_PACKET):
analyzeEvent(msg);
performActionsInSentHelloState(msg);
break;
case FSM_Exit(NORMAL):
analyzeEvent(msg);
performActionsInNormalState(msg);
break;
}
}
}
void Router::analyzeEvent(cMessage *msg)
{
switch(msg->kind())
{
case NETLAYER_HELLO_PACKET:
tcb.event = NETLAYER_HELLO_PACKET_EVENT;
break;
case NETLAYER_HELLO_REPLY_PACKET:
tcb.event = NETLAYER_HELLO_REPLY_PACKET_EVENT;
break;
case HELLO_RESEND_TIMER:
tcb.event = HELLO_RESEND_TIMER_EVENT;
break;
case NETLAYER_DATA_PACKET:
tcb.event = NETLAYER_DATA_PACKET_EVENT;
break;
case NETLAYER_BACKWARD_ANT:
tcb.event = NETLAYER_BACKWARD_ANT_EVENT;
break;
case NETLAYER_FORWARD_ANT:
tcb.event = NETLAYER_FORWARD_ANT_EVENT;
break;
case START_UP_MESSAGE:
tcb.event = START_UP_MESSAGE_EVENT;
break;
case TOPOLOGY_UPDATING_TIMER:
tcb.event = TOPOLOGY_UPDATING_TIMER_EVENT;
break;
case NEIGHBOR_DISCOVERED_COM:
tcb.event = NEIGHBOR_DISCOVERED_EVENT;
break;
case EOT_TIMER:
tcb.event = END_OF_TRANSMISSION_EVENT;
default:
if( msg->kind() >= SEND_NORMAL_PACKET_COM && msg->kind() < SEND_BACKWARD_ANT_COM)
{
tcb.event = SEND_NORMAL_PACKET_EVENT;
}
else if( msg->kind() >= SEND_BACKWARD_ANT_COM)
{
tcb.event = SEND_BACKWARD_ANT_EVENT;
}
else
{
if(debug) ev<<"Unknown event: " << msg->kind() << endl;
error("Unknow event in AnyalyzeEvent:");
}
break;
}
}
void Router::performExitInitActions(cMessage *msg)
{
switch(tcb.event)
{
case START_UP_MESSAGE_EVENT:
sendHelloPacket();
tcb.state = SENT_HELLO_PACKET_S;
neighborDiscovered = new cMessage("NeighborDiscovered", NEIGHBOR_DISCOVERED_COM);
scheduleAt(simTime()+ timeValues.waitHelloReplyTime, neighborDiscovered);
topologyUpdateTimer = new cMessage("topologyTimer", TOPOLOGY_UPDATING_TIMER);
scheduleAt(simTime()+ timeValues.topologyUpdatePeriod, topologyUpdateTimer);
tcb.state = SENT_HELLO_PACKET_S;
FSM_Goto(fsm, SENT_HELLO_PACKET);
break;
default:
if(debug)
{
ev << "In INIT state received: " << tcb.event << endl;
ev << "Ignoring case: not handeled in switch(INIT)";
}
break;
}
}
void Router::performActionsInSentHelloState(cMessage *msg)
{
int address;
int index;
switch(tcb.event)
{
case NETLAYER_HELLO_PACKET_EVENT:
if(debug) ev << "Hello packet received in sentHello" << endl;
address = processHelloAndReplyMessage((helloAndReplyMessage *) msg);
break;
case NETLAYER_HELLO_REPLY_PACKET_EVENT:
if(debug) ev << "Hello Reply Packet Received in sentHello" << endl;
processHelloAndReplyMessage((helloAndReplyMessage *) msg);
break;
case HELLO_RESEND_TIMER_EVENT:
if(debug) ev << "Hello TimeOut in Sent Hello State" << endl;
// we will retransmit this message five time
retransmitHelloMessageForThisTimerMessage(msg);
break;
case NEIGHBOR_DISCOVERED_EVENT:
deleteAllTimerEventsForThisID( (int) HELLO_RESEND_TIMER);
tcb.state = NORMAL_S;
topologyDiscovered = true;
initializeQueues();
FSM_Goto(fsm, NORMAL);
break;
case NETLAYER_DATA_PACKET_EVENT:
if(debug) ev << "Data Packet Received in sentHello" << endl;
handleDataPackets((samplePacket*) msg);
break;
case SEND_NORMAL_PACKET_EVENT:
if(debug) ev << "Send Normal Packet Received in sentHello" << endl;
index = msg->kind() - SEND_NORMAL_PACKET_COM;
handleMessageQueue(msg, index);
break;
case NETLAYER_FORWARD_ANT_EVENT:
if(debug) ev << "Forward Ant Received in sentHello" << endl;
handleForwardAnt((Ant *) msg);
break;
case NETLAYER_BACKWARD_ANT_EVENT:
if(debug) ev << "Backward Ant Received in sentHello" << endl;
handleBackwardAnt((Ant *) msg);
break;
case SEND_BACKWARD_ANT_EVENT:
if(debug) ev << "Send Backward Ant Event received in sentHello" << endl;
index = msg->kind() - SEND_BACKWARD_ANT_COM;
handleBackwardAntMessageQueue( (Ant *) msg, index);
break;
default:
if(debug) ev << "In sentHello State received: " << tcb.event << endl;
error("Unexpected Event: Case Not Handeled");
break;
}
}
void Router::performActionsInNormalState(cMessage *msg)
{
int address;
int index;
switch(tcb.event)
{
case NETLAYER_HELLO_PACKET_EVENT:
if(debug) ev << "Hello Packet Received in Normal State" << endl;
address = processHelloAndReplyMessage((helloAndReplyMessage *) msg);
sendHelloPacket(address);
neighborDiscovered = new cMessage("NeighborDiscovered", NEIGHBOR_DISCOVERED_COM);
scheduleAt(simTime()+ timeValues.waitHelloReplyTime, neighborDiscovered);
break;
case NETLAYER_HELLO_REPLY_PACKET_EVENT:
if(debug) ev << "Hello Reply Packet Received in sentHello" << endl;
processHelloAndReplyMessage((helloAndReplyMessage *) msg);
break;
case HELLO_RESEND_TIMER_EVENT:
if(debug) ev << "Hello TimeOut in Normal State" << endl;
// we will retransmit this message five time
retransmitHelloMessageForThisTimerMessage(msg);
break;
case NEIGHBOR_DISCOVERED_EVENT:
tcb.state = NORMAL_S;
initializeQueues();
FSM_Goto(fsm, NORMAL);
break;
case TOPOLOGY_UPDATING_TIMER_EVENT:
if(debug) ev << "Topology Update in Normal State" << endl;
sendHelloPacket();
tcb.state = SENT_HELLO_PACKET_S;
topologyUpdateTimer = new cMessage("topologyTimer", TOPOLOGY_UPDATING_TIMER);
scheduleAt(simTime()+ timeValues.topologyUpdatePeriod, topologyUpdateTimer);
sendHelloMsg = new cMessage("sendHelloPacket", SEND_HELLO_PACKET_COM);
scheduleAt(simTime()+ timeValues.waitHelloReplyTime, sendHelloMsg);
FSM_Goto(fsm, SENT_HELLO_PACKET);
break;
case NETLAYER_DATA_PACKET_EVENT:
if(debug) ev << "Data Packet Received in Normal State" << endl;
handleDataPackets((samplePacket*) msg);
break;
case SEND_NORMAL_PACKET_EVENT:
if(debug) ev << "Send Normal Packet Received in Normal State" << endl;
index = msg->kind() - SEND_NORMAL_PACKET_COM;
handleMessageQueue(msg, index);
break;
case NETLAYER_FORWARD_ANT_EVENT:
if(debug) ev << "Forward Ant Received in Normal" << endl;
handleForwardAnt((Ant *) msg);
break;
case NETLAYER_BACKWARD_ANT_EVENT:
if(debug) ev << "Backward Ant Received in Normal" << endl;
handleBackwardAnt((Ant *) msg);
break;
case SEND_BACKWARD_ANT_EVENT:
if(debug) ev << "Send Backward Ant Event received in Normal" << endl;
index = msg->kind() - SEND_BACKWARD_ANT_COM;
handleBackwardAntMessageQueue( (Ant *) msg, index);
break;
default:
if(debug) ev << "In Normal State received: " << tcb.event << endl;
ev << "Current State is" << tcb.state << endl;
error("Unexpected Event: Case Not Handeled");
break;
}
}
void Router::sendHelloPacket()
{
char msgname[70];
// We need to find out which ports are connected to another routers
// and then send hello message on all of these ports
cGate *outTempGate = gate("out");
int vectorSize = outTempGate->size();
for(int i=0; i<vectorSize; i++)
{
cGate *outRouterGate = gate("out", i); //access each gate of router
int gateIDtoNode = outRouterGate->id();
if(outRouterGate->isConnected())
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -