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

📄 router.cc

📁 In this implementation of AntNet-3.0 one could get the behavior of both algorithms through a simple
💻 CC
📖 第 1 页 / 共 4 页
字号:
			
			//get the gate of networkNode to which this gate is connected

			cGate *networkNodeGate = outRouterGate->toGate();
			
			// Determine if this gate is connected to the network or not
			// if yes then send on it hello packet

			if(networkNodeGate->isConnected())
			{

				cModule *neighborNetworkNode = networkNodeGate->toGate()->ownerModule();
				int neighborAddress = neighborNetworkNode->par("address");

				// just for debugging purposed otherwise neighbor address will
				// come in hello message from neighbor or Hello message from
				// send to neighbor by this router

				sprintf(msgname, "Hello Packet Source%d-Destination %d", myAddress, neighborAddress);
					
				helloAndReplyMessage *helloPacket = new helloAndReplyMessage(msgname);
				helloPacket->setSourceAddress(myAddress);
				helloPacket->setLength(BYTE * 68);
				helloPacket->setKind((int) NETLAYER_HELLO_PACKET);
				helloPacket->setTimestamp(simTime());

				int messageAndTimerID = (timerID++) % 10000;

				
				// set the message ID to the output gate
				// this ensures that if ack for this
				// gate is not forthcoming then we would
				// simply retransmit

				helloPacket->setMessageID(messageAndTimerID);

				helloAndReplyMessage *sendHelloCopy = 
					(helloAndReplyMessage*) helloPacket->dup();
				
				
				simtime_t helloTxTime = helloPacket->length() / (double) dataRate;
				
				send(sendHelloCopy, gateIDtoNode);

				if(debug)
				{
					ev << "Router :  " << myAddress << "Sending Hello Packet to "<< 
						neighborAddress << endl;
				}
				// we will just schedule one time out message, once this timer goes off
				// we will scan the queue of unacknowledged messages and then simply
				// resend all of them that are still in the queue

				// Prepare timer for important identities so that it becomes
				// easier for us to identify which timer has gone or to 
				// cancel which timer in case an acknowledgement comes back

				cMessage *helloTimer = new cMessage("helloTimer",HELLO_RESEND_TIMER);
				timerContextInfo *timerContext = new timerContextInfo();

				timerContext->setGateID(gateIDtoNode);
				timerContext->setTimerType((int) HELLO_RESEND_TIMER);
				timerContext->setTimerID(messageAndTimerID);
				timerContext->setNeighbor(neighborAddress); // debugging purpose
				timerContext->setResendAttempt(0);
				timerContext->setMsg(helloPacket);

				helloTimer->setContextPointer( (void *) timerContext);
				timerQueue.takeOwnership(false);
				timerQueue.insert(helloTimer);
				scheduleAt(simTime() + timeValues.helloTimeOutValue, helloTimer);
				delete helloPacket;

			}
		}
	}
}

void Router::sendHelloPacket(int neighbor)
{
	char msgname[70];

	helloAndReplyMessage *helloPacket;
	sprintf(msgname, "Hello Packet Source%d-Destination %d", myAddress, neighbor);

	helloPacket = new helloAndReplyMessage(msgname);
	helloPacket->setSourceAddress(myAddress);
	helloPacket->setNeighborAddress(neighbor);
	helloPacket->setLength(BYTE * 68);
	helloPacket->setTimestamp();
	helloPacket->setKind((int) NETLAYER_HELLO_PACKET);

	int messageAndTimerID = (timerID++) % 10000;
	helloPacket->setMessageID(messageAndTimerID);

	helloAndReplyMessage *sendHelloCopy = 
		(helloAndReplyMessage *) helloPacket->dup();

	// find out transmission time

	int gateID = getOutGateID(neighbor);
	simtime_t helloTxTime = helloPacket->length() / (double) dataRate;
	send(sendHelloCopy, gateID);

	// we will just schedule one time out message, once this timer goes off
	// we will scan the queue of unacknowledged messages and then simply
	// resend all of them that are still in the queue

	// Prepare timer for important identities so that it becomes
	// easier for us to identify which timer has gone or to 
	// cancel which timer in case an acknowledgement comes back

	cMessage *helloTimer = new cMessage("helloTimer",HELLO_RESEND_TIMER);

	timerContextInfo *timerContext = new timerContextInfo();
	timerContext->setGateID(gateID);
	timerContext->setTimerType((int) HELLO_RESEND_TIMER);
	timerContext->setTimerID(messageAndTimerID);
	timerContext->setNeighbor(neighbor); // debugging purpose
	timerContext->setResendAttempt(0);
	timerContext->setMsg(helloPacket);

	helloTimer->setContextPointer( (void *) timerContext);

	timerQueue.takeOwnership(false);
	timerQueue.insert(helloTimer);
	scheduleAt(simTime() + timeValues.helloTimeOutValue, helloTimer);
	delete helloPacket;

}


void Router::retransmitHelloMessageForThisTimerMessage(cMessage *pMsg)
{

	timerContextInfo *timerContext = (timerContextInfo *) pMsg->contextPointer();

	if(timerContext->getResendAttempt() < resendAttempts)
	{

		int outGateID = timerContext->getGateID();
		int neighborAddress = timerContext->getNeighbor();


		helloAndReplyMessage *tempHelloMsg = 
			(helloAndReplyMessage *) timerContext->getMsg();
		int messageAndTimerID = (timerID++) % 10000;

		tempHelloMsg->setMessageID(messageAndTimerID);

		helloAndReplyMessage *sendHelloCopy = (helloAndReplyMessage*) tempHelloMsg->dup();

		simtime_t helloTxTime = tempHelloMsg->length() / (double) dataRate;

		
		send(sendHelloCopy, outGateID);

		// we will just schedule one time out message, once this timer goes off
		// we will scan the queue of unacknowledged messages and then simply
		// resend all of them that are still in the queue

		// Prepare timer for important identities so that it becomes
		// easier for us to identify which timer has gone or to 
		// cancel which timer in case an acknowledgement comes back


		cMessage *helloTimer = new cMessage("helloTimer",HELLO_RESEND_TIMER);

		timerContext->setTimerID(messageAndTimerID);
		timerContext->setMsg(tempHelloMsg);
		int attempts = timerContext->getResendAttempt();
		attempts++;
		timerContext->setResendAttempt(attempts);
			
		helloTimer->setContextPointer((void*) timerContext);
		timerQueue.takeOwnership(false);
		timerQueue.insert(helloTimer);
		scheduleAt(simTime() + timeValues.helloTimeOutValue, helloTimer);
		delete tempHelloMsg;
	}
	else
	{

		// it means that either this neighbor or link is down, we will
		// assume that link is down and in this way all neighbors will
		// remove link from this node and hence it will be imperative
		// that in this way dwon nod is out of topology

		// delete this timer and associated messages
//		helloAndReplyMessage *thisMessage =
//			(helloAndReplyMessage*) timerContext->msg;
		int neighborAddress = timerContext->getNeighbor();
		deleteNeighbor(neighborAddress);
		delete timerContext;
	}

}


int Router::processHelloAndReplyMessage(helloAndReplyMessage *helloOrReplyPacket)
{

	//  Find out whether this is a hello message or
	//  reply to the hello message

	if(	helloOrReplyPacket->kind() == (int) NETLAYER_HELLO_PACKET) //this is helloMessage
	{

		// This means that this router has received a hello message,
		// hence router simply send an acknowledgement and provides
		// its own address in it.

		int neighborAddress = helloOrReplyPacket->getSourceAddress();

		int outGateID = getOutGateID(neighborAddress);
		helloOrReplyPacket->setNeighborAddress(myAddress);
		helloOrReplyPacket->setKind((int) NETLAYER_HELLO_REPLY_PACKET);

		simtime_t replyTxTime = helloOrReplyPacket->length() / (double) dataRate;
		send(helloOrReplyPacket, outGateID);


		// The idea here is maintain a pair of source address 
		// to port/gate so that in future we could just traverse
		// this small vector to find out the source is connected
		// to which gate/(port) of the router

		if( !existsNeighborGatePair(neighborAddress))
		{
			pairNumber *dPair = new pairNumber;
			dPair->first = neighborAddress;
			dPair->second = outGateID;
			destGate.push_back(dPair);
		}

		// now we know the address of one of the neighbors,
		// hence we use it add it in the topology graph
		// addRouter node ensures that we do not add
		// multiple nodes


		

		if( !neighborExists( neighborAddress ))
		{
			topology.push_back(neighborAddress);
		}

		if(debug)
		{
			ev << "Hello Packet Received at Router: " << myAddress  << endl;
			ev << "Hello Packet receievd from Router: " 
				<< helloOrReplyPacket->getSourceAddress() << endl;
		}
		return neighborAddress;
	}
	 // this is the reply message of my hello message
	else if( helloOrReplyPacket->kind() == (int) NETLAYER_HELLO_REPLY_PACKET)
	{

		int sourceAddress = helloOrReplyPacket->getSourceAddress();
		
		// This Packet will provide us with the address of one of the
		// neighbors, hence we extract its address and add its
		// identity to the graph data structure

		int messageID = helloOrReplyPacket->getMessageID();

		// now we must delete this timer message from the queue of timer
		// messages

		deleteHelloTimerMessage(messageID);

		// now we know the address of one of the neighbors,
		// hence we use it add it in the topology graph
		// addRouter node ensures that we do not add
		// multiple nodes


		int neighborAddress = helloOrReplyPacket->getNeighborAddress();
		int gateID = getOutGateID(neighborAddress);

		if( !existsNeighborGatePair(neighborAddress))
		{
			pairNumber *dPair = new pairNumber;
			dPair->first = neighborAddress;
			dPair->second = gateID;
			destGate.push_back(dPair);
		}
		
		if( !neighborExists( neighborAddress ))
		{
			topology.push_back(neighborAddress);
		}
		// this packet is no more needed, hence freeing memory.

		delete helloOrReplyPacket;

		if(debug)
		{
			ev << "Reply of Hello Packet Received at Router: " << myAddress  
				<< "from Router " << neighborAddress << endl;
		}
		return neighborAddress;
	}

	else
	{
		throw new cException("Error: Expecting Hello or Reply Message");
	}
}

void Router::deleteHelloTimerMessage(int hID)
{
	cMessage *tMsg = NULL;
	
	for(cQueueIterator iter(timerQueue,1); !iter.end(); iter++)
	{
		cMessage *hMsg = (cMessage *) iter();

		timerContextInfo *timerContext= (timerContextInfo *) hMsg->contextPointer();

		if( hMsg->kind() == (int) HELLO_RESEND_TIMER
			&& timerContext->getTimerID() == hID)
		{
			tMsg = hMsg;
			break;
		}
	}

	if(tMsg != NULL)
	{
		cMessage *temp = (cMessage *) timerQueue.remove(tMsg);
		timerContextInfo *timerContext= (timerContextInfo *) tMsg->contextPointer();
		delete timerContext;

		if( temp->isScheduled())
		{
			delete cancelEvent(temp);
		}

		else
		{
			delete temp;
		}
	}
}



void Router::handleForwardAnt(Ant *msg)
{
	findSourceForAnt( msg );

	if( tcb.source == ROUTER)
	{
		send( msg, "toAntNest");
	}

	else if( tcb.source == ANT_NEST)
	{
		int neighbor = msg->getNeighborChosen();
		int index = findIndexForNeighbor(neighbor);
		handleMessageQueue(msg, index);
	}

	else
	{
		throw new cException("Unknown source for Ant in Router %d",myAddress);
	}
}


void Router::handleMessageQueue(cMessage *msg, int index)
{

	if(msg == sendNormalAndForwardAnt[index])
	{
		if( sendNormalQueue[index].empty() )
		{
			msgServiced[index] = NULL;
		}
		else
		{
			msgServiced[index] = (cMessage *) sendNormalQueue[index].getTail();
			simtime_t txTime = sendPacketInQueue(msgServiced[index], index);
			sendNormalAndForwardAnt[index]->setKind( SEND_NORMAL_PACKET_COM + index);
			scheduleAt(simTime() + txTime, sendNormalAndForwardAnt[index]);

		}
	}
	else if( !msgServiced[index])
	{
		msgServiced[index] = msg;
		simtime_t txTime = processMessageWhenQueueIsEmpty(msg, index);
		sendNormalAndForwardAnt[index]->setKind( SEND_NORMAL_PACKET_COM + index);
		scheduleAt(simTime() + txTime, sendNormalAndForwardAnt[index]);

	}
	else
	{
		int type = msg->kind();

		if(type == NETLAYER_FORWARD_ANT)
		{
			receiveProcessStorePacket( (Ant *) msg,index);
		}
		else if(type == NETLAYER_DATA_PACKET)
		{
			processNormalDataPackets((samplePacket *) msg,index);
		}
		else
		{
			throw new cException("Unknown Message in handleQueueMessage%d", type);
		}
	}
}

simtime_t Router::processMessageWhenQueueIsEmpty(cMessage *msg, int index)
{

	int kind = msg->kind();
	simtime_t txTime = 0.0;

	if ( kind == NETLAYER_DATA_PACKET)
	{
		samplePacket *packet = (samplePacket *) msg;
			// if this node is the destination then give
			// packet to the sink

		int destination = packet->getDestAddress();
		
		if( destination == myAddress)
		{
			send(packet, "toDataSink");
			txTime = 0.0000001;
			return txTime;

		}

		else
		{
			simtime_t txTime = sendPacketInQueue(msg,index);
			return txTime;
		}
	}

	else if ( kind == NETLAYER_FORWARD_ANT)
	{
		Ant *forwardAnt = (Ant *) msg;
		simtime_t txTime = sendPacketInQueue(msg,index);
		return txTime;
	}

	else
	{
		throw new cException("Unknown Message in handleQueueMessage%d", kind);
	}

}

void Router::processNormalDataPackets(samplePacket *packet, int i)
{
	// if routing table is yet not constructed then simply
	// ignore the packet


	if(topologyDiscovered)
	{
		receiveProcessStorePacket( packet,i );

		
	}
	else 
	{
		delete packet;
	}
}

void Router::receiveProcessStorePacket(cMessage *packet, int i)
{

	int type = packet->kind();
	if(debug)
	{
		ev << "Ant Received at Router: " << myAddress  << packet->name() << endl;
		ev << "Message Kind is: " << type << endl;
	}

	// increment the counter
	numPacketsToSend[i]++;

	//if send queue is already full then we need to drop the packet

⌨️ 快捷键说明

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