⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 radio_link_agent.cpp

📁 各种视频压缩格式的网络传输的模拟信道分析
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	  fprintf(stderr,"!!error in module %s: SDU buffer overflow\n",ModuleName);
	  exit(-1);
	}

      upper_layer_status = Upper_Layer_Agent->get_PDU(simulation_time,&(SDU_Buffer[SDU_buffer_write_position].upper_layer_PDU));
      switch (upper_layer_status)
	{
	case 0:
	  // succeeded
	  SDU_Buffer[SDU_buffer_write_position].unsent_bytes = SDU_Buffer[SDU_buffer_write_position].upper_layer_PDU.size;
	  SDU_Buffer[SDU_buffer_write_position].received_bytes_counter = 0;
	  SDU_Buffer[SDU_buffer_write_position].correct_bytes_counter = 0;
	  SDU_buffer_write_position++;
	  if ( SDU_buffer_write_position == PACKET_BUFFER_SIZE )
	    {
	      SDU_buffer_write_position = 0;   // wrap around circular SDU buffer
	    }
	  SDU_buffer_total_length++;
	  SDU_buffer_unsent_length++;
	  break;

	case 1:
	  // failed: input file still contains data, but the timestamp is younger than the current simulation time
	  // send dummy frames to simulate idle periods
	  fprintf(LogFile_ptr,"%s: not enough data available for transmission at the moment - sending dummy frame at time %d\n",ModuleName,simulation_time);
	  if ( ((*outgoing_frame) = (RADIO_LINK_FRAME *) malloc(sizeof(RADIO_LINK_FRAME))) == NULL )
	    {
              fprintf(stderr,"!!error in module %s: cannot allocate enough memory for new radio link frame\n",ModuleName);
              exit(-1);
	    }
	  (*outgoing_frame)->sequence_number = send_sequence_number;
          send_sequence_number++;
          (*outgoing_frame)->size = frame_size;
	  (*outgoing_frame)->frame_type = DUMMY;
	  (*outgoing_frame)->number_of_contained_SDUs = 0;
	  (*outgoing_frame)->number_of_retransmissions = 0;
	  total_frames_counter++;
	  total_dummy_frames_counter++;
	  simulation_time += transmission_time_interval;
	  return TRUE;

	case 2:
	  // failed: end of input file already reached
	  if ( Retransmit_buffer_length > 0 )
	    {
	      // no new data available, but retransmission buffer still contains unsent frames - send dummy frames
	      fprintf(LogFile_ptr,"%s: no more data available for transmission - but retransmission buffer still full\n",ModuleName);
	      if ( ((*outgoing_frame) = (RADIO_LINK_FRAME *) malloc(sizeof(RADIO_LINK_FRAME))) == NULL )
	        {
                  fprintf(stderr,"!!error in module %s: cannot allocate enough memory for new radio link frame\n",ModuleName);
                  exit(-1);
	        }
	      (*outgoing_frame)->sequence_number = send_sequence_number;
              send_sequence_number++;
              (*outgoing_frame)->size = frame_size;
	      (*outgoing_frame)->frame_type = DUMMY;
	      (*outgoing_frame)->number_of_contained_SDUs = 0;
	      (*outgoing_frame)->number_of_retransmissions = 0;
	      total_frames_counter++;
	      total_dummy_frames_counter++;
	      simulation_time += transmission_time_interval;
	      return TRUE;
	    }
	  else
            {
	      fprintf(LogFile_ptr,"%s: no more data available for transmission - termination initiated\n",ModuleName);
	      return FALSE;
	    }
	default:
	  // unexpected return value
	  fprintf(stderr,"!!error in module %s: unexpected return value for <get_SDU>\n",ModuleName);
	  exit(-1);
	}
    }


  // enough data available in SDU buffer 
  // prepare outgoing radio link frame for transmission
  if ( ((*outgoing_frame) = (RADIO_LINK_FRAME *) malloc(sizeof(RADIO_LINK_FRAME))) == NULL )
    {
      fprintf(stderr,"!!error in module %s: cannot allocate enough memory for new radio link frame\n",ModuleName);
      exit(-1);
    }

  (*outgoing_frame)->sequence_number = send_sequence_number;
  send_sequence_number++;
  (*outgoing_frame)->size = 0;
  (*outgoing_frame)->frame_type = DATA;
  (*outgoing_frame)->number_of_contained_SDUs = 0;
  (*outgoing_frame)->number_of_retransmissions = 0;

  // (virtually) add header fields to outgoing radio link frame
  (*outgoing_frame)->size += agent_header_size*8;
  // (virtually) map data from SDU buffer to the outgoing radio link frame, until the latter is full or the SDU buffer is empty
  while ( (*outgoing_frame)->size < frame_size )
    {
      if ( SDU_Buffer[SDU_buffer_read_position].unsent_bytes <= (frame_size - (*outgoing_frame)->size)/8 )
        {
          // unsent bytes in current SDU do no exceed the space still left in the radio link frame
          (*outgoing_frame)->size += SDU_Buffer[SDU_buffer_read_position].unsent_bytes*8;
          (*outgoing_frame)->contained_SDU[(*outgoing_frame)->number_of_contained_SDUs].identifier = SDU_buffer_read_position;
          (*outgoing_frame)->contained_SDU[(*outgoing_frame)->number_of_contained_SDUs].size = SDU_Buffer[SDU_buffer_read_position].unsent_bytes;
          (*outgoing_frame)->number_of_contained_SDUs++;
          SDU_Buffer[SDU_buffer_read_position].unsent_bytes = 0;
          SDU_buffer_unsent_length--;
          SDU_buffer_read_position++;
          if ( SDU_buffer_read_position == PACKET_BUFFER_SIZE )
            {
	      SDU_buffer_read_position = 0;   // wrap around circular SDU buffer
	    }
        }
      else
	{
	  // unsent bytes in current SDU exceed the space still left in the radio link frame - take only a fraction of them
          mapped_data_size = (frame_size - (*outgoing_frame)->size)/8;
          (*outgoing_frame)->size = frame_size;
          (*outgoing_frame)->contained_SDU[(*outgoing_frame)->number_of_contained_SDUs].identifier = SDU_buffer_read_position;
          (*outgoing_frame)->contained_SDU[(*outgoing_frame)->number_of_contained_SDUs].size = mapped_data_size;
          (*outgoing_frame)->number_of_contained_SDUs++;
          SDU_Buffer[SDU_buffer_read_position].unsent_bytes -= mapped_data_size;
	}
      // check, if SDU buffer still contains unsent data parts and the radio link frame is not completely filled yet
      if ( (SDU_buffer_unsent_length == 0) && ((*outgoing_frame)->size < frame_size) )
	{
	  // we need to request a new SDU from the upper layer agent

          //check for buffer overflow first
          if ( SDU_buffer_total_length == PACKET_BUFFER_SIZE )
	    {
	      fprintf(stderr,"!!error in module %s: SDU buffer overflow\n",ModuleName);
	      exit(-1);
	    }

          upper_layer_status = Upper_Layer_Agent->get_PDU(simulation_time,&(SDU_Buffer[SDU_buffer_write_position].upper_layer_PDU));
          switch (upper_layer_status)
	    {
	    case 0:
	      // succeeded
	      SDU_Buffer[SDU_buffer_write_position].unsent_bytes = SDU_Buffer[SDU_buffer_write_position].upper_layer_PDU.size;
	      SDU_Buffer[SDU_buffer_write_position].received_bytes_counter = 0;
	      SDU_Buffer[SDU_buffer_write_position].correct_bytes_counter = 0;
	      SDU_buffer_write_position++;
	      if ( SDU_buffer_write_position == PACKET_BUFFER_SIZE )
	        {
	          SDU_buffer_write_position = 0;   // wrap around circular SDU buffer
	        }
	      SDU_buffer_total_length++;
	      SDU_buffer_unsent_length++;
	      break;

	    case 1:
	      // failed: input file still contains data, but the timestamp is younger than the current simulation time
	      // perform (virtual) stuffing for the rest of the radio link frame
	      fprintf(LogFile_ptr,"%s: not enough data available for transmission at the moment - perform (virtual) stuffing on frame at time %d\n",ModuleName,simulation_time);
              (*outgoing_frame)->size = frame_size;
              break;

	    case 2:
	      // failed: end of input file already reached
	      // also perform (virtual) stuffing for the rest of the radio link frame
	      fprintf(LogFile_ptr,"%s: no more data available for transmission - perform (virtual) stuffing on frame at time %d\n",ModuleName,simulation_time);
              (*outgoing_frame)->size = frame_size;
	      break;
 	    default:
	      // unexpected return value
	      fprintf(stderr,"!!error in module %s: unexpected return value for <get_SDU>\n",ModuleName);
	      exit(-1);
	    } 
	}
    }

  // finish generation of new radio link frame
  total_frames_counter++;
  simulation_time += transmission_time_interval;
  return TRUE;
}



// invoke reception procedure for radio link frames depending on radio link operation mode
void RADIO_LINK_AGENT::receive_frame(RADIO_LINK_FRAME *incoming_frame, Boolean frame_error_indicator)
{
  if ( ACK_mode )
    {
      // acknowledged mode
      AM_receive_frame(incoming_frame, frame_error_indicator);
    }
  else
    {
      //unacknowledged mode
      UM_receive_frame(incoming_frame, frame_error_indicator);
    }
}



void RADIO_LINK_AGENT::write_statistics(FILE *StatisticsFile_ptr)
{
  //calculate statistics first
  total_bitrate = (double)(total_frames_counter*frame_size)/(double)simulation_time;
  total_net_bitrate = (double)(total_frames_counter*(frame_size-agent_header_size*8))/(double)simulation_time;
  effective_net_bitrate = (double)total_correct_payload_bits_counter/(double)simulation_time;

  // write statistics to file
  fprintf(StatisticsFile_ptr,"----------------------------------------------------------------------------\n");
  fprintf(StatisticsFile_ptr,"%s: Statistics:\n\n",ModuleName);

  fprintf(StatisticsFile_ptr,"total number of radio link frames transmitted:  %10d\n",total_frames_counter);
  fprintf(StatisticsFile_ptr,"number of retransmissions:                      %10d\n",total_retransmitted_frames_counter);
  fprintf(StatisticsFile_ptr,"number of dummy frames:                         %10d\n\n",total_dummy_frames_counter);
  
  fprintf(StatisticsFile_ptr,"total bitrate (including radio link header):                %f kbit/s\n",total_bitrate);
  fprintf(StatisticsFile_ptr,"total net bitrate (excluding radio link header):            %f kbit/s\n",total_net_bitrate);
  fprintf(StatisticsFile_ptr,"effective net bitrate (including only correct data bits):   %f kbit/s\n",effective_net_bitrate);

  fprintf(StatisticsFile_ptr,"----------------------------------------------------------------------------\n");
  fprintf(StatisticsFile_ptr,"total simulation time: %d ms\n",simulation_time);
  fprintf(StatisticsFile_ptr,"----------------------------------------------------------------------------\n");
}



// reception procedure for acknowledged mode operation 
void RADIO_LINK_AGENT::AM_receive_frame(RADIO_LINK_FRAME *incoming_frame, Boolean frame_error_indicator)
{
  int32 i, identifier;

  // determine the type of the received frame
  switch ( incoming_frame->frame_type )
    {
    case DATA:
      // 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++;
      // check frame error status
      if ( frame_error_indicator )
	{
          // retransmission is allowed at least once per frame in acknowledged mode
	  incoming_frame->frame_type = RETRANSMIT;
	  incoming_frame->number_of_retransmissions = 0;
	  // check for retransmission buffer overflow
	  if ( Retransmit_buffer_length == FRAME_BUFFER_SIZE )
	    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -