📄 wlan_mac_tmac_nav_rpm_31jan06_ver2.function block
字号:
/* 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));
rcvd_frame_drate = wsn_data_rate;
/* First initialize the transmission data rate to the lowest supported */
/* data rate, which is the data rate used for control frames. */
tx_data_rate = control_data_rate;
/* It this is a CP period and the frame to be transmitted is a data/ACK.*/
if ((wlan_flags->pcf_active == OPC_FALSE) &&
((frame_type == WlanC_Data) || (frame_type == WlanC_Data_Ack)))
{
/* Adjust the transmission data rate based on the operational speed.*/
tx_data_rate = wsn_data_rate;
/* Set the variable which keeps track of the last transmitted frame. */
last_frametx_type = frame_type;
/* If it is a retransmission of a packet. Obtain the frame from the */
/* the copy pointer which was stored during the previous transmission */
if ((short_retry_count + long_retry_count > 0) && (wlan_transmit_frame_copy_ptr != OPC_NIL))
{
/* If it is a retransmission then just transmit the previous frame */
wlan_transmit_frame_ptr = op_pk_copy (wlan_transmit_frame_copy_ptr);
/* Reset header type in case Ack status has changed for frame */
op_pk_nfd_set_int32 (wlan_transmit_frame_ptr, "Type", frame_type);
/* If retry count is non-zero means that the frame is a */
/* retransmission of the last transmitted frame */
op_pk_nfd_access (wlan_transmit_frame_ptr, "Wlan Header", &pk_dhstruct_ptr);
pk_dhstruct_ptr->retry = 1;
/* Reset more_data bit in case queue status has changed since last transmission */
/* If this STA has been polled, and there are additional packets remaining */
if ((wlan_flags->polled == OPC_TRUE) && (op_prg_list_size (hld_list_ptr) != 0))
{
/* Set more data bit to tell AP that STA has more packets */
pk_dhstruct_ptr->more_data = 1;
}
/* Printing out information to ODB. */
if (wlan_trace_active == OPC_TRUE)
{
sprintf (msg_string, "Data fragment %d for packet " OPC_PACKET_ID_FMT " is retransmitted",
pk_dhstruct_ptr->fragment_number, pkt_in_service);
op_prg_odb_print_major (msg_string, OPC_NIL);
}
/* Calculate NAV duration till the channel will be occupied by */
/* station. The duration is SIFS time plus the ACK frame time, */
/* which the station needs in response to the data frame (note: */
/* no need to check for broadcast packets, since for broadcast */
/* packets the encapsulating if condition will be never true). */
duration = sifs_time + TXTIME_CTRL (WLANC_ACK_LENGTH);
/* Since the number of fragments for the last transmitted frame is */
/* already decremented, there will be more fragments to transmit */
/* if number of fragments is more than zero. */
if (num_fragments != 1)
{
/* If more fragments need to be transmitted then the station */
/* need to compute the duration until the receipt of the */
/* the acknowledgement for the next fragment. 224 bits (header */
/* size) is the length of the control fields in the data */
/* frame and needs to be accounted in the duration calculation. */
if (num_fragments == 2)
tx_datapacket_size = remainder_size + WLANC_MSDU_HEADER_SIZE;
else
tx_datapacket_size = (frag_threshold * 8) + WLANC_MSDU_HEADER_SIZE;
duration = 2 * duration + sifs_time + TXTIME_DATA (tx_datapacket_size);
}
/* Set the type of the expected response to "ACK". */
expected_frame_type = WlanC_Ack;
/* Station update its own nav_duration during CP */
/* NAV should be updated only during the CP period */
/* During CFP NAV duration is updated only during */
/* the transmission of the beacon frames */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -