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

📄 aodv.cpp

📁 OMNET++仿真三色算法的源码,三色算法是无线传感器中一个典型的分簇算法
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include "h/aodv.h"#include "h/aodvCostants.h"#define max(a,b) (a>b ? a : b)Define_Module_Like(AODV,Routing);//****************** costructors and destructors of secondary objects ****************AODV::~AODV(){}WaitingPkt::WaitingPkt(){};WaitingPkt::~WaitingPkt(){};OldReqs::OldReqs(){};OldReqs::~OldReqs(){};PrecursorElement::PrecursorElement(){};PrecursorElement::~PrecursorElement(){};BlackListElement::BlackListElement(){};BlackListElement::~BlackListElement(){};WaitingRREP::WaitingRREP(){};WaitingRREP::~WaitingRREP(){};RouteTableElement::RouteTableElement(){};RouteTableElement::~RouteTableElement(){};PartialStat::PartialStat(double lat, double th)
{
	latencySum = lat;
	throughSum = th;
	samples = 1;
};PartialStat::~PartialStat(){};Statistics::Statistics(){	hopsSum = 0;	deliveredDataMsg = 0;	sendDataMsg = 0;	sentCtrlPkt =0;	sentDataPkt =0;	maxHop =0;}Statistics::~Statistics(){};//function used by  queue.inset  to set up a oredered queueint compareFunc(cObject* a, cObject *b){	RouteTableElement* l = (RouteTableElement*)a;	RouteTableElement* r = (RouteTableElement*)b;	return ( l->destId - r->destId);}//***********************************************************************************void AODV::initialize(){	d("AODV protocol simulator based on the IEEE-MANET Internet Draft  v.10");	//initialize the local variables	sequenceNumber = 0;	//counter to generate unique  RREQs	reqId = 0;	//	pktHistogram.setName("paket kind histogram");	pktHistogram.setRange(0,13);	hopsHistogram.setName("hops number histogram");	hopsHistogram.setRange(1,20);	//give to the queue the sorting capability	routeTab.setup(compareFunc);	//let some vars to be editable from the TkEnv environment	WATCH(sequenceNumber);	WATCH(statistics.sentCtrlPkt);	//schedule the first message tho initialize the send hello chain	helloEvent  = new cMessage("sendHello",MK_SEND_HELLO,0,P_SEND_HELLO);	scheduleAt(simTime()+0.5, helloEvent);}void AODV::handleMessage(cMessage *msg){  cMessage* reply = NULL;  d("HANDLE message routine");  if (msg->arrivedOn("fromApp") )  {	 d("messasge arrived from app");	  reply = sendData(msg);	  broadcast(reply);	  delete msg;  }  else  {	 //collect the message kind	 pktHistogram.collect( msg->kind() );  	 switch(msg->kind())	 {	 case MK_SEND_HELLO:		 d("sendHello");		 reply = generateHELLOmsg();		 broadcast(reply);		 break;	 case MK_DELETE:		 /*		  * Note that the Lifetime field in the		  * routing table plays a dual role		  *  -- for an active route it is the		  *  expiry time, and for an invalid		  *  route it is the deletion time.		  *  If a data packet is received for an		  *  invalid route, the Lifetime field is		  *  updated to current time plus		  *  DELETE_PERIOD.		  */		d("delete");		 reply = handleDelete(msg);		 broadcast(reply);		 break;	 case HELLO:		d("hello");		 //AODV specification says that the HELLO messages		 //are a spcial kind of RREP msg.		 //For semplicity I've chosen to treat		 //them as a different kind of message.		 handleHELLO(msg);		 delete msg;		 break;	 case MK_FLUSH:		d("flush");		 //A RREQ has been timed out		 //so do what has to be done		 reply = handleFlush(msg);		 broadcast(reply);		 break;	 case RREQ: 		 d("rreq "<<msg->name());		 reply = handleRREQ(msg);		 //if the message received need a reply		 //then send it to the mac module that will		 //care about sending it around		 broadcast(reply);		 delete msg;		 break;	 case RREP:		 d("rrep");		reply = handleRREP(msg);		broadcast(reply);		delete msg;		break;	case RERR:		d("rerr");		reply = handleRERR(msg);		broadcast(reply);		delete msg;		break;	case DATA:		d("data");		reply = handleData(msg);		broadcast(reply);		delete msg;		break;	case RREP_ACK:		d("ack");		handleACK(msg);		delete msg;		break;	case MK_ESP_ACK:		d("esp_ack");		reply = handleESP_ACK(msg);		broadcast(reply);		break;	case MK_BLK_LIST:		d("black list");		handleBLK_LIST(msg);		delete msg;		break;	 }  }}void AODV::finish(){	//I will write on a file instead of usa recordScalar() beacuse of a bug in this	//function that rewrites the file on each run	FILE* fout = fopen("collectedData.dat","a");	dd("Hosts number..........."<< (int)parentModule()->par("numHost"));	dd("Sent control pakets...."<<statistics.sentCtrlPkt);	dd("Sent data pakets......."<<statistics.sentDataPkt);	dd("Delivered data pakets.."<<statistics.deliveredDataMsg);	if(statistics.deliveredDataMsg > 0)		dd("Hops Avarage..........."<<statistics.hopsSum / statistics.deliveredDataMsg );		PartialStat* cell;		fprintf(fout,"Hosts number:............... %d\n",(int)parentModule()->par("numHost"));		fprintf(fout,"Sent control pakets......... %d\n",statistics.sentCtrlPkt);		fprintf(fout,"Sent data pakets............ %d\n",statistics.sentDataPkt);		fprintf(fout,"Delivered data pakets....... %d\n",statistics.deliveredDataMsg);		for(int i=0; i<= statistics.maxHop; i++)		{			cell = (PartialStat*) statistics.hopsV[i];			if(cell)			{				fprintf(fout,"Per-Hop throughput misured... %d	%.0f\n",i, cell->throughSum/cell->samples);				dd("Per-Hop throughput misured..."<<i<<" "<<cell->throughSum / cell->samples);				fprintf(fout,"Per-Hop latency misured..... %d	%.6f\n",i, cell->latencySum / cell->samples);				dd("Per-Hop latency misured....."<<i<<" "<<cell->latencySum / cell->samples);			}		}		if(statistics.deliveredDataMsg > 0)			fprintf(fout,"Hops Avarage................ %d\n",statistics.hopsSum / statistics.deliveredDataMsg);		fclose(fout);}void AODV::broadcast(cMessage* reply){	if(reply !=NULL)	{		int ttl;		d("send to mac:"<<reply->name()<<" "<<reply->kind());		ttl = (int) reply->par("ttl")-1;		if( ttl >= 0 )		{			reply->par("ttl") = ttl;			reply->par("hopCount") = 1+ (int)reply->par("hopCount");			//add the source parmeter that is common to all the messages			if(reply->hasPar("source"))				reply->par("source") = (int)parentModule()->id();			else				reply->addPar("source") = (int)parentModule()->id();			send(reply,"toMac"); // FIXME it is illegal to send a msg object and keep referencing it!!! -Andras			//send Hello only when helloEvent is extracted from the FES (event queue)			//or the message(like data) do not make the route			//table to be refreshed			if((reply->kind() != HELLO) && (reply->kind() != DATA) )				if (helloEvent->isScheduled() )					cancelEvent( helloEvent );			//only control packets make the other nodes refresh			//their route			if( reply->kind() != DATA)			scheduleAt(simTime()+HELLO_INTERVAL,helloEvent );			if( (reply->kind() == RREQ) || (reply->kind() == RREP) ||  		    	    (reply->kind() == RERR) || (reply->kind() == RREP_ACK) )					statistics.sentCtrlPkt ++;		}		else		{			d("ttl espired! the msg will not be sent:");			delete reply;		}	}}void AODV::waitForAck(cMessage* msg){		d("waitForAck");		//schedule a trigger to simulate an ACK failure		WaitingRREP* e = new WaitingRREP();		e->destId = (int) msg->par("originator");		e->nextHopId = (int) msg->par("mac");		e->trials = 1;		//pointer to the rreq message		e->rreqMsg = new cMessage(*msg);		//trigger		e->espireEvent = new cMessage("rrep ack espired",MK_ESP_ACK,0,P_ESP_ACK);		//pointer to the RREP  entry in that has failed to arrive		e->espireEvent->addPar("element") = (WaitingRREP*) e;		waitingRrep.insert( (WaitingRREP*) e);		scheduleAt(simTime()+ NEXT_HOP_WAIT, e->espireEvent);}cMessage* AODV::handleESP_ACK(cMessage* msg){	bool done = false;	WaitingRREP*e = NULL;	d("handle MK_ESP_ACK");	//ugly but it is the only way...	e =  (WaitingRREP*) (cObject*) msg->par("element");	d("RREP ACK timed out (the ack message is not arrived) check out what's to be done");	e->trials++;	if(e->trials > RREP_RETRIES)	{		d("no more trials left...put the neig. in the black list");		//flush the RREP buffer!		waitingRrep.remove(e);		//add the node to the black list		BlackListElement* b = new BlackListElement();		b->id = e->nextHopId;		b->removeEvent = new cMessage("remove from B.L.",MK_BLK_LIST,0,P_BLK_LIST);		b->removeEvent->addPar("node") = (cObject*) b;		blackList.insert( (BlackListElement*) b );		//scehdule the node removal from the blacklist		scheduleAt(simTime()+BLACKLIST_TIMEOUT,b->removeEvent);		//delete the message here because it has to be deleted only in this case		delete msg;		//msg is stored in e so I have to delete it here rather than before		delete e;		return NULL;	}	else	{		d("there are more chance left");		//retrasmit the stored rrep		cMessage* rrep = new cMessage(*e->rreqMsg);		//schedule the next ack time out event		scheduleAt(simTime()+ NEXT_HOP_WAIT, e->espireEvent);		return rrep;	}}void AODV::handleBLK_LIST(cMessage* msg){	d("hanldle black list");	BlackListElement* e = (BlackListElement*)(cObject*) msg->par("node");	blackList.remove(e);	delete e;}bool AODV::isInBlackList(int node){	cQueue :: Iterator iter(blackList,1);	bool found = false;	BlackListElement* e = NULL;	d("isInBlackList");	while( ( !iter.end() ) && ( !found ) )	{		e = (BlackListElement*) iter();		if(e->id == node)		{			found = true;		}		else iter++;	}	return found;}cMessage* AODV::sendData(cMessage* msg){	RouteTableElement *e = NULL;	d("sendData");	//check for a route	e = findNode(msg->par("dest") );	if( (e == NULL) || (e->active==false))	{		cMessage* reply;		//bufferize the request while look for a route,		//returns the event that has to be scheduled to		//menage the retrasmit RREQ event		reply = bufferize(msg->par("dest"),msg->length());		if(reply !=NULL)		{			//schedule the RREQ failure			scheduleAt(simTime()+ 2 * TTL_START * NODE_TRAVERSAL_TIME , reply);			reply = generateRREQmsg(e,msg->par("dest"),TTL_START);			//remember the rreq  			addNewReq(reply);			//return the RREQ message that wil be sent out			return reply;		}		else		{	d("RREQ not generated");			return reply;		}	}	else	{		//add all the params that are needed		cMessage* m = generateDATAmsg(e,msg->length());		d("want to send data to a known destination "<<msg->par("dest"));		statistics.sentDataPkt ++;		return m;	};}cMessage* AODV::bufferize(int dest,int pktSize){	bool found = false;	WaitingPkt* p = NULL;	d("bufferize");	for(cQueue:: Iterator iter(pktBuffer,1); !iter.end(); iter++)	{		p = (WaitingPkt*) iter();		if(p->dest == dest)		{			//if there is a RREQ at work just add a new pkt			p->pktNum++;			return NULL;		}	}	//this is a new paket : create the message that	//make the RREQ msg to be timed-out and reseded	p = new WaitingPkt;	p->dest = dest;	p->trial = 1;	p->pktNum = 1;	p->pktSize = pktSize;	//RREQ time out trigger	p->deleteEvent = new cMessage("RREQ time out",MK_FLUSH,P_FLUSH);	p->deleteEvent->addPar("dest") = dest;	p->deleteEvent->addPar("ttl") = TTL_START;	pktBuffer.insert(p);	return p->deleteEvent;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -