📄 aodv.cpp
字号:
cMessage* AODV::handleFlush(cMessage* msg){ WaitingPkt* p = NULL; cMessage* reply = NULL; RouteTableElement *e = NULL; d("handleFlush"); for(cQueue::Iterator iter(pktBuffer,1); !iter.end(); iter++) { p = (WaitingPkt*) iter(); if(p->dest == (int) msg->par("dest")) { d("RREQ timed out (RREP is not arrived in time)"); //Perkins.... //Each attempt increments the RREQ ID //field in the RREQ packet. The RREQ can be broadcast with //TTL = NET_DIAMETER up to a maximum of RREQ_RETRIES times. if ((int)msg->par("ttl") == NET_DIAMETER) p->trial++; if(p->trial > RREQ_RETRIES) { d("data trasmissiond aborted: deleting the out data buffer"); //flush the buffer! pktBuffer.remove(p); delete p; delete msg; return NULL; } else { //try a new RREQ d("RREQ timed out: retrasmit"); //increse the TTL value. If this is bigger than a TTL_Threshold //then use NED_DIAMETER instead int ttl = (int)msg->par("ttl") + TTL_INCREMENT ; ttl = ttl < TTL_THRESHOLD ? ttl : NET_DIAMETER; msg->par("ttl") = ttl; scheduleAt(simTime()+ ( 2 * ttl * NODE_TRAVERSAL_TIME) , p->deleteEvent); reply = generateRREQmsg(e,msg->par("dest"),ttl); addNewReq(reply); return reply; } } }}cMessage* AODV::handleDelete(cMessage* msg){ RouteTableElement *e = NULL; cMessage* reply = NULL; int err = 0; //checkRouteRep needs a int& as the 3rd par d("hndle Delete"); e =(RouteTableElement*)(cObject*) msg->par("node") ; d("the route to "<<e->destId<<" is timed out."); if(e->active) { d("SET the route as inagible"); //route has exired, set it invalid //and schedule the final Delete event e->active = false; e->seqNum ++; scheduleAt(simTime()+ DELETE_PERIOD, msg); //check for other possible new invalid routes reply=checkRouteTable(e,reply,err); } else { d(" delete ROUTE! to "<<e->destId); //unlink the route from the table routeTab.remove(e); //delete it delete e; } return reply; //the precursor list should be deleted by //the destructor}cMessage* AODV::generateHELLOmsg(){ cMessage* reply = new cMessage("Hello",HELLO,CTRL_PKT_SIZE,P_HELLO); d("genHello"); reply->addPar("seqNumS") = sequenceNumber; reply->addPar("hopCount") = 0; //ttl is not needed due to the nature //of the message that is never retrasmitted reply->addPar("ttl") = 1; reply->addPar("mac") = BROADCAST; return reply;}void AODV::handleHELLO(cMessage* msg){d("hndleHello"); RouteTableElement *e = NULL; e = findNode( (int) msg->par("source") ); if( e == NULL) //add a new destination addNewDestination((int)msg->par("source"), (int) msg->par("source"), (int) msg->par("seqNumS"), (int) msg->par("hopCount"), simTime()+ACTIVE_ROUTE_TIMEOUT); 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"), simTime()+ACTIVE_ROUTE_TIMEOUT ); } d("fine handleHello");}cMessage* AODV::checkRouteTable(RouteTableElement*b,cMessage* reply,int& errors){ RouteTableElement* e = NULL; d("check RouteTable integrity"); //if the brand new invalid destination has hosts in the precursor list... if(!b->precList.empty()) { char s[10]; errors++; d("the prec list of "<<b->destId<<"is not empty"); //it can be not NULL! if(reply==NULL) { reply = new cMessage("RERR",RERR,CTRL_PKT_SIZE,P_RERR); reply->addPar("errCount") = 0; reply->addPar("ttl") = 1; reply->addPar("hopCount") = 0; reply->addPar("seqNumS") = sequenceNumber; reply->addPar("cc") ="fatto da check 1"; reply->addPar("mac") = BROADCAST; } sprintf(s,"%d",errors); reply->addPar(s) = b->destId; //add the seq number of the known route sprintf(s,"seqNumD%d",errors); reply->addPar(s) = b->seqNum; reply->par("errCount")= 1+(int)reply->par("errCount") ; } d("check other routes... "); //if it is a neighbour that is no more reachable //then there might be more ureachable desinations if(b->hopCount == 1) { d("it is a neighbour!"); for( cQueue::Iterator it(routeTab,1) ; !it.end(); it++) { //check if there are destination that use the broken link as next hop e = (RouteTableElement*) (cObject*) it(); if( (e->active) && (e->nextHop == b->nextHop)) { //the route is no more available cancelEvent(e->deleteMessage); scheduleAt(simTime()+DELETE_PERIOD, e->deleteMessage); e->active = false; //there might be more invalid routes... :-( if(!e->precList.empty()) { char s[20]; errors++; if(reply==NULL) { reply = new cMessage("RERR",RERR,CTRL_PKT_SIZE,P_RERR); reply->addPar("errCount") = 0; reply->addPar("ttl") = 1; reply->addPar("hopCount") = 0; //reply->addPar("cc") = "fatto da ck 2"; reply->addPar("seqNumS") = sequenceNumber; reply->addPar("mac") = BROADCAST; } //add the unreachable nodes to the RERR message sprintf(s,"%d",errors); reply->addPar(s) = e->destId; reply->par("errCount") = errors; sprintf(s,"seqNumD%d",errors); d(s); reply->addPar(s) = e->seqNum; } //there is not the need to check the //precList of the new invalid routes //beacause all of these have as next //hop the broken node "b" and so these //will be added to the RERR msg when //checked by the iterator } } } return reply;}cMessage* AODV::handleData(cMessage* msg){ cMessage* reply = NULL; RouteTableElement* e = NULL; d("hndleData"); //check if the message has been precessed due to the promiscue mode if(parentModule()->id() != (int)msg->par("mac") ) { d("received a message not for me...discarding!"); return NULL; } d("arrived data msg for "<<msg->par("dest")); //check if the message is for this host if(parentModule()->id() == (int)msg->par("dest") ) { d("DATA MESSAGE ARRIVED AT DESTINATION sent by "<<msg->par("source")); //collect all the statistic data statistics.collect(msg, simTime()); hopsHistogram.collect((int)msg->par("hopCount")); return NULL; } else { //this host in not the final destination but the message states that //this node is used to reach it. RouteTableElement* e = NULL; d("Data message not for me but i am on the route, forwarding..."); e = findNode( (int)msg->par("dest") ); if((e == NULL) || (!e->active)) { //the route is unknown or expired //do nothing... d("ERROR! The route to the destination is unknown!"); return NULL; } else { d("Data message updated, forwarding!"); reply = copyMessage(msg); reply->par("mac") = e->nextHop; /*Perkins.... * Each time a route is used to forward a data packet, its Active Route Lifetime field of both the destination and the next hop on the path to the destination is updated to be no less than the current time plus ACTIVE_ROUTE_TIMEOUT. */ e->expiration = max(e->expiration,simTime() +ACTIVE_ROUTE_TIMEOUT); //shift the invalidation of the route cancelEvent(e->deleteMessage); scheduleAt( e->expiration, e->deleteMessage); e = findNode(e->nextHop); e->expiration = max(e->expiration,simTime() +ACTIVE_ROUTE_TIMEOUT); //shift the invalidation of the route cancelEvent(e->deleteMessage); scheduleAt(e->expiration, e->deleteMessage); return reply; } }}cMessage* AODV::generateDATAmsg(RouteTableElement*e,int size){ cMessage* m = new cMessage("Data",DATA,size,P_DATA); m->addPar("dest") = e->destId; m->addPar("originator") = parentModule()->id(); m->addPar("hopCount") = 0; m->addPar("ttl") = e->hopCount; m->addPar("mac") = e->nextHop; m->addPar("sendingTime") = simTime(); return m;}cMessage* AODV::handleRERR(cMessage *msg){ cMessage* reply = NULL; d("handle RERR"); RouteTableElement * e; int errors = 0; //check if the trasmitting node is known e = findNode( (int)msg->par("source") ); if( e == NULL) //add a new destination addNewDestination((int)msg->par("source"), (int)msg->par("source"),0,1, simTime()+ACTIVE_ROUTE_TIMEOUT); else updateRouteTable(e, e->seqNum, (int)msg->par("hopCount"), (int)msg->par("source"), simTime()+ACTIVE_ROUTE_TIMEOUT); if(msg->hasPar("errCount")) { char s[5],d[10]; int k = (int) msg->par("errCount"); for(int i = 1; i <= k; i++) { //the parameter stores the nodes's id d("number of errors: "<<k); //extract the unreachable destination sprintf(s,"%d",i); //extract its sequence number sprintf(d,"seqNumD%d",i); //find the broken node and update the route table e = findNode( (int) msg->par(s) ); if((e != NULL) && (e->nextHop ==(int) msg->par("source")) && (e->active) && (e->seqNum <= (int)msg->par(d) ) ) { e->active = false; cancelEvent(e->deleteMessage); scheduleAt(simTime()+ DELETE_PERIOD, e->deleteMessage); //build an eventual new RERR message reply = checkRouteTable(e,reply,errors); } } } return reply;}cMessage* AODV::generateRERRmsg(RouteTableElement* e,int dest){ cMessage* msg = NULL;d("genRERR"); if((e == NULL) || !e->precList.empty()) { msg = new cMessage("RERR",RERR,CTRL_PKT_SIZE,P_RERR); msg->addPar("1") = dest; msg->addPar("errCount") = 1; msg->addPar("seqNumD1") = (e != NULL? e->seqNum : 0); msg->addPar("seqNumS") = sequenceNumber; msg->addPar("hopCount") = 0; msg->addPar("ttl") = 1; //msg->addPar("cc") ="fatto da genRERR"; msg->addPar("mac") = BROADCAST; } return msg;}cMessage* AODV::handleRREP(cMessage *msg){ cMessage* reply = NULL; d("handle RREP"); RouteTableElement *e, *f; //check if the trasmitting neighbour node is known d("check the route to the neighbour node"); e = findNode( (int)msg->par("source") ); if( e == NULL) //add a new destination e = 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); if (parentModule()->id() == (int)msg->par("dest")) { d("received a rrep generated by me, deleting"); return NULL; } //check the node that generated the RREP d("check if the RREP originating node is known..."); //if false, dest is the neighbour that has alredy been checked if ((int) msg->par("dest") != (int) msg->par("source")) { e = findNode( (int)msg->par("dest") ); d("rrep->Lifetime: "<<(int)msg->par("lifetime")); if( e == NULL) //add a new destination e = addNewDestination((int)msg->par("dest"), (int)msg->par("source"), (int)msg->par("seqNumD"), (int)msg->par("hopCount"), simTime()+(simtime_t)msg->par("lifetime")); else { //check whether there is the need of a refresh in the table data updateRouteTable(e,(int)msg->par("seqNumD"), (int)msg->par("hopCount"), (int)msg->par("source"), simTime()+ (simtime_t) msg->par("lifetime") ); } } //handle the RREP msg only if it is for this node if( parentModule()->id() != (int) msg->par("mac")) { d("received a RREP message that was not for me...siffing and discarding!"); return NULL; } //check whether I am not the originator node of the RREQ //message, just forward it toward the right node if( parentModule()->id() != (int)msg->par("originator") ) { d("I am on the route back to the RREQ originator --> Forward RREP "); reply = copyMessage(msg); f = findNode( (int)msg->par("originator") ); if(f == NULL) { d("ERROR! the route back to the RREQ originator is not known or espired!"); return NULL; } else { //add the RREP future next hop to the precursor list of the route toward
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -