?? radio_link_agent.cpp
字號:
/*
==========================================================================================
ITU-T Telecommunications Standardization Sector Document: VCEG-M77
Study Group 16 Question 6 Filename: radio_link_agent.cc
Video Coding Experts Group (VCEG) Generated: 02 July, 2001
----------------------------------------
Thirteenth meeting: Austin, Texas, 2-4 April, 2001
Intention:
~~~~~~~~~~~~
Simple offline software simulator for RTP/IP over 3GPP/3GPP2 bearers
Source:
~~~~~~~
Thomas Stockhammer, Guenther Liebl Tel: +49 89 28923473
Institute for Communications Engineering Fax: +49 89 28923490
Munich University of Technology Email: {stockhammer,liebl}@ei.tum.de
80290 Munich, Germany
==========================================================================================
*/
#include "radio_link_agent.h"
// constructor
RADIO_LINK_AGENT::RADIO_LINK_AGENT()
{
int32 i;
// basic initialization
ModuleName = "RADIO-LINK-AGENT";
for (i=0;i<PACKET_BUFFER_SIZE;i++)
{
SDU_Buffer[i].upper_layer_PDU.internal_identifier = 0;
SDU_Buffer[i].upper_layer_PDU.size = 0;
SDU_Buffer[i].unsent_bytes = 0;
SDU_Buffer[i].received_bytes_counter = 0;
SDU_Buffer[i].correct_bytes_counter = 0;
}
SDU_buffer_read_position = 0;
SDU_buffer_write_position = 0;
SDU_buffer_total_length = 0;
SDU_buffer_unsent_length = 0;
radio_bearer_bitrate = 0;
frame_size = 0;
agent_header_size = 0;
ACK_mode = FALSE;
fully_persistent_ARQ = FALSE;
max_number_of_retransmissions = 0;
for (i=0;i<FRAME_BUFFER_SIZE;i++)
{
Retransmit_Buffer[i].retransmission_frame = NULL;
Retransmit_Buffer[i].retransmission_time = 0;
}
Retransmit_buffer_read_position = 0;
Retransmit_buffer_write_position = 0;
Retransmit_buffer_length = 0;
total_frames_counter = 0;
total_retransmitted_frames_counter = 0;
total_dummy_frames_counter = 0;
total_correct_payload_bits_counter = 0;
total_bitrate = 0.;
total_net_bitrate = 0.;
effective_net_bitrate = 0.;
transmission_time_interval = 0;
simulation_time = 0;
send_sequence_number = 0;
receive_sequence_number = 0;
}
// destructor
RADIO_LINK_AGENT::~RADIO_LINK_AGENT()
{
}
// initialize the radio link agent from the given parameter file
void RADIO_LINK_AGENT::initialize(FILE *ParameterFile_ptr, FILE *CommonLogFile_ptr, PACKET_DATA_AGENT *upper_layer_agent)
{
char ack_mode, fully_persistent_arq;
LogFile_ptr = CommonLogFile_ptr;
fprintf(LogFile_ptr,"%s: start initialization process\n",ModuleName);
Upper_Layer_Agent = upper_layer_agent;
// get the desired radio bearer bitrate from the parameter file
fscanf(ParameterFile_ptr,"- nominal radio bearer bitrate (in kbit/s): %d\n",&radio_bearer_bitrate);
if ( (radio_bearer_bitrate <= 0) || (radio_bearer_bitrate%8 != 0) )
{
fprintf(stderr,"!!error in module %s: illegal value %d for the radio bearer bitrate\n",ModuleName,radio_bearer_bitrate);
exit(-1);
}
else
{
fprintf(LogFile_ptr,"%s: nominal radio bearer bitrate is %d kbit/s\n",ModuleName,radio_bearer_bitrate);
}
// get the desired frame size of the radio link agent from the parameter file
fscanf(ParameterFile_ptr,"- frame size (in bits): %d\n",&frame_size);
if ( (frame_size <= 0) || (frame_size%8 != 0) )
{
fprintf(stderr,"!!error in module %s: illegal value %d for the frame size\n",ModuleName,frame_size);
exit(-1);
}
else
{
fprintf(LogFile_ptr,"%s: using radio link frames of size %d bits\n",ModuleName,frame_size);
}
// compute the transmission time interval
transmission_time_interval = frame_size/radio_bearer_bitrate;
fprintf(LogFile_ptr,"%s: using a transmission time interval of %d ms\n",ModuleName,transmission_time_interval);
// get the header size of the radio link agent from the parameter file
fscanf(ParameterFile_ptr,"- radio link agent header size (in bytes): %d\n",&agent_header_size);
if ( agent_header_size <= 0 )
{
fprintf(stderr,"!!error in module %s: illegal value %d for the radio link agent header size\n",ModuleName,agent_header_size);
exit(-1);
}
else
{
fprintf(LogFile_ptr,"%s: adding %d bytes of header info to each PDU\n",ModuleName,agent_header_size);
}
// check, if acknowledged mode is to be used
fscanf(ParameterFile_ptr,"- acknowledged mode (y/n): %c\n",&ack_mode);
if ( ack_mode == 'y' )
{
ACK_mode = TRUE;
fprintf(LogFile_ptr,"%s: operates in acknowledged mode\n",ModuleName);
}
else if ( ack_mode == 'n' )
{
ACK_mode = FALSE;
fprintf(LogFile_ptr,"%s: operates in unacknowledged mode\n",ModuleName);
}
else
{
fprintf(stderr,"!!error in module %s: illegal value %c for the mode indicator\n",ModuleName,ack_mode);
exit(-1);
}
// determine, whether acknowledged mode is fully-persistent or not
fscanf(ParameterFile_ptr,"- fully-persistent ARQ (y/n): %c\n",&fully_persistent_arq);
if ( ACK_mode && (fully_persistent_arq == 'y') )
{
fully_persistent_ARQ = TRUE;
fprintf(LogFile_ptr,"%s: ARQ is fully-persistent\n",ModuleName);
}
else if ( ACK_mode && (fully_persistent_arq == 'n') )
{
fully_persistent_ARQ = FALSE;
// get the maximum number of retransmissions per frame from the parameter file
fscanf(ParameterFile_ptr,"- maximum number of retransmissions per frame in acknowledged mode: %d\n",&max_number_of_retransmissions);
if ( max_number_of_retransmissions <= 0 )
{
fprintf(stderr,"!!error in module %s: illegal value %d for the maximum number of retransmissions\n",ModuleName,max_number_of_retransmissions);
exit(-1);
}
else
{
fprintf(LogFile_ptr,"%s: maximum number of retransmissions per frame is limited to %d\n",ModuleName,max_number_of_retransmissions);
}
}
else if ( ACK_mode )
{
fprintf(stderr,"!!error in module %s: illegal value %c for the persistency indiator\n",ModuleName,fully_persistent_arq);
exit(-1);
}
fprintf(LogFile_ptr,"%s: end initialization process\n",ModuleName);
}
// generate a radio link frame either from retransmission buffer, SDU buffer, or new data from the upper layer agent
// if no data to be sent is available, generate a dummy frame and issue a streaming timer mismatch warning
// return value: TRUE, if there is still some unsent data somewhere in the transmitting side
// FALSE, if all data has been sent and there are no pending retransmissions anymore
Boolean RADIO_LINK_AGENT::send_frame(RADIO_LINK_FRAME **outgoing_frame)
{
int32 upper_layer_status;
int32 mapped_data_size;
// in acknowledged mode, retransmission buffer has highest priority
if ( ACK_mode && (Retransmit_buffer_length > 0) )
{
// retransmission buffer contains frames to be retransmitted
if ( simulation_time >= Retransmit_Buffer[Retransmit_buffer_read_position].retransmission_time )
{
// the first frame to be retransmitted is already due
(*outgoing_frame) = Retransmit_Buffer[Retransmit_buffer_read_position].retransmission_frame;
if ( (*outgoing_frame)->frame_type != RETRANSMIT )
{
fprintf(stderr,"!!error in module %s: illegal frame of type %d found in retransmission queue\n",ModuleName,(*outgoing_frame)->frame_type);
exit(-1);
}
Retransmit_Buffer[Retransmit_buffer_read_position].retransmission_frame = NULL;
Retransmit_Buffer[Retransmit_buffer_read_position].retransmission_time = 0;
Retransmit_buffer_length--;
Retransmit_buffer_read_position++;
if ( Retransmit_buffer_read_position == FRAME_BUFFER_SIZE )
{
Retransmit_buffer_read_position = 0; // wrap around circular retransmission buffer
}
(*outgoing_frame)->number_of_retransmissions++;
total_frames_counter++;
total_retransmitted_frames_counter++;
//printf("retransmission done at time %d\n",simulation_time);
simulation_time += transmission_time_interval;
return TRUE;
}
}
// check, if the SDU buffer is empty and new SDUs have to be requested from the upper layer agent
if ( SDU_buffer_unsent_length == 0 )
{
// SDU buffer is empty
//check for buffer overflow first
if ( SDU_buffer_total_length == PACKET_BUFFER_SIZE )
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -