📄 aodv_wlan_mac.pr.c
字号:
/* 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. */
if ((packet_size > (frag_threshold * 8)) && (frag_threshold != -1))
{
/* Determine number of fragments for the packet */
/* and the size of the last fragment */
num_fragments = (int) (packet_size / (frag_threshold * 8));
remainder_size = packet_size - (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
{
/* If no fragments needed then number of */
/* packets to be transmitted is set to 1 */
num_fragments = 1;
remainder_size = packet_size;
}
/* 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 %d is removed from higher layer buffer", pkt_in_service);
sprintf (msg_string1, "The queueing delay for data packet %d 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 = hld_ptr->time_rcvd;
/* Freeing 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 */
if ((packet_size > (rts_threshold * 8)) && (rts_threshold != -1))
{
retry_limit = long_retry_limit;
/* Prepare Rts frame for transmission */
wlan_prepare_frame_to_send (WlanC_Rts);
/* Break the routine as Rts is already prepared */
FOUT;
}
else
{
retry_limit = short_retry_limit;
}
}
}
/* Prepare data frame to transmit */
wlan_prepare_frame_to_send (WlanC_Data);
FOUT;
}
static void
wlan_prepare_frame_to_send (int frame_type)
{
char msg_string [120];
Packet* hld_pkptr;
Packet* seg_pkptr;
int dest_addr, src_addr;
int protocol_type = -1;
int tx_datapacket_size;
int type;
char error_string [512];
int outstrm_to_phy;
double duration, mac_delay;
WlanT_Data_Header_Fields* pk_dhstruct_ptr;
WlanT_Control_Header_Fields* pk_chstruct_ptr;
Packet* wlan_transmit_frame_ptr;
/** 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 older copy of the packet is resent. **/
FIN (wlan_prepare_frame_to_send (int frame_type));
outstrm_to_phy = LOW_LAYER_OUT_STREAM_CH1;
if(DEBUG) printf("--- MAC Msg @ node %d --- prepare frame to send\n", my_address);
/* The code is divided as per the frame types */
switch (frame_type)
{
case WlanC_Data:
{
if (operational_speed == 2000000)
{
outstrm_to_phy = LOW_LAYER_OUT_STREAM_CH2;
}
else if (operational_speed == 5500000)
{
outstrm_to_phy = LOW_LAYER_OUT_STREAM_CH3;
}
else if (operational_speed == 11000000)
{
outstrm_to_phy = LOW_LAYER_OUT_STREAM_CH4;
}
/* If it is a retransmission of a packet then no need */
/* of preparing data frame. */
if ((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);
/* 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;
/* Printing out information to ODB. */
if (wlan_trace_active == OPC_TRUE)
{
sprintf (msg_string, "Data fragment %d for packet %d is retransmitted", pk_dhstruct_ptr->fragment_number, pkt_in_service);
op_prg_odb_print_major (msg_string, OPC_NIL);
}
if(DEBUG) printf("--- MAC Msg @ node %d --- Data fragment %d for packet %d is retransmitted\n",my_address, pk_dhstruct_ptr->fragment_number, pkt_in_service);
/* 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. */
duration = WLAN_ACK_DURATION + sifs_time + WLAN_AIR_PROPAGATION_TIME;
/* 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 broadcast the time 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 */
duration = 2 * duration + ((frag_threshold * 8) + WLANC_MSDU_HEADER_SIZE) / operational_speed +
sifs_time + WLAN_AIR_PROPAGATION_TIME;
}
/* Station update of it's own nav_duration. To keep track of the next */
/* available contention window. */
nav_duration = current_time + duration + (double) (op_pk_total_size_get (wlan_transmit_frame_ptr)) / operational_speed;
}
else
{
/* Creating transmit data packet type */
wlan_transmit_frame_ptr = op_pk_create_fmt ("wlan_mac");
/* Prepare data frame fields for transmission. */
pk_dhstruct_ptr = wlan_mac_pk_dhstruct_create ();
type = WlanC_Data;
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. */
duration = WLAN_ACK_DURATION + sifs_time + WLAN_AIR_PROPAGATION_TIME;
/* If there is more than one fragment to transmit and there are */
/* equal sized fragments then remove fragmentation threshold size */
/* length of data from the buffer for transmission. */
if ((num_fragments > 1) || (remainder_size == 0))
{
/* 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 */
/* if more than one fragments are left */
if (num_fragments != 1)
{
pk_dhstruct_ptr->more_frag = 1;
/* If more fragments need to be transmitted then the station */
/* need to broadcast the time until the receipt of the */
/* 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 */
duration = 2 * duration + ((frag_threshold * 8) + WLANC_MSDU_HEADER_SIZE) / operational_speed +
sifs_time + WLAN_AIR_PROPAGATION_TIME;
}
else
{
/* If no more fragments to transmit then set more fragment field to be 0 */
pk_dhstruct_ptr->more_frag = 0;
}
/* 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 %d is transmitted",packet_frag_number, pkt_in_service);
op_prg_odb_print_major (msg_string, OPC_NIL);
}
if(DEBUG) printf ("Data fragment %d for packet %d is transmitted\n",packet_frag_number, pkt_in_service);
/* Setting packet fragment number for next fragment to be transmitted */
packet_frag_number = packet_frag_number + 1;
}
else
{
/* Remove last fragments (if any left) 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 %d is transmitted",packet_frag_number, pkt_in_service);
op_prg_odb_print_major (msg_string, OPC_NIL);
}
if(DEBUG) printf ("Data fragment %d for packet %d is transmitted\n",packet_frag_number, pkt_in_service);
pk_dhstruct_ptr->fragment_number = packet_frag_number;
}
/* Setting the Header field structure. */
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_BOOLINT_ENABLED) && (ap_flag == OPC_BOOLINT_DISABLED))
{
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 = bss_id;
pk_dhstruct_ptr->address3 = destination_addr;
}
else
{
pk_dhstruct_ptr->tods = 0;
}
/* 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 == op_pk_total_size_get (seg_pkptr) + op_sar_buf_size (fragmentation_buffer_ptr))
{
mac_delay = current_time - receive_time;
op_stat_write (media_access_delay, mac_delay);
op_stat_write (media_access_delay, 0.0);
op_stat_write (global_mac_delay_handle, mac_delay);
op_stat_write (global_mac_delay_handle, 0.0);
}
op_pk_nfd_set (wlan_transmit_frame_ptr, "Type", type);
/* Setting the variable which keeps track of the last transmitted frame. */
last_frametx_type = typ
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -