📄 wlan_mac_smac_nav_rpm_3mar06_ver1.function block
字号:
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 */
if (cfp_ap_medium_control == OPC_FALSE)
nav_duration = current_time + duration + (double) (op_pk_total_size_get (wlan_transmit_frame_ptr)) / wsn_data_rate;
}
else
{
/* Creating transmit data packet type. */
wlan_transmit_frame_ptr = op_pk_create_fmt ("wsn_data");
/* Prepare data frame fields for transmission. */
pk_dhstruct_ptr = wlan_mac_pk_dhstruct_create ();
type = frame_type;
pk_dhstruct_ptr->retry = 0;
pk_dhstruct_ptr->order = 1;
pk_dhstruct_ptr->sequence_number = packet_seq_number;
/* 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. For */
/* broadcast packets, the duration is zero since they are not */
/* acknowledged. */
if (destination_addr >= 0)
duration = sifs_time + TXTIME_CTRL (WLANC_ACK_LENGTH);
else
duration = 0.0;
/* If there is more than one fragment to transmit then remove */
/* fragmentation threshold size length of data from the buffer */
/* for transmission. */
if (num_fragments > 1)
{
/* Remove next fragment from the fragmentation buffer for */
/* transmission and set the appropriate fragment number. */
seg_pkptr = op_sar_srcbuf_seg_remove (fragmentation_buffer_ptr, frag_threshold * 8);
/* Indicate in transmission frame that more fragments need */
/* to be sent. */
pk_dhstruct_ptr->more_frag = 1;
/* Since more fragments need to be transmitted then the */
/* station need to broadcast the time until the receipt of */
/* the acknowledgement for the next fragment. 224 bits */
/* (header size) is the length of control fields in the */
/* data frame and need to be accounted for 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 fragment number in packet field. */
pk_dhstruct_ptr->fragment_number = packet_frag_number ;
/* Printing out information to ODB. */
if (wlan_trace_active == OPC_TRUE)
{
sprintf (msg_string, "Data fragment %d for packet " OPC_PACKET_ID_FMT " is transmitted", packet_frag_number, pkt_in_service);
op_prg_odb_print_major (msg_string, OPC_NIL);
}
/* Setting packet fragment number for next fragment to be */
/* transmitted. */
packet_frag_number = packet_frag_number + 1;
}
else
{
/* Remove the last fragment from the fragmentation buffer for */
/* transmission and disable more fragmentation bit. */
seg_pkptr = op_sar_srcbuf_seg_remove (fragmentation_buffer_ptr, remainder_size);
pk_dhstruct_ptr->more_frag = 0;
/* Printing out information to ODB. */
if (wlan_trace_active == OPC_TRUE)
{
sprintf (msg_string, "Data fragment %d for packet " OPC_PACKET_ID_FMT " is transmitted", packet_frag_number, pkt_in_service);
op_prg_odb_print_major (msg_string, OPC_NIL);
}
pk_dhstruct_ptr->fragment_number = packet_frag_number;
}
/* Setting the Header field structure. */
/* This is the CP, so set duration field. */
pk_dhstruct_ptr->duration = duration;
pk_dhstruct_ptr->address1 = destination_addr;
pk_dhstruct_ptr->address2 = my_address;
/* In the BSS network the Data frame is going from AP to sta then fromds bit is set. */
if (ap_flag == OPC_BOOLINT_ENABLED)
pk_dhstruct_ptr->fromds = 1;
else
pk_dhstruct_ptr->fromds = 0;
/* if in the BSS network the Data frame is going from sta to AP then tods bit is set. */
if ((bss_flag == OPC_TRUE) &&
(ap_flag == OPC_BOOLINT_DISABLED) &&
(ap_relay == OPC_TRUE))
{
pk_dhstruct_ptr->tods = 1;
/* If Infrastructure BSS then the immediate destination will be Access point, which */
/* then forward the frame to the appropriate destination. */
pk_dhstruct_ptr->address1 = ap_mac_address ;
pk_dhstruct_ptr->address3 = destination_addr;
}
else
{
pk_dhstruct_ptr->tods = 0;
}
/* 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;
}
/* If we are sending the first fragment of the data fragment for the first */
/* time, then this is the end of media access duration, hence we must */
/* update the media access delay statistics. */
if (packet_size_dcf == op_pk_total_size_get (seg_pkptr) + op_sar_buf_size (fragmentation_buffer_ptr))
{
mac_delay = current_time - receive_time_dcf;
op_stat_write (media_access_delay, mac_delay);
op_stat_write (global_mac_delay_handle, mac_delay);
}
/* Populate the packet fields. */
op_pk_nfd_set_int32 (wlan_transmit_frame_ptr, "Type", type);
op_pk_nfd_set_int32 (wlan_transmit_frame_ptr, "Accept", OPC_TRUE);
op_pk_nfd_set_pkid (wlan_transmit_frame_ptr, "Data Packet ID", pkt_in_service);
/* Set the frame control field and nav duration. */
op_pk_nfd_set (wlan_transmit_frame_ptr, "Wlan Header", pk_dhstruct_ptr,
wlan_mac_pk_dhstruct_copy, wlan_mac_pk_dhstruct_destroy, sizeof (WlanT_Data_Header_Fields));
/* The actual data is placed in the Frame Body field. */
op_pk_nfd_set_pkt (wlan_transmit_frame_ptr, "Frame Body", seg_pkptr);
/* Add some bulk to the packet to model the transmission */
/* delay of PLCP fields accurately which are always */
/* transmitted at 1 Mbps regardless of the actual data rate */
/* used for data frames. */
// mib data size
// took all bytes out of wlan_mac packet format, and inherited bit made it the size of the data!
// original data code
//total_plcp_overhead = PLCP_OVERHEAD_DATA ((int) op_pk_total_size_get (wlan_transmit_frame_ptr) - WLANC_DEFAULT_PLCP_OVERHEAD);
//op_pk_bulk_size_set (wlan_transmit_frame_ptr, (OpT_Packet_Size) (total_plcp_overhead * wsn_data_rate - WLANC_DEFAULT_PLCP_OVERHEAD));
#ifndef OPD_NO_DEBUG
printf("\n");
printf("The MSDU header size is %d \n", WLANC_MSDU_HEADER_SIZE);
printf("The tx_datapacket_size is %d\n",tx_datapacket_size);
printf("The PHY size is %d\n", (int)(WLANC_PLCP_OVERHEAD_DSSS_LONG * WSNC_DATA_RATE));
printf("The real packet size in function is is %d bits\n\n",(int)(WLANC_PLCP_OVERHEAD_DSSS_LONG * WSNC_DATA_RATE) + WLANC_MSDU_HEADER_SIZE + op_pk_total_size_get (wlan_transmit_frame_ptr));
#endif
// mib added
op_pk_total_size_set (wlan_transmit_frame_ptr, (OpT_Packet_Size) ( (int)(WLANC_PLCP_OVERHEAD_DSSS_LONG * WSNC_DATA_RATE) + WLANC_MSDU_HEADER_SIZE + op_pk_total_size_get (wlan_transmit_frame_ptr)));
/* Expect acknowledgement only for directed frames. */
if (destination_addr < 0)
{
expected_frame_type = WlanC_None;
/* Reset the retry count because we won't await an ACK. */
/* The retry count can be non-zero even for a broadcast */
/* frame since it can be proceeded by a CTS-to-self */
/* frame in an 11g WLAN, which may have been */
/* retransmitted. */
short_retry_count = 0;
/* Due to possible earlier use of CTS-to-self frame */
/* exchange, reset the rts_sent flag. */
wlan_flags->rts_sent = OPC_FALSE;
/* Transmission of a broadcast frame is always assumed */
/* successful. Hence, set the flag for CW backoff. */
wlan_flags->cw_required = OPC_TRUE;
}
else
{
/* Ack frame is expected in response to data frame. */
expected_frame_type = WlanC_Ack;
}
/* Make copy of the frame before transmission -- make sure */
/* that a packet destined for broadcast addresses is not */
/* copied as that would never to destroyed (due to unACKing */
/* nature of broadcast traffic). */
if (destination_addr >= 0)
wlan_transmit_frame_copy_ptr = op_pk_copy (wlan_transmit_frame_ptr);
else
wlan_transmit_frame_copy_ptr = (Packet *) OPC_NIL;
/* Station update of its own nav_duration. */
if (cfp_ap_medium_control == OPC_FALSE)
nav_duration = current_time + duration + (double) (op_pk_total_size_get (wlan_transmit_frame_ptr)) / wsn_data_rate ;
}
/* Place the transmission data rate and physical layer */
/* technology information into the packet. */
wlan_frame_tx_phy_info_set (wlan_transmit_frame_ptr, tx_data_rate);
/* Update the data traffic sent statistics. */
total_pk_size = (double) op_pk_total_size_get (wlan_transmit_frame_ptr);
op_stat_write (data_traffic_sent_handle_inbits, total_pk_size);
op_stat_write (data_traffic_sent_handle, 1.0);
/* Write a value of 0 for the end of transmission. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -