📄 dsr_send_buffer.ex.c
字号:
/* dsr_send_buffer.ex.c *//* C support file for the send buffer *//****************************************//* 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 DsrT_Packet_Entry* dsr_send_buffer_pkt_entry_create (Packet*);static void dsr_send_buffer_all_expired_pkts_delete (DsrT_Send_Buffer*);static Boolean dsr_send_buffer_size_exceeded (DsrT_Send_Buffer*);static Compcode dsr_send_buffer_overflow_handle (DsrT_Send_Buffer*);static void dsr_send_buffer_size_stat_update (DsrT_Send_Buffer*);static void dsr_send_buffer_route_discovery_time_stat_update (DsrT_Send_Buffer*, List*);static DsrT_Send_Buffer* dsr_send_buffer_mem_alloc (void);static DsrT_Packet_Entry* dsr_send_buffer_pkt_entry_mem_alloc (void);static void dsr_send_buffer_pkt_entry_mem_free (DsrT_Packet_Entry*);DsrT_Send_Buffer*dsr_send_buffer_create (int max_buffer_size, double expiry_time, DsrT_Stathandles* stat_handle_ptr, DsrT_Global_Stathandles* global_stat_handle_ptr) { DsrT_Send_Buffer* send_buffer_ptr = OPC_NIL; /** Creates the send buffer to enqueue packets **/ FIN (dsr_send_buffer_create (<args>)); /* Allocate memory and creates the send buffer */ send_buffer_ptr = dsr_send_buffer_mem_alloc (); /* Set the maximum size of the send buffer */ send_buffer_ptr->max_buffer_size = max_buffer_size; /* Set the time for packet expiry in this buffer */ send_buffer_ptr->pkt_expiry_time = expiry_time; /* Set the statistic handles */ send_buffer_ptr->dsr_stat_ptr = stat_handle_ptr; send_buffer_ptr->global_dsr_stat_ptr = global_stat_handle_ptr; FRET (send_buffer_ptr); }Compcodedsr_send_buffer_packet_enqueue (DsrT_Send_Buffer* send_buffer_ptr, Packet* pkptr, InetT_Address dest_address) { List* packet_queue_lptr = OPC_NIL; DsrT_Packet_Entry* dsr_pkt_entry_ptr = OPC_NIL; char dest_addr_str [INETC_ADDR_STR_LEN]; void* old_contents_ptr = OPC_NIL; /** Enqueues a packet in the send buffer **/ FIN (dsr_send_buffer_packet_enqueue (<args>)); /* Get the destination address as a */ /* string to index the hash table */ inet_address_print (dest_addr_str, dest_address); /* Delete all packets that have expired */ dsr_send_buffer_all_expired_pkts_delete (send_buffer_ptr); /* Check if there already exists packets waiting */ /* to be sent to the destination of this packet */ packet_queue_lptr = (List*) prg_string_hash_table_item_get (send_buffer_ptr->send_buffer_table, dest_addr_str); if (packet_queue_lptr == OPC_NIL) { /* No packets exist to the destination */ /* Create a packet queue and insert the */ /* packet into the queue */ packet_queue_lptr = op_prg_list_create (); /* Set the packet queue in the send buffer table */ prg_string_hash_table_item_insert (send_buffer_ptr->send_buffer_table, dest_addr_str, packet_queue_lptr, &old_contents_ptr); } /* Check if there is any space in the send buffer */ /* to enqueue the packet */ if (dsr_send_buffer_size_exceeded (send_buffer_ptr) == OPC_TRUE) { /* There is no space in the send buffer */ /* Based on the type of priority scheme */ /* for packets to be discarded, this */ /* packet may or may not be enqueued. */ /* Typically a FIFO scheme is used to */ /* discard packets from this buffer */ if (dsr_send_buffer_overflow_handle (send_buffer_ptr) == OPC_COMPCODE_FAILURE) { FRET (OPC_COMPCODE_FAILURE); } } /* Enqueue the packet in the send buffer */ dsr_pkt_entry_ptr = dsr_send_buffer_pkt_entry_create (pkptr); op_prg_list_insert (packet_queue_lptr, dsr_pkt_entry_ptr, OPC_LISTPOS_TAIL); /* Increment the size of the send buffer */ send_buffer_ptr->current_buffer_size++; /* Update the size of the send buffer statistic */ dsr_send_buffer_size_stat_update (send_buffer_ptr); /* The packet was inserted successfully */ FRET (OPC_COMPCODE_SUCCESS); } List*dsr_send_buffer_pkt_list_get (DsrT_Send_Buffer* send_buffer_ptr, InetT_Address dest_address, Boolean remove) { DsrT_Packet_Entry* pkt_entry_ptr = OPC_NIL; List* pkt_queue_lptr = OPC_NIL; List* pkt_lptr = OPC_NIL; char dest_addr_str [INETC_ADDR_STR_LEN]; int num_packets, count; int num_pkts_deleted; /** Returns the list of of packets enqueued for **/ /** a particular destination. If the remove **/ /** flag is set, all the packets to that **/ /** destination will be removed from the buffer **/ /** An OPC_NIL is returned if no packets exist **/ FIN (dsr_send_buffer_pkt_list_get (<args>)); /* Get the destination address as a */ /* string to index the hash table */ inet_address_print (dest_addr_str, dest_address); /* Delete all packets that have expired */ dsr_send_buffer_all_expired_pkts_delete (send_buffer_ptr); /* Get the list of packets to the particular destination */ if (remove) { pkt_queue_lptr = (List*) prg_string_hash_table_item_remove (send_buffer_ptr->send_buffer_table, dest_addr_str); if (pkt_queue_lptr == OPC_NIL) FRET (pkt_queue_lptr); /* Update the route discovery time statistics */ dsr_send_buffer_route_discovery_time_stat_update (send_buffer_ptr, pkt_queue_lptr); /* Get the number of packets removed */ num_packets = op_prg_list_size (pkt_queue_lptr); num_pkts_deleted = num_packets; /* Create a list to return the packets */ pkt_lptr = op_prg_list_create (); while (num_packets > 0) { /* Get each packet */ pkt_entry_ptr = (DsrT_Packet_Entry*) op_prg_list_remove (pkt_queue_lptr, OPC_LISTPOS_HEAD); /* Place each packet in the queue */ op_prg_list_insert (pkt_lptr, pkt_entry_ptr->pkptr, OPC_LISTPOS_TAIL); /* Free each entry */ op_prg_mem_free (pkt_entry_ptr); num_packets--; } /* Free the list */ op_prg_mem_free (pkt_queue_lptr); /* Decrement the number of entries in the send buffer */ send_buffer_ptr->current_buffer_size -= num_pkts_deleted; /* Update the size of the send buffer statistic */ dsr_send_buffer_size_stat_update (send_buffer_ptr); } else { pkt_queue_lptr = (List*) prg_string_hash_table_item_get (send_buffer_ptr->send_buffer_table, dest_addr_str); if (pkt_queue_lptr == OPC_NIL) FRET (pkt_queue_lptr); /* Get the number of packets accessed */ num_packets = op_prg_list_size (pkt_queue_lptr); /* Create a list to return the packets */ pkt_lptr = op_prg_list_create (); for (count = 0; count < num_packets; count++) { /* Get each packet */ pkt_entry_ptr = (DsrT_Packet_Entry*) op_prg_list_access (pkt_queue_lptr, count); /* Place each packet in the queue */ op_prg_list_insert (pkt_lptr, pkt_entry_ptr->pkptr, OPC_LISTPOS_TAIL); } } FRET (pkt_lptr); }static DsrT_Packet_Entry*dsr_send_buffer_pkt_entry_create (Packet* pkptr) { DsrT_Packet_Entry* pkt_entry_ptr = OPC_NIL; /** Create an entry for a packet to a specific **/ /** destination, setting its timout value **/ FIN (dsr_send_buffer_pkt_entry_create (<args>)); /* Create the packet entry */ pkt_entry_ptr = dsr_send_buffer_pkt_entry_mem_alloc (); pkt_entry_ptr->pkptr = pkptr; pkt_entry_ptr->insert_time = op_sim_time (); FRET (pkt_entry_ptr); }static voiddsr_send_buffer_all_expired_pkts_delete (DsrT_Send_Buffer* send_buffer_ptr) { double current_time; double update_time; int num_dest, num_pkts; int count, size; char* key_ptr = OPC_NIL; List* keys_lptr = OPC_NIL; List* pkt_queue_lptr = OPC_NIL; DsrT_Packet_Entry* pkt_entry_ptr = OPC_NIL; /** Deletes all packets that have expired in the send buffer **/ /** This function should be called every time a packet is **/ /** either inserted or accessed **/ FIN (dsr_send_buffer_all_expired_pkts_delete (<args>)); /* Get the current time */ current_time = op_sim_time (); /* Get all the keys in the hash table. This represents */ /* the number of destinations that packets need to be */ /* sent out to */ keys_lptr = prg_string_hash_table_keys_get (send_buffer_ptr->send_buffer_table); /* Get the size of the keys */ num_dest = op_prg_list_size (keys_lptr); for (count = 0; count < num_dest; count++) { /* Initialize the variables */ size = 0; /* Access the destination key */ key_ptr = (char*) op_prg_list_access (keys_lptr, count); /* Access the packet queue for that destination */ pkt_queue_lptr = (List*) prg_string_hash_table_item_get (send_buffer_ptr->send_buffer_table, key_ptr); /* Get the number of packets in the queue */ num_pkts = op_prg_list_size (pkt_queue_lptr); while (size < num_pkts) { /* Get each packet entry */ pkt_entry_ptr = (DsrT_Packet_Entry*) op_prg_list_access (pkt_queue_lptr, size); /* Determine if the entry has expired */ if ((current_time - pkt_entry_ptr->insert_time) >= send_buffer_ptr->pkt_expiry_time) { /* Remove the packet from the queue */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -