📄 radio_link_agent.cpp
字号:
fprintf(stderr,"!!error in module %s: Retransmit buffer overflow\n",ModuleName);
exit(-1);
}
else
{
Retransmit_Buffer[Retransmit_buffer_write_position].retransmission_frame = incoming_frame;
Retransmit_Buffer[Retransmit_buffer_write_position].retransmission_time = simulation_time + RETRANSMISSION_DELAY_FACTOR*transmission_time_interval;
Retransmit_buffer_length++;
Retransmit_buffer_write_position++;
if ( Retransmit_buffer_write_position == FRAME_BUFFER_SIZE )
{
Retransmit_buffer_write_position = 0; // wrap around circular retransmission_buffer
}
//printf("retransmission scheduled at time %d \n",simulation_time);
}
return;
}
else
{
// frame has been received correctly
// determine the SDUs for which segments are contained in the frame, update the receive counters
// if all segments of an SDU have been received now, either:
// - forward it to the upper layer agent in case of no erroneous segments
// - envoke the discard procedure of the upper layer agent, if there is at least one erroneous segment
for (i=0;i<incoming_frame->number_of_contained_SDUs;i++)
{
identifier = incoming_frame->contained_SDU[i].identifier;
SDU_Buffer[identifier].received_bytes_counter += incoming_frame->contained_SDU[i].size;
SDU_Buffer[identifier].correct_bytes_counter += incoming_frame->contained_SDU[i].size;
total_correct_payload_bits_counter += incoming_frame->contained_SDU[i].size*8;
if ( SDU_Buffer[identifier].received_bytes_counter == SDU_Buffer[identifier].upper_layer_PDU.size )
{
// all segments of an SDU have already arrived
if ( SDU_Buffer[identifier].correct_bytes_counter == SDU_Buffer[identifier].upper_layer_PDU.size )
{
// all segments of an SDU are error-free
// printf("sequence number of current frame: %d\n",incoming_frame->sequence_number);
// printf("identifier %d\n",identifier);
// printf("last segment size: %d\n",incoming_frame->contained_SDU[i].size);
Upper_Layer_Agent->put_PDU(simulation_time,&(SDU_Buffer[identifier].upper_layer_PDU));
}
else
{
// at least one segment is corrupt
Upper_Layer_Agent->discard_PDU(simulation_time,&(SDU_Buffer[identifier].upper_layer_PDU));
}
// update SDU buffer
SDU_Buffer[identifier].upper_layer_PDU.internal_identifier = 0;
SDU_Buffer[identifier].upper_layer_PDU.size = 0;
SDU_Buffer[identifier].unsent_bytes = 0;
SDU_Buffer[identifier].received_bytes_counter = 0;
SDU_Buffer[identifier].correct_bytes_counter = 0;
SDU_buffer_total_length--;
}
}
free(incoming_frame);
}
break;
case RETRANSMIT:
// check frame error status
if ( frame_error_indicator )
{
// determine, if further retransmissions of this frame are still allowed
if ( fully_persistent_ARQ || (incoming_frame->number_of_retransmissions < max_number_of_retransmissions) )
{
// check for retransmission buffer overflow
if ( Retransmit_buffer_length == FRAME_BUFFER_SIZE )
{
fprintf(stderr,"!!error in module %s: Retransmit buffer overflow\n",ModuleName);
exit(-1);
}
else
{
Retransmit_Buffer[Retransmit_buffer_write_position].retransmission_frame = incoming_frame;
Retransmit_Buffer[Retransmit_buffer_write_position].retransmission_time = simulation_time + RETRANSMISSION_DELAY_FACTOR*transmission_time_interval;
Retransmit_buffer_length++;
Retransmit_buffer_write_position++;
if ( Retransmit_buffer_write_position == FRAME_BUFFER_SIZE )
{
Retransmit_buffer_write_position = 0; // wrap around circular retransmission_buffer
}
//printf("retransmission rescheduled at time %d\n",simulation_time);
}
return;
}
else
{
// frame cannot be retransmitted anymore
// determine the SDUs for which segments are contained in the frame, update the receive counter
// if all segments of an SDU have been received now, envoke the discard procedure of the upper layer agent,
// since there is at least one erroneous segment
for (i=0;i<incoming_frame->number_of_contained_SDUs;i++)
{
identifier = incoming_frame->contained_SDU[i].identifier;
SDU_Buffer[identifier].received_bytes_counter += incoming_frame->contained_SDU[i].size;
if ( SDU_Buffer[identifier].received_bytes_counter == SDU_Buffer[identifier].upper_layer_PDU.size )
{
// at least one segment is corrupt
Upper_Layer_Agent->discard_PDU(simulation_time,&(SDU_Buffer[identifier].upper_layer_PDU));
// update SDU buffer
SDU_Buffer[identifier].upper_layer_PDU.internal_identifier = 0;
SDU_Buffer[identifier].upper_layer_PDU.size = 0;
SDU_Buffer[identifier].unsent_bytes = 0;
SDU_Buffer[identifier].received_bytes_counter = 0;
SDU_Buffer[identifier].correct_bytes_counter = 0;
SDU_buffer_total_length--;
}
}
free(incoming_frame);
}
}
else
{
// frame has been received correctly
// determine the SDUs for which segments are contained in the frame, update the receive counters
// if all segments of an SDU have been received now, either:
// - forward it to the upper layer agent in case of no erroneous segments
// - envoke the discard procedure of the upper layer agent, if there is at least one erroneous segment
for (i=0;i<incoming_frame->number_of_contained_SDUs;i++)
{
identifier = incoming_frame->contained_SDU[i].identifier;
SDU_Buffer[identifier].received_bytes_counter += incoming_frame->contained_SDU[i].size;
SDU_Buffer[identifier].correct_bytes_counter += incoming_frame->contained_SDU[i].size;
total_correct_payload_bits_counter += incoming_frame->contained_SDU[i].size*8;
if ( SDU_Buffer[identifier].received_bytes_counter == SDU_Buffer[identifier].upper_layer_PDU.size )
{
// all segments of an SDU have already arrived
if ( SDU_Buffer[identifier].correct_bytes_counter == SDU_Buffer[identifier].upper_layer_PDU.size )
{
// all segments of an SDU are error-free
// printf("sequence number of current frame: %d\n",incoming_frame->sequence_number);
// printf("identifier %d\n",identifier);
// printf("last segment size: %d\n",incoming_frame->contained_SDU[i].size);
Upper_Layer_Agent->put_PDU(simulation_time,&(SDU_Buffer[identifier].upper_layer_PDU));
}
else
{
// at least one segment is corrupt
Upper_Layer_Agent->discard_PDU(simulation_time,&(SDU_Buffer[identifier].upper_layer_PDU));
}
// update SDU buffer
SDU_Buffer[identifier].upper_layer_PDU.internal_identifier = 0;
SDU_Buffer[identifier].upper_layer_PDU.size = 0;
SDU_Buffer[identifier].unsent_bytes = 0;
SDU_Buffer[identifier].received_bytes_counter = 0;
SDU_Buffer[identifier].correct_bytes_counter = 0;
SDU_buffer_total_length--;
}
}
free(incoming_frame);
}
break;
case DUMMY:
// check for frame sequence reordering
if ( incoming_frame->sequence_number != receive_sequence_number )
{
fprintf(stderr,"!!error in module %s: frame reordering in acknowledged mode has occurred\n",ModuleName);
}
receive_sequence_number++;
// discard all dummy frames
free(incoming_frame);
return;
default:
fprintf(stderr,"!!error in module %s: illegal frame type %d received\n",ModuleName,incoming_frame->frame_type);
exit(-1);
}
}
// reception procedure for unacknowledged mode operation
void RADIO_LINK_AGENT::UM_receive_frame(RADIO_LINK_FRAME *incoming_frame, Boolean frame_error_indicator)
{
int32 i, identifier;
// check for frame sequence reordering
if ( incoming_frame->sequence_number != receive_sequence_number )
{
fprintf(stderr,"!!error in module %s: frame reordering in unacknowledged mode has occurred\n",ModuleName);
}
// determine the type of the received frame
switch ( incoming_frame->frame_type )
{
case DATA:
receive_sequence_number++;
break;
case DUMMY:
receive_sequence_number++;
// discard all dummy frames
free(incoming_frame);
return;
default:
fprintf(stderr,"!!error in module %s: illegal frame type %d received\n",ModuleName,incoming_frame->frame_type);
exit(-1);
}
// determine the SDUs for which segments are contained in the frame, update the receive counters depending on the
// error indication for the radio link frame;
// if all segments of an SDU have been received now, either:
// - forward it to the upper layer agent in case of no erroneous segments
// - envoke the discard procedure of the upper layer agent, if there is at least one erroneous segment
for (i=0;i<incoming_frame->number_of_contained_SDUs;i++)
{
identifier = incoming_frame->contained_SDU[i].identifier;
SDU_Buffer[identifier].received_bytes_counter += incoming_frame->contained_SDU[i].size;
if ( !frame_error_indicator )
{
SDU_Buffer[identifier].correct_bytes_counter += incoming_frame->contained_SDU[i].size;
total_correct_payload_bits_counter += incoming_frame->contained_SDU[i].size*8;
}
if ( SDU_Buffer[identifier].received_bytes_counter == SDU_Buffer[identifier].upper_layer_PDU.size )
{
// all segments of an SDU have already arrived
if ( SDU_Buffer[identifier].correct_bytes_counter == SDU_Buffer[identifier].upper_layer_PDU.size )
{
// all segments of an SDU are error-free
// printf("sequence number of current frame: %d\n",incoming_frame->sequence_number);
// printf("identifier %d\n",identifier);
// printf("last segment size: %d\n",incoming_frame->contained_SDU[i].size);
Upper_Layer_Agent->put_PDU(simulation_time,&(SDU_Buffer[identifier].upper_layer_PDU));
}
else
{
// at least one segment is corrupt
Upper_Layer_Agent->discard_PDU(simulation_time,&(SDU_Buffer[identifier].upper_layer_PDU));
}
// update SDU buffer
SDU_Buffer[identifier].upper_layer_PDU.internal_identifier = 0;
SDU_Buffer[identifier].upper_layer_PDU.size = 0;
SDU_Buffer[identifier].unsent_bytes = 0;
SDU_Buffer[identifier].received_bytes_counter = 0;
SDU_Buffer[identifier].correct_bytes_counter = 0;
SDU_buffer_total_length--;
}
}
free(incoming_frame);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -