List* aodv_packet_queue_all_pkts_to_dest_get (AodvT_Packet_Queue* pkt_queue_ptr, InetT_Address dest_addr, Boolean remove, Boolean update_discovery_time_stat) { AodvT_Packet_Entry* pkt_entry_ptr; List* pkt_lptr; List* data_pkt_lptr; int num_pkts, count; /** Based on the input flag either access or **/ /** remove packets from the queue **/ FIN (aodv_packet_queue_all_pkts_to_dest_get (<args>)); /* Based on the input flag either just access */ /* or remove the packets from the packet queue */ if (remove) { /* Remove the packets from the queue */ data_pkt_lptr = (List *) inet_addr_hash_table_item_remove (pkt_queue_ptr->pkt_queue_table, &dest_addr); /* Return if there's no packet to remove */ if (data_pkt_lptr == OPC_NIL) FRET (OPC_NIL); if (update_discovery_time_stat) { /* Write the statistic for the route discovery */ /* time for this destination. */ aodv_packet_queue_route_discovery_time_stat_update (pkt_queue_ptr, data_pkt_lptr); } if (op_prg_list_size (data_pkt_lptr) > 0) { /* Update the packet queue size statistic */ aodv_packet_queue_size_stat_update (pkt_queue_ptr); } pkt_queue_ptr->current_queue_size -= op_prg_list_size (data_pkt_lptr); } else { /* Only access the packets in the queue */ pkt_lptr = (List *) inet_addr_hash_table_item_get (pkt_queue_ptr->pkt_queue_table, &dest_addr); /* Create a list to return the packets */ data_pkt_lptr = op_prg_list_create (); num_pkts = op_prg_list_size (pkt_lptr); for (count = 0; count < num_pkts; count++) { pkt_entry_ptr = (AodvT_Packet_Entry*) op_prg_list_access (pkt_lptr, count); op_prg_list_insert (data_pkt_lptr, pkt_entry_ptr->pkptr, OPC_LISTPOS_TAIL); } } FRET (data_pkt_lptr); }
static void aodv_packet_queue_route_discovery_time_stat_update (AodvT_Packet_Queue* pkt_queue_ptr, List* pkt_queue_lptr) { int num_pkts, count; AodvT_Packet_Entry* pkt_entry_ptr = OPC_NIL; AodvT_Global_Stathandles* global_stathandle_ptr = OPC_NIL; double first_enqueue_time = OPC_DBL_INFINITY; double route_discovery_time; /** Updates the statistic for the route discovery time **/ FIN (aodv_packet_queue_route_discovery_time_stat_update (<args>)); /* Get the number of packets for the */ /* destination whose route has just */ /* been discovered */ num_pkts = op_prg_list_size (pkt_queue_lptr); for (count = 0; count < num_pkts; count++) { /* Access each packet information */ /* and determine the first packet */ /* that was enqueued. */ pkt_entry_ptr = (AodvT_Packet_Entry*) op_prg_list_access (pkt_queue_lptr, count); if (pkt_entry_ptr->insert_time < first_enqueue_time) { /* This entry is earlier than */ /* any other so far */ first_enqueue_time = pkt_entry_ptr->insert_time; } } /* The route discovery time is the time */ /* difference between the first packet */ /* enqueued to this destination and the */ /* current simulation time when the */ /* route was discovered */ route_discovery_time = op_sim_time () - first_enqueue_time; /* Get a handle to the global statistics */ global_stathandle_ptr = aodv_support_global_stat_handles_obtain (); /* Update the route discovery time for */ /* a specific destination */ op_stat_write (pkt_queue_ptr->stat_handle_ptr->route_discovery_time_shandle, route_discovery_time); /* Update the global route discovery time statistic */ op_stat_write (global_stathandle_ptr->route_discovery_time_global_shandle, route_discovery_time); FOUT; }
Boolean aodv_route_request_forward_entry_exists (AodvT_Request_Table* req_table_ptr, int req_id, InetT_Address originator_addr) { AodvT_Forward_Request_Entry* req_entry_ptr; List* req_entry_lptr; int size, count; /** Checks if a specific request ID exists **/ /** in the route request table **/ FIN (aodv_route_request_forward_entry_exists (<args>)); /* Check if there exists an entry for this address */ req_entry_lptr = (List*) inet_addr_hash_table_item_get (req_table_ptr->forward_request_table, &originator_addr); /* Error Check */ if ((req_entry_lptr == OPC_NIL)) FRET (OPC_FALSE); size = op_prg_list_size (req_entry_lptr); for (count = 0; count < size; count++) { req_entry_ptr = (AodvT_Forward_Request_Entry*) op_prg_list_access (req_entry_lptr, count); if (req_entry_ptr->request_id == req_id) FRET (OPC_TRUE); } if (prg_list_size (req_entry_lptr) == 0) { inet_addr_hash_table_item_remove (req_table_ptr->forward_request_table, &originator_addr); prg_mem_free (req_entry_lptr); } FRET (OPC_FALSE); }
Compcode aodv_route_table_precursor_add (AodvT_Route_Entry* route_entry_ptr, InetT_Address precursor_addr) { InetT_Address* precursor_addr_ptr; InetT_Address* pre_addr_ptr; InetT_Address existing_precursor_addr; int num, size; Boolean FOUND = OPC_FALSE; /** Adds a percursor node to the entry in **/ /** the route table for a destination **/ FIN (aodv_route_table_precursor_add (<args>)); if (route_entry_ptr == OPC_NIL) FRET (OPC_COMPCODE_FAILURE); /* Insert this precursor node in the list */ /* Here we need to check and insert the precursor addr */ /* First check if the precursor addr is already in the list,*/ /* if yes, then don't insert, if no then insert. */ size = op_prg_list_size (route_entry_ptr->precursor_lptr); for(num = 0; num < size; num++) { pre_addr_ptr = (InetT_Address*) op_prg_list_access (route_entry_ptr->precursor_lptr, num); existing_precursor_addr = *pre_addr_ptr; if(inet_address_equal (precursor_addr, existing_precursor_addr)) FOUND = OPC_TRUE; } if(FOUND == OPC_FALSE) { precursor_addr_ptr = inet_address_create_dynamic (precursor_addr); op_prg_list_insert (route_entry_ptr->precursor_lptr, precursor_addr_ptr, OPC_LISTPOS_TAIL); } FRET (OPC_COMPCODE_SUCCESS); }
void aodv_route_request_orig_entry_delete (AodvT_Request_Table* req_table_ptr, InetT_Address dest_addr) { AodvT_Orig_Request_Entry* req_entry_ptr; int num_requests, count; List* requests_lptr; /** Deletes all route requests that have the target address **/ FIN (aodv_route_request_orig_entry_delete (<args>)); /* Get the keys */ requests_lptr = (List *) prg_bin_hash_table_item_list_get (req_table_ptr->orig_request_table); num_requests = op_prg_list_size (requests_lptr); for (count = 0; count < num_requests; count++) { /* Check if there exists an entry for this address */ req_entry_ptr = (AodvT_Orig_Request_Entry *) op_prg_list_access (requests_lptr, count); if (inet_address_equal (req_entry_ptr->target_address, dest_addr)) { req_entry_ptr = (AodvT_Orig_Request_Entry *) prg_bin_hash_table_item_remove (req_table_ptr->orig_request_table, (void *) &(req_entry_ptr->request_id)); /* Cancel the previously scheduled event */ op_ev_cancel (req_entry_ptr->rreq_expiry_evhandle); /* Free the request entry */ aodv_request_table_orig_entry_mem_free (req_entry_ptr); } } /* Destroy the list. */ prg_list_destroy (requests_lptr, OPC_FALSE); FOUT; }
Boolean aodv_request_table_orig_rreq_exists (AodvT_Request_Table* req_table_ptr, InetT_Address dest_address) { AodvT_Orig_Request_Entry* req_entry_ptr; List* requests_lptr; int num_requests, count; Boolean retval = OPC_FALSE; /** Checks if an entry exists in the originating **/ /** table with the specified target address **/ FIN (aodv_request_table_orig_rreq_exists (<args>)); /* Get the keys */ requests_lptr = (List *) prg_bin_hash_table_item_list_get (req_table_ptr->orig_request_table); num_requests = op_prg_list_size (requests_lptr); if (requests_lptr == OPC_NIL) FRET (OPC_FALSE); for (count = 0; count < num_requests; count++) { /* Get the current request. */ req_entry_ptr = (AodvT_Orig_Request_Entry *) op_prg_list_access (requests_lptr, count); if (inet_address_equal (req_entry_ptr->target_address, dest_address)) { /* An entry exists for this target address **/ retval = OPC_TRUE; break; } } /* Destroy the list. */ prg_list_destroy (requests_lptr, OPC_FALSE); FRET (retval); }
void coexist_bt_error (Packet * pkptr) { double pe, r, p_accum, p_exact; double data_rate, elap_time; double log_p1, log_p2, log_arrange; int seg_size, num_errs, prev_num_errs; int invert_errors = OPC_FALSE; /* Coexist added */ List* error_list; double rx_start_time; int first_bit; int i, j, new_loc; int* error_location; int* prev_error_loc; char pk_type[30]; Format_Information* format_info; extern Initialize_Formats; extern Format_List; extern Read_Formats(); extern Get_Format_Info(char*); /** Compute the number of errors assigned to a segment of bits within **/ /** a packet based on its length and the bit error probability. **/ FIN (coexist_btr_error (pkptr)); /* Obtain the expected Bit-Error-Rate 'pe' */ pe = op_td_get_dbl (pkptr, OPC_TDA_RA_BER); /* Calculate time elapsed since last BER change */ elap_time = op_sim_time () - op_td_get_dbl (pkptr, OPC_TDA_RA_SNR_CALC_TIME); /* Use datarate to determine how many bits in the segment. */ data_rate = op_td_get_dbl (pkptr, OPC_TDA_RA_RX_DRATE); seg_size = elap_time * data_rate; /* Coexist - Calculate the first bit location of this segment */ rx_start_time = op_td_get_dbl(pkptr, OPC_TDA_RA_START_RX); first_bit = (int) floor((op_td_get_dbl (pkptr, OPC_TDA_RA_SNR_CALC_TIME) - rx_start_time) * data_rate); /* Case 1: if the bit error rate is zero, so is the number of errors. */ if (pe == 0.0 || seg_size == 0) num_errs = 0; /* Case 2: if the bit error rate is 1.0, then all the bits are in error. */ /* (note however, that bit error rates should not normally exceed 0.5). */ else if (pe >= 1.0) num_errs = seg_size; /* Case 3: The bit error rate is not zero or one. */ else { /* If the bit error rate is greater than 0.5 and less than 1.0, invert */ /* the problem to find instead the number of bits that are not in error */ /* in order to accelerate the performance of the algorithm. Set a flag */ /* to indicate that the result will then have to be inverted. */ if (pe > 0.5) { pe = 1.0 - pe; invert_errors = OPC_TRUE; } /* The error count can be obtained by mapping a uniform random number */ /* in [0, 1[ via the inverse of the cumulative mass function (CMF) */ /* for the bit error count distribution. */ /* Obtain a uniform random number in [0, 1[ to represent */ /* the value of the CDF at the outcome that will be produced. */ r = op_dist_uniform (1.0); /* Integrate probability mass over possible outcomes until r is exceeded. */ /* The loop iteratively corresponds to "inverting" the CMF since it finds */ /* the bit error count at which the CMF first meets or exceeds the value r. */ for (p_accum = 0.0, num_errs = 0; num_errs <= seg_size; num_errs++) { /* Compute the probability of exactly 'num_errs' bit errors occurring. */ /* The probability that the first 'num_errs' bits will be in error */ /* is given by pow (pe, num_errs). Here it is obtained in logarithmic */ /* form to avoid underflow for small 'pe' or large 'num_errs'. */ log_p1 = (double) num_errs * log (pe); /* Similarly, obtain the probability that the remaining bits will not */ /* be in error. The combination of these two events represents one */ /* possible configuration of bits yielding a total of 'num_errs' errors.*/ log_p2 = (double) (seg_size - num_errs) * log (1.0 - pe); /* Compute the number of arrangements that are possible with the same */ /* number of bits in error as the particular case above. Again obtain */ /* this number in logarithmic form (to avoid overflow in this case). */ /* This result is expressed as the logarithmic form of the formula for */ /* the number N of combinations of k items from n: N = n!/(n-k)!k! */ log_arrange = log_factorial (seg_size) - log_factorial (num_errs) - log_factorial (seg_size - num_errs); /* Compure the probability that exactly 'num_errs' are present */ /* in the segment of bits, in any arrangement. */ p_exact = exp (log_arrange + log_p1 + log_p2); /* Add this to the probability mass accumulated so far for previously */ /* tested outcomes to obtain the value of the CMF at outcome = num_errs.*/ p_accum += p_exact; /*'num_errs' is the outcome for this trial if the CMF meets or exceeds */ /* the uniform random value selected earlier. */ if (p_accum >= r) break; } /* If the bit error rate was inverted to compute correct bits instead, then */ /* Reinvert the result to obtain the number of bits in error. */ if (invert_errors == OPC_TRUE) num_errs = seg_size - num_errs; } /* Increase number of bit errors in packet transmission data attribute. */ prev_num_errs = op_td_get_int (pkptr, OPC_TDA_RA_NUM_ERRORS); op_td_set_int (pkptr, OPC_TDA_RA_NUM_ERRORS, num_errs + prev_num_errs); op_pk_format (pkptr, pk_type); /* Coexist - If there are errors in this segment allocate thier location */ if (num_errs > 0 && (pk_type[0] != 'w' && pk_type[1] != 'l')) { /* Initialize the format list if this is the first invocation */ if (Initialize_Formats == OPC_TRUE) { Format_List = Read_Formats(); Initialize_Formats = OPC_FALSE; } /* Get the format information */ /* We'll use this info to bail on the first bit found in the */ /* payload of a Bluetooth DH(1|3|5) packet to increase performance */ format_info = Get_Format_Info(pk_type); /* There are some errors */ if (prev_num_errs == 0) { /* We not gotten any errors yet so we need to create the list */ error_list = op_prg_list_create(); } else { /* We have previous errors so we need to retrive that list */ error_list = (List*) op_td_get_ptr(pkptr, OPC_TDA_RA_MAX_INDEX + COEXIST_FIELD_LIST_OF_ERRORS); } /* Allocate each error */ for (i = 0; num_errs > i; i++) { error_location = (int*) op_prg_mem_alloc(sizeof(int)); /* Set up the new location while loop */ new_loc = OPC_FALSE; while (new_loc == OPC_FALSE) { new_loc = OPC_TRUE; /* Roll the dice on the location in the segment */ *error_location = ((int) floor(op_dist_uniform(seg_size))) + first_bit; /* Check to see if this is a Bluetooth DH(1|3|5) packet */ if (format_info->crc == OPC_TRUE && format_info->ecc_type == FEC_NONE) { /* check to see if the error falls in the payload */ if (*error_location >= (format_info->preamble_bits + format_info->header_bits)) { /* discontinue further error allocations, since a single */ /* error to the payload of this packet will cause it to fail. */ i = num_errs; prev_num_errs = num_errs; } } /* Make sure this error is not in the same place as a prevous selection */ for (j = prev_num_errs; j < i; j++) { prev_error_loc = (int*) op_prg_list_access(error_list, j); if (*prev_error_loc == *error_location) { /* This was already determined to be an error location */ new_loc = OPC_FALSE; break; /* j loop */ } } /* j loop */ } /* while loop */ /* This location is unique */ op_prg_list_insert(error_list, error_location, OPC_LISTPOS_TAIL); } /* i loop */ /* Set the list back into the TD attributes */ op_td_set_ptr(pkptr, OPC_TDA_RA_MAX_INDEX + COEXIST_FIELD_LIST_OF_ERRORS, error_list); } /* Assign actual (allocated) bit-error rate over tested segment. */ if (seg_size != 0) op_td_set_dbl (pkptr, OPC_TDA_RA_ACTUAL_BER, (double) num_errs / seg_size); else op_td_set_dbl (pkptr, OPC_TDA_RA_ACTUAL_BER, pe); FOUT; }