📄 aodv_routing.pr.c
字号:
#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 + -