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

📄 aodv_routing.pr.c

📁 在OPNET中实现AODV路由协议
💻 C
📖 第 1 页 / 共 5 页
字号:
#define send_buffer_size        		pr_state_ptr->send_buffer_size/* 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_state *op_sv_ptr = pr_state_ptr;/* Function Block */enum { _block_origin = __LINE__ };/********************************************/* This routine is called when a route breaks /* and node wants to attempt a local repair/* to restore it.*********************************************/void aodv_initiate_maintenance(int dest, int source)	{	Aodv_Route_Table_Entry  *entry;	Packet                  *rreq_pk_ptr;	int                     hop_count_to_source = 0;	int                     hop_count_to_dest   = 0;	int                     rreq_ttl = MIN_REPAIR_TTL;	int                     rreq_dest_seq_nb;	char                    msg[64];	// Trace	sprintf(msg, "Checking if repair is possible:");	aodv_print_minor(msg, TRACE_LEV_1);	// Trace	sprintf(msg, "Unreachable destination is %d", dest);	aodv_print_minor(msg, TRACE_LEV_1);	// Print entry	aodv_prg_print_entry(dest,TRACE_LEV_2);	// Trace	sprintf(msg, "Source node is %d", source);	aodv_print_minor(msg, TRACE_LEV_1);	//aodv_prg_print_entry(source,TRACE_LEV_2);		// Read entry for source node	if(my_route_table[source].entry_exist)		{		hop_count_to_source = min_int(my_route_table[source].hop_count,										my_route_table[source].last_hop_count);		if(my_route_table[source].hop_count == OPC_INT_INFINITY)			hop_count_to_source = my_route_table[source].last_hop_count;		}	// Read entry for destination node	if(my_route_table[dest].entry_exist)		{		hop_count_to_dest = min_int(my_route_table[dest].hop_count,										my_route_table[dest].last_hop_count);		if(hop_count_to_dest >= num_nodes)			hop_count_to_dest = MAX_REPAIR_TTL;		}	else		op_sim_end("Error @ initiate maintenance", "No route was found","Node should not have deleted it","");	// Check if route is repairable--	// destination should not be farther	// than MAX_REPAIR_TTL hops away from	// the current node	if(hop_count_to_dest <= MAX_REPAIR_TTL)		{		// Trace		aodv_print_minor("Repair is possible: Initiating process", TRACE_LEV_1);		// update stats		repair_attempts++;		// Invalidating entry 		aodv_print_minor("Invalidating entry", TRACE_LEV_1);		aodv_entry_invalidate(&my_route_table[dest]);		// Set the under repair flag		my_route_table[dest].repair_flag = 1;		// Reset the breakage flag		my_route_table[dest].breakage_flag = 0;		// Computing RREQ.TTL		rreq_ttl = max_int(MIN_REPAIR_TTL, (int)(0.5*hop_count_to_source));		rreq_ttl = rreq_ttl + LOCAL_ADD_TTL;		// Getting dest seq nb value		rreq_dest_seq_nb = my_route_table[dest].dest_seq_nb;		// Trace		aodv_print_minor("Generating RREQ packet", TRACE_LEV_1);				// create packet		rreq_pk_ptr = op_pk_create_fmt("AODV_RREQ");		op_pk_nfd_set(rreq_pk_ptr, "BroadcastID", my_broadcast_id);		// Increment broadcast ID		my_broadcast_id++;		op_pk_nfd_set(rreq_pk_ptr, "Dest"       , dest);		op_pk_nfd_set(rreq_pk_ptr, "DestSeqNb"  , rreq_dest_seq_nb);		op_pk_nfd_set(rreq_pk_ptr, "Source"     , my_node_addr);		op_pk_nfd_set(rreq_pk_ptr, "SrcSeqNb"   , my_seq_nb);		// Incrment seq nb (Optional)		my_seq_nb++;		op_pk_nfd_set(rreq_pk_ptr, "HopCount"   , 0);		op_pk_nfd_set(rreq_pk_ptr, "TTL"        , rreq_ttl);		op_pk_nfd_set(rreq_pk_ptr, "G"          , 1);		// Set size		op_pk_total_size_set(rreq_pk_ptr, 192);		// If a request was pending, then cancel it		if(req_sent_rep[dest].pending)			aodv_cancel_pending_request(dest);		// Record the request in the req_sent_rep		req_sent_rep[dest].pending         = 1;		req_sent_rep[dest].attempts_count++;		req_sent_rep[dest].retries_count   = 0;		req_sent_rep[dest].rreq_pk_copy    = op_pk_copy(rreq_pk_ptr);		req_sent_rep[dest].evh             = op_intrpt_schedule_self(op_sim_time()+2*rreq_ttl*NODE_TRAVERSAL_TIME, dest+N);		req_sent_rep[dest].emission_time   = op_sim_time();				// Send packet to mac layer		aodv_pk_send(rreq_pk_ptr, BROADCAST);		}	else		{		// Trace		sprintf(msg, "Unreachable node is too far: Generating RERR");		aodv_print_minor(msg, TRACE_LEV_1);		// reset the breakage flag		my_route_table[dest].breakage_flag = 0;		// Generate RERR (case_ii)		aodv_rerr_pk_generate(dest, case_ii);		}	}/*****************************************************************/* 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).*****************************************************************/void aodv_ack_timeout_schedule(Packet* data_pk_ptr)
{
int                   final_dest;Ack_Pending_Struct*   ack;
// Read packet's final destinationop_pk_nfd_get(data_pk_ptr, "Dest", &final_dest);// create an Ack vent structure to store interruption attributesack = (Ack_Pending_Struct*) op_prg_mem_alloc(sizeof(Ack_Pending_Struct));
if (ack!= OPC_NIL)
	{	// set retry count to 0	ack->retry_count = 0;	// Schedule interruption with the appropriate code (destination to which packet has been sent)
	ack->evh = op_intrpt_schedule_remote(op_sim_time()+ ACK_WAIT_TIME ,final_dest , op_id_self());	// store a copy of the sent packet	ack->data_pk_copy = op_pk_copy(data_pk_ptr);
	// Store the Ack evt in the ack pending list	aodv_list_insert(ack_pending_list, ack, final_dest);
	}
}/************************************/* This procedure is called when the /* node up stream an active link is lost./* In this case, and if the REPAIR mode/* is enabled, then node flags all the /* other destinations that have been /* lost because of the link breakage/* before it attempts to repair the route/* for the final destination.*************************************/void aodv_flag_lost_entries(int node_upstream, int final_destination)	{	Aodv_Route_Table_Entry * entry;	char                     msg[64];	int   i;	// go through all the entries of the routing	// tables (except the final destination), and	// check whether the lost node (node_upstream) is	// the next hop toward this destination or not.	// If so, then mark the entry as broken. Else, skip	// to next entry.	// Initiate the cursor to the first position 	    // For each entry    for(i = 0; i < N; i++)		{		// Read entry		if(my_route_table[i].entry_exist && my_route_table[i].hop_count != OPC_INT_INFINITY)			{				// Trace			sprintf(msg, ">>> Processing entry %d :", i);			aodv_print_minor(msg, TRACE_LEV_3);			// Proceed only if entry->next_hop is the node upstream			if(my_route_table[i].next_hop == node_upstream && my_route_table[i].dest_ip_addr != final_destination)			  {			  // Trace			  sprintf(msg, ">>>>>> Entry %d is marked broken", i);			  aodv_print_minor(msg, TRACE_LEV_1);			  // Set the breakage flag			  my_route_table[i].breakage_flag = 1;			  my_route_table[i].dest_seq_nb++;			  // Schedule deletion			  aodv_entry_reschedule_intrpt(&my_route_table[i], op_sim_time()+DELETE_PERIOD);			  // Trace			  aodv_prg_print_entry(i, TRACE_LEV_3);			  }		    else			  {			  // Trace			  sprintf(msg, ">>>>>> Entry %d is skipped", i);			  aodv_print_minor(msg, TRACE_LEV_3);			  }			}		}	}/************************************/* This procedure is called when the /* discovery process has arrived to an/* end, and no reply was received./* The node, then, drops the data buffer/* and resets the request record within/* the request sent repository.*************************************/void aodv_terminate_discovery(int dest)	{	// if request is not pending, then stop the	// simulation	if(!req_sent_rep[dest].pending)		{		printf("Error @ terminate discovery", "No request is pending\n");		}	else		{		// update stats		discovery_failures++;		// Drop buffer		pk_destroyed_discov_fail+=aodv_buffer_size(dest);		aodv_buffer_drop(dest);		// Reset request's record		req_sent_rep[dest].pending         = 0;		req_sent_rep[dest].attempts_count  = 0;		req_sent_rep[dest].retries_count   = 0;		op_pk_destroy(req_sent_rep[dest].rreq_pk_copy);				}	}/************************************/* Rebroadcast a request for a given/* destination./* This function is called when no reply/* was received for the previous request/* and there is still a possibility to /* renew it./* An expanded ring search method is /* automatically used here.*************************************/void aodv_continue_discovery(int dest)	{	int    rreq_dest_seq_nb;	int    rreq_ttl;	int    last_dest_seq_nb;	int    last_ttl;	char   msg[64];		if(!req_sent_rep[dest].pending)		{		printf("Error @ continue discovery", "No request is pending\n");		}	else		{		// trace		sprintf(msg, "Renewing request for destination %d",dest);		aodv_print_minor(msg, TRACE_LEV_1);		sprintf(msg, "Attempt number %d",++req_sent_rep[dest].attempts_count);		aodv_print_minor(msg, TRACE_LEV_1);		// Step 1: Compute TTL value		// Read last TTL		op_pk_nfd_get(req_sent_rep[dest].rreq_pk_copy, "TTL", &last_ttl);		rreq_ttl = last_ttl+ TTL_INCREMENT;		// If rreq_ttl > treshold, then use NET_DIAMETER value		if(rreq_ttl >= TTL_TRESHOLD)			{			// trace			aodv_print_minor("( i ) TTL_TRESHOLD reached",TRACE_LEV_1);			rreq_ttl = NET_DIAMETER;			req_sent_rep[dest].retries_count++;			}		// Step 2: check destination seq nb		op_pk_nfd_get(req_sent_rep[dest].rreq_pk_copy, "DestSeqNb", &last_dest_seq_nb);		// Set rreq.dest_seq_nb to max(last dest_seq_nb, RouteTable(dest).dest_seq_nb		rreq_dest_seq_nb = max_int(aodv_rt_lookup_dest_seq_nb(my_route_table,dest),last_dest_seq_nb);		// set new value of ttl and dest_seq_nb		op_pk_nfd_set(req_sent_rep[dest].rreq_pk_copy, "TTL"        , rreq_ttl);		op_pk_nfd_set(req_sent_rep[dest].rreq_pk_copy, "DestSeqNb"  , rreq_dest_seq_nb);				op_pk_nfd_set(req_sent_rep[dest].rreq_pk_copy, "BroadcastID", my_broadcast_id++);		op_pk_nfd_set(req_sent_rep[dest].rreq_pk_copy, "SrcSeqNb"   , my_seq_nb++);		// trace		aodv_print_minor("RREQ has been generated",TRACE_LEV_1);		// Broadcast a copy		aodv_pk_send(op_pk_copy(req_sent_rep[dest].rreq_pk_copy),BROADCAST);		// schedule intrpt		req_sent_rep[dest].evh             = op_intrpt_schedule_self(op_sim_time()+2*rreq_ttl*NODE_TRAVERSAL_TIME, dest+N);		}		}/************************************/* Initiates discovery service for a given/* destination.*************************************/void aodv_initiate_discovery(int dest)	{	int    rreq_dest_seq_nb = 0;	int    rreq_ttl         = TTL_START;	char   msg[64];	Aodv_Route_Table_Entry *entry;	Packet                 *rreq_pk_ptr;	// Trace 	sprintf(msg, "Initiating discovery for destination %d", dest);	aodv_print_minor(msg,TRACE_LEV_1);	// if a request is already pending, then do 	// nothing	if(req_sent_rep[dest].pending)		{		// Trace		aodv_print_minor("A request is already pending: wait for reply",TRACE_LEV_1);		}	else		{		// trace		aodv_print_minor("Generating RREQ",TRACE_LEV_1);		// update stats		discovery_attempts++;		// if entry exists, then		// RREQ.ttl = RouteTable(dest).last_hop_count + TTL_INCREMENT		// and RREQ.dest_seq_nb = RouteTable(dest).dest_seq_nb		if(aodv_rt_lookup_entry(my_route_table,dest) == OPC_TRUE)			{			// read entry			//entry = aodv_rt_access_entry(my_route_table,dest);			rreq_dest_seq_nb = aodv_rt_lookup_dest_seq_nb(my_route_table, dest);			rreq_ttl         = max_int(my_route_table[dest].last_hop_count, TTL_START);			if(rreq_ttl == OPC_INT_INFINITY)				op_sim_end("Error @ initiate discov: TTL = infinity","","","");			}		// create packet		rreq_pk_ptr = op_pk_create_fmt("AODV_RREQ");		op_pk_nfd_set(rreq_pk_ptr, "BroadcastID", my_broadcast_id);		// Increment broadcast ID		my_broadcast_id++;				op_pk_nfd_set(rreq_pk_ptr, "Dest"       , dest);		op_pk_nfd_set(rreq_pk_ptr, "DestSeqNb"  , rreq_dest_seq_nb);		op_pk_nfd_set(rreq_pk_ptr, "Source"     , my_node_addr);		op_pk_nfd_set(rreq_pk_ptr, "SrcSeqNb"   , my_seq_nb);		// Increment seq nb

⌨️ 快捷键说明

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