⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wlan_mac_tmac_nav_rpm_31jan06_ver2.function block

📁 opnet无线网络编程
💻 FUNCTION BLOCK
📖 第 1 页 / 共 5 页
字号:
	llc_iciptr = op_ici_create ("wlan_mac_ind");
	if (llc_iciptr == OPC_NIL)
	{
		wlan_mac_error ("Unable to create ICI for communication with LLC.", OPC_NIL, OPC_NIL);
	}

	/* Initialize the variable which keeps track of number of PCF enabled nodes	*/
	/* in the network 															*/	
	pcf_network = 0;

	/* Create the mutex that will be used to serialize calling of prg_mapping	*/
	/* functions, which read/write global model related mapping information,	*/
	/* under multi-threaded execution with multiple CPUs.						*/
	mapping_info_mutex = op_prg_mt_mutex_create (OPC_MT_MUTEX_READER_WRITER, 0, "WLAN Mapping Info Mutex");

	// wsn mutex
	// creates the mutex that controls access to energy consumption and node status global varaibles
	wsn_network_mutex = op_prg_mt_mutex_create (OPC_MT_MUTEX_READER_WRITER, 0, "WLAN Network Lifetime Mutex");
	wsn_global_energy_pool_mutex	= op_prg_mt_mutex_create (OPC_MT_MUTEX_READER_WRITER, 0, "WLAN Network Global Energy Pool Mutex");

	// wsn mutex
	// creates the mutex that controls a medium busy global variable used by the adaptive timeout 
	wsn_channel_busy_mutex = op_prg_mt_mutex_create (OPC_MT_MUTEX_READER_WRITER, 0, "WSN Channel Busy Mutex");

	FOUT;
}

static void
wlan_transceiver_channel_init (void)
{
	Objid		mac_params_comp_attr_objid;
	Objid		params_attr_objid;
	Objid		chann_params_comp_attr_objid;
	Objid		subchann_params_attr_objid;	
	int			bss_index;
	double		bandwidth_mhz;
	double		frequency;
	char		err_msg1 [256];

	/** This function determines the WLAN channel that the surrounding	**/
	/** node will use and configures the transceiver with the			**/
	/** corresponding minimum frequency and bandwidth values.			**/
	FIN (wlan_transceiver_channel_init (void));

	/* Get a handle to node's WLAN parameters.							*/
	op_ima_obj_attr_get (my_objid, "Wireless LAN Parameters", &mac_params_comp_attr_objid);
	params_attr_objid = op_topo_child (mac_params_comp_attr_objid, OPC_OBJTYPE_GENERIC, 0);

	/* Get the provided channel configuration.							*/
	op_ima_obj_attr_get (params_attr_objid, "Channel Settings", &chann_params_comp_attr_objid);
	subchann_params_attr_objid = op_topo_child (chann_params_comp_attr_objid, OPC_OBJTYPE_GENERIC, 0);
	op_ima_obj_attr_get (subchann_params_attr_objid, "Bandwidth", &bandwidth_mhz);	
	op_ima_obj_attr_get (subchann_params_attr_objid, "Min Frequency", &frequency);	

	/* Check whether the bandwidth is specified using a special value.	*/
	if (bandwidth_mhz == PHY_TECH_BASED_BW_USED)
	{
		/* Set the bandwidth to the standard value of used physical		*/
		/* layer technology.											*/
		bandwidth_mhz = (phy_char_flag == WlanC_OFDM_11a) ? WLANC_11a_CHNL_BANDWIDTH : WLANC_11b_CHNL_BANDWIDTH;
	}

	/* Determine the channel number we are going to use.				*/ 
	if (frequency == BSS_BASED_FREQ_USED)
	{
		/* The channel will be selected based on node's BSS ID. Check	*/
		/* whether the BSS IDs are auto-assigned or not.				*/
		if (bss_id_type == WlanC_Entire_Subnet)
		{
			/* BSS IDs are auto assigned and their are set to node's	*/
			/* subnet ID. Use BSS index for channel selection.			*/
			bss_index = wlan_bss_id_list_manage (bss_id, "get_index");
		}
		else
		{
			/* BSS IDs are explicitly assigned. Use the BSS ID as the	*/
			/* BSS index.												*/
			bss_index = bss_id;
		}

		/* Assign channels from 1 through 11 (North America) with a gap */
		/* of 5 channels in between. The sequence will look like 1, 6,  */
		/* 11, 5, 10, 4, 9,... The channel will be picked as a function */
		/* BSS ID, that is mapped to a BSS index. Note that only		*/
		/* channels that are 5 channels apart are non-overlapping.		*/
		/* Assume that BSS indices run serially: 0, 1, 2, ... 			*/
		/* WLANC_CHANNEL_COUNT = 11, and								*/
		/* WLANC_CH_STEP_FOR_NO_OVERLAP = ceil (22.0/5.0) = 5			*/
		/*																*/
		/* Follow the same logic in case of 802.11a operation, where	*/
		/* WLANC_CHANNEL_COUNT = 12, and								*/
		/* WLANC_CH_STEP_FOR_NO_OVERLAP = ceil (20.0/20.0) = 1 (i.e.,	*/
		/* in 802.11a, the adjacent WLAN channels don't overlap.)		*/
		channel_num = (WLANC_CH_STEP_FOR_NO_OVERLAP * bss_index) % channel_count + 1;

		/* Get the minimum frequency that corresponds to the selected	*/
		/* channel.														*/
		frequency = wlan_min_freq_for_chan (channel_num);
	}
	else
	{
		/* The frequency band that will be used by this node is			*/
		/* explicitly specified. Validate it and determine its channel	*/
		/* number. 														*/

		/* In 802.11/11b/11g networks, for a standard, acceptable		*/
		/* channel, the bandwidth has to be 22 MHz, and the minimum		*/
		/* frequency between 2401 and 2451 MHz, inclusive, with			*/
		/* intervals of 5 MHz (i.e. the roaming feature is currently	*/
		/* supported only within first 11 channels. These numbers refer	*/
		/* to the values of the constants used below as specified in	*/
		/* the standard).												*/
		if (phy_char_flag != WlanC_OFDM_11a  && bandwidth_mhz == channel_bandwidth && frequency >= first_chan_min_freq && 
			frequency == ceil (frequency)    && (frequency - first_chan_min_freq) / channel_spacing < channel_count && 
			(int) (frequency - first_chan_min_freq) % (int) channel_spacing == 0)
		{
			/* The radio band has a valid configuration. Compute its	*/
			/* channel number.											*/
			channel_num = (frequency - first_chan_min_freq) / channel_spacing + 1;
		}

		/* Invalid (irregular) channel bands are acceptable if the node	*/
		/* is not expected to roam.										*/
		else if (!roam_state_ptr->enable_roaming)
		{
			/* When the roaming is disabled, the value of the state		*/
			/* variable channel_num is not used by regular MACs. For	*/
			/* APs, this means that the APs with irregular channel		*/
			/* bandwidths cannot support roaming WLAN MACs, since they	*/
			/* will not be able to discover such an AP during scanning.	*/
			channel_num = 0;
		}

		else
		{
			/* Terminate the simulation with an error message.			*/
			sprintf (err_msg1, "bandwidth must be %.1f MHz for 802.11a networks, and %.1f MHz for 802.11/11b/11g networks.",
				WLANC_11a_CHNL_BANDWIDTH, WLANC_11b_CHNL_BANDWIDTH);
			wlan_mac_error ("Cannot support WLAN roaming with configured radio channel settings. Roaming is supported", 
				"only for the operation channels specified in 802.11a and 802.11/11b/11g standards. Channel", err_msg1);
		}
	}

	/* Configure the transmitter channel based on selected/assigned		*/
	/* frequency band.													*/
	op_ima_obj_attr_set (txch_objid, "bandwidth", bandwidth_mhz * 1000.0);
	op_ima_obj_attr_set (txch_objid, "min frequency", frequency);

	/* Similarly configure the receiver channel.						*/
	op_ima_obj_attr_set (rxch_objid, "bandwidth", bandwidth_mhz * 1000.0);
	op_ima_obj_attr_set (rxch_objid, "min frequency", frequency);

	FOUT;
}

static void
wlan_rxgroup_reduce (void)
{
	unsigned int			old_rxch_count, new_rxch_count = 0;
	int						rxch_index, i;
	Objid*					old_rxch_objid_arr;
	Objid*					temp_rxch_objid_arr;
	Objid*					new_rxch_objid_arr = OPC_NIL;
	WlanT_Phy_Char_Code		rx_phy_char_code;
	double					tx_bandwidth, rx_bandwidth, tx_min_freq, rx_min_freq;	
	WlanT_Rx_State_Info*	rxch_state_ptr;
	List*					proc_record_lptr;
	static int				rxgroup_config_count = -1;

	/** This function is called after the channel/frequency			**/
	/** assignments are finalized in order to reduce the receiver	**/
	/** group of our transmitter channel by excluding the receiver	**/
	/** channels with non-overlapping frequency bands, which we can	**/
	/** neither interfere nor communicate with, for simulation		**/
	/** efficiency purposes. Receiver channels whose WLAN nodes		**/
	/** have roaming functionality enabled are not excluded in any	**/
	/** case since they can change their channels during the		**/
	/** simulation. Similarly, we will not remove any receiver from	**/
	/** the receiver group, if roaming is enabled for our own node.	**/
	/** The receivers that follow a different standard (i.e. we		**/
	/** operate in 802.11/11b/11g mode while the receiver in		**/
	/** question operates in 802.11a mode) will be excluded			**/
	/** regardless of our and their roaming functionality			**/
	/** configuration.												**/
	FIN (wlan_rxgroup_reduce (void));

	/* First check whether a dynamic receiver group configuration	*/
	/* utility object exists in the network. If it does, we will	*/
	/* not perform any changes in our transmitter's receiver group	*/
	/* and rely on user's configuration using that utility object.	*/
	/* Search the network-wide process registery to find out. There	*/
	/* is no need to do the search again, if it is already one by	*/
	/* another WLAN MAC process.									*/
	if (rxgroup_config_count < 0)
	{
		proc_record_lptr = op_prg_list_create ();
		oms_pr_process_discover (OPC_OBJID_INVALID, proc_record_lptr, 
			"protocol", OMSC_PR_STRING, "rx_group_config", OPC_NIL);

		/* The size of the list is equal to the number of objects	*/
		/* in the network that we are looking for.					*/
		rxgroup_config_count = op_prg_list_size (proc_record_lptr);

		/* Destroy the list and its elements.						*/
		for (i = rxgroup_config_count; i > 0; i--)
			op_prg_list_remove (proc_record_lptr, OPC_LISTPOS_HEAD);
		op_prg_mem_free (proc_record_lptr);
	}

	/* Quit if receiver group configuration utility object count is	*/
	/* more than 0.													*/
	if (rxgroup_config_count > 0)
	{
		FOUT;
	}

	/* Get the current rxgroup set of our transmitter channel.		*/
	op_radio_txch_rxgroup_get (txch_objid, &old_rxch_count, &old_rxch_objid_arr);

	/* Quit if the initial receiver group is already empty.			*/
	if (old_rxch_count == 0)
	{
		FOUT;
	}

	/* Retrieve the channel settings of our transmitter channel.	*/
	op_ima_obj_attr_get (txch_objid, "min frequency", &tx_min_freq);
	op_ima_obj_attr_get (txch_objid, "bandwidth",     &tx_bandwidth);

	/* Convert the bandwidth from KHz to MHz.						*/
	tx_bandwidth /= 1000.0;

	/* Create a temporary array to store the receiver channel IDs	*/
	/* that are kept in the receiver group. Set the size of the		*/
	/* array considering the extreme case where none of the current	*/
	/* receiver channels are eliminated.							*/
	temp_rxch_objid_arr = (Objid *) op_prg_mem_alloc (old_rxch_count * sizeof (Objid));

	/* For every receiver channel in the group, check whether it	*/
	/* needs to be kept or removed from the group.					*/
	for (rxch_index = 0; rxch_index < old_rxch_count; rxch_index++)
	{
		/* Obtain the channel settings of the receiver channel.		*/
		op_ima_obj_attr_get (old_rxch_objid_arr [rxch_index], "min frequency", &rx_min_freq);
		op_ima_obj_attr_get (old_rxch_objid_arr [rxch_index], "bandwidth",     &rx_bandwidth);

		/* Convert the bandwidth from KHz to MHz.					*/
		rx_bandwidth /= 1000.0;

		/* Check for an overlap between the frequency bands.		*/
		if (tx_min_freq + tx_bandwidth > rx_min_freq && rx_min_freq + rx_bandwidth > tx_min_freq)
		{
			/* Because of overlap, we will keep the current 		*/
			/* receiver channel in the group.						*/
			temp_rxch_objid_arr [new_rxch_count++] = old_rxch_objid_arr [rxch_index];
		}
		else
		{
			/* Even though there is no overlap, don't exclude the	*/
			/* receiver if our node or its node has the roaming		*/
			/* functionality enabled. Check this by accessing the	*/
			/* receiver channel's state information. Identify the	*/
			/* channel as a WLAN receiver channel by checking its	*/
			/* first 4 bytes (state_info_id) of its state			*/
			/* information.											*/
			rxch_state_ptr = (WlanT_Rx_State_Info *) op_ima_obj_state_get (old_rxch_objid_arr [rxch_index]);
			if (rxch_state_ptr != OPC_NIL && rxch_state_ptr->state_info_id == WLANC_RXCH_STATE_ID && 
				rxch_state_ptr->roaming_info_ptr->enable_roaming)
			{
				/* The receiver's node is roaming capable.			*/
				/* Determine whether it operates 802.11a or			*/
				/* 802.11/11b/11g. Use DSSS to represent any		*/
				/* non-11a physical layer.							*/
				rx_phy_char_code = (rx_min_freq <= WLANC_11b_LAST_CHNL_MAX_FREQ) ? WlanC_Direct_Sequence : WlanC_OFDM_11a;

				/* Check whether our node is roaming capable.		*/
				if (roam_state_ptr->enable_roaming)
				{
					/* Keep the receiver in the list if both nodes	*/
					/* use the same WLAN channel set.				*/
					if ((rx_phy_char_code == WlanC_OFDM_11a && phy_char_flag == WlanC_OFDM_11a) ||
						(rx_phy_char_code != WlanC_OFDM_11a && phy_char_flag != WlanC_OFDM_11a))
						temp_rxch_objid_arr [new_rxch_count++] = old_rxch_objid_arr [rxch_index];
				}
				else
				{
					/* Keep the receiver in the list if there is a	*/
					/* potential overlap due to its roaming			*/
					/* capability.									*/
					if ((rx_phy_char_code == WlanC_OFDM_11a && tx_min_freq + tx_bandwidth > WLANC_11a_FIRST_CHNL_MIN_FREQ) ||
						(rx_phy_char_code != WlanC_OFDM_11a && tx_min_freq < WLANC_11b_LAST_CHNL_MAX_FREQ))
						temp_rxch_objid_arr [new_rxch_count++] = old_rxch_objid_arr [rxch_index];
				}
			}
			else if (roam_state_ptr->enable_roaming)
			{
				/* Our node is roaming capable, while the			*/
				/* receiver's node is not. Keep the receiver in the	*/
				/* rxgroup if there is potential overlap due to our	*/
				/* roaming capability.								*/
				if ((phy_char_flag == WlanC_OFDM_11a && rx_min_freq + rx_bandwidth > WLANC_11a_FIRST_CHNL_MIN_FREQ) ||
					(phy_char_flag != WlanC_OFDM_11a && rx_min_freq < WLANC_11b_LAST_CHNL_MAX_FREQ))
					temp_rxch_objid_arr [new_rxch_count++] = old_rxch_objid_arr [rxch_index];
			}
		}
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -