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

📄 aodv_routing.pr.c

📁 在OPNET中实现AODV路由协议
💻 C
📖 第 1 页 / 共 5 页
字号:
/* generates a RERR for the lost destination.
*/

// init vars
entryPtr =   aodv_routingTable_entry_get(dest);

//begin
if(DEBUG > 1 ) printf("    - Function aodv_link_repair_attempt(destination %d)\n", dest);



if(entryPtr != OPC_NIL)
	{
	// reset request sent repository
	if(RequestSent[dest].status != WAITING_FOR_REPAIR)
		{
		if(RequestSent[dest].status != OFF)
			aodv_requestSent_repository_reset(dest);
		

		// check if destination is no farther than MAX_REPAIR_TTL
		if(entryPtr->lastHopCount <(MAX_REPAIR_TTL+1))
			{
			if(DEBUG > 1 ) printf("    > Link is repairable: mark entry UNDER_REPAIR\n");

			// Set entry status to "UNDER_REPAIR"
			entryPtr->status = UNDER_REPAIR;
			// print entry
			if(DEBUG) aodv_entryPtr_print(entryPtr);
			// Update the RequestSent repository:
			// Compute the TTL value to use
			RequestSent[dest].ttl = max(MIN_REPAIR_TTL, ttl_src)+LOCAL_ADD_TTL; 
			// generate RREQ
			if(DEBUG > 1 ) printf("    > Generating RREQ\n");
			
			aodv_rreq_pk_generate(dest,WAITING_FOR_REPAIR);

			}
		else
			{
			// generate RERR packet for the lost destination
			if(DEBUG > 1 ) printf("    > Node is too far: generating RERR\n");
			aodv_rerr_pk_generate(dest,0);
			}
		}
	else
		if(DEBUG > 1 ) printf("    > Link already under repair: waiting for reply\n");

	}
}






/***********************************************************/

/********* aodv_listOfPrecursors_node_remove  **************/

/***********************************************************/

void 
aodv_listOfPrecursors_node_remove(int precursor)

	{

	// var

	int*                 destPtr;

	int                  dest,size,t;

	int*                 precursorPtr;

	RoutingTableEntry*   entryPtr;

	sFifo*               listOfDestination;

	/*
	/* When a node (precursor) is no longer available, 
	/* the current function is called to remove it from
	/* any precursor list within the routing table. To 
	/* do so, the function reads the entry corresponding
	/* to the node "precursor" within the 
	/* reversePrecursorList and gets the list of entries
	/* where "precursor" is a precursor. It then goes 
	/* through these entries and removes the lost node
	/* form their precursor lists.
	*/

	// begin

	if(DEBUG > 3 ) printf("      - Function aodv_listOfPrecursors_node_remove(): precursor = %d\n",  precursor);

	

	// check if the unreachableDestination has an entry in the reversePrecursorList

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

	if(listOfDestination != OPC_NIL)

		{

		size= getFifoSize(listOfDestination);
		if(DEBUG > 3 ) printf("      > Node is at least on one node\'s precursor list: total = %d\n",size);

		for(t=0;t<size;t++)

			{

			destPtr=getInFifo(listOfDestination);

			dest= (*destPtr); // PRECURSOR is present in DEST routing table entry

			if(DEBUG > 3 ) printf("         - on entry# %d... ", dest);

			op_prg_mem_free(destPtr);

			// the entry is read

			entryPtr= aodv_routingTable_entry_get( dest);


			if(entryPtr != OPC_NIL)
				{
				// the PRECURSOR entry is extracted from the list of precursors

				precursorPtr= (int*) getInFifoMultiplex(

							entryPtr->listOfPrecursors,precursor);

				op_prg_mem_free(precursorPtr);

				}
			else
				{
				if(DEBUG > 3 ) printf("         - Entry# %d does not exist", dest);
				}
			}

		}

	else
		if(DEBUG > 3 ) printf("      > Node was not found on any list of precursors !\n");
	if(DEBUG > 3 ) printf("\n      - Function aodv_listOfPrecursors_node_remove()... done !\n");

	}






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

/******************** update list of precursors ****************/

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


void 
aodv_listOfPrecursors_node_put(RoutingTableEntry* forwardEntryPtr,int previousHop)
	{
	int      *int_ptr,
	         *previousHopPtr;
	
	/*
	/* Add the node "previousHop" to the precursor list of 
	/* the given entry. 
	/* Note that node is put in subqueue whose index equals
	/* to its MAC address (previousHop). This makes it easier
	/* to remove the node if it lost.
	*/
	
	// if listOfPrecursors not initialized, then initialize it
	if(forwardEntryPtr->listOfPrecursors == OPC_NIL)
		{	
		forwardEntryPtr->listOfPrecursors = newFifo();
		}
	
	//check if node is already in
	int_ptr= (int*) readInFifoMultiplex(forwardEntryPtr->listOfPrecursors, 	previousHop); 
	if(int_ptr != OPC_NIL)

		{
		if(DEBUG > 3 ) printf("      > Precursor is already on the list !\n");
		}

	 else
		{
		if(DEBUG > 3 ) printf("      > Precursor does not exist, function has to add it!\n");
		// create a pointer to the node's address value
		previousHopPtr = (int*) op_prg_mem_alloc(sizeof(int));
		*previousHopPtr
= previousHop;
		// add node to the precursol list
		if(DEBUG > 3 ) printf("      > Adding precursor %d\n",previousHop);
		putInFifoMultiplex(forwardEntryPtr->listOfPrecursors,
previousHopPtr, previousHop);

		if(DEBUG > 3 ) printf("      > Previous Hop (%d) should have been added to precursor list of entry# %d\n", previousHop, forwardEntryPtr->dest);
		// update reverse list of precursors
		aodv_reverseListOfPrecursors_update(previousHop,forwardEntryPtr->dest);

		}
	}
	


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

/*********************** HANDLE HELLO MESSAGE ******************/

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

void 
aodv_hello_msg_receive(Packet* rrep_pk_ptr)

{

// var



int                 source, dest, hopCount, lastHopCount;

int                 destSeqNb, previousHop;

double              lifetime;
RoutingTableEntry * newEntryPtr, * forwardEntryPtr;
Boolean             request_was_pending = 
OPC_FALSE;


/*
/* This routine processes the upcoming hello message.
*/
// begin



// packet read

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

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

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

op_pk_nfd_get (rrep_pk_ptr,"DestSeqNb",&destSeqNb);

// N.B. hop count field is incremented by 1
at reception
op_pk_nfd_get (rrep_pk_ptr,"HopCount",&hopCount);

op_pk_nfd_set (rrep_pk_ptr,"HopCount",hopCount+1);

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

op_pk_nfd_get (rrep_pk_ptr,"Lifetime",&lifetime);


if(DEBUG > 3) printf("    - Function aodv_hello_msg_receive(from node %d)\n",source);

// check if entry already exists
forwardEntryPtr=aodv_routingTable_entry_get( dest);
// if entry does not exist: create it and add it to table (with default values)
if(forwardEntryPtr == OPC_NIL)
	{
	// entry does not exist
	if(DEBUG > 1 ) printf("      > Entry does not exist\n");
	forwardEntryPtr=aodv_entry_create_new();

	forwardEntryPtr->listOfPrecursors=newFifo();
	forwardEntryPtr->dest = source;
	// add entry to routing table
	aodv_routingTable_entryPtr_put(forwardEntryPtr);
	}



if(aodv_entryPtr_hopCount_get(forwardEntryPtr) == INFINITY) 
	{
	// entry is either invalid or under repair or newly created
	if(DEBUG > 1 ) printf("      > Node creates entry\n");
	// Set entry values
	forwardEntryPtr->dest=dest;

	forwardEntryPtr->destSeqNb=destSeqNb;
	forwardEntryPtr->hopCount=hopCount;

	forwardEntryPtr->nextHop=previousHop;

	// check whether a request is pending
	if(RequestSent[dest].status != OFF)
		{
		if(DEBUG > 1 ) printf("      > A request was running for the newly created entry\n");
		// update requestSent repository
		aodv_requestSent_repository_reset(dest);

		// set serve buffer flag
		request_was_pending = OPC_TRUE;
		}
	}
else  // entry is active
	{
	if(DEBUG > 1 ) printf("      > Active entry already exist\n");
	// forward entry already exists
	if((destSeqNb > forwardEntryPtr->destSeqNb) ||
((destSeqNb==forwardEntryPtr->destSeqNb)&&
(hopCount < forwardEntryPtr->hopCount)))

		{
		// node updates his entry for the DESTINATION node only if (greater destSeqNb) or (same seqNbs but smaller hopCount)
		if(DEBUG > 1 ) printf("      > Node updates its entry\n");

		
		forwardEntryPtr->destSeqNb=destSeqNb;

		forwardEntryPtr->lastHopCount=forwardEntryPtr->hopCount;

		forwardEntryPtr->hopCount=hopCount;

		forwardEntryPtr->nextHop=previousHop;

		} /* end of if entry has to be udated */
	else
		if(DEBUG > 1 ) printf("      > Entry does not need to be updated\n");
	} /* end of if forward entry is active */


// Timeout always updated
if((op_sim_time()+lifetime) > forwardEntryPtr->expirationTime)
	{
	aodv_entry_expirationTime_set(dest,op_sim_time()+lifetime);
	}
else
	if(DEBUG > 1) printf("      > Entry timeout does not need to be updated\n");


// set status to active
forwardEntryPtr->status = ACTIVE;

// destroy packet
op_pk_destroy(rrep_pk_ptr);
// serve buffer if needed
if( request_was_pending == OPC_TRUE)
	{
	// serve buffer
	aodv_buffer_serve(dest);
	}

if(DEBUG > 1 ) printf("    - Function handleHelloMsg()  done\n");

} /* end of handleHelloMsg */

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

/*********************** HANDLE REPLY **************************/

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



void  
aodv_rrep_pk_receive(Packet* rrep_pk_ptr)

{

// var

Boolean    forward_entry_created_or_updated = OPC_FALSE;


int        source, dest, destSeqNb, hopCount;

Ici*       ici_ptr;


/*
/* Receive RREP and decide whether to update or create
/* the corresponding entry and whether to forward or 
/* discard the received RREP.
*/

// begin

if(DEBUG > 1 ) printf("    - Function aodv_rrep_pk_receive()\n");

// packet read

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

op_pk_nfd_set (rrep_pk_ptr,"HopCount",hopCount+1);


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

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

op_pk_nfd_get (rrep_pk_ptr,"DestSeqNb",&destSeqNb);

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


// nodes checks compares his own destSeqNb for this destination to the destSeqNb in the RREP packet
if(aodv_entry_destSeqNb_get(dest) <= destSeqNb)
	{
	if(DEBUG > 1) printf("      > Reply is fresh enough: node updates its routingTable\n");

  	forward_entry_created_or_updated = 	aodv_entry_update_or_create_from_rrep(rrep_pk_ptr);
	}
// if node's relay and a forward route's been updated or created, node forwards RREP
if((node_addr != source) && (forward_entry_created_or_updated == OPC_TRUE))
	{
	// node checks his routing table for a reverse entry 
	// if a route's available, node updates its reverse entry (list of precursor) and forwards rrep to nextHop
	if ((aodv_entry_nextHop_get(source) != NOT_VALID) && (aodv_entry_nextHop_get(source) != NON_EXISTENT))
		{
		// Packet has a reverse entry
		// add next Hop Toward Source to the precursor list of the forward entry

		aodv_listOfPrecursors_node_put(aodv_routingTable_entry_get(dest), aodv_entry_nextHop_get(source));
		// node forwards RREP
		aodv_rrep_pk_forward(rrep_pk_ptr);
		}
	else
		{
		// no reverse entry was found
		if(DEBUG > 1 ) printf("      > ERROR @ node %d: No reverse entry was found to forward RREP!\n", node_addr);
		}	 
	}

// if a forward entry's been created or updated, node schedule interruption to serve data buffer
if(forward_entry_created_or_updated == OPC_TRUE)
	{
	if(DEBUG > 1 ) printf("      > Serve the buffer\n");

	// serve buffer 

	aodv_buffer_serve(dest);
	}
if(DEBUG > 1 ) printf("      > Print forward entry if any available\n");
if(DEBUG > 1 ) aodv_entry_print(dest);
if(DEBUG > 1 ) printf("      > Print reverse entry if any available\n");
if(DEBUG > 1 ) aodv_entry_print(source);
if(DEBUG > 1 ) printf("    - Function aodv_rrep_pk_receive() done\n");

}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
// void aodv_rrep_pk_forward(Packet *rrep_pk_ptr)                       //
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//

void 
aodv_rrep_pk_forward(Packet *rrep_pk_ptr)
	{
	// vars
	int source;
	
	/*
	/* Unicast the RREP to next hop along 
	/* the reverse path (next hop toward
	/* the source that generate the RREQ.
	*/
	
	// init
	op_pk_nfd_get (rrep_pk_ptr,"SRC",&source);
	// send to mac layer
	if(DEBUG > 1 ) printf("    > Forward RREP to source node [next hop is %d]\n",aodv_entry_nextHop_get(source));
	aodv_pk_send_to_mac_layer(rrep_pk_ptr,aodv_entry_nextHop_get(source));
	// refresh reverse entry's timeout
	aodv_entry_expirationTime_set(source, op_sim_time()+ ACTIVE_RO

⌨️ 快捷键说明

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