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

📄 aodv_routing.pr.c

📁 Ad hoc网络AODV路由协议源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
op_ici_install(ici_ptr);// send packet to mac layerop_pk_send(pk,SEND_STRM);
if (DEBUG > 1) printf("      > Packet succesfully sent to MAC layer\n ");
}  
/////////////////////////////////////////////////////////////////
/*****************   aodv_data_pk_route()   *********************//////////////////////////////////////////////////////////////////
void aodv_data_pk_route(Packet* data_pk_ptr) 
{
RoutingTableEntry *   entryPtr;
int                   dest, g_flag, nextHop;
/*/* Receive the upcoming data packet stream from the /* upper layer and route it to its destination./* Two scenarios are possible:/* 1. Another packet destined for the same node/* is waiting in the sub-queue. The procedure then/* only enqueues the data packet in the sub-queue/* and waits for the next call./* 2. Sub-queue is empty. The procedure checks its/* routing table in order to find out the next hop/* toward the destination. /* 2.a. If no entry was found, the procedure /* enqueues the packet in the corresponding sub-/* queue. Then, the procedure checks whether a RREQ /* has been generated for this destination or not. /* If not, the procedure calls the appropriate function/* to generate a RREQ. Else, it waits for the next call. /* 2.b. If an entry exists, the procedure send the/* packet to the MAC layer with the appropriate next /* hop destination address.*/
// read packet
op_pk_nfd_get(data_pk_ptr,"DEST",&dest);
op_pk_nfd_get(data_pk_ptr,"G",&g_flag);

if(DEBUG > 1) printf("    - Function aodv_data_pk_route(destination %d)\n", dest);
if(aodv_buffer_is_empty(dest) == OPC_FALSE)	{	// enqueue data packet into appropriate buffer	if(DEBUG > 1) printf("      > Buffer not empty: enqueue packet into buffer\n");	aodv_data_pk_queue(data_pk_ptr);	}else	{	// check routing table for entry	if(DEBUG > 1) printf("      > Check routing table for entry\n");	entryPtr = aodv_routingTable_entry_get(dest);	// print entry if any	if(DEBUG > 1) aodv_entry_print(dest);	// get next hop along the path if any		nextHop = aodv_entry_nextHop_get(dest);	if ((nextHop != NOT_VALID) && (nextHop != NON_EXISTENT))		{		//node has an active entry for dest		if(DEBUG > 1) printf("      > Node has active fresh enough entry: packet is sent [next hop is %d]\n", nextHop);		// schedule an event if no ack received within the waiting window 
		if(DEBUG > 3) printf("      > Schedule ack-timeout event\n");
		aodv_ack_timeout_schedule(data_pk_ptr,dest);
		// send packet to mac layer
		aodv_pk_send_to_mac_layer(data_pk_ptr,nextHop);		// refresh entry timeout		if(DEBUG > 1 ) printf("      > Refresh expiration time for entry\n");		aodv_entry_expirationTime_set(dest,op_sim_time()+ACTIVE_ROUTE_TIMEOUT); 		}	else		{		if(DEBUG > 1 ) printf("      > No entry available: Data packet is inserted into buffer.\n");		// insert packet into buffer		aodv_data_pk_queue(data_pk_ptr);
		// check 
whether node should generate a request or not 		if(RequestSent[dest].status==OFF)			{
			// No request pending for this destination			// generate route request for desination 			if(DEBUG > 1 ) printf("      > No request pending: Generate RREQ packet\n");			RequestSent[dest].gratuitous = g_flag;			if(nextHop == NOT_VALID)  // Entry invalid: Set TTL to last known Hop Count				RequestSent[dest].ttl = max(entryPtr->lastHopCount,TTL_START);			// Generate rreq			aodv_rreq_pk_generate(dest, WAITING_FOR_REPLY);			}
		else
			{			// request is either under repair or waiting for a reply
			if(DEBUG > 1 ) printf("      > A request has already been sent: node waiting for reply\n");
			}
		}	}if(DEBUG > 1 ) printf("    - Function aodv_data_pk_route() done\n");
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//// void aodv_data_pk_queue(Packet* pack)                    ////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//void aodv_data_pk_queue(Packet* pk)
{
int destination;
/*/* Queue data packet in the corresponding sub-queue.*/// Read the DEST field (packet's final destination) in order to have index of subqueueop_pk_nfd_get(pk,"DEST",&destination);

// Enqueue packet in the correct subqueue if (op_subq_pk_insert(destination,pk,OPC_QPOS_TAIL) != OPC_QINS_OK)
	{
	if(DEBUG > 3) printf("      > Fail to insert packet in subqueue \n");
	op_pk_destroy(pk);
	}else	{	if(DEBUG > 1 ) printf("      > %d data packets waiting for destination %d\n", aodv_buffer_size_get(destination),destination);
	data_pk_buffer++;	stats[node_addr].data_pk_buffer++;	}}//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//// Boolean aodv_buffer_is_empty(int destination)            ////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//Boolean aodv_buffer_is_empty(int destination)
	{	/*	/* Check whether the given sub-queue (the one whose	/* index equals to destination) is empty or not.	/* Return OPC_TRUE if buffer is empty. OPC_FALSE otherwise.	*/	return op_subq_empty(destination);	}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//// int aodv_buffer_size_get(int destination)
               ////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//int aodv_buffer_size_get(int destination)
	{	/*	/* Return the number of data packets waiting	/* for this destination.	*/
	return op_subq_stat(destination, OPC_QSTAT_PKSIZE);	}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//// Packet* aodv_data_pk_dequeue(int destination)             ////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//Packet* aodv_data_pk_dequeue(int destination)
{Packet* data_pk_ptr;
/*/* Return the first packet (first in) from /* the indicated data buffer.*/// If buffer not emptyif (aodv_buffer_is_empty(destination) == OPC_FALSE)
	{	// get data packet from queue
	data_pk_ptr = op_subq_pk_remove(destination,OPC_QPOS_HEAD);
	// Decrement the number of data packets waiting into the buffer	data_pk_buffer--;	stats[node_addr].data_pk_buffer--;
	}
else 
	if(DEBUG > 3) printf("      > Buffer empty \n");

return data_pk_ptr;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//// void aodv_buffer_serve(int dest)                          ////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//void aodv_buffer_serve(int destination)
{
Packet*   data_pk_ptr;int       nextHop = aodv_entry_nextHop_get(destination);
/*/* This routine is called when a new entry is available for /* a given destination. When called, the procedure dequeues the first packet/* waiting in the corresponding buffer, reads the next hop destination /* from the routing table, then sends the data packet to the MAC layer /* with the appropriate destination IP address.*/if(DEBUG > 1 ) printf("    - Function aodv_buffer_serve(destination %d)\n",destination);
if(! aodv_buffer_is_empty(destination)){	// Check routing table for entryif(DEBUG > 1 ) printf("      > Check routing table for entry\n");
// print entry if any availableif(DEBUG >1) aodv_entry_print(destination);// get packet from sub-queueif(DEBUG > 1 ) printf("      > Get packet from buffer\n");
data_pk_ptr = aodv_data_pk_dequeue(destination);if((nextHop != NOT_VALID) && (nextHop != NON_EXISTENT))	{	if(DEBUG > 1 ) printf("      > Node has a fresh active entry\n");
	// schedule an event if no ack received within the waiting window 
	if(DEBUG > 3 ) printf("      > Arming Ack Timer\n");
	aodv_ack_timeout_schedule(data_pk_ptr,destination);	// send packet to mac layer	aodv_pk_send_to_mac_layer(data_pk_ptr,nextHop);
	// refresh entry timeout	if(DEBUG > 2 ) printf("      > Refresh expiration time for entry:\n");	aodv_entry_expirationTime_set(destination,op_sim_time()+ACTIVE_ROUTE_TIMEOUT); 	}
else	{	if(DEBUG > 1 ) printf("    > Error @ aodv_buffer_serve():: no valid entry was found !\n");	// call route function	aodv_data_pk_route(data_pk_ptr);
	}
}else	{	if(DEBUG > 1 ) printf("    > Error @ aodv_buffer_serve():: buffer empty !\n");	}if(DEBUG > 1 ) printf("    - Function aodv_buffer_serve() done\n");
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//// void aodv_ack_timeout_schedule(Packet* pk, int destination)  ////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//void aodv_ack_timeout_schedule(Packet* pk, int destination)
{
AckEvt*   ackEvt;
/*/* This routine is called when a data packet is sent to the /* MAC Layer. As a matter of fact, this procedure schedules /* an interruption in Wait_Ack seconds of the current time. /* If no ack is received within this period of time, the /* process transits to the Ack_Timeout State in order to re-/* transmit the lost packet./* However, if an ack is received, the ack-timeout interruption/* is cancelled (see Rcv_Ack State).*/if(DEBUG > 3 ) printf("      - Function aodv_ack_timeout_schedule(destination %d)\n", destination);
// create an AckEvt structure to store interruption attributesackEvt= (AckEvt*) op_prg_mem_alloc(sizeof(AckEvt));
if (ackEvt!=NULL)
	{	// Schedule interruption with the appropriate code (destination to which packet has been sent)
	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 destinationif(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));
	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

⌨️ 快捷键说明

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