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

📄 dsr_routing_layer.pr.c

📁 afit的ad hoc路由协议源码
💻 C
📖 第 1 页 / 共 5 页
字号:

			/* If the route_found returns 0 it could have been the case that the cached route included 1 or 
			   more of the nodes found in the request packet path...if this was the case then the final route 
			   that would be provided would have had a loop in it.  Thus the call to dsr_transmit_reply_from_relay
			   eliminates those routes from its cache and returns a zero.
			
			   Thus another check should be done to see if there is another route that was not deleted from the cache
			*/
			if ((route_found == 0) && (route_cache[destination_dsr_address].node_route[0].size_route > 0) && 
				((route_cache[destination_dsr_address].node_route[0].size_route + size_route) < MAX_SIZE_ROUTE))
				{ 
				// a reply (from relay) packet must be built and sent
				route_found = dsr_transmit_reply_from_relay(pk_ptr);
				}

			}
		
		// otherwise if the request is not too hold (life time and number of hops) and 
		// a route is not found in the cache, then forward the request on
		if ((route_found == 0) && (creation_time+MAX_REQUEST_PERIOD>op_sim_time()) && (seg_left>0))
			{
			// the packet must be forwarded
			dsr_forward_request(pk_ptr);
			}
		// otherwise
		else if (route_found == 0)
            {
			// the packet must be destroyed
			dsr_message("Route not found and the request is too old or non-propagating, thus I am destroying the packet\n");
			op_pk_destroy(pk_ptr);

			}
		
		}
	}
// otherwise if the packet has been already seen it must not be processed in order to avoid loops or multiple similar replies
else
	{
	// thus it is destroyed
	op_pk_destroy(pk_ptr);
	}

// breakpoint for debugging purpose
if (1)
	{
	op_prg_odb_bkpt("handle_request");
	}
}

/*************************************************************/
/*               DSR_REQUEST_ALREADY_SEEN                    */
/*************************************************************/
/* This function checks if the request identified by its source,
/* its destination and its sequence_number has been already seen
/* and consequently handled
/*
/* int source_dsr_address: the dsr address of the request source
/* int destination_dsr_address: the dsr address of the request destination
/* int sequence_number: the sequence number of the request
/*		RETURN: 1 if the request packet has been already seen 
/*				0 otherwise
/*************************************************************/
int dsr_request_already_seen(int source_dsr_address,int destination_dsr_address,int sequence_number)
{
// the request has been already seen since its sequence number is lower or equal than the one stored in memory
if (request_seen[source_dsr_address][destination_dsr_address]>=sequence_number)
	{
	dsr_message("I have already seen this request\n");
	return(1);
    }
else
	{
	// store the fact that the request has been already seen for the future by storing its sequence number
	request_seen[source_dsr_address][destination_dsr_address]=sequence_number;
	dsr_message("It is the first time that I am seeing this request\n");
	return (0);
	}
}

/*************************************************************/
/*                  DSR_FORWARD_REQUEST                      */
/*************************************************************/
/* This function forward the request received by the node
/*
/* 		Packet* pk_ptr: a pointer to the request packet to forward
/*************************************************************/
void dsr_forward_request(Packet* pk_ptr)
{
int size_route;
int seg_left;
char field[10];
int destination_dsr_address;

// get the size of the route from the request packet
op_pk_nfd_get (pk_ptr,"Opt_Data_Len",&size_route);
op_pk_nfd_get (pk_ptr,"IP_TTL",&seg_left);

// the current node adds its own dsr address in the request path
sprintf(field,"Node_%d",size_route);
op_pk_nfd_set (pk_ptr,field,my_dsr_address);

// decrement by one the Seg_left field of the packet
op_pk_nfd_set(pk_ptr,"IP_TTL",--seg_left);
// increment by one the Size_Route  
op_pk_nfd_set(pk_ptr,"Opt_Data_Len",++size_route);

// write the node_objid in the packet for the transmission range purpose
op_pk_nfd_set(pk_ptr,"TR_source",my_node_objid);

op_pk_nfd_get(pk_ptr,"Node_0",&destination_dsr_address);
sprintf(message,"I forward the request destined for %d\n",destination_dsr_address);
dsr_message(message);

// update statistics
++total_forward_request;
++node_forward_request;
op_stat_write(stat_node_forward_request,node_forward_request);
op_stat_write(stat_total_forward_request,total_forward_request);

// send the request to the MAC layer which will BROADCAST it
dsr_send_to_mac(pk_ptr,BROADCAST);

// breakpoint for debugging purpose
if (1)
	{
	op_prg_odb_bkpt("forward request");
	}
}

/*************************************************************/
/*            DSR_TRANSMIT_REPLY_FROM_TARGET                 */
/*************************************************************/
/* This function build and transmit a reply packet from target
/* (the node is the destination of the received request)
/*
/* 		Packet* pk_ptr: a pointer to the request packet to reply
/*************************************************************/
void dsr_transmit_reply_from_target(Packet* pk_ptr)
{
Packet* reply_pk_ptr;
int request_source_dsr_address;
int node_dsr_address;
int relay_dsr_address;
int relay_mac_address;
char field[10];
int seg_left,size_route;
int sequence_number;
int i;

// create the reply packet and set its Type field
reply_pk_ptr = op_pk_create_fmt("dsr_reply");
op_pk_nfd_set(pk_ptr,"Option_Type",REPLY_PACKET_TYPE);

// since I am the request target I am also the reply source
op_pk_nfd_set(reply_pk_ptr,"SRC",my_dsr_address);
// set the reply DEST field => the request source is the reply destination
op_pk_nfd_get(pk_ptr,"SRC",&request_source_dsr_address);
op_pk_nfd_set(reply_pk_ptr,"DEST",request_source_dsr_address);
// set the field in the packet indicating that it is a reply from target
op_pk_nfd_set(reply_pk_ptr,"Reply_From_Target",1);

// set the reply Identification field => same sequence number than the request
op_pk_nfd_get(pk_ptr,"Identification",&sequence_number);
op_pk_nfd_set(reply_pk_ptr,"Identification",sequence_number);

op_pk_nfd_get(pk_ptr,"Opt_Data_Len",&size_route);
// add the source node to the size_route
size_route = size_route + 1;

// Print the source route to the screen
if (DEBUG != 0)
	{
	printf("Reply from Target route: ");
	printf("%d...",request_source_dsr_address);	
	}

// Copy the fields "Node_i" from the request to the reply in the same order
for (i=0; i<size_route-2; i++)	{
	sprintf(field,"Node_%d",i+1);
	op_pk_nfd_get(pk_ptr,field,&node_dsr_address);
	sprintf(field,"Node_%d",i);
	op_pk_nfd_set(reply_pk_ptr,field,node_dsr_address);
	if (DEBUG != 0)
		{
		printf("%d...",node_dsr_address);	
		}
	}

// Set the target address (my_dsr_address) to the last address of the source route in reply
sprintf(field,"Node_%d",size_route-2);
op_pk_nfd_set(reply_pk_ptr,field,my_dsr_address);
if (DEBUG != 0)
	{
	printf("%d...end\n",my_dsr_address);
	}

// Assign the first relay on the reply packet's route (-2 for the index of the last node of the route and another -1 for the previous one)
if (size_route > 2)
	{
	sprintf(field,"Node_%d",size_route-3);
	op_pk_nfd_get(reply_pk_ptr,field,&relay_dsr_address);
	}
else
	{
	op_pk_nfd_get(reply_pk_ptr,"DEST",&relay_dsr_address);
	}

// update the seg_left and size route fields (-1 = number of hops in the route, another -1 = segment left)
seg_left=size_route-2;
op_pk_nfd_set(reply_pk_ptr,"IP_TTL",seg_left);
// Set Opt_Data_Len to size_route minus source node
op_pk_nfd_set(reply_pk_ptr,"Opt_Data_Len",size_route-1);

// set the TR_source fields for the Transmission range purpose
op_pk_nfd_set(reply_pk_ptr,"TR_source",my_node_objid);

// since I am the reply transmitter I will not have to process it in the future
dsr_reply_already_seen(request_source_dsr_address,my_dsr_address,sequence_number);

// convert the dsr address of the first relay in its mac address
relay_mac_address = dsr_support_get_mac_from_dsr_address(relay_dsr_address);
// and send the reply packet instantanetly since I am the target of the request
dsr_send_to_mac(reply_pk_ptr,relay_mac_address);
//dsr_send_to_mac(reply_pk_ptr,relay_dsr_address);

sprintf(message,"I am sending a reply from target for %d to %d with sequence_number %d\n",request_source_dsr_address,relay_dsr_address,sequence_number);
dsr_message(message);

// update replies statistics
++total_replies_from_target;
++total_replies;
op_stat_write(stat_total_replies_from_target,total_replies_from_target);
op_stat_write(stat_total_replies,total_replies);

// and destroy the request packet
op_pk_destroy(pk_ptr);

// breakpoints for debugging purpose
if (1)
	{
	op_prg_odb_bkpt("transmit_reply");
	op_prg_odb_bkpt("transmit_reply_from_target");
	}
}

/*************************************************************/
/*            DSR_TRANSMIT_REPLY_FROM_RELAY                  */
/*************************************************************/
/* This function builds and transmits a reply packet from relay
/* (the node is not the destination of the received request, but
/* can reply by using its route cache)
/*
/* Packet* pk_ptr: a pointer to the request packet to reply
/*************************************************************/
int dsr_transmit_reply_from_relay(Packet *pk_ptr)
{
Packet* reply_pk_ptr;
int request_source_dsr_address; 
int request_destination_dsr_address;
int relay_dsr_address;
int node_dsr_address;
char field[10];
int seg_left;
int size_route;
int sequence_number;
sNodeRoute reply_route;
Distribution* delay_reply_dist;
double delay;
sReply* reply;
int* intPtr;
int i,j;
int node_found;
int route_found;

// read the Size_Route and request destination address from the request packet
op_pk_nfd_get(pk_ptr,"Opt_Data_Len",&size_route);
op_pk_nfd_get(pk_ptr,"Node_0",&request_destination_dsr_address);

// Check if the pasted route's length will be still < MAX_SIZE_ROUTE length
if ((size_route+route_cache[request_destination_dsr_address].node_route[0].size_route)<MAX_SIZE_ROUTE)
	{
	// create the reply packet and set its Type field
	reply_pk_ptr = op_pk_create_fmt("dsr_reply");
	op_pk_nfd_set(reply_pk_ptr,"Option_Type",REPLY_PACKET_TYPE);

	// assign the Source and Dest field to the reply packet
	op_pk_nfd_set(reply_pk_ptr,"SRC",my_dsr_address);
	op_pk_nfd_get(pk_ptr,"SRC",&request_source_dsr_address);
	op_pk_nfd_set(reply_pk_ptr,"DEST",request_source_dsr_address);

	// set the field in the packet indicating that it is a reply from relay
	op_pk_nfd_set(reply_pk_ptr,"Reply_From_Target",0);

	// set the reply Identification field => same sequence number than the request
	op_pk_nfd_get(pk_ptr,"Identification",&sequence_number);
	op_pk_nfd_set(reply_pk_ptr,"Identification",sequence_number);

	// copy the first part of the route coming from the request in the reply_route
	reply_route.route[0]=request_source_dsr_address;
	for (i=1; i<size_route; i++)	
		{
		sprintf(field,"Node_%d",i);
		op_pk_nfd_get(pk_ptr,field,&node_dsr_address);
		reply_route.route[i]=node_dsr_address;
		}

	// copy the second part of the route coming from the route_cache in the reply_route
	for (i=size_route;i<(size_route+route_cache[request_destination_dsr_address].node_route[0].size_route);i++)
		{
		reply_route.route[i]=route_cache[request_destination_dsr_address].node_route[0].route[i-size_route];
		}
	
	// calculate the size ot the reply_route
	reply_route.size_route=size_route+route_cache[request_destination_dsr_address].node_route[0].size_route;
	
	// clear every loop from the reply_route
	dsr_no_loop_in_route(&reply_route);
	
	// check if the node is still in the path and find its position 
	i=0;
	do
		{
		i++;

⌨️ 快捷键说明

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