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

📄 aodv_routing_add.pr.c

📁 adhoc网络中AODV协议的仿真码, 并有改进的
💻 C
📖 第 1 页 / 共 5 页
字号:
	ackEvt->evt=op_intrpt_schedule_remote(op_sim_time()+ Wait_ACK,destination,op_id_self());
	// store a copy of the sent packet
	ackEvt->copy_pk_ptr = op_pk_copy(pk);

	// Store the Ack evt in the AckEvt list
	putInFifoMultiplex(&ackEvtFifo,ackEvt,destination);
	}

}


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

/*********************** Generate RREQ *************************/
/////////////////////////////////////////////////////////////////



void 
aodv_rreq_pk_generate(int destination, Request_Status_Type status) 

{


Packet*       rreq_pk_ptr;

/*
/* Initiate the discovery process by generating a RREQ for a given
/* destination.
/* The procedure not only generates a RREQ packet with the appropiate
/* fields. But it also updates node's "RequestSent" repository (see 
/* function aodv_requestSent_repository_update).
*/

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


// check if no request is already pending for that destination
if(RequestSent[destination].status == OFF)
	{
	// Create a request type packet 

	rreq_pk_ptr = op_pk_create_fmt("AODV_RREQ");


	// set RREQ fields
	op_pk_nfd_set(rreq_pk_ptr,"TTL",RequestSent[destination].ttl);

	op_pk_nfd_set(rreq_pk_ptr,"G",RequestSent[destination].gratuitous);
	op_pk_nfd_set(rreq_pk_ptr,"SRC",node_addr);

	op_pk_nfd_set(rreq_pk_ptr,"DEST",destination);

	op_pk_nfd_set(rreq_pk_ptr,"DestSeqNb",aodv_entry_destSeqNb_get(destination));

	mySeqNb++;
	op_pk_nfd_set(rreq_pk_ptr,"SrcSeqNb",mySeqNb);

	op_pk_nfd_set(rreq_pk_ptr,"BroadcastID",myBroadcastID);
	//increment node's boadcastID
	myBroadcastID++;

	// send to mac layer
	if(DEBUG > 1 ) printf("      > RREQ packet has been generated\n");

	aodv_pk_send_to_mac_layer(rreq_pk_ptr, BROADCAST);
	// update RequestSent repository
	aodv_requestSent_repository_update(destination, status);
	}
else 
	{
	if(DEBUG > 1 ) printf("      > A request is pending: cannot renew it\n");

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


}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
// void aodv_requestSent_repository_update(int dest  )  //
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void 
aodv_requestSent_repository_update(int destination, Request_Status_Type status)
	{
	
	/*
	/* When a request is sent, a corresponding entry is      
	/* updated in the RequestSent repository in order 
	/* to control route requests broadcast. For each request    
	/* that has been generated, node stores the destination
	/* sequence number, the number of retries, the status
	/* of the request, the expiration time (time before 
	/* renewal), and finally the future TTL to use in case 
	/* of renewal
	*/
	
	
	// Store the dest seq nb of the request
	RequestSent[destination].sequence_number=aodv_entry_destSeqNb_get(destination);

	// Set the status of the request 
	RequestSent[destination].status= status;

	
	// schedule for interruption if no reply received within appropriate period
	RequestSent[destination].evt = op_intrpt_schedule_remote(op_sim_time()+2*RequestSent[destination].ttl*NODE_TRAVERSAL_TIME,NREPLY_CODE+destination,op_id_self());
	RequestSent[destination].expirationTime= op_sim_time()+ 2*RequestSent[destination].ttl* NODE_TRAVERSAL_TIME;

	
	// increment TTL for next eventual renewal 
	RequestSent[destination].ttl=RequestSent[destination].ttl+TTL_INCREMENT;
	if(RequestSent[destination].ttl > TTL_TRESHOLD)
		{
		RequestSent[destination].ttl= NET_DIAMETER;
		// Increment the number of retries
		RequestSent[destination].nbOfRetries++;
		}
	}



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

/*********************** HANDLE REQUEST ************************/
/////////////////////////////////////////////////////////////////



void 
aodv_rreq_pk_receive(Packet* rreq_pk_ptr)

{


int       dest, 
		  destSeqNb, 
		  source,G;

/*
/* Process the received RREQ. This procedure decides 
/* whether node should generate a RREP packet for the 
/* requested destination or simply forward it to the 
/* neighbouring nodes.
/* Note that RREQ is automatically discarded if seen 
/* less than BROADCAST_RECORD_TIME seconds ago
*/


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

// reading packet 
op_pk_nfd_get (rreq_pk_ptr,"DEST",&dest); 

op_pk_nfd_get (rreq_pk_ptr,"SRC",&source);
op_pk_nfd_get (rreq_pk_ptr,"DestSeqNb",&destSeqNb);

op_pk_nfd_get (rreq_pk_ptr,"G",&G);


// check if RREQ has already been seen

if(aodv_rreq_pk_is_fresh_enough(rreq_pk_ptr) == OPC_TRUE)
				

	{
	//request NEVER seen OR SEEN more than BROADCAST_RECORD_TIME ago

	if(DEBUG > 1 ) printf("      > RREQ is fresh enough: request handled \n");

	// update or create reverse entry 
	aodv_entry_update_or_create_from_rreq(rreq_pk_ptr);
	
	// handle request

	if(node_addr == dest) // the current node is the destination

		{

		if(DEBUG > 1 ) printf("      > RREQ has reached its destination: node replies\n");

		aodv_rrep_pk_generate_from_destination(rreq_pk_ptr);
		}
	else  // the node is an intermediate node

		{
		

		if(DEBUG > 1 ) printf("      > Node is a relay\n");

		if(aodv_fresh_enough_entry_is_available(dest,destSeqNb)== OPC_TRUE)
			{
			if(DEBUG > 1) aodv_entry_print(dest);  
			// node has a fresh enough route

			if(DEBUG > 1 ) printf("      > Node has active fresh enough entry: node replies\n");

			// if gratuitous mode requested, generate gratuitous RREP for destination
			if(G)
				{
				if(DEBUG > 1 ) printf("      > Gratuitous reply requested: generate reply for destination\n");
				aodv_gratuitous_rrep_pk_generate(rreq_pk_ptr);
				}
			// generate rrep for source



			if(DEBUG > 1 ) printf("      > Generate reply for the source node\n");
			
 
			aodv_rrep_pk_generate_from_relay(rreq_pk_ptr);
			}

		else // node doesn't have any active entry for the requested
route

			{

			if(DEBUG > 1 ) printf("      > No active entry for requested route: RREQ should be forwarded\n");
			
			aodv_rreq_pk_forward(rreq_pk_ptr);
			}
		}
	// print reverse entry if any
	if(DEBUG > 1) printf("      > Print reverse entry if any available\n");
	if(DEBUG > 1) aodv_entry_print(source);
	// print forward entry if any
	if(DEBUG > 1) printf("      > Print forward entry if any available\n");
	if(DEBUG > 1) aodv_entry_print(dest);
	

	}
else //request seen less than BROADCAST_RECORD_TIME ago

	{

	// RREQ discarded 

	if(DEBUG > 1 ) printf("      > Request seen less than BRODCAST_RECORD_TIME ago: RREQ discarded\n");

	op_pk_destroy(rreq_pk_ptr);

	}

		

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

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
// void aodv_rrep_pk_generate_from_destination(Packet* rreq_pk_ptr)   //
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//

void 
aodv_rrep_pk_generate_from_destination(Packet* rreq_pk_ptr)
	{
	
	Packet*     rrep_pk_ptr;	
	int         previousHop,        
		        source,
	            dest,
				destSeqNb;
	/*
	/* This function is called when a RREQ has reached its 
	/* destination and node wants to reply.
	/* Once the RREQ packet is generated, the procedure unicat
	/* it back to the node upstream (node from which RREQ was
	/* received) (PreviousHop field).
	*/
	
	// Read the received 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,"PreviousHop",&previousHop);
	op_pk_nfd_get (rreq_pk_ptr,"DestSeqNb",&destSeqNb);

	// Create reply packet
	rrep_pk_ptr = op_pk_create_fmt("AODV_RREP");
	// 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",0);

	op_pk_nfd_set(rrep_pk_ptr,"Lifetime",MY_ROUTE_TIMEOUT);

	
	// Assign seq number  
	mySeqNb = max_int(destSeqNb, mySeqNb);

	op_pk_nfd_set(rrep_pk_ptr,"DestSeqNb",mySeqNb);

	if(DEBUG > 1 ) printf("      > RREP has been generated from destination: unicast it to source node [next hop is %d]\n", previousHop);

	// send reply packet 
	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_gratuitous_rrep_pk_generate(rreq_pk_ptr)   //
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//

void 
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");
	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);

	
	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");

	/* 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);


	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;

	/*
	/* 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 

⌨️ 快捷键说明

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