📄 gpr_wlan_mac.pr.c
字号:
wlan_flags = (WlanT_Mac_Flags *) op_prg_mem_alloc (sizeof (WlanT_Mac_Flags));
/* Disabling all flags as a default. */
wlan_flags->data_frame_to_send = OPC_FALSE;
wlan_flags->backoff_flag = OPC_FALSE;
wlan_flags->rts_sent = OPC_FALSE;
wlan_flags->rcvd_bad_packet = OPC_FALSE;
wlan_flags->receiver_busy = OPC_FALSE;
wlan_flags->transmitter_busy = OPC_FALSE;
wlan_flags->gateway_flag = OPC_FALSE;
wlan_flags->bridge_flag = OPC_FALSE;
wlan_flags->wait_eifs_dur = OPC_FALSE;
wlan_flags->immediate_xmt = OPC_FALSE;
wlan_flags->forced_bk_end = OPC_FALSE;
wlan_flags->cw_required = OPC_FALSE;
wlan_flags->perform_cw = OPC_FALSE;
wlan_flags->nav_updated = OPC_FALSE;
wlan_flags->collision = OPC_FALSE;
wlan_flags->collided_packet = OPC_FALSE;
wlan_flags->duration_zero = OPC_FALSE;
wlan_flags->ignore_busy = OPC_FALSE;
wlan_flags->tx_beacon = OPC_FALSE;
wlan_flags->tx_cf_end = OPC_FALSE;
wlan_flags->pcf_active = OPC_FALSE;
wlan_flags->polled = OPC_FALSE;
wlan_flags->more_data = OPC_FALSE;
wlan_flags->more_frag = OPC_FALSE;
wlan_flags->pcf_side_traf = OPC_FALSE;
wlan_flags->active_poll = OPC_FALSE;
/* Initialize polling index. */
poll_index = -1;
/* Initialize pcf retry count. */
pcf_retry_count = 0;
/* Initialize pcf retry count. */
poll_fail_count = 0;
/* Initialize pcf queue offset. */
pcf_queue_offset = 0;
/* Initialize retry and back-off slot counts. */
retry_count = 0;
backoff_slots = BACKOFF_SLOTS_UNSET;
/* Initialize the packet pointers that holds the last */
/* transmitted packets to be used for retransmissions when */
/* necessary. */
wlan_transmit_frame_copy_ptr = OPC_NIL;
wlan_pcf_transmit_frame_copy_ptr = OPC_NIL;
/* Initialize NAV duration. */
nav_duration = 0;
/* Initialize receiver idle timer. */
rcv_idle_time = -2.0 * difs_time;
/* Initializing the sum of sizes of the packets in the higher layer queue. */
total_hlpk_size = 0;
/* Initializing the sum of sizes of the packets in the Contention Free Period queue. */
total_cfpd_size = 0;
/* Initialize the state variables related with the current frame that is being handled. */
packet_size_dcf = 0;
packet_size_pcf = 0;
receive_time_dcf = 0.0;
receive_time_pcf = 0.0;
/* Initializing frame response to send to none. */
fresp_to_send = WlanC_None;
/* Determines if the ap is controlling the medium. This */
/* variable is used to determine when the NAV's can be */
/* updates. */
cfp_ap_medium_control = OPC_FALSE;
/* Initializing expected frame type to none. */
expected_frame_type = WlanC_None;
/* Data arrived from higher layer is queued in the buffer. Pool memory is used for */
/* allocating data structure for the higher layer packet and the random destination */
/* for the packet. This structure is then inserted in the higher layer arrival queue. */
hld_pmh = op_prg_pmo_define ("WLAN hld list elements", sizeof (WlanT_Hld_List_Elem), 32);
/* Obtaining transmitter objid for accessing channel data rate attribute. */
tx_objid = op_topo_assoc (my_objid, OPC_TOPO_ASSOC_OUT, OPC_OBJTYPE_RATX, 0);
/* If no receiver is attach then generate error message and abort the simulation. */
if (tx_objid == OPC_OBJID_INVALID)
{
wlan_mac_error ("No transmitter attached to this MAC process", OPC_NIL, OPC_NIL);
}
/* Obtaining number of channels available. */
op_ima_obj_attr_get (tx_objid, "channel", &chann_objid);
num_chann = op_topo_child_count (chann_objid, OPC_OBJTYPE_RATXCH);
/* Check for error conditions. The transmitter is expected to have a single */
/* channel. */
if (num_chann > 1)
wlan_mac_error ("The transmitter of the surrounding node has too many channels. This MAC",
"is implemented to use a single channel for all supported data rates.",
"Possibly, the new MAC process model is deployed in an old node model.");
else if (num_chann == 0)
wlan_mac_error ("No channel is available for transmission.", OPC_NIL, OPC_NIL);
/* Set the transmitter's transmission power. */
txch_objid = op_topo_child (chann_objid, OPC_OBJTYPE_RATXCH, 0);
op_ima_obj_attr_set (txch_objid, "power", tx_power);
/* Free the transmitter channel state information set at the rxgroup */
/* pipeline stage. */
temp_ptr = (void *) op_ima_obj_state_get (txch_objid);
op_prg_mem_free (temp_ptr);
/* Obtaining receiver's objid for accessing channel data rate attribute. */
rx_objid = op_topo_assoc (my_objid, OPC_TOPO_ASSOC_IN, OPC_OBJTYPE_RARX, 0);
/* If no receiver is attach then generate error message and abort the */
/* simulation. */
if (rx_objid == OPC_OBJID_INVALID)
{
wlan_mac_error ("No receiver attached to this MAC process", OPC_NIL, OPC_NIL);
}
/* Obtaining number of channels available. */
op_ima_obj_attr_get (rx_objid, "channel", &chann_objid);
num_chann = op_topo_child_count (chann_objid, OPC_OBJTYPE_RARXCH);
/* Check for error conditions. The receiver is expected to have a single */
/* channel. */
if (num_chann > 1)
wlan_mac_error ("The receiver of the surrounding node has too many channels. This MAC",
"is implemented to use a single channel for all supported data rates.",
"Possibly, the new MAC process model is deployed in an old node model.");
else if (num_chann == 0)
wlan_mac_error (" No channel is available for reception", OPC_NIL, OPC_NIL);
/* Free the receiver channel state information set at the rxgroup stage. */
rxch_objid = op_topo_child (chann_objid, OPC_OBJTYPE_RARXCH, 0);
temp_ptr = (void *) op_ima_obj_state_get (rxch_objid);
op_prg_mem_free (temp_ptr);
/* Initialize the roaming related information. */
roam_state_ptr = (WlanT_Roam_State_Info *) op_prg_mem_alloc (sizeof (WlanT_Roam_State_Info));
roam_state_ptr->ap_reliability = 1.0;
roam_state_ptr->scan_mode = OPC_FALSE;
roam_state_ptr->current_bss_id = bss_id;
/* Initially, set roaming based on the attribute. In the next state, if it */
/* is determined that this is an ad-hoc network or if PCF is active in the */
/* BSS then roaming will be disabled. */
op_ima_obj_attr_get (params_attr_objid, "Roaming Capability", &roaming_cap_flag);
roam_state_ptr->enable_roaming = (roaming_cap_flag == OPC_BOOLINT_ENABLED) ? OPC_TRUE : OPC_FALSE;
/* Initialize the receiver channel state information. */
rx_state_info_ptr = (WlanT_Rx_State_Info *) op_prg_mem_alloc (sizeof (WlanT_Roam_State_Info));
rx_state_info_ptr->state_info_id = WLANC_RXCH_STATE_ID;
rx_state_info_ptr->rx_power_thresh = rx_power_threshold;
rx_state_info_ptr->rx_end_time = 0.0;
rx_state_info_ptr->roaming_info_ptr = roam_state_ptr;
/* Set the new "state" information of the receiver channel. */
op_ima_obj_state_set (rxch_objid, rx_state_info_ptr);
/* Also overwrite the high threshold trigger attribute values of the */
/* statwires that come into the MAC from the radio receiver by using the */
/* reception power threshold. First determine the total count of incoming */
/* statwires. */
num_statwires = op_topo_assoc_count (my_objid, OPC_TOPO_ASSOC_IN, OPC_OBJTYPE_STATWIRE);
for (i = 0; i < num_statwires; i++)
{
/* Access the next statwire. Skip it if it is coming from the */
/* transmitter. */
statwire_objid = op_topo_assoc (my_objid, OPC_TOPO_ASSOC_IN, OPC_OBJTYPE_STATWIRE, i);
op_ima_obj_attr_get (statwire_objid, "high threshold trigger", &threshold);
/* If the trigger is not disabled then the statwire is from the */
/* receiver. Overwrite the attribute value unless they are already same.*/
if (threshold != OPC_BOOLDBL_DISABLED && threshold != rx_power_threshold)
op_ima_obj_attr_set (statwire_objid, "high threshold trigger", rx_power_threshold);
}
/* Create an ICI to be used during the communication with LLC. */
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");
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];
char err_msg2 [256];
/** This function determines the 802.11b 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);
/* Determine the 802.11b channel number we are going to use. */
if (frequency == WLAN_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 */
channel_num = (WLANC_CH_STEP_FOR_NO_OVERLAP * bss_index) % WLANC_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 if roaming is enabled. */
if (roam_state_ptr->enable_roaming)
{
/* For a standard
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -