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

📄 aodv_routing.pr.c

📁 Ad hoc网络AODV路由协议源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*/* 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; /*/* 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); 

if(DEBUG > 1 ) printf("    - Function aodv_data_pk_receive(destination is %d )\n",dest);
// update statsif(previousHop != source)	{	stats[previousHop].forward_output++;	}// check packet final destinationif (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++;	}
else  
	{	// 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 	if(DEBUG > 1) printf("      > Check routing table for entry\n");	if(DEBUG > 1) aodv_entry_print(dest);	if ((aodv_entry_nextHop_get(dest) != NOT_VALID) && (aodv_entry_nextHop_get(dest) != NON_EXISTENT))		 {
		 // entry available: node forwards the packet 
		 if(DEBUG > 1 ) printf("      > Node has fresh enough active entry\n      > Data packet forwarded\n");		 // schedule an event if no ack received within the waiting window 		 if(DEBUG > 3) printf("      > Schedule Event if no ack received\n");
		 aodv_ack_timeout_schedule(data_pk_ptr,dest);
		 //send to mac
		 aodv_pk_send_to_mac_layer(data_pk_ptr,aodv_entry_nextHop_get(dest));
		 // re-active the route timeout (must delay the expiration event 
		 // which has been scheduled for the current entry)		 aodv_entry_expirationTime_set(dest,op_sim_time()+ACTIVE_ROUTE_TIMEOUT); 		 }
	 else if(aodv_entry_nextHop_get(dest) == NOT_VALID)		 {
		 printf("      > Error @ node %d: No forward route available: no active entry for dest %d\n",node_addr,dest);		 // insert data packet into buffer and try to repair the broken link		 if(DEBUG > 1 ) printf("      > Insert packet into buffer\n");		 aodv_data_pk_queue(data_pk_ptr);		 // if no repair pending		 if(RequestSent[dest].status != WAITING_FOR_REPAIR)			 {			 // cancel expiration time			 aodv_entryPtr_expirationInterrupt_cancel(aodv_routingTable_entry_get(dest));			 // attempt to repair			 if(DEBUG > 1 ) printf("      > Attempt to repair link\n");			 aodv_link_repair_attempt(dest, aodv_entry_hopCount_get(source));			 }		 }	 else // entry does not exist		 {		 // generate a rreq		 aodv_rreq_pk_generate(dest, WAITING_FOR_REPLY);		 }
	 }
	if(DEBUG > 1 ) printf("    - Function aodv_data_pk_receive() done\n");
}


/***********************************************************/
/***************** INIT ROUTING TABLE ENTRY ****************/
/***********************************************************/
RoutingTableEntry* aodv_entry_create_new()
{
RoutingTableEntry* entryPtr;
/*/* Returns a new routing table entry with the default/* values.*/entryPtr= (RoutingTableEntry*) op_prg_mem_alloc(sizeof(RoutingTableEntry));entryPtr->status             = ACTIVE;
entryPtr->dest               = -1;entryPtr->nextHop            = -1;
entryPtr->destSeqNb          =  0; entryPtr->hopCount           = -1;entryPtr->lastHopCount       = -1;entryPtr->expirationTime     =  0;entryPtr->lastExpirationTime =  0;return entryPtr;
}

/////////////////////////////////////////////////////////////////
/*********************** GENERATE ERROR ************************/
/////////////////////////////////////////////////////////////////
void aodv_rerr_pk_generate(int unreachableNode, int n_flag)
{
// vars
RoutingTableEntry *  indexEntryError;ErrorContentStruct*  newErrorStructPtr;
 sObject*             object;
Packet*              rerr_pk_ptr;int                  source,                     dest,					 destSeqNb,					 unreachableDest,					 unreachableDestSeqNb,					 i;
/*/* Generate a RERR packet containing the list of all/* destinations (and their associated Dest. Seq. Nb.)/* that are now unreachable because of the loss of /* node given in the first parameter (unreachableNode). /* The N flag (n_flag) indicates whether entry should /* be deleted or not.*///init varsobject=  routingTable->firstObject;newErrorStructPtr= (ErrorContentStruct *) 
		 				op_prg_mem_alloc(sizeof(ErrorContentStruct));
newErrorStructPtr->listOfUnreachableDest=newFifo();
// Beginif(DEBUG > 1) printf("    - Function aodv_rerr_pk_generate(destination %d)\n", unreachableNode);
// Read corresponding entryindexEntryError = aodv_routingTable_entry_get(unreachableNode);// check the non_delete flagif(n_flag == 0)	{	// If not set, invalidate entry and go through all listOfPrecursors and remove the unreachable 
	// destination from them: this is done via reverseListOfPrecursors
	// invalidate entry (dest seq nb was previously incremented while attempting to repair)	// this function will also schedule deletion for the current entry	if(DEBUG > 1) printf("    - Invalidate entry\n");	aodv_entry_invalidate(indexEntryError->dest, indexEntryError->destSeqNb, n_flag);	if(DEBUG > 1 ) printf("      > Remove unreachable node from all the precursor lists\n");
	aodv_listOfPrecursors_node_remove(indexEntryError->dest);	}// add the new unreachable destination to the RERR packet
if(DEBUG > 1 ) printf("      > Add destination to RERR packet\n");
// add destination to the list of new unreachable destinations aodv_listOfUnreachableDest_insert(newErrorStructPtr, indexEntryError->dest, indexEntryError->destSeqNb);// If non_delete flag is not set, process the rest of routingTable entries:// go through all entries, and process only those whos nextHop is the unreachable nodeif(DEBUG > 1) printf("    - Look for other lost destinations\n");if(n_flag == 0)	{	for(i=0;i<getFifoSize(routingTable);i++)
		{		// read entry
		indexEntryError = (RoutingTableEntry*)(object->data);		// Proceed only if the unreachable node is the next hop for this destination		if(indexEntryError->nextHop == unreachableNode && indexEntryError->dest != unreachableNode) 			{			// read entry 			unreachableDest = indexEntryError->dest;			unreachableDestSeqNb = indexEntryError->destSeqNb;						// invalidate entry			if(DEBUG > 1) printf("    >  Ivalidate entry %d\n",unreachableDest);			// invalidate entry and schedule deletion			aodv_entry_invalidate(unreachableDest, unreachableDestSeqNb+1, n_flag);			// go through all listOfPrecursors and remove the unreachable 
			// destination from them: this is done via reverseListOfPrecursors
			if(DEBUG > 1 ) printf("      > Remove unreachable node from all the precursor lists\n");
			aodv_listOfPrecursors_node_remove(unreachableDest);			// add the new unreachable destination to the RERR packet
			if(DEBUG > 1 ) printf("      > Add destination to RERR packet\n");
			// add destination to the list of new unreachable destinations 			aodv_listOfUnreachableDest_insert(newErrorStructPtr, unreachableDest, unreachableDestSeqNb);			// print entry			if(DEBUG) aodv_entryPtr_print(indexEntryError);			}		else			if(DEBUG > 1) printf("      > skip entry %d\n",indexEntryError->dest);				object=object->next;		}
	
}// if list of unreachable destinations is not empty, then // generate a RERR packet.if(getFifoSize(newErrorStructPtr->listOfUnreachableDest)>0)

	{	// Create RERR packet	rerr_pk_ptr = op_pk_create_fmt("AODV_RERR");	// Set N field value	op_pk_nfd_set(rerr_pk_ptr,"N", n_flag);
	// Set the error structure and add it to packet	newErrorStructPtr->destCount = getFifoSize(newErrorStructPtr->listOfUnreachableDest);	op_pk_nfd_set(rerr_pk_ptr,"ErrorContent",newErrorStructPtr,op_prg_mem_copy_create,op_prg_mem_free,sizeof(ErrorContentStruct));
	if(DEBUG > 1) printf("      > RERR packet has been generated\n");
	// Send to mac Layer 	aodv_pk_send_to_mac_layer(rerr_pk_ptr, BROADCAST);	}else	{	if(DEBUG > 1) printf("      > No unreachable destination caused by link breakage\n");
	}	
if(DEBUG > 1) printf("    - Function aodv_rerr_pk_generate done !\n");
}
/*****************************************************************/
/************************ handle link breakage  ******************/
/*****************************************************************/
void aodv_link_repair_attempt(int dest, int ttl_src)
{// varsRoutingTableEntry* entryPtr;int                TTL_REQUEST;/*/* This function checks whether the lost link/* is repairable or not. If so, it generates a /* RREQ with the appropriate TTL. Else, it /* generates a RERR for the lost destination.*/// init varsentryPtr =   aodv_routingTable_entry_get(dest);//beginif(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;	/*

⌨️ 快捷键说明

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