/****************************************************************************** # Eurecom OpenAirInterface # Copyright(c) 1999 - 2013 Eurecom # This program is free software; you can redistribute it and/or modify it # under the terms and conditions of the GNU General Public License, # version 2, as published by the Free Software Foundation. # This program is distributed in the hope it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # You should have received a copy of the GNU General Public License along with # this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution in # the file called "COPYING". # Contact Information # Openair Admin: openair_admin@eurecom.fr # Openair Tech : openair_tech@eurecom.fr # Forums : http://forums.eurecom.fsr/openairinterface # Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France #***************************************************************************** # \file openair2_proc # \brief print openair2 statistics # \author Navid Nikaein # \date 2013 # \version 0.1 # \email navid.nikaein@eurecom.fr # @ingroup _mac */ #ifdef USER_MODE # include #else #include #include #include # ifndef PRIu64 # if __WORDSIZE == 64 # define PRIu64 "lu" # else # define PRIu64 "llu" # endif # endif #endif #include "LAYER2/RLC/rlc.h" #include "LAYER2/MAC/defs.h" #include "LAYER2/MAC/extern.h" #include "LAYER2/PDCP_v10.1.0/pdcp.h" #include "UTIL/LOG/log.h" static mapping rrc_status_names[] = { {"RRC_IDLE", 0}, {"RRC_SI_RECEIVED",1}, {"RRC_CONNECTED",2}, {"RRC_RECONFIGURED",3}, {NULL, -1} }; int dump_eNB_l2_stats(char *buffer, int length){ uint8_t eNB_id,UE_id,number_of_cards; int len= length; #ifdef EXMIMO number_of_cards=1; #else number_of_cards=NB_eNB_INST; #endif for (eNB_id=0;eNB_id 0 ) { eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].dlsch_bitrate=((eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].TBS*8)/((eNB_mac_inst[eNB_id].frame + 1)*10)); eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_dlsch_bitrate= ((eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_pdu_bytes*8)/((eNB_mac_inst[eNB_id].frame + 1)*10)); eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_overhead_bytes+= eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].overhead_bytes; eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].avg_overhead_bytes=((eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_overhead_bytes*8)/((eNB_mac_inst[eNB_id].frame + 1)*10)); len += sprintf(&buffer[len],"UE %d %s, RNTI %x : CQI %d, MCS(%d->%d), RB(tx %d, retx %d, total %d), ncce (tx %d, retx %d) \n ", UE_id, map_int_to_str(rrc_status_names, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].rrc_status), eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].crnti, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].dl_cqi, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].dlsch_mcs1, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].dlsch_mcs2, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].rbs_used, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].rbs_used_retx, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_rbs_used, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].ncce_used, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].ncce_used_retx ); len += sprintf(&buffer[len], "[MAC] DLSCH bitrate (TTI %d, avg %d), Transmitted bytes " "(TTI %d, total %"PRIu64"), Total Transmitted PDU %d, Overhead " "(TTI %"PRIu64", total %"PRIu64", avg %"PRIu64, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].dlsch_bitrate, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_dlsch_bitrate, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].TBS, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_pdu_bytes, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_num_pdus, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].overhead_bytes, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_overhead_bytes, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].avg_overhead_bytes ); } } } return len + 1 /* SR: for trailing \0 */; } #ifdef PROC #ifndef USER_MODE static int openair2_stats_read(char *buffer, char **my_buffer, off_t off, int length) #else int openair2_stats_read(char *buffer, char **my_buffer, off_t off, int length) #endif { int len = 0,fg,Overhead, Sign; unsigned int i,j,k,kk; unsigned int Mod_id = 0,CH_index; unsigned int tx_pdcp_sdu; unsigned int tx_pdcp_sdu_discarded; unsigned int tx_retransmit_pdu_unblock; unsigned int tx_retransmit_pdu_by_status; unsigned int tx_retransmit_pdu; unsigned int tx_data_pdu; unsigned int tx_control_pdu; unsigned int rx_sdu; unsigned int rx_error_pdu; unsigned int rx_data_pdu; unsigned int rx_data_pdu_out_of_window; unsigned int rx_control_pdu; // if (mac_xface->is_cluster_head == 0) { for (k=0;kIs_cluster_head[k] == 0){ #ifndef PHY_EMUL_ONE_MACHINE Mod_id=k-NB_CH_INST; len+=sprintf(&buffer[len],"UE TTI: %d\n",Mac_rlc_xface->frame); for (CH_index = 0;CH_index>5, UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.NB_RX, UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.NB_RX_ERRORS); for(i=1;i>5, Pdcp_stats_rx[k][CH_index][i], Pdcp_stats_rx_rate[k][CH_index][i], (10*Pdcp_stats_rx_rate[k][CH_index][i])>>5, Sign*(10*Overhead)>>5); int status = rlc_stat_req (k, UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, &tx_pdcp_sdu, &tx_pdcp_sdu_discarded, &tx_retransmit_pdu_unblock, &tx_retransmit_pdu_by_status, &tx_retransmit_pdu, &tx_data_pdu, &tx_control_pdu, &rx_sdu, &rx_error_pdu, &rx_data_pdu, &rx_data_pdu_out_of_window, &rx_control_pdu) ; if (status == RLC_OP_STATUS_OK) { len+=sprintf(&buffer[len],"RLC LCHAN %d, NB_SDU_TO_TX = %d\tNB_SDU_DISC %d\tNB_RX_SDU %d\n", UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, tx_pdcp_sdu, tx_pdcp_sdu_discarded, rx_sdu); len+=sprintf(&buffer[len],"RLC LCHAN %d, NB_TB_TX_DATA = %d\tNB_TB_TX_CONTROL %d\tNB_TX_TB_RETRANS %d", UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, tx_data_pdu, tx_control_pdu, tx_retransmit_pdu); len+=sprintf(&buffer[len],"\tRLC LCHAN %d, NB_TX_TB_RETRANS_BY_STATUS = %d\tNB_TX_TB_RETRANS_PADD %d\n", UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, tx_retransmit_pdu_by_status, tx_retransmit_pdu_unblock); len+=sprintf(&buffer[len],"RLC LCHAN %d, NB_RX_DATA = %d\tNB_RX_TB_OUT_WIN %d\tNB_RX_TB_CORRUPT %d\n", UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, rx_data_pdu, rx_data_pdu_out_of_window, rx_error_pdu); } len+=sprintf(&buffer[len],"[MAC]: LCHAN %d, NB_TX_MAC = %d (%d bits/TTI, %d kbits/s), NB_RX_MAC = %d (%d errors)\n", UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_TX, UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.output_rate, (10*UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.output_rate)>>5, UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX, UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX_ERRORS); len+=sprintf(&buffer[len]," TX per TB: "); for(kk=0;kkIs_cluster_head[k] ==1){ Mod_id=k; len+=sprintf(&buffer[len],"-------------------------------------------------------------------CH %d: TTI: %d------------------------------------------------------------------\n", NODE_ID[Mod_id],Mac_rlc_xface->frame); for(i=1;i<=NB_CNX_CH;i++){ if (CH_mac_inst[Mod_id].Dcch_lchan[i].Active==1) { len+=sprintf(&buffer[len],"\nMR index %d: DL SINR (feedback) %d dB, CQI: %s\n\n", i,//CH_rrc_inst[Mod_id].Info.UE_list[i].L2_id[0], CH_mac_inst[Mod_id].Def_meas[i].Wideband_sinr, print_cqi(CH_mac_inst[Mod_id].Def_meas[i].cqi)); len+=sprintf(&buffer[len],"[MAC] LCHAN %d (DCCH), NB_TX_MAC= %d (%d bits/TTI, %d kbits/s), NB_RX_MAC= %d (errors %d, sacch errors %d, sach errors %d, sach_missing %d)\n\n", CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.Lchan_id.Index, CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_TX, CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.output_rate, (10*CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.output_rate)>>5, CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX, CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_ERRORS, CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_SACCH_ERRORS, CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_SACH_ERRORS, CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_SACH_MISSING); for(j=0;j>5, Pdcp_stats_rx[k][i][j], Pdcp_stats_rx_rate[k][i][j], (10*Pdcp_stats_rx_rate[k][i][j])>>5, Sign*(10*Overhead)>>5); int status = rlc_stat_req (k, CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, &tx_pdcp_sdu, &tx_pdcp_sdu_discarded, &tx_retransmit_pdu_unblock, &tx_retransmit_pdu_by_status, &tx_retransmit_pdu, &tx_data_pdu, &tx_control_pdu, &rx_sdu, &rx_error_pdu, &rx_data_pdu, &rx_data_pdu_out_of_window, &rx_control_pdu) ; /* if (status == RLC_OP_STATUS_OK) { len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_SDU_TO_TX = %d\tNB_SDU_DISC %d\tNB_RX_SDU %d\n", CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, tx_pdcp_sdu, tx_pdcp_sdu_discarded, rx_sdu); len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_TB_TX_DATA = %d\tNB_TB_TX_CONTROL %d\tNB_TX_TB_RETRANS %\n", CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, tx_data_pdu, tx_control_pdu, tx_retransmit_pdu); len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_TX_TB_RETRANS_BY_STATUS = %d\tNB_TX_TB_RETRANS_PADD %d\n", CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, tx_retransmit_pdu_by_status, tx_retransmit_pdu_unblock); len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_RX_DATA = %d\tNB_RX_TB_OUT_WIN %d\tNB_RX_TB_CORRUPT %d\n", CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, rx_data_pdu, rx_data_pdu_out_of_window, rx_error_pdu); } */ len+=sprintf(&buffer[len],"[MAC]LCHAN %d (CNX %d,RAB %d), NB_TX_MAC= %d (%d bits/TTI, %d kbit/s), NB_RX_MAC= %d (errors %d, sacch_errors %d, sach_errors %d, sach_missing %d)\n", CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, i,j, CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_TX, CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.output_rate, (10*CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.output_rate)>>5, CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX, CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_ERRORS, CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_SACCH_ERRORS, CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_SACH_ERRORS, CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_SACH_MISSING); len+=sprintf(&buffer[len],"[MAC][SCHEDULER] TX Arrival Rate %d, TX Service Rate %d, RX Arrival rate %d, RX Service rate %d, NB_BW_REQ_RX %d\n\n", CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Arrival_rate, CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Tx_rate, CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Req_rate, CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Rx_rate, CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_BW_REQ_RX); /* len+=sprintf(&buffer[len]," TX per TB: "); for(kk=0;kk