📄 wlan_mac_smac_nav_rpm_3mar06_ver1.function block
字号:
/* 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");
// 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 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_frame_transmit ()
{
char msg_string [120];
char msg_string1 [120];
WlanT_Hld_List_Elem* hld_ptr;
double pkt_tx_time;
/** Main procedure to invoke function for preparing and **/
/** transmitting the appropriate frames. **/
FIN (wlan_frame_transmit());
/* If not PCF, an Ack needs to be sent for the data */
/* prepare Ack for transmission */
if ((wlan_flags->polled == OPC_FALSE) &&
(fresp_to_send == WlanC_Ack))
{
wlan_prepare_frame_to_send (fresp_to_send);
/* Break the routine once Ack is prepared to transmit */
FOUT;
}
/* Beacon transmission has priority unless we are in the middle of */
/* transmitting fragments of a data packet. */
else if (wlan_flags->tx_beacon == OPC_TRUE &&
(op_sar_buf_size (fragmentation_buffer_ptr) == 0 ||
(wlan_flags->rts_sent == OPC_FALSE && op_sar_buf_size (fragmentation_buffer_ptr) == packet_size_dcf)))
{
/* Reset any pending responses since beacon will terminate sequence anyway */
fresp_to_send = WlanC_None;
/* Prepare beacon frame to be transmitted */
wlan_prepare_frame_to_send (WlanC_Beac);
/* Break the routine once beacon prepared to transmit */
FOUT;
}
/* Send a CTS frame if it is the type of frame we need to send a */
/* response of. */
else if (fresp_to_send == WlanC_Cts)
{
wlan_prepare_frame_to_send (fresp_to_send);
/* Break the routine if Cts or Ack is already prepared to transmit. */
FOUT;
}
/* If it is a retransmission then check which type of frame needs to be */
/* retransmitted and then prepare and transmit that frame. */
else if (short_retry_count + long_retry_count > 0)
{
/* If the last frame unsuccessfully transmitted was an RTS or a */
/* CTS-to-self then transmit it again. */
if ((last_frametx_type == WlanC_Rts || last_frametx_type == WlanC_Cts) &&
wlan_flags->rts_sent == OPC_FALSE && wlan_flags->polled == OPC_FALSE)
{
wlan_prepare_frame_to_send (last_frametx_type);
}
/* If our last transmission was a data packet, then it means it was */
/* not acknowledged. Restart the transmission process. Do the same */
/* if we are resuming our retransmission after sending a beacon */
/* frame or a management frame reporting end of CFP. */
else if ((last_frametx_type == WlanC_Data || last_frametx_type == WlanC_Beac ||
last_frametx_type == WlanC_Cf_End || last_frametx_type == WlanC_Cf_End_A) && wlan_flags->polled == OPC_FALSE)
{
/* Check whether we need to start the retransmission with an */
/* RTS message. */
if (wlan_flags->frame_size_req_rts == OPC_TRUE && wlan_flags->rts_sent == OPC_FALSE)
{
/* Retransmit the RTS frame to again contend for the data . */
wlan_prepare_frame_to_send (WlanC_Rts);
}
/* Just retransmit the data packet if no protection is needed. */
else
{
wlan_prepare_frame_to_send (WlanC_Data);
}
}
else
{
/* We continue with the retransmission process. Either we have */
/* received the expected CTS for our last RTS before and now we */
/* can retransmit our data frame, or we moved from DCF period */
/* into PCF period and have been polled by the AP for */
/* transmission. In case of PCF, also check whether we have an */
/* ACK to append to our data packet. */
wlan_prepare_frame_to_send (WlanC_Data);
}
FOUT;
}
/* If higher layer queue is not empty then dequeue a packet */
/* from the higher layer and insert it into fragmentation */
/* buffer check whether fragmentation and RTS-CTS exchange */
/* is needed based on thresholds */
/* Check if fragmentation buffer is empty. If it is empty */
/* then dequeue a packet from the higher layer queue. */
else if ((op_prg_list_size (hld_list_ptr) != 0) && (op_sar_buf_size (fragmentation_buffer_ptr) == 0))
{
/* If rts is already sent then transmit data otherwise */
/* check if rts needs to be sent or not. */
if (wlan_flags->rts_sent == OPC_FALSE)
{
/* Remove packet from higher layer queue. */
hld_ptr = (WlanT_Hld_List_Elem *) op_prg_list_remove (hld_list_ptr, 0);
/* Update the higher layer queue size statistic. */
if (active_pc)
op_stat_write (hl_packets_rcvd, (double) (op_prg_list_size (hld_list_ptr) + op_prg_list_size (cfpd_list_ptr)));
else
op_stat_write (hl_packets_rcvd, (double) op_prg_list_size (hld_list_ptr));
/* Determine packet size to determine later whether fragmentation */
/* and/or rts-cts exchange is needed. */
packet_size_dcf = op_pk_total_size_get (hld_ptr->pkptr);
/* Updating the total packet size of the higher layer buffer. */
total_hlpk_size = total_hlpk_size - packet_size_dcf;
/* Setting destination address state variable */
destination_addr = hld_ptr->destination_address;
/* Packet seq number modulo 4096 counter. */
packet_seq_number = (packet_seq_number + 1) % 4096;
/* Packet fragment number is initialized. */
packet_frag_number = 0;
/* Packet needs to be fragmented if it is more than */
/* fragmentation threshold, provided fragmentation is */
/* enabled. Broadcast packets are not fragmented regardless */
/* of their sizes. */
if (frag_threshold != -1 && destination_addr >= 0 && packet_size_dcf > (frag_threshold * 8))
{
/* Determine number of fragments for the packet */
/* and the size of the last fragment */
num_fragments = (int) (packet_size_dcf / (frag_threshold * 8));
remainder_size = packet_size_dcf - (num_fragments * frag_threshold * 8);
/* If the remainder size is non zero it means that the */
/* last fragment is fractional but since the number */
/* of fragments is a whole number we need to transmit */
/* one additional fragment to ensure that all of the */
/* data bits will be transmitted */
if (remainder_size != 0)
num_fragments = num_fragments + 1;
else
/* Special case: data size is a multiple of the */
/* fragment size, so all the fragments will be the */
/* same size. To be consistent with other cases, */
/* set remainder_size to the size of the last */
/* fragment. */
remainder_size = frag_threshold * 8;
}
else
{
/* If no fragments needed then number of */
/* packets to be transmitted is set to 1 */
num_fragments = 1;
remainder_size = packet_size_dcf;
}
/* Storing Data packet id for debugging purposes. */
pkt_in_service = op_pk_id (hld_ptr->pkptr);
/* Insert packet to fragmentation buffer */
op_sar_segbuf_pk_insert (fragmentation_buffer_ptr, hld_ptr->pkptr, 0);
/* Computing packet duration in the queue in seconds */
/* and reporting it to the statistics */
pkt_tx_time = (current_time - hld_ptr->time_rcvd);
/* Printing out information to ODB. */
if (wlan_trace_active == OPC_TRUE)
{
sprintf (msg_string, "Data packet " OPC_PACKET_ID_FMT " is removed from higher layer buffer", pkt_in_service);
sprintf (msg_string1, "The queueing delay for data packet " OPC_PACKET_ID_FMT " is %fs",
pkt_in_service, pkt_tx_time);
op_prg_odb_print_major (msg_string, msg_string1, OPC_NIL);
}
/* Store the arrival time of the packet. */
receive_time_dcf = hld_ptr->time_rcvd;
/* Free up allocated memory for the data packet removed from the higher */
/* layer queue. */
op_prg_mem_free (hld_ptr);
/* Send RTS if RTS is enabled and packet size is more than RTS threshold. */
/* No RTS message is sent for broadcast packets regradless of their sizes. */
if (rts_threshold != -1 && destination_addr >= 0 &&
(packet_size_dcf + WLANC_MSDU_HEADER_SIZE) > (rts_threshold * 8) &&
wlan_flags->polled == OPC_FALSE)
{
/* Set the flag indicating that an RTS is needed for the current frame */
/* due to its size. */
wlan_flags->frame_size_req_rts = OPC_TRUE;
/* Prepare RTS frame for transmission. */
wlan_prepare_frame_to_send (WlanC_Rts);
/* Break the routine as RTS is already prepared. */
FOUT;
}
else
{
/* Reset the flag indicating an RTS was not necessary due to current */
/* frame size. */
wlan_flags->frame_size_req_rts = OPC_FALSE;
}
}
}
/* This is a normal DCF transmission. Prepare the frame for */
/* for transmission. */
wlan_prepare_frame_to_send (WlanC_Data);
FOUT;
}
static void
wlan_prepare_frame_to_send (WlanT_Mac_Frame_Type frame_type)
{
Packet* seg_pkptr;
OpT_Packet_Size tx_datapacket_size;
WlanT_Mac_Frame_Type type;
//int i;
double tx_data_rate;
double duration, mac_delay;
double total_pk_size;
double tx_end_time;
double total_plcp_overhead;
WlanT_Data_Header_Fields* pk_dhstruct_ptr;
WlanT_Control_Header_Fields* pk_chstruct_ptr;
WlanT_Beacon_Body_Fields* pk_bbstruct_ptr;
Packet* wlan_transmit_frame_ptr;
char msg_string [120];
char frame_type_str [32];
/** Prepare frames to transmit by setting appropriate fields in the **/
/** packet format for Data,Cts,Rts or Ack. If data or Rts packet needs **/
/** to be retransmitted then the copy of the packet is resent. **/
FIN (wlan_prepare_frame_to_send (frame_type));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -