Beispiel #1
0
AodvT_Route_Entry*
aodv_route_table_entry_create (AodvT_Route_Table* route_table_ptr, InetT_Address dest_addr, InetT_Subnet_Mask subnet_mask,
	InetT_Address next_hop_addr, IpT_Port_Info out_port_info, int num_hops, int dest_seq_num, double expiry_time)
	{
	AodvT_Route_Entry*			route_entry_ptr;
	AodvT_Global_Stathandles*	global_stathandle_ptr;
	void*						old_contents_ptr;
	
	/** Adds a new route table entry	**/
	/** in the route table				**/
	FIN (aodv_route_table_entry_create (<args>));

	/* Allocate memory for the route entry	*/
	route_entry_ptr = aodv_route_table_entry_mem_alloc ();
	route_entry_ptr->dest_prefix = ip_cmn_rte_table_dest_prefix_create (dest_addr, subnet_mask);
	route_entry_ptr->dest_seq_num = dest_seq_num;
	
	if (dest_seq_num != AODVC_DEST_SEQ_NUM_INVALID)
		route_entry_ptr->valid_dest_sequence_number_flag = OPC_TRUE;
	else
		route_entry_ptr->valid_dest_sequence_number_flag = OPC_FALSE;
	
	route_entry_ptr->route_entry_state = AodvC_Valid_Route;
	route_entry_ptr->next_hop_addr = inet_address_copy (next_hop_addr);
	route_entry_ptr->next_hop_port_info = out_port_info;
	route_entry_ptr->hop_count = num_hops;
	route_entry_ptr->route_expiry_time = op_sim_time () + expiry_time;
	
	/* This event will be processed by aodv_rte_entry_expiry_handle */
	/* function when the timer expires.								*/
	route_entry_ptr->route_expiry_evhandle = op_intrpt_schedule_call (route_entry_ptr->route_expiry_time,
		AODVC_ROUTE_ENTRY_INVALID,	aodv_rte_entry_expiry_handle, route_entry_ptr);
	
	/* Set the route entry for this destination	*/
	/* in the route table						*/
	inet_addr_hash_table_item_insert (route_table_ptr->route_table, &dest_addr, route_entry_ptr, &old_contents_ptr);
	
	/* Insert the route in the IP common route table	*/
	Inet_Cmn_Rte_Table_Entry_Add_Options (route_table_ptr->ip_cmn_rte_table_ptr, OPC_NIL, route_entry_ptr->dest_prefix, 
		route_entry_ptr->next_hop_addr, route_entry_ptr->next_hop_port_info, route_entry_ptr->hop_count, 
		route_table_ptr->aodv_protocol_id, 1, OPC_NIL, IPC_CMN_RTE_TABLE_ENTRY_ADD_INDIRECT_NEXTHOP_OPTION);
	
	/* Update the size of the route table	*/
	route_table_ptr->active_route_count++;

	/* Update the route table size statistic	*/
	op_stat_write (route_table_ptr->stat_handles_ptr->route_table_size_shandle, route_table_ptr->active_route_count);
	
	/* Update the statistic for the number of hops	*/
	op_stat_write (route_table_ptr->stat_handles_ptr->num_hops_shandle, route_entry_ptr->hop_count);	
	
	/* Get a handle to the global statistics	*/
	global_stathandle_ptr = aodv_support_global_stat_handles_obtain ();
	
	/* Update the global statistic for the number of hops	*/
	op_stat_write (global_stathandle_ptr->num_hops_global_shandle, route_entry_ptr->hop_count);

	FRET (route_entry_ptr);
	}
/*--------------------------------------------------------------------------------
 * Function:	wban_up0_traffic_generate
 *
 * Description:	creates a MSDU requiring acknowledge based on the MSDU generation		
 *				 specifications of the source model and sends it to the lower layer.
 *
 * No parameters
 *--------------------------------------------------------------------------------*/
static void wban_up0_traffic_generate() {
	Packet*	msdu_ptr;
	Packet*	app_traffic_ptr;

	int	msdu_size; /* size in bits */
	double next_intarr_time;	/*  interarrival time of next MSDU */
	double abs_next_intarr_time; /* absolute interarrival time of next MSDU */

	/* Stack tracing enrty point */
	FIN (wban_up0_traffic_generate);
	
	/* Generate a MSDU size outcome.		*/
	msdu_size = (int) ceil (oms_dist_outcome (up0_msdu_size_dist_ptr));
		
	/* 0 <= MAC frame body <= pMaxFrameBodyLength_Bits */
	if (msdu_size > pMaxFrameBodyLength_Bits)
		msdu_size = pMaxFrameBodyLength_Bits;	/* The size of generated MSDU is bigger than the maximum - the size is set to the maximum. */
		
	if (msdu_size < 0)
		msdu_size = 0;
	
	/* We produce unformatted packets. Create one.	*/
	msdu_ptr = op_pk_create (msdu_size);
	/* create a App traffic frame that encapsulates the msdu packet */
	app_traffic_ptr = op_pk_create_fmt ("wban_app_traffic_format");
	/* increment the data sequence number by 1 at a time */
	dataSN = (dataSN + 1) % 32768;
	op_pk_nfd_set (app_traffic_ptr, "App Sequence Number", dataSN);
	op_pk_nfd_set (app_traffic_ptr, "User Priority", 0);
	op_pk_nfd_set_pkt (app_traffic_ptr, "MSDU Payload", msdu_ptr); // wrap msdu in app traffic

	/* schedule next MSDU generation */
	next_intarr_time = oms_dist_outcome (up0_msdu_interarrival_dist_ptr);

	/* Make sure that interarrival time is not negative. In that case it will be set to 0. */
	if (next_intarr_time <0)
		next_intarr_time = 0.0;

	abs_next_intarr_time = op_sim_time () + next_intarr_time;
	
	// printf(" [Node %s] t = %f, msdu_create_time = %f, app_pkt_create_time = %f\n", \
	// 	node_name, op_sim_time(), op_pk_creation_time_get(msdu_ptr), op_pk_creation_time_get(app_traffic_ptr));
	/* send the App traffic via the stream to the lower layer.	*/
	op_pk_send (app_traffic_ptr, STRM_FROM_UP_TO_MAC);
	// printf (" [Node %s] t= %f -> UP7 MSDU (size = %d bits) \
		// was generated and sent to MAC layer.\n", node_name, op_sim_time(), msdu_size);
	
	if ((abs_next_intarr_time <= up0_stop_time) || (up0_stop_time == SC_INFINITE_TIME)) {
		up0_next_msdu_evh = op_intrpt_schedule_self (abs_next_intarr_time, SC_GENERATE_UP0);
		// printf ("\t Next UP0 MSDU will be generated at %f\n\n", abs_next_intarr_time);
	}

	/* Stack tracing exit point */
	FOUT;
}
void
aodv_request_table_forward_rreq_insert (AodvT_Request_Table* req_table_ptr, int req_id, InetT_Address originator_addr)
	{
	List*							req_entry_lptr;
	AodvT_Forward_Request_Entry*	req_entry_ptr;
	InetT_Address*					orig_addr_ptr;
	void*							old_contents_ptr;
	
	/** Inserts a new route request into the request table	**/
	/** for nodes forwarding the route request packet		**/
	FIN (aodv_request_table_forward_rreq_insert (<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);
	
	if (req_entry_lptr == OPC_NIL)
		{
		/* No entry exists for this destination	*/
		/* Create a list and insert 			*/
		req_entry_lptr = op_prg_list_create ();
		inet_addr_hash_table_item_insert (req_table_ptr->forward_request_table, &originator_addr, req_entry_lptr, &old_contents_ptr);
		}
	
	/* Create an entry for this new request	*/
	req_entry_ptr = aodv_request_table_forward_entry_mem_alloc ();
	req_entry_ptr->request_id = req_id;
	req_entry_ptr->insert_time = op_sim_time ();
	
	/* Insert this new request into the request table	*/
	op_prg_list_insert (req_entry_lptr, req_entry_ptr, OPC_LISTPOS_TAIL);
	
	orig_addr_ptr = inet_address_copy_dynamic (&originator_addr);
	op_intrpt_schedule_call (
		op_sim_time () + req_table_ptr->forward_request_expiry_time,  // Time when entry may expire
		req_id,																			   // Interrupt ID
		aodv_rte_forward_request_delete,                              // Procedure to remove entry
		orig_addr_ptr);                                               // data used to locate an entry (list) in the forward RREQ table 
	
	FOUT;
	}
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;
	}
// MHAVH 11/13/08 - insert an rreq entry with the broadcast level included
void
aodv_request_table_orig_rreq_insert_geo (AodvT_Request_Table* req_table_ptr, int req_id, InetT_Address dest_address, 
										int ttl_value, double request_expiry_time, int rreq_retry,
												int request_level)
	{
	AodvT_Orig_Request_Entry*	req_entry_ptr;
	void*						old_contents_ptr;
	int*						req_id_ptr;
	
	/** Inserts a new request ID into the originating request table	**/
	FIN (aodv_request_table_orig_rreq_insert (<args>));
	
	/* Create an entry for this new request	*/
	req_entry_ptr = aodv_request_table_orig_entry_mem_alloc ();
	req_entry_ptr->target_address = inet_address_copy (dest_address);
	req_entry_ptr->request_id = req_id;
	req_entry_ptr->current_ttl_value = ttl_value;
	req_entry_ptr->insert_time = op_sim_time ();
	req_entry_ptr->current_request_expiry_time = request_expiry_time;
	req_entry_ptr->num_retries = rreq_retry;
	
	// MHAVH 13/11/08 - our request level for sending a rreq
	req_entry_ptr->request_level = request_level;
	// END MHAVH
	
	/* Allocate memory for the request ID	*/
	req_id_ptr = (int*) op_prg_mem_alloc (sizeof (int));
	*req_id_ptr = req_id;
	
	req_entry_ptr->rreq_expiry_evhandle = 
		op_intrpt_schedule_call (req_entry_ptr->insert_time + req_entry_ptr->current_request_expiry_time, 
								AODVC_ROUTE_REQUEST_EXPIRY, aodv_rte_rreq_timer_expiry_handle, req_id_ptr);
			
	/* Insert this new request into the request table	*/
	prg_bin_hash_table_item_insert (req_table_ptr->orig_request_table, (void *) &req_id, req_entry_ptr, &old_contents_ptr);
	
	FOUT;
	}
/*--------------------------------------------------------------------------------
 * Function:	wban_source_init
 *
 * Description:	- initialize the process
 *				- read the values of source attributes
 *              - schedule a self interrupt that will indicate start time	
 *					for MSDU generation
 *
 * No parameters
 *--------------------------------------------------------------------------------*/
static void wban_source_init() {
	Objid own_id;	/* Object ID of the surrounding processor or queue */
	Objid traffic_source_comp_id; 
	Objid traffic_source_id;
	char device_mode[20];	/* mode of the device: Hub or Node */
	double temp;
	
	/* Stack tracing enrty point */
	FIN(wban_source_init);

	/* obtain self object ID of the surrounding processor or queue */
	own_id = op_id_self ();
	/* obtain object ID of the parent object (node) */
	parent_id = op_topo_parent (own_id);
	/* set the initial number of sequence number to 0 */
	dataSN = 0;
	/* get the value to check if this node is PAN coordinator or not */
	op_ima_obj_attr_get (parent_id, "Device Mode", device_mode);
	/* get destination ID */
	op_ima_obj_attr_get (own_id, "Destination ID", &destination_id);
	/* get the name of the node */
	op_ima_obj_attr_get (parent_id, "name", node_name);

	printf("%s User Priority Traffic initialization.\n", node_name);
	op_ima_obj_attr_get (own_id, "User Priority 7 Traffic Parameters", &traffic_source_id); 
	traffic_source_comp_id = op_topo_child (traffic_source_id, OPC_OBJTYPE_GENERIC, 0);
	/* Read the values of the up7-MSDU generation parameters, i.e. the attribute values of the surrounding module. */
	op_ima_obj_attr_get (traffic_source_comp_id, "MSDU Interval Time", up7_msdu_interarrival_dist_str);
	op_ima_obj_attr_get (traffic_source_comp_id, "MSDU Size",              up7_msdu_size_dist_str);
	op_ima_obj_attr_get (traffic_source_comp_id, "Start Time",             &up7_start_time);
	op_ima_obj_attr_get (traffic_source_comp_id, "Stop Time",              &up7_stop_time);	

	op_ima_obj_attr_get (own_id, "User Priority 6 Traffic Parameters", &traffic_source_id); 
	traffic_source_comp_id = op_topo_child (traffic_source_id, OPC_OBJTYPE_GENERIC, 0);
	/* Read the values of the up6-MSDU generation parameters, i.e. the attribute values of the surrounding module. */
	op_ima_obj_attr_get (traffic_source_comp_id, "MSDU Interval Time", up6_msdu_interarrival_dist_str);
	op_ima_obj_attr_get (traffic_source_comp_id, "MSDU Size",              up6_msdu_size_dist_str);
	op_ima_obj_attr_get (traffic_source_comp_id, "Start Time",             &up6_start_time);
	op_ima_obj_attr_get (traffic_source_comp_id, "Stop Time",              &up6_stop_time);	

	op_ima_obj_attr_get (own_id, "User Priority 5 Traffic Parameters", &traffic_source_id); 
	traffic_source_comp_id = op_topo_child (traffic_source_id, OPC_OBJTYPE_GENERIC, 0);
	/* Read the values of the up5-MSDU generation parameters, i.e. the attribute values of the surrounding module. */
	op_ima_obj_attr_get (traffic_source_comp_id, "MSDU Interval Time", up5_msdu_interarrival_dist_str);
	op_ima_obj_attr_get (traffic_source_comp_id, "MSDU Size",              up5_msdu_size_dist_str);
	op_ima_obj_attr_get (traffic_source_comp_id, "Start Time",             &up5_start_time);
	op_ima_obj_attr_get (traffic_source_comp_id, "Stop Time",              &up5_stop_time);	

	op_ima_obj_attr_get (own_id, "User Priority 4 Traffic Parameters", &traffic_source_id); 
	traffic_source_comp_id = op_topo_child (traffic_source_id, OPC_OBJTYPE_GENERIC, 0);
	/* Read the values of the up4-MSDU generation parameters, i.e. the attribute values of the surrounding module. */
	op_ima_obj_attr_get (traffic_source_comp_id, "MSDU Interval Time", up4_msdu_interarrival_dist_str);
	op_ima_obj_attr_get (traffic_source_comp_id, "MSDU Size",              up4_msdu_size_dist_str);
	op_ima_obj_attr_get (traffic_source_comp_id, "Start Time",             &up4_start_time);
	op_ima_obj_attr_get (traffic_source_comp_id, "Stop Time",              &up4_stop_time);	

	op_ima_obj_attr_get (own_id, "User Priority 3 Traffic Parameters", &traffic_source_id); 
	traffic_source_comp_id = op_topo_child (traffic_source_id, OPC_OBJTYPE_GENERIC, 0);
	/* Read the values of the up3-MSDU generation parameters, i.e. the attribute values of the surrounding module. */
	op_ima_obj_attr_get (traffic_source_comp_id, "MSDU Interval Time", up3_msdu_interarrival_dist_str);
	op_ima_obj_attr_get (traffic_source_comp_id, "MSDU Size",              up3_msdu_size_dist_str);
	op_ima_obj_attr_get (traffic_source_comp_id, "Start Time",             &up3_start_time);
	op_ima_obj_attr_get (traffic_source_comp_id, "Stop Time",              &up3_stop_time);	

	op_ima_obj_attr_get (own_id, "User Priority 2 Traffic Parameters", &traffic_source_id); 
	traffic_source_comp_id = op_topo_child (traffic_source_id, OPC_OBJTYPE_GENERIC, 0);
	/* Read the values of the up2-MSDU generation parameters, i.e. the attribute values of the surrounding module. */
	op_ima_obj_attr_get (traffic_source_comp_id, "MSDU Interval Time", up2_msdu_interarrival_dist_str);
	op_ima_obj_attr_get (traffic_source_comp_id, "MSDU Size",              up2_msdu_size_dist_str);
	op_ima_obj_attr_get (traffic_source_comp_id, "Start Time",             &up2_start_time);
	op_ima_obj_attr_get (traffic_source_comp_id, "Stop Time",              &up2_stop_time);	

	op_ima_obj_attr_get (own_id, "User Priority 1 Traffic Parameters", &traffic_source_id); 
	traffic_source_comp_id = op_topo_child (traffic_source_id, OPC_OBJTYPE_GENERIC, 0);
	/* Read the values of the up1-MSDU generation parameters, i.e. the attribute values of the surrounding module. */
	op_ima_obj_attr_get (traffic_source_comp_id, "MSDU Interval Time", up1_msdu_interarrival_dist_str);
	op_ima_obj_attr_get (traffic_source_comp_id, "MSDU Size",              up1_msdu_size_dist_str);
	op_ima_obj_attr_get (traffic_source_comp_id, "Start Time",             &up1_start_time);
	op_ima_obj_attr_get (traffic_source_comp_id, "Stop Time",              &up1_stop_time);	

	op_ima_obj_attr_get (own_id, "User Priority 0 Traffic Parameters", &traffic_source_id); 
	traffic_source_comp_id = op_topo_child (traffic_source_id, OPC_OBJTYPE_GENERIC, 0);
	/* Read the values of the up0-MSDU generation parameters, i.e. the attribute values of the surrounding module. */
	op_ima_obj_attr_get (traffic_source_comp_id, "MSDU Interval Time", up0_msdu_interarrival_dist_str);
	op_ima_obj_attr_get (traffic_source_comp_id, "MSDU Size",              up0_msdu_size_dist_str);
	op_ima_obj_attr_get (traffic_source_comp_id, "Start Time",             &up0_start_time);
	op_ima_obj_attr_get (traffic_source_comp_id, "Stop Time",              &up0_stop_time);	

	/* if you are Hub do not send packets itself */
	if ((strcmp(device_mode, "Hub") == 0) && (destination_id == HUB_ID)) {
		up7_start_time = SC_INFINITE_TIME;
		up6_start_time = SC_INFINITE_TIME;
		up5_start_time = SC_INFINITE_TIME;
		up4_start_time = SC_INFINITE_TIME;
		up3_start_time = SC_INFINITE_TIME;
		up2_start_time = SC_INFINITE_TIME;
		up1_start_time = SC_INFINITE_TIME;
		up0_start_time = SC_INFINITE_TIME;
	}

	/* Load the PDFs that will be used in computing the MSDU Interval Times and MSDU Sizes. */
	up7_msdu_interarrival_dist_ptr = oms_dist_load_from_string (up7_msdu_interarrival_dist_str);
	up7_msdu_size_dist_ptr       = oms_dist_load_from_string (up7_msdu_size_dist_str);

	/* Load the PDFs that will be used in computing the MSDU Interval Times and MSDU Sizes. */
	up6_msdu_interarrival_dist_ptr = oms_dist_load_from_string (up6_msdu_interarrival_dist_str);
	up6_msdu_size_dist_ptr       = oms_dist_load_from_string (up6_msdu_size_dist_str);

	/* Load the PDFs that will be used in computing the MSDU Interval Times and MSDU Sizes. */
	up5_msdu_interarrival_dist_ptr = oms_dist_load_from_string (up5_msdu_interarrival_dist_str);
	up5_msdu_size_dist_ptr       = oms_dist_load_from_string (up5_msdu_size_dist_str);

	/* Load the PDFs that will be used in computing the MSDU Interval Times and MSDU Sizes. */
	up4_msdu_interarrival_dist_ptr = oms_dist_load_from_string (up4_msdu_interarrival_dist_str);
	up4_msdu_size_dist_ptr       = oms_dist_load_from_string (up4_msdu_size_dist_str);

	/* Load the PDFs that will be used in computing the MSDU Interval Times and MSDU Sizes. */
	up3_msdu_interarrival_dist_ptr = oms_dist_load_from_string (up3_msdu_interarrival_dist_str);
	up3_msdu_size_dist_ptr       = oms_dist_load_from_string (up3_msdu_size_dist_str);

	/* Load the PDFs that will be used in computing the MSDU Interval Times and MSDU Sizes. */
	up2_msdu_interarrival_dist_ptr = oms_dist_load_from_string (up2_msdu_interarrival_dist_str);
	up2_msdu_size_dist_ptr       = oms_dist_load_from_string (up2_msdu_size_dist_str);

	/* Load the PDFs that will be used in computing the MSDU Interval Times and MSDU Sizes. */
	up1_msdu_interarrival_dist_ptr = oms_dist_load_from_string (up1_msdu_interarrival_dist_str);
	up1_msdu_size_dist_ptr       = oms_dist_load_from_string (up1_msdu_size_dist_str);

	/* Load the PDFs that will be used in computing the MSDU Interval Times and MSDU Sizes. */
	up0_msdu_interarrival_dist_ptr = oms_dist_load_from_string (up0_msdu_interarrival_dist_str);
	up0_msdu_size_dist_ptr       = oms_dist_load_from_string (up0_msdu_size_dist_str);

	/* Make sure we have valid start and stop times, i.e. stop time is not earlier than start time.	*/
	if ((up7_stop_time <= up7_start_time) && (up7_stop_time != SC_INFINITE_TIME)) {
		/* Stop time is earlier than start time. Disable the source.	*/
		up7_start_time = SC_INFINITE_TIME;

		/* Display an appropriate warning.								*/
		op_prg_odb_print_major ("Warning from a Traffic source model:", 
								"Although the user priority 7 generator is not disabled (start time is set to a finite value) a stop time that is not later than the start time is specified.",
								"Disabling the user priority 7 generator.", OPC_NIL);
	}

	/* Make sure we have valid start and stop times, i.e. stop time is not earlier than start time.	*/
	if ((up6_stop_time <= up6_start_time) && (up6_stop_time != SC_INFINITE_TIME)) {
		/* Stop time is earlier than start time. Disable the source.	*/
		up6_start_time = SC_INFINITE_TIME;

		/* Display an appropriate warning.								*/
		op_prg_odb_print_major ("Warning from a Traffic source model:", 
								"Although the user priority 6 generator is not disabled (start time is set to a finite value) a stop time that is not later than the start time is specified.",
								"Disabling the user priority 6 generator.", OPC_NIL);
	}

	/* Make sure we have valid start and stop times, i.e. stop time is not earlier than start time.	*/
	if ((up5_stop_time <= up5_start_time) && (up5_stop_time != SC_INFINITE_TIME)) {
		/* Stop time is earlier than start time. Disable the source.	*/
		up5_start_time = SC_INFINITE_TIME;

		/* Display an appropriate warning.								*/
		op_prg_odb_print_major ("Warning from a Traffic source model:", 
								"Although the user priority 5 generator is not disabled (start time is set to a finite value) a stop time that is not later than the start time is specified.",
								"Disabling the user priority 5 generator.", OPC_NIL);
	}

	/* Make sure we have valid start and stop times, i.e. stop time is not earlier than start time.	*/
	if ((up4_stop_time <= up4_start_time) && (up4_stop_time != SC_INFINITE_TIME)) {
		/* Stop time is earlier than start time. Disable the source.	*/
		up4_start_time = SC_INFINITE_TIME;

		/* Display an appropriate warning.								*/
		op_prg_odb_print_major ("Warning from a Traffic source model:", 
								"Although the user priority 4 generator is not disabled (start time is set to a finite value) a stop time that is not later than the start time is specified.",
								"Disabling the user priority 4 generator.", OPC_NIL);
	}

	/* Make sure we have valid start and stop times, i.e. stop time is not earlier than start time.	*/
	if ((up3_stop_time <= up3_start_time) && (up3_stop_time != SC_INFINITE_TIME)) {
		/* Stop time is earlier than start time. Disable the source.	*/
		up3_start_time = SC_INFINITE_TIME;

		/* Display an appropriate warning.								*/
		op_prg_odb_print_major ("Warning from a Traffic source model:", 
								"Although the user priority 3 generator is not disabled (start time is set to a finite value) a stop time that is not later than the start time is specified.",
								"Disabling the user priority 3 generator.", OPC_NIL);
	}

	/* Make sure we have valid start and stop times, i.e. stop time is not earlier than start time.	*/
	if ((up2_stop_time <= up2_start_time) && (up2_stop_time != SC_INFINITE_TIME)) {
		/* Stop time is earlier than start time. Disable the source.	*/
		up2_start_time = SC_INFINITE_TIME;

		/* Display an appropriate warning.								*/
		op_prg_odb_print_major ("Warning from a Traffic source model:", 
								"Although the user priority 2 generator is not disabled (start time is set to a finite value) a stop time that is not later than the start time is specified.",
								"Disabling the user priority 2 generator.", OPC_NIL);
	}

	/* Make sure we have valid start and stop times, i.e. stop time is not earlier than start time.	*/
	if ((up1_stop_time <= up1_start_time) && (up1_stop_time != SC_INFINITE_TIME)) {
		/* Stop time is earlier than start time. Disable the source.	*/
		up1_start_time = SC_INFINITE_TIME;

		/* Display an appropriate warning.								*/
		op_prg_odb_print_major ("Warning from a Traffic source model:", 
								"Although the user priority 1 generator is not disabled (start time is set to a finite value) a stop time that is not later than the start time is specified.",
								"Disabling the user priority 1 generator.", OPC_NIL);
	}

	/* Make sure we have valid start and stop times, i.e. stop time is not earlier than start time.	*/
	if ((up0_stop_time <= up0_start_time) && (up0_stop_time != SC_INFINITE_TIME)) {
		/* Stop time is earlier than start time. Disable the source.	*/
		up0_start_time = SC_INFINITE_TIME;

		/* Display an appropriate warning.								*/
		op_prg_odb_print_major ("Warning from a Traffic source model:", 
								"Although the user priority 0 generator is not disabled (start time is set to a finite value) a stop time that is not later than the start time is specified.",
								"Disabling the user priority 0 generator.", OPC_NIL);
	}

	/* Schedule a self interrupt that will indicate transition to next state.	*/
	if ((up7_start_time == SC_INFINITE_TIME) && (up6_start_time == SC_INFINITE_TIME) 
		&& (up5_start_time == SC_INFINITE_TIME) && (up4_start_time == SC_INFINITE_TIME) 
		&& (up3_start_time == SC_INFINITE_TIME) && (up2_start_time == SC_INFINITE_TIME) 
		&& (up1_start_time == SC_INFINITE_TIME) && (up0_start_time == SC_INFINITE_TIME) 
		) {
		op_intrpt_schedule_self (op_sim_time (), SC_STOP);	//DISABLED
	} else {
		op_intrpt_schedule_self (op_sim_time (), SC_START); //START
		
		/* In this case, also schedule the interrupt for starting of the MSDU generation */		
		if (up7_start_time != SC_INFINITE_TIME)
			op_intrpt_schedule_self (up7_start_time, SC_GENERATE_UP7);	//UP7_MSDU_GENERATE
		if (up6_start_time != SC_INFINITE_TIME)
			op_intrpt_schedule_self (up6_start_time, SC_GENERATE_UP6);	//UP6_MSDU_GENERATE
		if (up5_start_time != SC_INFINITE_TIME)
			op_intrpt_schedule_self (up5_start_time, SC_GENERATE_UP5);	//UP5_MSDU_GENERATE	
		if (up4_start_time != SC_INFINITE_TIME)
			op_intrpt_schedule_self (up4_start_time, SC_GENERATE_UP4);	//UP4_MSDU_GENERATE	
		if (up3_start_time != SC_INFINITE_TIME)
			op_intrpt_schedule_self (up3_start_time, SC_GENERATE_UP3);	//UP3_MSDU_GENERATE
		if (up2_start_time != SC_INFINITE_TIME)
			op_intrpt_schedule_self (up2_start_time, SC_GENERATE_UP2);	//UP2_MSDU_GENERATE
		if (up1_start_time != SC_INFINITE_TIME)
			op_intrpt_schedule_self (up1_start_time, SC_GENERATE_UP1);	//UP1_MSDU_GENERATE	
		if (up0_start_time != SC_INFINITE_TIME)
			op_intrpt_schedule_self (up0_start_time, SC_GENERATE_UP0);	//UP0_MSDU_GENERATE	

		/* In this case, also schedule the interrupt when we will stop	generating */
		/* MSDUs, unless we are configured to run until the end of the simulation. */
		if ((up7_stop_time != SC_INFINITE_TIME) && (up6_stop_time != SC_INFINITE_TIME)
			&& (up5_stop_time != SC_INFINITE_TIME) && (up4_stop_time != SC_INFINITE_TIME) 
			&& (up3_stop_time != SC_INFINITE_TIME) && (up2_stop_time != SC_INFINITE_TIME) 
			&& (up1_stop_time != SC_INFINITE_TIME) && (up0_stop_time != SC_INFINITE_TIME) 
			){
			temp = max_double(max_double(up7_stop_time, up6_stop_time), max_double(up5_stop_time, up4_stop_time));
			temp = max_double(temp, max_double(max_double(up3_stop_time, up2_stop_time), max_double(up1_stop_time, up0_stop_time)));
			op_intrpt_schedule_self (temp, SC_STOP);
		}
	}

	wban_print_parameters ();

	/* Stack tracing exit point */
	FOUT;
}
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;
	}
void
aodv_packet_queue_insert (AodvT_Packet_Queue* pkt_queue_ptr, Packet* data_pkptr, InetT_Address dest_addr)
	{
	List*						pkt_lptr;
	AodvT_Packet_Entry*			pkt_entry_ptr;
	void*						old_contents_ptr;
	AodvT_Global_Stathandles*	global_stathandle_ptr = OPC_NIL;
	
	/** Inserts a new data packet into the packet queue. If the queue is full	**/
	/** the oldest packet in the queue that has the same destination with the	**/
	/** new packet is dropped and the new packet inserted; or the new packet is	**/
	/** dropped if there is no packet to the same destination in the full queue.**/
	FIN (aodv_packet_queue_insert (<args>));
	
	/* Check if there are already other packets */
	/* waiting for this destination.			*/
	pkt_lptr = (List *) inet_addr_hash_table_item_get (pkt_queue_ptr->pkt_queue_table, &dest_addr);

	/* Is the queue already full?				*/
	if ((pkt_queue_ptr->max_queue_size != AODVC_INFINITE_PACKET_QUEUE) &&
		(pkt_queue_ptr->max_queue_size == pkt_queue_ptr->current_queue_size))
		{
		/* There is no more space in the queue to insert	*/
		/* any other packet. Delete the oldest packet in 	*/
		/* packet queue to the same destination to make		*/
		/* space for the new packet.						*/
		if (pkt_lptr == OPC_NIL)
			{
			/* There is no packet in the queue for the same	*/
			/* destination. Hence drop the new packet.		*/
			manet_rte_ip_pkt_destroy (data_pkptr);

			/* Update the local and global number of		*/
			/* packets dropped statistics.					*/	
			op_stat_write (pkt_queue_ptr->stat_handle_ptr->num_pkts_discard_shandle, 1.0);
			global_stathandle_ptr = aodv_support_global_stat_handles_obtain ();
			op_stat_write (global_stathandle_ptr->num_pkts_discard_global_shandle, 1.0);
			
			FOUT;
			}
		else
			{
			/* Drop the oldest packet to the same			*/
			/* destination, which is at the head of the		*/
			/* queue.										*/
			pkt_entry_ptr = (AodvT_Packet_Entry*) op_prg_list_remove (pkt_lptr, OPC_LISTPOS_HEAD);
			aodv_packet_queue_entry_mem_free (pkt_entry_ptr);

			/* Update the local and global number of		*/
			/* packets dropped statistics.					*/	
			op_stat_write (pkt_queue_ptr->stat_handle_ptr->num_pkts_discard_shandle, 1.0);
			global_stathandle_ptr = aodv_support_global_stat_handles_obtain ();
			op_stat_write (global_stathandle_ptr->num_pkts_discard_global_shandle, 1.0);

			/* Decrement the size of the packet queue.		*/
			pkt_queue_ptr->current_queue_size--;
	
			/* Update the packet queue size statistic.		*/
			aodv_packet_queue_size_stat_update (pkt_queue_ptr);
			}
		}
	
	if (pkt_lptr == OPC_NIL)
		{
		/* No entry exists for this destination	*/
		/* Create a queue for the destination.	*/
		pkt_lptr = op_prg_list_create ();
		inet_addr_hash_table_item_insert (pkt_queue_ptr->pkt_queue_table, &dest_addr, pkt_lptr, &old_contents_ptr);
		}
	
	/* Allocate memory to store the new packet	*/
	pkt_entry_ptr = aodv_packet_queue_entry_mem_alloc ();
	pkt_entry_ptr->pkptr = data_pkptr;
	pkt_entry_ptr->insert_time = op_sim_time ();
	
	/* Always insert at the tail of the list so	*/
	/* that the oldest packets are at the head 	*/
	/* of the list automatically				*/
	op_prg_list_insert (pkt_lptr, pkt_entry_ptr, OPC_LISTPOS_TAIL);
	pkt_queue_ptr->current_queue_size++;
	
	/* Update the packet queue size statistic	*/
	aodv_packet_queue_size_stat_update (pkt_queue_ptr);
	
	FOUT;
	}