⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aodv.cc

📁 this is source code for adhoc network using omnet
💻 CC
📖 第 1 页 / 共 3 页
字号:
		//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			//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 = new cMessage(*msg);			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 route 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 acquired route unavailable!");			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 failure trigger				 if(p->deleteEvent->isScheduled()) {					cancelEvent(p->deleteEvent);					// NB Now we can delete the msg from memory					delete p->deleteEvent;				 }				//send all the packets				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				/* NB */				/*if(e->rreqMsg)*/ delete e->rreqMsg;				/*if(e->espireEvent)*/ 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 already 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 object	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 : expire = "<<expire);	e->active = true;	sprintf(d,"r.time out to %d",dest);	e->deleteMessage = new cMessage(d,DELETE,0,P_DELETE);	e->deleteMessage->addPar("node") = (cObject*) e;	//if within 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 updated");}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;}/* *	Adds a RREQ message to oldReqs queue *	NB: When this will be flushed? */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;	dd("isNewReq msg:"<<msg->name());	origin = msg->par("originator");	reqId = msg->par("reqId");	dd("reqId="<<reqId<<" origin="<<origin);	OldReqs* r = NULL;	for(cQueue::Iterator iter(oldReqs,1); !iter.end(); iter++)	{		r =(OldReqs*) iter();		if((r->originator == origin)&& (r->reqId == reqId ))		{			dd("OldReq:"<<					"originator="<<r->originator<<" reqId="<<r->reqId<<"time="<<r->time);			//the same request can not be served twice			//within a period of  PATH_TRAVERSAL_TIME			if( (simTime()- r->time) >= PATH_TRAVERSAL_TIME)			{				dd("deleting OldReq:"<<						"originator="<<r->originator<<" reqId="<<r->reqId<<"time="<<r->time);				//the request is processable				//remove just unlink 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 + -