📄 dsr_wlan_mac.pr.c
字号:
{
wlan_prepare_frame_to_send (fresp_to_send);
/* Break the routine if Cts or Ack is already prepared to tranmsit */
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 (retry_count != 0)
{
/* If the last frame unsuccessfully transmitted was Rts then transmit it again. */
if ((last_frametx_type == WlanC_Rts) && (wlan_flags->rts_sent == OPC_BOOLINT_DISABLED))
{
/* Retransmit the Rts frame. */
wlan_prepare_frame_to_send (WlanC_Rts);
}
/* For the retransmission of data frame first check whether Rts needs to be sent or not. */
/* If it Rts needs to be sent and it is not already sent then first transmit Rts and then */
/* transmit data frame. */
else if (last_frametx_type == WlanC_Data)
{
if ((op_pk_total_size_get (wlan_transmit_frame_copy_ptr) > (8 * rts_threshold + WLANC_MSDU_HEADER_SIZE)) &&
(rts_threshold != -1) && (wlan_flags->rts_sent == OPC_BOOLINT_DISABLED))
{
/* Retransmit the Rts frame to again contend for the data . */
wlan_prepare_frame_to_send (WlanC_Rts);
}
else
{
wlan_prepare_frame_to_send (WlanC_Data);
}
}
else
{
/* We continue with the retransmission process. We */
/* received the expected Cts for our last Rts. */
/* Hence, now we can retransmit our data frame. */
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 fragmenetation 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_BOOLINT_DISABLED)
{
/* Remove packet from higher layer queue. */
hld_ptr = (WlanT_Hld_List_Elem*) op_prg_list_remove (hld_list_ptr, 0);
//$$$$$$$$$$$$$$$$$$ DSR $$$$$$$$$$$$$$$$$$$$$$$$
/*
op_pk_nfd_get((Packet*)(hld_ptr->pkptr),"Type",&data_packet_type);
if (data_packet_type==DATA_PACKET_TYPE)
{
op_pk_nfd_get((Packet*)(hld_ptr->pkptr),"RELAY",&data_packet_dest);
op_pk_nfd_get((Packet*)(hld_ptr->pkptr),"DEST",&data_packet_final_dest);
}
else
{
data_packet_dest=-1;
data_packet_final_dest=-1;
}
*/
op_pk_nfd_get((Packet*)(hld_ptr->pkptr),"Option_Type",&data_packet_type);
if (data_packet_type==DATA_PACKET_TYPE)
{
op_pk_nfd_get((Packet*)(hld_ptr->pkptr),"DEST",&data_packet_final_dest);
op_pk_nfd_get((Packet*)(hld_ptr->pkptr),"Segs_Left",&seg_left);
op_pk_nfd_get((Packet*)(hld_ptr->pkptr),"Opt_Data_Len",&size_route);
size_route = size_route + 2;
if ((size_route > 2) && (seg_left > 0))
{
sprintf(field,"Node_%d",((size_route-2) - seg_left));
op_pk_nfd_get((Packet*)(hld_ptr->pkptr),field,&data_packet_dest);
}
else
{
op_pk_nfd_get((Packet*)(hld_ptr->pkptr),"DEST",&data_packet_dest);
}
}
else
{
data_packet_dest=-1;
data_packet_final_dest=-1;
}
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
/* Update the higher layer queue size statistic. */
op_stat_write (hl_packets_rcvd, (double) (op_prg_list_size (hld_list_ptr)));
/* Determine packet size to determine later wether fragmentation */
/* and/or rts-cts exchange is needed. */
packet_size = 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;
/* 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 */
//if (FRAME_TO_SEND)
wlan_prepare_frame_to_send (WlanC_Data);
FOUT;
}
static void
wlan_prepare_frame_to_send (int frame_type)
{
char msg_string [120];
Packet* seg_pkptr;
int protocol_type = -1;
int tx_datapacket_size;
int type;
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;
/* 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);
}
/* 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_PROPAGATI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -