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

📄 aodv_routing_nexttwo.pr.c

📁 adhoc网络中AODV协议的仿真码, 并有改进的
💻 C
📖 第 1 页 / 共 5 页
字号:
aodv_gratuitous_rrep_pk_generate(rreq_pk_ptr)
	{
	
	Packet*             grat_rrep_pk_ptr;
	RoutingTableEntry * forwardEntryPtr;
	int                 dest,
	                    source,
            		    srcSeqNb,
			            hopCount;
					
	double              lifetime;
	 
	/*
	/* Generate a gratuitous RREP and unicast it to
	/* the destination node (node for which RREQ was
	/* originally generated).
	*/
	
	// Read RREQ packet
	op_pk_nfd_get (rreq_pk_ptr,"SRC",&source);
	op_pk_nfd_get (rreq_pk_ptr,"DEST",&dest); 

	op_pk_nfd_get (rreq_pk_ptr,"SrcSeqNb",&srcSeqNb);

	op_pk_nfd_get (rreq_pk_ptr,"HopCount",&hopCount);

	
	// read forward entry
	forwardEntryPtr = aodv_routingTable_entry_get(dest);
	// create a gratuitous rrep packet and unicast it to the next hop toward the Destination
	grat_rrep_pk_ptr= op_pk_create_fmt("AODV_RREP_NEXTTWO");
	op_pk_nfd_set(grat_rrep_pk_ptr,"SRC",dest);

	op_pk_nfd_set(grat_rrep_pk_ptr,"DEST",source);

	op_pk_nfd_set(grat_rrep_pk_ptr,"DestSeqNb",srcSeqNb);
	op_pk_nfd_set(grat_rrep_pk_ptr,"HopCount",hopCount+1);

	op_pk_nfd_set(grat_rrep_pk_ptr,"PreviousTwoHop", -1);
	
	lifetime = forwardEntryPtr->expirationTime - op_sim_time();
	if(lifetime <= 0)
		lifetime = ACTIVE_ROUTE_TIMEOUT;
	op_pk_nfd_set(grat_rrep_pk_ptr,"Lifetime",lifetime);
	
	// send to MAC Layer
	aodv_pk_send_to_mac_layer(grat_rrep_pk_ptr,aodv_entry_nextHop_get(dest));
	// Refresh timeout
	aodv_entry_expirationTime_set(dest,op_sim_time()+ACTIVE_ROUTE_TIMEOUT);

	if (DEBUG > 1) printf("      > Gratuitous RREP has been generated: unicast it to destination [next hop is %d]\n", aodv_entry_nextHop_get(dest));
	}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
// void aodv_rrep_pk_generate_from_relay(Packet*    )   //
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//

void 
aodv_rrep_pk_generate_from_relay(Packet* rreq_pk_ptr)
	{

	Packet                *rrep_pk_ptr;
	double				  lifetime;
	RoutingTableEntry     *forwardEntryPtr;
	RoutingTableEntry     *reverseEntryPtr;
	int                   dest;
	int                   source;
	int					  previousHop;
	
	/*
	/* This routine is called when an intermediate node 
	/* receives a RREQ an has fresh enough route to 
	/* to generate a RREP for the requested destination. 
	*/
	
	// Read request packet
	op_pk_nfd_get (rreq_pk_ptr,"SRC",&source);

	op_pk_nfd_get (rreq_pk_ptr,"DEST",&dest); 


   op_pk_nfd_get (rreq_pk_ptr,"PreviousHop",&previousHop);

	// Read forward entry
	forwardEntryPtr=aodv_routingTable_entry_get(dest);
	// Create reply packet 
	rrep_pk_ptr = op_pk_create_fmt("AODV_RREP_NEXTTWO");

	/* Assign source and dest to the reply packet */

	op_pk_nfd_set(rrep_pk_ptr,"SRC",source);

	op_pk_nfd_set(rrep_pk_ptr,"DEST",dest);

	op_pk_nfd_set(rrep_pk_ptr,"HopCount",forwardEntryPtr->hopCount);

	op_pk_nfd_set(rrep_pk_ptr,"PreviousTwoHop",-1);

	lifetime = forwardEntryPtr->expirationTime - op_sim_time();
	if(lifetime <= 0)
		lifetime = ACTIVE_ROUTE_TIMEOUT;
		op_pk_nfd_set(rrep_pk_ptr,"Lifetime",lifetime);

	
	op_pk_nfd_set(rrep_pk_ptr,"DestSeqNb",forwardEntryPtr->destSeqNb);

	// add previousHop toward "source" to the precursor list of the forward entry
	aodv_listOfPrecursors_node_put(forwardEntryPtr,previousHop);
	// add nextHop toward "destination" to the precursor list of the reverse entry
	reverseEntryPtr=aodv_routingTable_entry_get(source);
	aodv_listOfPrecursors_node_put(reverseEntryPtr,forwardEntryPtr->nextHop);

	// send reply to mac layer
	if(DEBUG > 1 ) printf("      > RREP has been generated from relay: unicast it to source node [next hop is %d]\n",previousHop);
	aodv_pk_send_to_mac_layer(rrep_pk_ptr,previousHop);
	// Refresh timeout
	aodv_entry_expirationTime_set(source,op_sim_time()+ACTIVE_ROUTE_TIMEOUT);

	// Destroy rreq 
	op_pk_destroy(rreq_pk_ptr);
	}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
// void aodv_rreq_pk_forward(Packet* rreq_pk_ptr)       //
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
	
void 
aodv_rreq_pk_forward(Packet* rreq_pk_ptr)
	{
	
	int      ttl, 
	         hopCount,
			 previousHop;

	/*
	/* Node does not have a fresh enough entry
	/* (or does not have an entry at all) to answer
	/* the received RREQ, so it decides to forward 
	/* it. Node increments the Hop Count field
	/* and decrements the TTL field. 
	/* Note that packet is sent to mac layer only if 
	/* TTL > 0.
	*/
	op_pk_nfd_get (rreq_pk_ptr,"TTL",&ttl);		
	op_pk_nfd_get (rreq_pk_ptr,"HopCount",&hopCount);

	op_pk_nfd_get (rreq_pk_ptr,"PreviousHop",&previousHop);

	if(ttl > 1)
		{
		if(DEBUG > 1 ) printf("      > Node forwards request\n",ttl);

		op_pk_nfd_set(rreq_pk_ptr,"TTL",ttl-1);

		op_pk_nfd_set(rreq_pk_ptr,"HopCount",hopCount+1);
		op_pk_nfd_set(rreq_pk_ptr,"PreviousTwoHop",previousHop);

		// send to mac
		aodv_pk_send_to_mac_layer(rreq_pk_ptr, BROADCAST);

		}
	else
		{
		if(DEBUG > 1 ) printf("      > TTL expired: rreq destroyed\n");
		op_pk_destroy(rreq_pk_ptr);
		}
	}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
// void aodv_entry_update_or_create_from_rreq(Packet*     ) //
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//

void 
aodv_entry_update_or_create_from_rreq(Packet* rreq_pk_ptr)
	{

	RoutingTableEntry *    reverseEntryPtr;
	int                    source,
	                       previousHop,
						   srcSeqNb,
						   hopCount,
						   previousTwoHop;
	/*
	/* Update or create reverse entry following a RREQ reception.
	*/
	
	// Read RREQ packet
	op_pk_nfd_get (rreq_pk_ptr,"SRC",&source);
	op_pk_nfd_get (rreq_pk_ptr,"PreviousHop",&previousHop); 

	op_pk_nfd_get (rreq_pk_ptr,"SrcSeqNb",&srcSeqNb);

	op_pk_nfd_get (rreq_pk_ptr,"HopCount",&hopCount);

	op_pk_nfd_get (rreq_pk_ptr,"PreviousTwoHop",&previousTwoHop);
	
	// Check if any request is pending for this destination
	if(RequestSent[source].status != OFF)
		aodv_requestSent_repository_reset(source);
	
	// Node creates or updates a REVERSE route

	reverseEntryPtr=aodv_routingTable_entry_get(source);

	if(reverseEntryPtr != OPC_NIL) 


		{

		//entry already exists
		if((srcSeqNb > reverseEntryPtr->destSeqNb) ||
((srcSeqNb == reverseEntryPtr->destSeqNb)

		&&((hopCount+1)< reverseEntryPtr->hopCount)) || (reverseEntryPtr->status != ACTIVE) )

			{
			// entry updated only if (greater seqNb) or 

			//(same seqNbs but smaller hopCount)
			if(DEBUG > 1 ) printf("      > Node updates its reverse route to source node\n");

			reverseEntryPtr->destSeqNb=srcSeqNb;

			reverseEntryPtr->nextHop= previousHop;
			reverseEntryPtr->nextTwoHop = previousTwoHop;
			if(reverseEntryPtr->hopCount != INFINITY)

				reverseEntryPtr->lastHopCount= reverseEntryPtr->hopCount;

			reverseEntryPtr->hopCount=hopCount+1;

			}
		else
			if(DEBUG > 1) printf("      > Node does not need to update its reverse entry\n");

		
		// Refresh entry timeout to max(current expiration time, currentTime+REV_ROUTE_LIFE)	
		if((op_sim_time()+REV_ROUTE_LIFE) > reverseEntryPtr->expirationTime)			
			{			
			aodv_entry_expirationTime_set(source,op_sim_time()+REV_ROUTE_LIFE);
			}
		else
			if(DEBUG > 1) printf("      > Reverse entry timeout does not need to be refreshened\n");


		// set entry status
		reverseEntryPtr->status = ACTIVE;
		}
	else  

		{
		//entry doesn't exist: node creates it
		if(DEBUG > 1 ) printf("      > Node creates a reverse entry to source node\n");

		reverseEntryPtr=aodv_entry_create_new();
		reverseEntryPtr->listOfPrecursors=newFifo();

		reverseEntryPtr->status = ACTIVE;
		reverseEntryPtr->dest=source;

		reverseEntryPtr->destSeqNb=srcSeqNb;

		reverseEntryPtr->nextHop= previousHop;

		reverseEntryPtr->nextTwoHop = previousTwoHop; 
		reverseEntryPtr->hopCount=hopCount+1;
		reverseEntryPtr->lastHopCount = hopCount+1;
		// Add the entry to the RoutingTable
		aodv_routingTable_entryPtr_put(reverseEntryPtr);

		// Refresh entry timeout
		aodv_entry_expirationTime_set(source,op_sim_time()+REV_ROUTE_LIFE);
		}
	
	// if reverse entry updated or created, then
	// Serve buffer if any packet's waiting
	if(reverseEntryPtr->hopCount != INFINITY)
		aodv_buffer_serve(source);
	}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
// void aodv_rreq_pk_regenerate(int destination)            //
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//

void 
aodv_rreq_pk_regenerate(int destination)

{


/*
/* This function is called in the Renew_Request state when 
/* the previous RREQ didn't receive any RREP and the number
/* of retries is smaller than TTL_RETRIES_TRESHOLD
*/

aodv_rreq_pk_generate(destination, WAITING_FOR_REPLY);

}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
// void aodv_reverseListOfPrecursors_update(int prec, int dest)       //
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//

void 
aodv_reverseListOfPrecursors_update(int precursor, int destination)

	{


	int      *destinationPtr; 

	sFifo    *listOfDestination;


	/*
	/* Each time a node "A" (precursor) is added to the list of precursor of 
	/* a given destination "B" (detination), this function is called to add
	/* "B" in the list of nodes to which "A" is a precursor. Thus, when 
	/* link to A is no longer available and node wants to expunge it from 
	/* its routing table, node has only to process entry that are listed
	/* within the reverseListOfPrecursol at the entry "A".
	*/
	
	// var init
	destinationPtr = (int*) op_prg_mem_alloc(sizeof(int));

	*destinationPtr = destination;

	// begin

	if(DEBUG > 3 ) printf("      - Function aodv_reverseListOfPrecursors_update(): precursor = %d || entry = %d\n", precursor,destination);

	// check if a reverse entry already exists for PRECURSOR

	if(DEBUG > 3 ) printf("      > check if a reverse entry already exists\n");

	listOfDestination= (sFifo*) readInFifoMultiplex(reverseListOfPrecursors, precursor);

	

	if(listOfDestination == OPC_NIL) // no entry available

		{

		if(DEBUG > 3 ) printf("      > No entry available: node has to create a new one\n");

		// have to create a new entry

		listOfDestination=newFifo();

		putInFifo(listOfDestination, destinationPtr);

		putInFifoMultiplex(reverseListOfPrecursors,listOfDestination, precursor);

		}

	else

		{

		// only add destination to the list of destination

		if(DEBUG > 3 ) printf("      > entry already exists: only add destination to the list of destination\n");

		putInFifo(listOfDestination, destinationPtr);

		}

	if(DEBUG > 3 ) printf("      - function aodv_reverseListOfPrecursors_update()... done !\n");

   }


///////////////////////////////////////////////////////////

/***************** HANDLE_DATA ***************************/

///////////////////////////////////////////////////////////



void 
aodv_data_pk_receive(Packet* data_pk_ptr)

{

// var

int        previousHop, source, dest; 
int        twoHopRepairFlag;
int        nextHop_PnodeInfor, nextTwoHop;
RoutingTableEntry * entryPtr, *forwardEntryPtr;

/*
/* This function receives the upcoming data packet from the MAC Layer.
/* Two possibilities:
/* 1. Packet has reached its destination. Packet is then discarded toward
/*    the upper_layer.
/* 2. Packet has to be forwarded. Node checks its routing table and
/*    either forwards the packet if an entry is available or generates
/*    a RERR otherwise.
/* 
*/

// Read data packet 
op_pk_nfd_get (data_pk_ptr,"PreviousHop",&previousHop);


op_pk_nfd_get (data_pk_ptr,"SRC",&source);

op_pk_nfd_get (data_pk_ptr,"DEST",&dest); 

op_pk_nfd_get (data_pk_ptr,"TwoHopRepairFlag",&twoHopRepairFlag);
op_pk_nfd_get (data_pk_ptr,"NextTwoHop",&nextHop_PnodeInfor);


if(DEBUG > 1 ) printf("    - Function aodv_data_pk_receive(destination is %d )\n",dest);

// update stats
if(previousHop != source)
	{
	stats[previousHop].forward_output++;
	}

// check packet final destination
if (dest == node_addr)  

	{
	// pk has reached its destination
	if(DEBUG > 1 ) printf("      > Data packet has reached its destination\n");
	// send packet to upper layer 
	if(DEBUG > 1 ) printf("      > Data packet sent to app_manager layer\n");
	op_pk_send(data_pk_ptr,DISCARD_STRM); 

	// update stats
	output ++;
	stats[source].own_output++;
	op_stat_write(global_receive_data_pk_cnt_stathandle, ++global_receive_data_pk_cnt);
	}

else//(if (dest == node_addr) )  

	{
	// pk has to be forwarded
	if(DEBUG > 1 ) printf("      > Node is a relay: packet has to be routed\n");
	// update forward input stat
	stats[node_addr].forward_input++;

	// check routing table for desired entry 

⌨️ 快捷键说明

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