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

📄 asyncnetlayer.cc

📁 基于omnet++开发的Mf框架下的802.11协议仿真。
💻 CC
字号:
/* -*- mode:c++ -*- ********************************************************
 * file:        AsyncNetwLayer.cc
 *
 * author:      Yupeng.hu
 *
 * copyright:   (C) 2006 HUNAN Universtiy, ChangSha China
 *
 ***************************************************************************
 * part of:     Async Simulation
 * description: - Async Description
 *
 ***************************************************************************
 * changelog:   $Revision$
 *              last modified:   $Date: 2006-7-7 10:21 $
 *              by:              $Author: Yupeng.hu $
 ***************************************************************************/
//#include <iostream.h>
//#include <fstream.h>
#include "AsyncNetLayer.h"
#include <NetwPkt_m.h>
#include <time.h>
#include<fstream>

#define EV (ev.disabled()||!debug) ? (std::ostream&)ev : ev << logName() << "::AsyncNetLayer: "

Define_Module(AsyncNetLayer);


/**
 * Reads all parameters from the ini file. If a parameter is not
 * specified in the ini file a default value will be set.
 **/
void AsyncNetLayer::initialize(int stage)
{
	BasicNetwLayer::initialize(stage);
  
	if(stage==0)
	{       	   	
    	maxHops=14;
    	for(int i=0;i<maxHops;i++)
    	{
    		mean[i]=0;
    	}
    	for(int i=0;i<maxHops;i++)
    		for(int j=0;j<2;j++)
    			{delay[i][j]=0;}
    	
    	for(int i=0; i<15; ++i)
    	  clu[i]=0;
    	head[0]=48;
    	head[1]=43;
    	head[2]=36;
    	head[3]=14;
    	head[4]=22;
    	head[5]=27;
    	head[6]=33;
    	head[7]=7;
    	/*for(int i=0;i<15;i++)
    	{ EV<<endl;
    		EV<<"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"<<endl;
    		EV<<clu[i]<<endl;
    		//EV<<endl;
    	}*/

    	status=NO_CLUSTER;
    	conStatus=NO_CONNECT;
    	r=par("round");  //簇的稳定的时间,一段时间后要重新生成簇头。    	clusterEvent=new cMessage("clusterEvent");
    	scheduleAt(simTime(), clusterEvent);
    	topo = new cTopology("topo");
     //	int clusterHead=0;  //这个地方好像有点问题      clusterHead=0;
    	WATCH(status);
    	WATCH(conStatus);
    	WATCH(clu);  //多的    	
    	EV <<"AsyncNetLayer is loaded"<<endl;
    	
  	}
}


/** 
 * Convienience function which calls sendDelayedDown with delay set to
 * 0.0.
 *
 * @sa sendDelayedDown
 **/
void AsyncNetLayer::handleUpperMsg(NetwPkt* msg)
{    
   
    msg->setTimestamp();
    ev<<logName()<<"AsyncNetLayer::"<<"The timeStamp is"<<msg->timestamp()<<endl;
    topo = new cTopology("topo");
    topo->extractByModuleType(findHost()->className(), NULL); 
    int dest=findHost()->submodule("appl")->par("destAddress");//topo->node 's index() is i 		  		
    topo->unweightedSingleShortestPathsTo(topo->node(dest));
    int  distance=topo->nodeFor(findHost())->distanceToTarget();
        
    ev << logName() << "::AsyncNetLayer:" <<" distance to sink node is: "<<distance<<endl;
    msg->setKind(distance);//put hops into packet
    if(status==IS_CLUSTER)//如果是簇头节点生成的数据报则进入路由,寻找下一跳;否则,直接    {                     //赋值下一跳为簇头       Routing(msg);
    }
    else if(status==NO_CLUSTER && conStatus==NO_CONNECT) //既不是簇头,也不是簇内,则按原有路由    {
    	Routing(msg);
    }
    else
    {
	    MacControlInfo* cInfo = new MacControlInfo;
	    cInfo->setNextHopMac(clusterHead);
	    //msg->setControlInfo(cInfo);
	    sendDown(msg,-2,lowergateOut);
	    EV <<"ControlInfo set; sending down msg\n";
    }
}


/**
 * Redefine this function if you want to process messages from lower
 * layers before they are forwarded to upper layers
 *
 *
 * If you want to forward the message to upper layers please use
 * @ref sendUp which will take care of decapsulation and thelike
 **/
void AsyncNetLayer::handleLowerMsg(NetwPkt* msg) //变化了{
	  ev<<logName()<<"!!!!!!!!!!!!!!!!"<<endl;
    ev<<logName()<<"msg->getTag()="<<msg->getTag()<<endl;
    topo = new cTopology("topo");
    topo->extractByModuleType(findHost()->className(), NULL); 
    int dest=findHost()->submodule("appl")->par("destAddress");//topo->node 's index() is i 		  		
    topo->unweightedSingleShortestPathsTo(topo->node(dest));
    int distance=topo->nodeFor(findHost())->distanceToTarget();
    ev<<logName()<<"distance is "<<distance<<endl;
    
    
    if(msg->getTag()==4&& status==NO_CLUSTER&& conStatus==NO_CONNECT&&distance!=0)//kind()不能用    {   //msg->getTag()is verdicting whether it is a broadcasting frame or not
    	  //status == N0_CLUSTER is verdicting whether it is a cluster or not
    	  //conStatus == NO_CONNECT is verdicting whether it is connecting to other cluster or not
    	  //distance != 0 is verdicting it is not a sink node
    	findHost()->displayString().setTagArg("i",1, "green");
    	ev<<logName()<<"AsyncNetLayer:: Is connected with clusterHead node!"<<endl;
    	conStatus=IS_CONNECT;
    	ev<<logName()<<"AsyncNetLayer::clusterHead's macAddr is"<<msg->getSrcAddr()<<endl;
    	clusterHead=msg->getSrcAddr()+1;
    	WATCH(clusterHead);
    	ev<<logName()<<"clusterHead="<<clusterHead<<endl;
    	delete msg;
    	sendClusterAckMsg();  //多的    }
    else if(msg->getTag()==5&&status==IS_CLUSTER)  //多的    {
    	int i=0;
    	//EV<<"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"<<endl;
     	while(clu[i]!=0)
     	{
     		i++;
     	}
     	clu[i]=msg->getSrcAddr();     	
    }
    else if(msg->getTag()!=4&&msg->getTag()!=5)
    {
   	  double t = simTime()-msg->timestamp();	
      EV<<"pkt delay:"<<t<<"="<<simTime()<<"-"<<msg->timestamp()<<endl;
      delay[msg->kind()-1][0]+=t;
      delay[msg->kind()-1][1]+=1;
      ev<<"hop-"<<msg->kind()<<" delay:"<<delay[msg->kind()-1][0]<<"*****"<<delay[msg->kind()-1][1]<<endl;

      qstats.collect( t );
    
      if(status==IS_CLUSTER)
      {
      	int flag = 0;
      	for(int i=0;i<15;i++)
        {
          if(msg->getSrcAddr()==clu[i])//如果数据报来自于簇内节点,上传到app层进行相关数据报的小波变换          {
        	   ev<<"This msg is from the node of cluster"<<endl;
        	   flag = 1;
        	   //sendUp(msg);
        	   break;
          }
        }
        if(flag == 1)
        {
        	sendUp(msg);
        }
        else
        	Routing(msg);
      }
      else{
     	 Routing(msg);
      }
   }
    
}


/** 
 * Convienience function which calls sendDelayedDown with delay set to
 * 0.0.
 *
 * @sa sendDelayedDown
 **/
void AsyncNetLayer::sendDown(NetwPkt *msg, int nHop, int nicGate)
{
	sendDelayedDown( msg, 0.0, nHop, nicGate );
}


/**
 * Call this function to hand your message to layer n-1
 *
 * It just calls the OMNeT++ sendDelayed function.
 *
 * In the case of the network layer we also have to provide a nextHop (nHop)
 * network address the msg has to be send to. nHop may be read
 * from a static table or the result of a routing query or whatever
 * else you want to implement.
 *
 * Additionally the network layer has to provide a mapping of the nHop
 * network address to the corresponding mac address (if the message is
 * no broadcast message). getMacAddr() is called to achive this task.
 *
 * The returned mac address is attached to the netwPkt within the
 * ControlInfo object MacControlInfo used to pass control information
 * from the network to the mac layer.
 * @todo update as soon as Andras updated the ControlInfo stuff in omnet
 * 
 * This function is only for convenience so that the programmer does
 * not have to take care about the details of message sending
 * 
 * @param msg msg to send
 * @param delay Delay (in seconds) to wait before sending the message
 * @param nHop next hop netw address to forward the msg to
 * @param nicGate gate of the nic to send the packet out on
 * @sa getMacAddr()
 *
 * to be called within @ref handleUpperMsg
 **/
void AsyncNetLayer::sendDelayedDown(NetwPkt* msg, double delay, int nHop, int nicGate)
{
	int macAddr;
  	if( nHop == -1 )
  	{
    	EV <<"sendDown: nHop=-1 -> message has to be broadcasted -> set destMac=-1\n";
    	macAddr=-2;
    }
    else if(nHop==-2)
    {
       EV <<"sendDown: nHop=-2 -> message has to sent to clusterHead -> set destMac="<<clusterHead<<endl;
	     macAddr=clusterHead;
    }
    else{
    	EV <<"sendDown: get the MAC address\n";//?
    	macAddr = getMacAddr( nHop );
  	}

  	MacControlInfo* cInfo = new MacControlInfo;
  	cInfo->setNextHopMac( macAddr );
  	msg->setControlInfo( cInfo );
  	EV <<"ControlInfo set; sending down msg\n";
  	sendDelayed((cMessage*) msg, delay, nicGate);
}


/** 
 * map the net module id to parent host's index
 * @param id to map
 **/
int AsyncNetLayer::NetModuleID2Index(int id)
{
  	int index=-1;
  	for (int i=0; i<topo->nodes(); i++)
  	{
  		if( topo->node(i)->module()->findSubmodule("net")==id)
    	{
    		index=topo->node(i)->module()->index();   			
   			return index;
    	}    		
  	}			
	return index;	
}


/** 
 * find the next hop to all other nodes
 * @param topo the topology
 **/
void AsyncNetLayer::findNextHop(cTopology *topo)
{	
  	topo->extractByModuleType(parentModule()->className(), NULL); 	  	
  	cTopology::Node *thisNode = topo->nodeFor(parentModule());
  	for (int i=0; i<topo->nodes(); i++)
  	{
  		if (topo->node(i)==thisNode)
  			 continue; // skip ourselves
    	topo->unweightedSingleShortestPathsTo(topo->node(i));//find route to node(i) for this host	    	
    	if (thisNode->paths()==0) continue; // not connected		
    	
    	int address = topo->node(i)->module()->findSubmodule("net");
    	int nHop = thisNode->path(0)->remoteNode()->module()->findSubmodule("net");    	
  		rtable[address] = nHop;
   		EV << "  towards address " << NetModuleID2Index(address) << " next hop is: " << NetModuleID2Index(nHop) <<endl;
  	}	
}


/** 
 * handle all packets
 * @param msg msg to send
 **/
void AsyncNetLayer::Routing(NetwPkt* msg)
{  	    
  	
  	findNextHop(topo);
  	
  	int destAddr = msg->getDestAddr();    
  	if (destAddr == myNetwAddr())
  	{        
     	EV << "local delivery of packet--- " << endl;
     	sendUp(msg);
     	return;
  	}
  	
  	ShortestNetwLayerTable::iterator it = rtable.find(destAddr);
    if (it==rtable.end())
   	{
    	EV << "address " << NetModuleID2Index(destAddr) << " unreachable, discarding packet " <<msg->name()<< endl;
       	delete msg;
       	return;
   	}
   	
    int nHop = (*it).second;
    EV<< "forwarding packet " << msg->name()<<" to next hop: " <<NetModuleID2Index(nHop) <<" to dest "<<NetModuleID2Index(destAddr)<< endl;
    sendDown(msg, nHop,lowergateOut);   
    
      
        
    	
}
/**
 * 利用时钟调度,周期性的建立拓扑结构。 *(1)调用该函数,通过门限判断该节点是否能成为簇头: *(2)是,则生成一个簇头广播报; *(3)否,检查队列,是否有可通信邻居节点已经成为簇头: *(4)        是,与该节点建立连接,将其作为数据报的目的节点; *(5)         否,等待一段时间后,再进入步骤(1)。**/

void AsyncNetLayer::handleSelfMsg(cMessage* msg)
{
	if(msg==clusterEvent)
	{       
	
		status=NO_CLUSTER;
		conStatus=NO_CONNECT;
		double a=1.0*rand()/32767;
		ev<<logName()<<"::AsyncNetLayer: "<<" a is "<<a<<endl;
		//if(a<(double)par("minLine")&&findHost()->index()!=(int)findHost()->submodule("appl")->par("destAddress"))//在ned文件中添加minLine变量		int flag=0;
		for(int i=0;i<8;i++)
		{
			if(findHost()->index()==(int)head[i])
				{
					flag=1;
					break;
					}
			}
		if(flag==1&&findHost()->index()!=(int)findHost()->submodule("appl")->par("destAddress"))
		{
			status=IS_CLUSTER;
			for(int i=0;i<15;i++)
			{
			 clu[i]=0;
			}
			
			findHost()->displayString().setTagArg("i",1, "red");
			ev<<a<<"<"<<par("minLine")<<endl;
			ev<<logName()<<" AsyncNetLayer:: this node is the cluster-head"<<endl;
			sendClusterMsg();
			scheduleAt(simTime()+r, clusterEvent);
		}
		else if(findHost()->index()!=(int)findHost()->submodule("appl")->par("destAddress"))
		{scheduleAt(simTime()+r, clusterEvent);
		findHost()->displayString().setTagArg("i",1, "black");
	
		}
		
	}
	
}

/**
 * 簇头确定后,发送广播帧**/
void AsyncNetLayer::sendClusterMsg()
{
	sendDown(buildClusterMsg(), -1,lowergateOut);  
	ev<<logName()<<":AsyncNetLayer:: send out the clusterMsg"<<endl;
	}

/**

/**
 * 簇内节点向簇头发送确认帧**/
void AsyncNetLayer::sendClusterAckMsg()
{
	sendDown(buildClusterAckMsg(), -2,lowergateOut);  
	ev<<logName()<<":AsyncNetLayer:: send out the clusterMsg"<<endl;
	}

/**
*  build the message to tell the cluster
   Written by Fang shi
**/

NetwPkt* AsyncNetLayer::buildClusterMsg()
{

  NetwPkt* frame = static_cast<NetwPkt *>(createCapsulePkt());
  
  frame->setTag(CLUSTER);
  frame->setSrcAddr(myNetwAddr());
  frame->setDestAddr(-2);///???需在mac的handleLOwerMsg中增加对destAddr=-2情况的处理  //frame->setDuration(0);
  ev<<logName()<<":AsyncNetLayer:: a clusterMsg has been build!!!!"<<endl;
  return(frame);
}
/**
*  build the ackMessage to tell the cluster
   Written by Fang shi
**/

NetwPkt* AsyncNetLayer::buildClusterAckMsg()
{

  NetwPkt* frame = static_cast<NetwPkt *>(createCapsulePkt());
  
  frame->setTag(CLUSTER_ACK);
  frame->setSrcAddr(myNetwAddr());
  frame->setDestAddr(clusterHead);///???需在mac的handleLOwerMsg中增加对destAddr=-2情况的处理  //frame->setDuration(0);
  ev<<logName()<<":AsyncNetLayer:: a clusterMsg has been build!!!!"<<endl;
  return(frame);
}

void AsyncNetLayer::finish()
{    
    EV << " node ID: " << findHost()->index()<<endl;
    EV << " Total jobs processed: " << qstats.samples() << endl;    
    EV << " Max transmission:         " << qstats.max() << " sec" << endl;
    EV << " Min transmission:         " << qstats.min() << " sec" << endl;
    EV << " Avg transmission:         " << qstats.mean() << " sec" << endl;
    EV << " Standard deviation:   " << qstats.stddev() << " sec" << endl;
    
    if(findHost()->index()==0){
    	for(int i=0;i<maxHops;i++)
    	{   
    		mean[i]=(delay[i][0]/delay[i][1]);
     	 	EV<<mean[i]<<endl;
    	
    	} 
    
    }    
   
    recordScalar("node id",findHost()->index());
    recordScalar("avg trans time",qstats.mean());
    recordScalar("max trans time",qstats.max());
    recordScalar("min trans time",qstats.min());
}

⌨️ 快捷键说明

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