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

📄 aodv_routing_add.pr.c

📁 adhoc网络中AODV协议的仿真码, 并有改进的
💻 C
📖 第 1 页 / 共 5 页
字号:
#define global_control_pk_cnt_stathandle		pr_state_ptr->global_control_pk_cnt_stathandle
#define global_data_pk_cnt_stathandle		pr_state_ptr->global_data_pk_cnt_stathandle
#define pk_error_count          		pr_state_ptr->pk_error_count
#define pk_error_cnt_stathandle 		pr_state_ptr->pk_error_cnt_stathandle
#define global_error_pk_cnt_stathandle		pr_state_ptr->global_error_pk_cnt_stathandle
#define global_nerror_pk_cnt_stathandle		pr_state_ptr->global_nerror_pk_cnt_stathandle
#define global_repair_pk_cnt_stathandle		pr_state_ptr->global_repair_pk_cnt_stathandle
#define global_receive_data_pk_cnt_stathandle		pr_state_ptr->global_receive_data_pk_cnt_stathandle
#define global_buffer_size_stathandle		pr_state_ptr->global_buffer_size_stathandle

/* This macro definition will define a local variable called	*/
/* "op_sv_ptr" in each function containing a FIN statement.	*/
/* This variable points to the state variable data structure,	*/
/* and can be used from a C debugger to display their values.	*/
#undef FIN_PREAMBLE
#define FIN_PREAMBLE	aodv_routing_add_state *op_sv_ptr = pr_state_ptr;


/* Function Block */

enum { _block_origin = __LINE__ };
/////////////////////////////////////////////////////////////////

/****************  aodv_pk_send_to_mac_layer () ****************/
/////////////////////////////////////////////////////////////////

void 
aodv_pk_send_to_mac_layer(Packet *pk, int nextHop)

{


Ici*   ici_ptr;

int    pk_type,src;

/*
/* Send packet (pk) to the MAC layer interface. The routine also 
/* installs an ICI in order to indicate the next hop address to 
/* which the packet should be sent.
*/

op_pk_nfd_get(pk,"Type",&pk_type);
if(pk_type == DATA_PACKET_TYPE)
{
   pk_data_count = pk_data_count + 1;
   op_stat_write(pk_data_cnt_stathandle, pk_data_count);
   op_stat_write(global_data_pk_cnt_stathandle, ++global_data_pk_cnt);
}
else
{
   pk_control_count = pk_control_count + 1;
   op_stat_write(pk_control_cnt_stathandle, pk_control_count);
   op_stat_write(global_control_pk_cnt_stathandle, ++global_control_pk_cnt);
}

if(pk_type == ERROR_PACKET_TYPE)
{
   //pk_error_count = pk_error_count + 1;
   //op_stat_write(pk_error_cnt_stathandle, pk_error_count);
   op_stat_write(global_error_pk_cnt_stathandle, ++global_error_pk_cnt);
}
else
{
   //op_stat_write(global_nerror_pk_cnt_stathandle, ++global_nerror_pk_cnt);
}

// set IP header 
// PreviousHop field = source IP address
op_pk_nfd_set(pk,"PreviousHop",node_addr);
// NextHop field = destination IP address
op_pk_nfd_set(pk,"NextHop",nextHop);

// set TR_source field for Transmission Range purpouse
op_pk_nfd_set(pk,"TR_source",node_id);
// print packet
if(DEBUG > 1) aodv_pk_print(pk);
// create and install an ici to communicate the packet destination 
// to the MAC layer interface.
ici_ptr = op_ici_create("aodv_notice_to_send");
op_ici_attr_set(ici_ptr,"Packet_Destination",nextHop);
op_ici_install(ici_ptr);
// send packet to mac layer
op_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_int(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 subqueue
op_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++;
	op_stat_write(global_buffer_size_stathandle, 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 empty
if (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--;
	op_stat_write(global_buffer_size_stathandle, 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 entry
if(DEBUG > 1 ) printf("      > Check routing table for entry\n");

// print entry if any available
if(DEBUG >1) aodv_entry_print(destination);
// get packet from sub-queue
if(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 attributes
ackEvt= (AckEvt*) op_prg_mem_alloc(sizeof(AckEvt));

if (ackEvt!=NULL)

	{
	// Schedule interruption with the appropriate code (destination to which packet has been sent)

⌨️ 快捷键说明

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