📄 aodv.cpp
字号:
//the RREP originating node (the RREQ target node) d("update the precursor list"); f->updatePrecList((int)msg->par("source")); //e->updatePrecList((int)msg->par("source")); //send the ack message to the neighbour node broadcast( generateACKmsg(msg) ); //set the RREP future next hop reply->par("mac")= f->nextHop; /*Perkins... *Also, at each node the (reverse) route used to forward *a RREP has its lifetime changed to be the maximum *of (existing-lifetime, (current time + ACTIVE_ROUTE_TIMEOUT)). */ f->expiration = max(f->expiration,simTime() +ACTIVE_ROUTE_TIMEOUT); //shift the invalidation of the route if( f->deleteMessage->isScheduled() ) cancelEvent(f->deleteMessage); scheduleAt(f->expiration, f->deleteMessage); //setup the wait for the ack message waitForAck(reply); return reply; } } else { //I am the destination,now a new reoute is available //and all data can be sent WaitingPkt* p = NULL; bool done = false; e = findNode( (int)msg->par("dest") ); d("I received the RREP that I needed..."); if(e == NULL) { d("error: newly aquired route unaviable!"); exit(1); } //send the ack message to the neighbour node broadcast( generateACKmsg(msg)); d("....sending data."); cQueue::Iterator iter(pktBuffer,1); while( ( !iter.end() ) && ( !done ) ) { p = (WaitingPkt*) iter(); if( ( p->dest ==(int) msg->par("dest"))) { //now it is possible to send data, cancel the RREQ failre trigger if(p->deleteEvent->isScheduled()) cancelEvent(p->deleteEvent); //send all the pakets for(int i=0 ; i < p->pktNum ; i++) { d("sending pkt..."); reply = generateDATAmsg(e,p->pktSize); statistics.sentDataPkt++; broadcast(reply); } pktBuffer.remove(p); delete (p); done = true; } else iter++; } return NULL; }}cMessage* AODV::generateRREPmsg(cMessage* msg, int seqNumD,int hops){ cMessage* rrep = new cMessage("RREP",RREP,CTRL_PKT_SIZE,P_RREP); d("genRREP"); //spcify the node addtess for wich a route //is supplyed rrep->addPar("dest") = msg->par("dest"); //the destination seqNum associated to //the route rrep->addPar("seqNumD") = seqNumD; //rrep.originator is the address of the //node which originated the RREQ rrep->addPar("originator") =(int) msg->par("originator"); //the time for wich nodes receiving the RREP cosider //the route to be valid rrep->addPar("lifetime") = MY_ROUTE_TIMEOUT; //if the node is the destinatary of the rreq then hopcount is 0 //otherwise it is the distance to the destination rrep->addPar("hopCount")=0; //ask for a RREP-ACK. used for unidir.links rrep->addPar("flagA") = 1; rrep->addPar("seqNumS") = sequenceNumber; rrep->addPar("ttl") = hops ; rrep->addPar("mac") = msg->par("source"); return rrep;}cMessage* AODV::generateRREQmsg(RouteTableElement* e,int dest,int ttl){ cMessage* reply = new cMessage("RREQ",RREQ,CTRL_PKT_SIZE,P_RREQ); d("genRREQ"); reply->addPar("originator") = parentModule()->id(); reply->addPar("dest") = dest; reply->addPar("seqNumS") = sequenceNumber++; reply->addPar("seqNumD") = (e == NULL? 0 : e->seqNum); reply->addPar("reqId") = reqId++; reply->addPar("hopCount") = 0; reply->addPar("ttl") = ttl; reply->addPar("mac") = BROADCAST; return reply;}void AODV::handleACK(cMessage* msg){ d("handle ACK"); //if it is not for this node, discard if((int) msg->par("mac") != parentModule()->id()) { d("received an ACK message not for me, discarding..."); } else { bool done = false; WaitingRREP* e = NULL; cQueue::Iterator iter(waitingRrep,1); while( ( !iter.end() ) && ( !done ) ) { e = (WaitingRREP*) iter(); if( ( e->destId ==(int) msg->par("originator"))) { //it is the right rrep d("buffered RREP found and acked"); if(e->espireEvent->isScheduled()) cancelEvent(e->espireEvent); waitingRrep.remove(e); //delete all the triggers delete e->espireEvent; delete (e); done = true; } else iter++; } }}cMessage* AODV::generateACKmsg(cMessage* msg){ cMessage* reply = new cMessage("RREP_ACK",RREP_ACK,CTRL_PKT_SIZE,P_RREP_ACK); d("generateACK"); reply->addPar("mac") = msg->par("source"); reply->addPar("originator") = msg->par("originator"); reply->addPar("ttl") = 1; reply->addPar("hopCount") = 0; return reply;}cMessage* AODV::handleRREQ(cMessage *msg){ cMessage* reply; RouteTableElement * e; d("hndRREQ"); //check if the message has been alredy received and processed if (! isNewReq(msg) ) return NULL; else addNewReq(msg); //avoid the RREQ messages form black list's node if( isInBlackList(msg->par("source") ) ) { d("received a RREQ msg from a node in the black list. DISCARDING"); return NULL; } //check the neighbour node that sent the message d("check the neighbour node that sent the message"); e = findNode( (int)msg->par("source") ); if(e == NULL) //add a new neighbour //but I don't know the seqNumber -->0 //the hopCount is 1 addNewDestination((int)msg->par("source"), (int)msg->par("source"),0,1,simTime()+ACTIVE_ROUTE_TIMEOUT); else updateRouteTable(e,e->seqNum,1, (int)msg->par("source"), simTime()+ACTIVE_ROUTE_TIMEOUT);
//check if the originator node is known
d("check if the originator node is known");
if( (int)msg->par("originator") != (int) msg->par("source"))
{
e = findNode( (int)msg->par("originator") );
if( e == NULL)
//add a new destination
addNewDestination((int)msg->par("originator"),
(int)msg->par("source"),
(int)msg->par("seqNumS"),
(int)msg->par("hopCount"),
simTime()+REV_ROUTE_LIFE);
else
//check whether there is the need of
//a refresh in the table data
updateRouteTable(e, (int)msg->par("seqNumS"),
(int)msg->par("hopCount"),
(int)msg->par("source"),
max(e->expiration,simTime()+ REV_ROUTE_LIFE));
}
//now check the destination e = findNode((int) msg->par("dest") ); d("now check the RREQ destination"); if( parentModule()->id() == (int)msg->par("dest") ) { // I am the destination d("---- I am the RREQ destination generate RREP ---- "); //a host must increment his seq.num //before genereting a new RREP mesage sequenceNumber = max(sequenceNumber,(int)msg->par("seqNumD")); reply = generateRREPmsg(msg, sequenceNumber,(int) msg->par("hopCount")); //setup the wait for the ack message waitForAck(reply); return reply; } else if (e == NULL) { // the destination is unknown // copy the RREQ message,increment hopCount, // decrement TTL and rebroadcast it d("RREQ destination unknown, forwarding..."); reply = new cMessage(*msg); reply->par("hopCount") = (int) reply->par("hopCount")+1; return reply;; } else if( (e->seqNum < (int) msg->par("seqNumD") ) || (!e->active) ) { //I am an intermediary node but //the informations in the routeTable are old.Do nothing d("the informations in the routeTable are old, do nothing..."); return NULL; } else { //I am an intermediary node. d("I am an intermediary node: I've got a route to the destination!"); //uses the last known sequence number as seqNumberD //rrep ttl is the sum of the rreq made hops and the hops remaining toward the destination reply = generateRREPmsg(msg, e->seqNum,(int) msg->par("hopCount")); reply->par("hopCount") = e->hopCount ; reply->par("lifetime") = e->expiration - simTime(); //add the source node into the precursor list of the destination e->updatePrecList( (int)msg->par("source")); //setup the wait for the ack message waitForAck(reply); return reply; }}cMessage* AODV::copyMessage(cMessage* msg){ //copy the data within the msg oject cMessage* newMsg = new cMessage(*msg); return newMsg; d("cpy");}RouteTableElement* AODV::addNewDestination(int dest,int source,int seqN,int hopCount,simtime_t expire){ RouteTableElement* e = new RouteTableElement(); d("addNewDest"); char d[20]; d("aggiungo :"<<dest); e->destId = dest; //the neighbour node that sent the message e->nextHop = source; e->seqNum = seqN; e->hopCount = hopCount ; d("hops:"<<hopCount); e->expiration = expire; d("add new dest : espire = "<<expire); e->active = true; sprintf(d,"r.time out to %d",dest); e->deleteMessage = new cMessage(d,MK_DELETE,0,P_DELETE); e->deleteMessage->addPar("node") = (cObject*) e; //if whithin a preconfigured period the route //will not be refreshed it will be cancelled scheduleAt(expire ,e->deleteMessage); routeTab.insert( (RouteTableElement*) e); return e;}void AODV::updateRouteTable(RouteTableElement* e,int seqNum,int hopCount,int nextHop, simtime_t time){ d("updRoute per :"<<e->destId); if( (seqNum > e->seqNum) || ((seqNum==e->seqNum) && (hopCount < e->hopCount )) || ((seqNum==e->seqNum) && (hopCount == e->hopCount) && (e->expiration < time) ) ) { d("updating... "); //update the entry e->hopCount = hopCount; e->nextHop = nextHop; e->seqNum = seqNum; e->active = true; e->expiration = time; //shift the invalidation of the route cancelEvent(e->deleteMessage); scheduleAt(e->expiration, e->deleteMessage); } else d("table not upadated");}RouteTableElement* AODV::findNode(int n){ RouteTableElement * e = NULL; d("find :"<<n); for( cQueue::Iterator iter(routeTab,1) ; !iter.end(); iter++) { e = (RouteTableElement*) iter(); if(e->destId == n ) return e; } return NULL;}void AODV::addNewReq(cMessage* msg){ OldReqs* r = new OldReqs(); d("addNewReq"); r->originator = msg->par("originator"); r->reqId = msg->par("reqId"); r->time = simTime(); oldReqs.insert( (OldReqs*) r);}bool AODV::isNewReq(cMessage *msg){ int origin, reqId; d("isNewReq msg:"<<msg->name()); origin = msg->par("originator"); reqId = msg->par("reqId"); OldReqs* r = NULL; for(cQueue::Iterator iter(oldReqs,1); !iter.end(); iter++) { r =(OldReqs*) iter(); if((r->originator == origin)&&(r->reqId == reqId )) { //the same request can not be served twice //within a period of PATH_TRAVERSAL_TIME if( (simTime()- r->time) >= PATH_TRAVERSAL_TIME) { //the request is processable //remove just unlik r from the queue oldReqs.remove( (OldReqs*)r); delete r; return true; } else return false; } } return true;}bool RouteTableElement:: updatePrecList(int ip){ PrecursorElement * e = NULL; for( cQueue::Iterator iter(precList,1) ; !iter.end(); iter++) { e = (PrecursorElement*) iter(); if(e->ip == ip) { return false; } } //ip is a new element so add it to the list e = new PrecursorElement(); e->ip = ip; precList.insert( (PrecursorElement*) e); return true;}void Statistics::collect(cMessage* msg, double now){ double latency = now - (double) msg->par("sendingTime"); int i = (int)msg->par("hopCount"); maxHop = max(maxHop, i); //if the vector cell is not empty PartialStat* cell = (PartialStat*)hopsV[i]; if(cell) { cell->latencySum += latency; cell->throughSum += msg->length() / latency; cell->samples ++; } else { PartialStat* cell = new PartialStat(latency, msg->length() / latency); hopsV.addAt(i,cell) ; } hopsSum += i; deliveredDataMsg++;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -