📄 dsr_maintenance_buffer.ex.c
字号:
/* dsr_maintenace_buffer.ex.c *//* C support file for the route request table *//****************************************//* Copyright (c) 1987-2005 *//* by OPNET Technologies, Inc. *//* (A Delaware Corporation) *//* 7255 Woodmont Av., Suite 250 *//* Bethesda, MD 20814, U.S.A. *//* All Rights Reserved. *//****************************************//***** Includes *****/#include <opnet.h>#include <manet.h>#include <dsr.h>#include <dsr_ptypes.h>#include <ip_addr_v4.h>/**** Prototypes ****/static void dsr_maintenance_buffer_last_confirm_time_update (DsrT_Maintenance_Buffer*, InetT_Address);static Boolean dsr_maintenance_buffer_size_exceeded (DsrT_Maintenance_Buffer*);static void dsr_maintenance_buffer_size_stat_update (DsrT_Maintenance_Buffer*);static DsrT_Maintenance_Buffer* dsr_support_maint_buffer_mem_alloc (void);static DsrT_Maintenance_Queue* dsr_support_maintenance_buffer_next_hop_mem_alloc (void);static void dsr_support_maintenance_buffer_next_hop_mem_free (DsrT_Maintenance_Queue*);EXTERN_C_BEGINvoid dsr_rte_maintenance_expiry_handle (void*, int);EXTERN_C_END/**************************************************//************** MAINTENANCE BUFFER ****************//**************************************************/DsrT_Maintenance_Buffer*dsr_maintenance_buffer_create (int max_size, double maint_holdoff_time, double maint_ack_timer, int max_maint_retrans, DsrT_Stathandles* stat_handle_ptr) { DsrT_Maintenance_Buffer* maint_buffer_ptr = OPC_NIL; /** Creates the maintenace buffer to enqueue packets **/ /** waiting next hop reachability confirmation **/ FIN (dsr_maintenance_buffer_create (<args>)); /* Allocate memory and creates the send buffer */ maint_buffer_ptr = dsr_support_maint_buffer_mem_alloc (); /* Set the attributes of the maintenance buffer */ maint_buffer_ptr->max_buffer_size = max_size; maint_buffer_ptr->holdoff_time = maint_holdoff_time; maint_buffer_ptr->ack_timeout = maint_ack_timer; maint_buffer_ptr->max_retransmissions = max_maint_retrans; maint_buffer_ptr->dsr_stat_ptr = stat_handle_ptr; FRET (maint_buffer_ptr); }Compcodedsr_maintenance_buffer_pkt_enqueue (DsrT_Maintenance_Buffer* maint_buffer_ptr, Packet* pkptr, InetT_Address next_hop_address, int maint_id) { char maint_id_str [20]; DsrT_Maintenance_Queue* pkt_info_ptr = OPC_NIL; void* old_contents_ptr = OPC_NIL; int* maint_id_ptr; /** Enqueues a packet into the maintenance buffer **/ /** Returns a Success if packet was enqueued **/ FIN (dsr_maintenance_buffer_pkt_enqueue (<args>)); /* Get the maintenance ID string */ sprintf (maint_id_str, "%d", maint_id); /* Check if there is space in the maintenace */ /* buffer to enqueue the packet */ if (dsr_maintenance_buffer_size_exceeded (maint_buffer_ptr) == OPC_TRUE) { /* There is no space in the maintenace buffer */ /* to enqueue the packet. Do not enqueue packet */ FRET (OPC_COMPCODE_FAILURE); } if (maint_buffer_ptr->max_retransmissions == 0) FRET (OPC_COMPCODE_FAILURE); /* There is space in the maintenace buffer to */ /* enqueue the packet. Check is the maintenace */ /* ID string exists. */ pkt_info_ptr = (DsrT_Maintenance_Queue*) prg_string_hash_table_item_get (maint_buffer_ptr->maintenance_buffer_table, maint_id_str); if (pkt_info_ptr != OPC_NIL) { /* The maintenace ID has to be unique */ op_sim_end ("Invalid maintenace identifier being inserted in the maintenace buffer", OPC_NIL, OPC_NIL, OPC_NIL); } /* No entry exists for the next hop */ /* Create an entry and enqueue */ pkt_info_ptr = dsr_support_maintenance_buffer_next_hop_mem_alloc (); /* Insert the packet into the queue */ pkt_info_ptr->pkptr = manet_rte_ip_pkt_copy (pkptr); /* Set the next hop address */ pkt_info_ptr->next_hop_addr = inet_address_copy (next_hop_address); /* Schedule the maintenance request expiry timer */ maint_id_ptr = (int *) op_prg_mem_alloc (sizeof (int)); *maint_id_ptr = maint_id; pkt_info_ptr->maint_request_expiry_timer = op_intrpt_schedule_call ( op_sim_time () + maint_buffer_ptr->ack_timeout, DSRC_ROUTE_MAINTENANCE_TIMER, dsr_rte_maintenance_expiry_handle, (void *) maint_id_ptr); /* Update the statistics */ pkt_info_ptr->num_attempts++; /* Set the next hop queue into the maintenace table */ prg_string_hash_table_item_insert (maint_buffer_ptr->maintenance_buffer_table, maint_id_str, pkt_info_ptr, &old_contents_ptr); /* Increment the size of the buffer */ maint_buffer_ptr->current_buffer_size++; /* Update the statistic for the maintenance buffer size */ dsr_maintenance_buffer_size_stat_update (maint_buffer_ptr); FRET (OPC_COMPCODE_SUCCESS); }Booleandsr_maintenance_buffer_maint_needed (DsrT_Maintenance_Buffer* maint_buffer_ptr, InetT_Address next_hop_addr) { double current_time; double* confirm_time_ptr = OPC_NIL; char next_hop_str [INETC_ADDR_STR_LEN]; /** Determines whether next hop maintenance **/ /** is needed based on the maintenance **/ /** holdoff time. **/ FIN (dsr_maintenance_buffer_maint_needed (<args>)); /* Get the next hop address as a */ /* string to index the hash table */ inet_address_print (next_hop_str, next_hop_addr); /* Get the next hop maintenance information */ confirm_time_ptr = (double*) prg_string_hash_table_item_get (maint_buffer_ptr->dest_confirm_time_table, next_hop_str); if (confirm_time_ptr == OPC_NIL) { /* Maintenace has never been done */ FRET (OPC_TRUE); } /* Get the current time */ current_time = op_sim_time (); /* If the time elapsed since the last maintenace */ /* confirmation is greater than the holdoff time */ /* then next hop confirmation is needed */ if ((current_time - (*confirm_time_ptr)) > maint_buffer_ptr->holdoff_time) { FRET (OPC_TRUE); } else { FRET (OPC_FALSE); } }List*dsr_maintenance_buffer_ack_request_expire (DsrT_Maintenance_Buffer* maint_buffer_ptr, int maint_id, Boolean* max_retrans_reached, InetT_Address* next_hop_address) { List* pkt_lptr = OPC_NIL; List* keys_lptr = OPC_NIL; char* key_str; int num_pkts, count; char maint_id_str [20]; DsrT_Maintenance_Queue* pkt_info_ptr = OPC_NIL; DsrT_Maintenance_Queue* check_pkt_info_ptr = OPC_NIL; Packet* copy_pkptr = OPC_NIL; int* maint_id_ptr; /* The acknowledgement request has expired */ /* Handle the internals of the maintenace */ /* buffer on expiry of this maintenance ID */ FIN (dsr_maintenance_buffer_ack_request_expire (<args>)); /* Create a packet list */ pkt_lptr = op_prg_list_create (); /* Get the maintenance ID string */ sprintf (maint_id_str, "%d", maint_id); /* Get the next hop maintenance information */ pkt_info_ptr = (DsrT_Maintenance_Queue*) prg_string_hash_table_item_get (maint_buffer_ptr->maintenance_buffer_table, maint_id_str); if (pkt_info_ptr == OPC_NIL) { /* No packets in the maintenance */ /* buffer with the requested ID */ FRET (pkt_lptr); } if (op_ev_valid (pkt_info_ptr->maint_request_expiry_timer) && op_ev_pending (pkt_info_ptr->maint_request_expiry_timer)) { /* Cancel the maintenance request timer if valid */ op_ev_cancel (pkt_info_ptr->maint_request_expiry_timer); } if (pkt_info_ptr->num_attempts >= maint_buffer_ptr->max_retransmissions) { /* Set the return values */ *max_retrans_reached = OPC_TRUE; *next_hop_address = inet_address_copy (pkt_info_ptr->next_hop_addr); /* Maximum retransmission attempts have been reached */ /* This destination is unreachable. Remove all packets */ /* in the maintenance buffer that are waiting this next */ /* hop confirmation. Get all packets waiting next hop */ /* confirmation and determine find this destination */ keys_lptr = prg_string_hash_table_keys_get (maint_buffer_ptr->maintenance_buffer_table); num_pkts = op_prg_list_size (keys_lptr); for (count = 0; count < num_pkts; count++) { key_str = (char*) op_prg_list_access (keys_lptr, count); check_pkt_info_ptr = (DsrT_Maintenance_Queue*) prg_string_hash_table_item_get (maint_buffer_ptr->maintenance_buffer_table, key_str); /* Check for NIL ptr */ if (check_pkt_info_ptr == PRGC_NIL) continue; if (inet_address_equal (check_pkt_info_ptr->next_hop_addr, (*next_hop_address))) { /* Do not retransmit this packet again. Remove this */ /* packet information from the maintenance buffer */ check_pkt_info_ptr = (DsrT_Maintenance_Queue*) prg_string_hash_table_item_remove (maint_buffer_ptr->maintenance_buffer_table, key_str); /* Return a copy of the packet so as to send */ /* a route error if needed */ copy_pkptr = manet_rte_ip_pkt_copy (check_pkt_info_ptr->pkptr); op_prg_list_insert (pkt_lptr, copy_pkptr, OPC_LISTPOS_TAIL); /* Reduce the current size of the buffer */ maint_buffer_ptr->current_buffer_size -= 1; /* Destroy the packet */ dsr_support_maintenance_buffer_next_hop_mem_free (check_pkt_info_ptr); } } /* Update the statistic for the maintenance buffer size */ dsr_maintenance_buffer_size_stat_update (maint_buffer_ptr); /* Free the keys list */ op_prg_list_free (keys_lptr); op_prg_mem_free (keys_lptr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -