see https://gitlab.eurecom.fr/oai/openairinterface5g/issues/227 When the UE connects to the eNodeB and receives its IP address from the network, it calls system() to set it in the linux kernel world. This call is not done in a realtime thread, but in the NAS, which uses its own thread, independent of the realtime processing. In some situations this totally disrupts realtime processing. It is difficult to know precisely why that happens, but it seems that calling fork(), as system() does, in a multi-threaded program is not a good idea. (So say several people on the internet.) It is not clear why the softmodem is impacted, but it seems that fork() is really what triggers the disruption. Several tests lead to that conclusion. To fix the problem, we create a child background process very early in main() (before anything else basically). Then instead of calling system(), the main process sends the string to the background process. The background process gets the string, passes it to system() and reports the success/failure back to the main process. This solution involves a lot of system calls, but calling system() in the first place is not cheap either. As long as no realtime thread uses this mechanism, things should be fine. Time will tell.
1933 lines
66 KiB
C
1933 lines
66 KiB
C
/*
|
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
|
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
|
* except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.openairinterface.org/?page_id=698
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*-------------------------------------------------------------------------------
|
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
|
* contact@openairinterface.org
|
|
*/
|
|
|
|
/*! \file oaisim.c
|
|
* \brief oaisim top level
|
|
* \author Navid Nikaein
|
|
* \date 2013-2015
|
|
* \version 1.0
|
|
* \company Eurecom
|
|
* \email: openair_tech@eurecom.fr
|
|
* \note
|
|
* \warning
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <math.h>
|
|
#include <unistd.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <cblas.h>
|
|
#include <execinfo.h>
|
|
|
|
#include "event_handler.h"
|
|
#include "SIMULATION/RF/defs.h"
|
|
#include "PHY/types.h"
|
|
#include "PHY/defs.h"
|
|
#include "PHY/LTE_TRANSPORT/proto.h"
|
|
#include "PHY/vars.h"
|
|
|
|
#include "SIMULATION/ETH_TRANSPORT/proto.h"
|
|
|
|
//#ifdef OPENAIR2
|
|
#include "LAYER2/MAC/defs.h"
|
|
#include "LAYER2/MAC/proto.h"
|
|
#include "LAYER2/MAC/vars.h"
|
|
#include "pdcp.h"
|
|
#include "RRC/LITE/vars.h"
|
|
#include "RRC/NAS/nas_config.h"
|
|
|
|
#include "SCHED/defs.h"
|
|
#include "SCHED/vars.h"
|
|
#include "system.h"
|
|
|
|
|
|
#include "PHY/TOOLS/lte_phy_scope.h"
|
|
|
|
|
|
#ifdef SMBV
|
|
// Rohde&Schwarz SMBV100A vector signal generator
|
|
#include "PHY/TOOLS/smbv.h"
|
|
char smbv_fname[] = "smbv_config_file.smbv";
|
|
unsigned short smbv_nframes = 4; // how many frames to configure 1,..,4
|
|
unsigned short config_frames[4] = {2,9,11,13};
|
|
unsigned char smbv_frame_cnt = 0;
|
|
uint8_t config_smbv = 0;
|
|
char smbv_ip[16];
|
|
#endif
|
|
|
|
#if defined(FLEXRAN_AGENT_SB_IF)
|
|
# include "flexran_agent.h"
|
|
#endif
|
|
|
|
|
|
#include "oaisim_functions.h"
|
|
|
|
#include "oaisim.h"
|
|
#include "oaisim_config.h"
|
|
#include "UTIL/OCG/OCG_extern.h"
|
|
#include "cor_SF_sim.h"
|
|
#include "UTIL/OMG/omg_constants.h"
|
|
#include "UTIL/FIFO/pad_list.h"
|
|
#include "enb_app.h"
|
|
|
|
#include "../PROC/interface.h"
|
|
#include "../PROC/channel_sim_proc.h"
|
|
#include "../PROC/Tsync.h"
|
|
#include "../PROC/Process.h"
|
|
|
|
#include "UTIL/LOG/vcd_signal_dumper.h"
|
|
#include "UTIL/OTG/otg_kpi.h"
|
|
#include "assertions.h"
|
|
|
|
#if defined(ENABLE_ITTI)
|
|
# include "intertask_interface.h"
|
|
# include "create_tasks.h"
|
|
#endif
|
|
|
|
#include "T.h"
|
|
|
|
/*
|
|
DCI0_5MHz_TDD0_t UL_alloc_pdu;
|
|
DCI1A_5MHz_TDD_1_6_t CCCH_alloc_pdu;
|
|
DCI2_5MHz_2A_L10PRB_TDD_t DLSCH_alloc_pdu1;
|
|
DCI2_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu2;
|
|
*/
|
|
|
|
#define UL_RB_ALLOC computeRIV(lte_frame_parms->N_RB_UL,0,24)
|
|
#define CCCH_RB_ALLOC computeRIV(lte_frame_parms->N_RB_UL,0,3)
|
|
#define RA_RB_ALLOC computeRIV(lte_frame_parms->N_RB_UL,0,3)
|
|
#define DLSCH_RB_ALLOC 0x1fff
|
|
|
|
#define DECOR_DIST 100
|
|
#define SF_VAR 10
|
|
|
|
//constant for OAISIM soft realtime calibration
|
|
//#define SF_DEVIATION_OFFSET_NS 100000 /*= 0.1ms : should be as a number of UE */
|
|
//#define SLEEP_STEP_US 100 /* = 0.01ms could be adaptive, should be as a number of UE */
|
|
//#define K 2 /* averaging coefficient */
|
|
//#define TARGET_SF_TIME_NS 1000000 /* 1ms = 1000000 ns */
|
|
|
|
uint8_t usim_test = 0;
|
|
|
|
frame_t frame = 0;
|
|
char stats_buffer[16384];
|
|
channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs];
|
|
channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
|
|
//Added for PHY abstraction
|
|
node_desc_t *enb_data[NUMBER_OF_eNB_MAX];
|
|
node_desc_t *ue_data[NUMBER_OF_UE_MAX];
|
|
|
|
pthread_cond_t sync_cond;
|
|
pthread_mutex_t sync_mutex;
|
|
int sync_var=-1;
|
|
|
|
pthread_mutex_t subframe_mutex;
|
|
int subframe_eNB_mask=0,subframe_UE_mask=0;
|
|
|
|
openair0_config_t openair0_cfg[MAX_CARDS];
|
|
uint32_t downlink_frequency[MAX_NUM_CCs][4];
|
|
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
|
openair0_rf_map rf_map[MAX_NUM_CCs];
|
|
|
|
#if defined(ENABLE_ITTI)
|
|
volatile int start_eNB = 0;
|
|
volatile int start_UE = 0;
|
|
#endif
|
|
volatile int oai_exit = 0;
|
|
|
|
|
|
//int32_t **rxdata;
|
|
//int32_t **txdata;
|
|
|
|
|
|
// Added for PHY abstraction
|
|
extern node_list* ue_node_list;
|
|
extern node_list* enb_node_list;
|
|
extern int pdcp_period, omg_period;
|
|
|
|
extern double **s_re, **s_im, **r_re, **r_im, **r_re0, **r_im0;
|
|
int map1, map2;
|
|
extern double **ShaF;
|
|
double snr_dB, sinr_dB, snr_direction; //,sinr_direction;
|
|
extern double snr_step;
|
|
extern uint8_t set_sinr;
|
|
extern uint8_t ue_connection_test;
|
|
extern uint8_t set_seed;
|
|
extern uint8_t target_dl_mcs;
|
|
extern uint8_t target_ul_mcs;
|
|
extern uint8_t abstraction_flag;
|
|
extern uint8_t ethernet_flag;
|
|
extern uint16_t Nid_cell;
|
|
|
|
extern LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs];
|
|
|
|
double cpuf;
|
|
#include "threads_t.h"
|
|
threads_t threads= {-1,-1,-1};
|
|
|
|
//#ifdef XFORMS
|
|
int otg_enabled;
|
|
int xforms=0;
|
|
//#endif
|
|
|
|
time_stats_t oaisim_stats;
|
|
time_stats_t oaisim_stats_f;
|
|
time_stats_t dl_chan_stats;
|
|
time_stats_t ul_chan_stats;
|
|
|
|
// this should reflect the channel models in openair1/SIMULATION/TOOLS/defs.h
|
|
mapping small_scale_names[] = {
|
|
{ "custom", custom }, { "SCM_A", SCM_A },
|
|
{ "SCM_B", SCM_B }, { "SCM_C", SCM_C },
|
|
{ "SCM_D", SCM_D }, { "EPA", EPA },
|
|
{ "EVA", EVA }, { "ETU", ETU },
|
|
{ "MBSFN", MBSFN }, { "Rayleigh8", Rayleigh8 },
|
|
{ "Rayleigh1", Rayleigh1 }, { "Rayleigh1_800", Rayleigh1_800 },
|
|
{ "Rayleigh1_corr", Rayleigh1_corr }, { "Rayleigh1_anticorr", Rayleigh1_anticorr },
|
|
{ "Rice8", Rice8 }, { "Rice1", Rice1 }, { "Rice1_corr", Rice1_corr },
|
|
{ "Rice1_anticorr", Rice1_anticorr }, { "AWGN", AWGN }, { NULL,-1 }
|
|
};
|
|
#if !defined(ENABLE_ITTI)
|
|
static void *
|
|
sigh (void *arg);
|
|
#endif
|
|
void
|
|
oai_shutdown (void);
|
|
|
|
void reset_opp_meas_oaisim (void);
|
|
|
|
void
|
|
help (void)
|
|
{
|
|
printf ("Usage: oaisim -h -a -F -C tdd_config -K [log_file] -V [vcd_file] -R N_RB_DL -e -x transmission_mode -m target_dl_mcs -r(ate_adaptation) -n n_frames -s snr_dB -k ricean_factor -t max_delay -f forgetting factor -A channel_model -z cooperation_flag -u nb_local_ue -U UE mobility -b nb_local_enb -B eNB_mobility -M ethernet_flag -p nb_master -g multicast_group -l log_level -c ocg_enable -T traffic model -D multicast network device\n");
|
|
|
|
printf ("-h provides this help message!\n");
|
|
printf ("-a Activates PHY abstraction mode\n");
|
|
printf ("-A set the multipath channel simulation, options are: SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr,Rayleigh1_anticorr, Rice8,, Rice1, AWGN \n");
|
|
printf ("-b Set the number of local eNB\n");
|
|
printf ("-B Set the mobility model for eNB, options are: STATIC, RWP, RWALK, \n");
|
|
printf ("-c [1,2,3,4] Activate the config generator (OCG) to process the scenario descriptor, or give the scenario manually: -c template_1.xml \n");
|
|
printf ("-C [0-6] Sets TDD configuration\n");
|
|
printf ("-e Activates extended prefix mode\n");
|
|
printf ("-E Random number generator seed\n");
|
|
printf ("-f Set the forgetting factor for time-variation\n");
|
|
printf ("-F Activates FDD transmission (TDD is default)\n");
|
|
printf ("-g Set multicast group ID (0,1,2,3) - valid if M is set\n");
|
|
printf ("-G Enable background traffic \n");
|
|
printf ("-H Enable handover operation (default disabled) \n");
|
|
printf ("-I Enable CLI interface (to connect use telnet localhost 1352)\n");
|
|
printf ("-k Set the Ricean factor (linear)\n");
|
|
printf ("-K [log_file] Enable ITTI logging into log_file\n");
|
|
printf ("-l Set the global log level (8:trace, 7:debug, 6:info, 4:warn, 3:error) \n");
|
|
printf ("-L [0-1] 0 to disable new link adaptation, 1 to enable new link adapatation\n");
|
|
printf ("-m Gives a fixed DL mcs for eNB scheduler\n");
|
|
printf ("-M Set the machine ID for Ethernet-based emulation\n");
|
|
printf ("-n Set the number of frames for the simulation\n");
|
|
printf ("-O [enb_conf_file] eNB configuration file name\n");
|
|
printf ("-p Set the total number of machine in emulation - valid if M is set\n");
|
|
printf ("-P [trace type] Enable protocol analyzer. Possible values for OPT:\n");
|
|
printf (" - wireshark: Enable tracing of layers above PHY using an UDP socket\n");
|
|
printf (" - pcap: Enable tracing of layers above PHY to a pcap file\n");
|
|
printf (" - tshark: Not implemented yet\n");
|
|
printf ("-q Enable Openair performance profiler \n");
|
|
printf ("-Q Activate and set the MBMS service: 0 : not used (default eMBMS disabled), 1: eMBMS and RRC Connection enabled, 2: eMBMS relaying and RRC Connection enabled, 3: eMBMS enabled, RRC Connection disabled, 4: eMBMS relaying enabled, RRC Connection disabled\n");
|
|
printf ("-R [6,15,25,50,75,100] Sets N_RB_DL\n");
|
|
printf ("-r Activates rate adaptation (DL for now)\n");
|
|
printf ("-s snr_dB set a fixed (average) SNR, this deactivates the openair channel model generator (OCM)\n");
|
|
printf ("-S snir_dB set a fixed (average) SNIR, this deactivates the openair channel model generator (OCM)\n");
|
|
printf ("-t Gives a fixed UL mcs for eNB scheduler\n");
|
|
printf ("-T activate the traffic generator. Valide options are m2m,scbr,mcbr,bcbr,auto_pilot,bicycle_race,open_arena,team_fortress,m2m_traffic,auto_pilot_l,auto_pilot_m,auto_pilot_h,auto_pilot_e,virtual_game_l,virtual_game_m,virtual_game_h,virtual_game_f,alarm_humidity,alarm_smoke,alarm_temperature,openarena_dl,openarena_ul,voip_g711,voip_g729,video_vbr_10mbps,video_vbr_4mbps,video_vbr_2mbp,video_vbr_768kbps,video_vbr_384kbps,video_vbr_192kpbs,background_users\n");
|
|
printf ("-u Set the number of local UE\n");
|
|
printf ("-U Set the mobility model for UE, options are: STATIC, RWP, RWALK\n");
|
|
printf ("-V [vcd_file] Enable VCD dump into vcd_file\n");
|
|
printf ("-w number of CBA groups, if not specified or zero, CBA is inactive\n");
|
|
#ifdef SMBV
|
|
printf ("-W IP address to connect to Rohde&Schwarz SMBV100A and configure SMBV from config file. -W0 uses default IP 192.168.12.201\n");
|
|
#else
|
|
printf ("-W [Rohde&Schwarz SMBV100A functions disabled. Recompile with SMBV=1]\n");
|
|
#endif
|
|
printf ("-x deprecated. Set the transmission mode in config file!\n");
|
|
printf ("-y Set the number of receive antennas at the UE (1 or 2)\n");
|
|
printf ("-Y Set the global log verbosity (none, low, medium, high, full) \n");
|
|
printf ("-z Set the cooperation flag (0 for no cooperation, 1 for delay diversity and 2 for distributed alamouti\n");
|
|
printf ("-Z Reserved\n");
|
|
printf ("--xforms Activate the grapical scope\n");
|
|
|
|
#if T_TRACER
|
|
printf ("--T_port [port] use given port\n");
|
|
printf ("--T_nowait don't wait for tracer, start immediately\n");
|
|
printf ("--T_dont_fork to ease debugging with gdb\n");
|
|
#endif
|
|
}
|
|
|
|
pthread_t log_thread;
|
|
|
|
void
|
|
log_thread_init (void)
|
|
{
|
|
//create log_list
|
|
//log_list_init(&log_list);
|
|
#ifndef LOG_NO_THREAD
|
|
|
|
log_shutdown = 0;
|
|
|
|
if ((pthread_mutex_init (&log_lock, NULL) != 0)
|
|
|| (pthread_cond_init (&log_notify, NULL) != 0)) {
|
|
return;
|
|
}
|
|
|
|
if (pthread_create (&log_thread, NULL, log_thread_function, (void*) NULL)
|
|
!= 0) {
|
|
log_thread_finalize ();
|
|
return;
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
//Call it after the last LOG call
|
|
int
|
|
log_thread_finalize (void)
|
|
{
|
|
int err = 0;
|
|
|
|
#ifndef LOG_NO_THREAD
|
|
|
|
if (pthread_mutex_lock (&log_lock) != 0) {
|
|
return -1;
|
|
}
|
|
|
|
log_shutdown = 1;
|
|
|
|
/* Wake up LOG thread */
|
|
if ((pthread_cond_broadcast (&log_notify) != 0)
|
|
|| (pthread_mutex_unlock (&log_lock) != 0)) {
|
|
err = -1;
|
|
}
|
|
|
|
if (pthread_join (log_thread, NULL) != 0) {
|
|
err = -1;
|
|
}
|
|
|
|
if (pthread_mutex_unlock (&log_lock) != 0) {
|
|
err = -1;
|
|
}
|
|
|
|
if (!err) {
|
|
//log_list_free(&log_list);
|
|
pthread_mutex_lock (&log_lock);
|
|
pthread_mutex_destroy (&log_lock);
|
|
pthread_cond_destroy (&log_notify);
|
|
}
|
|
|
|
#endif
|
|
|
|
return err;
|
|
}
|
|
|
|
#if defined(ENABLE_ITTI)
|
|
static void set_cli_start(module_id_t module_idP, uint8_t start)
|
|
{
|
|
if (module_idP < NB_eNB_INST) {
|
|
oai_emulation.info.cli_start_enb[module_idP] = start;
|
|
} else {
|
|
oai_emulation.info.cli_start_ue[module_idP - NB_eNB_INST] = start;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifdef OPENAIR2
|
|
int omv_write(int pfd, node_list* enb_node_list, node_list* ue_node_list, Data_Flow_Unit omv_data)
|
|
{
|
|
module_id_t i, j;
|
|
omv_data.end = 0;
|
|
|
|
//omv_data.total_num_nodes = NB_UE_INST + NB_eNB_INST;
|
|
for (i = 0; i < NB_eNB_INST; i++) {
|
|
if (enb_node_list != NULL) {
|
|
omv_data.geo[i].x = (enb_node_list->node->x_pos < 0.0) ? 0.0 : enb_node_list->node->x_pos;
|
|
omv_data.geo[i].y = (enb_node_list->node->y_pos < 0.0) ? 0.0 : enb_node_list->node->y_pos;
|
|
omv_data.geo[i].z = 1.0;
|
|
omv_data.geo[i].mobility_type = oai_emulation.info.omg_model_enb;
|
|
omv_data.geo[i].node_type = 0; //eNB
|
|
enb_node_list = enb_node_list->next;
|
|
omv_data.geo[i].Neighbors = 0;
|
|
|
|
for (j = NB_eNB_INST; j < NB_UE_INST + NB_eNB_INST; j++) {
|
|
if (is_UE_active (i, j - NB_eNB_INST) == 1) {
|
|
omv_data.geo[i].Neighbor[omv_data.geo[i].Neighbors] = j;
|
|
omv_data.geo[i].Neighbors++;
|
|
LOG_D(
|
|
OMG,
|
|
"[eNB %d][UE %d] is_UE_active(i,j) %d geo (x%d, y%d) num neighbors %d\n", i, j-NB_eNB_INST, is_UE_active(i,j-NB_eNB_INST), omv_data.geo[i].x, omv_data.geo[i].y, omv_data.geo[i].Neighbors);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = NB_eNB_INST; i < NB_UE_INST + NB_eNB_INST; i++) {
|
|
if (ue_node_list != NULL) {
|
|
omv_data.geo[i].x = (ue_node_list->node->x_pos < 0.0) ? 0.0 : ue_node_list->node->x_pos;
|
|
omv_data.geo[i].y = (ue_node_list->node->y_pos < 0.0) ? 0.0 : ue_node_list->node->y_pos;
|
|
omv_data.geo[i].z = 1.0;
|
|
omv_data.geo[i].mobility_type = oai_emulation.info.omg_model_ue;
|
|
omv_data.geo[i].node_type = 1; //UE
|
|
//trial
|
|
omv_data.geo[i].state = 1;
|
|
omv_data.geo[i].rnti = 88;
|
|
omv_data.geo[i].connected_eNB = 0;
|
|
omv_data.geo[i].RSRP = 66;
|
|
omv_data.geo[i].RSRQ = 55;
|
|
omv_data.geo[i].Pathloss = 44;
|
|
omv_data.geo[i].RSSI[0] = 33;
|
|
omv_data.geo[i].RSSI[1] = 22;
|
|
|
|
if ((sizeof(omv_data.geo[0].RSSI) / sizeof(omv_data.geo[0].RSSI[0])) > 2) {
|
|
omv_data.geo[i].RSSI[2] = 11;
|
|
}
|
|
|
|
ue_node_list = ue_node_list->next;
|
|
omv_data.geo[i].Neighbors = 0;
|
|
|
|
for (j = 0; j < NB_eNB_INST; j++) {
|
|
if (is_UE_active (j, i - NB_eNB_INST) == 1) {
|
|
omv_data.geo[i].Neighbor[omv_data.geo[i].Neighbors] = j;
|
|
omv_data.geo[i].Neighbors++;
|
|
LOG_D(
|
|
OMG,
|
|
"[UE %d][eNB %d] is_UE_active %d geo (x%d, y%d) num neighbors %d\n", i-NB_eNB_INST, j, is_UE_active(j,i-NB_eNB_INST), omv_data.geo[i].x, omv_data.geo[i].y, omv_data.geo[i].Neighbors);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LOG_E(OMG, "pfd %d \n", pfd);
|
|
|
|
if (write (pfd, &omv_data, sizeof(struct Data_Flow_Unit)) == -1)
|
|
perror ("write omv failed");
|
|
|
|
return 1;
|
|
}
|
|
|
|
void omv_end(int pfd, Data_Flow_Unit omv_data)
|
|
{
|
|
omv_data.end = 1;
|
|
|
|
if (write (pfd, &omv_data, sizeof(struct Data_Flow_Unit)) == -1)
|
|
perror ("write omv failed");
|
|
}
|
|
#endif
|
|
|
|
#ifdef OPENAIR2
|
|
int pfd[2]; // fd for omv : fixme: this could be a local var
|
|
#endif
|
|
|
|
#ifdef OPENAIR2
|
|
static Data_Flow_Unit omv_data;
|
|
#endif //ALU
|
|
static module_id_t UE_inst = 0;
|
|
static module_id_t eNB_inst = 0;
|
|
|
|
Packet_OTG_List_t *otg_pdcp_buffer;
|
|
|
|
typedef enum l2l1_task_state_e {
|
|
L2L1_WAITTING, L2L1_RUNNING, L2L1_TERMINATED,
|
|
} l2l1_task_state_t;
|
|
|
|
l2l1_task_state_t l2l1_state = L2L1_WAITTING;
|
|
|
|
extern openair0_timestamp current_eNB_rx_timestamp[NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
|
|
extern openair0_timestamp current_UE_rx_timestamp[NUMBER_OF_UE_MAX][MAX_NUM_CCs];
|
|
extern openair0_timestamp last_eNB_rx_timestamp[NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
|
|
extern openair0_timestamp last_UE_rx_timestamp[NUMBER_OF_UE_MAX][MAX_NUM_CCs];
|
|
|
|
/*------------------------------------------------------------------------------*/
|
|
void *
|
|
l2l1_task (void *args_p)
|
|
{
|
|
|
|
int CC_id;
|
|
|
|
// Framing variables
|
|
int32_t sf;
|
|
|
|
char fname[64], vname[64];
|
|
|
|
//#ifdef XFORMS
|
|
// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
|
|
// at eNB 0, an UL scope for every UE
|
|
FD_lte_phy_scope_ue *form_ue[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
|
|
FD_lte_phy_scope_enb *form_enb[NUMBER_OF_UE_MAX];
|
|
char title[255];
|
|
char xname[32] = "oaisim";
|
|
int xargc = 1;
|
|
char *xargv[1];
|
|
//#endif
|
|
|
|
#undef PRINT_STATS /* this undef is to avoid gcc warnings */
|
|
#define PRINT_STATS
|
|
#ifdef PRINT_STATS
|
|
int len;
|
|
FILE *UE_stats[NUMBER_OF_UE_MAX];
|
|
FILE *UE_stats_th[NUMBER_OF_UE_MAX];
|
|
FILE *eNB_stats[NUMBER_OF_eNB_MAX];
|
|
FILE *eNB_avg_thr;
|
|
FILE *eNB_l2_stats;
|
|
char UE_stats_filename[255];
|
|
char eNB_stats_filename[255];
|
|
char UE_stats_th_filename[255];
|
|
char eNB_stats_th_filename[255];
|
|
#endif
|
|
|
|
|
|
if (xforms==1) {
|
|
xargv[0] = xname;
|
|
fl_initialize (&xargc, xargv, NULL, 0, 0);
|
|
eNB_inst = 0;
|
|
for (UE_inst = 0; UE_inst < NB_UE_INST; UE_inst++) {
|
|
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
|
|
// DL scope at UEs
|
|
form_ue[CC_id][UE_inst] = create_lte_phy_scope_ue();
|
|
sprintf (title, "LTE DL SCOPE eNB %d to UE %d CC_id %d", eNB_inst, UE_inst, CC_id);
|
|
fl_show_form (form_ue[CC_id][UE_inst]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
|
|
|
|
if (PHY_vars_UE_g[UE_inst][CC_id]->use_ia_receiver == 1) {
|
|
fl_set_button(form_ue[CC_id][UE_inst]->button_0,1);
|
|
fl_set_object_label(form_ue[CC_id][UE_inst]->button_0, "IA Receiver ON");
|
|
fl_set_object_color(form_ue[CC_id][UE_inst]->button_0, FL_GREEN, FL_GREEN);
|
|
}
|
|
|
|
}
|
|
// UL scope at eNB 0
|
|
form_enb[UE_inst] = create_lte_phy_scope_enb();
|
|
sprintf (title, "LTE UL SCOPE UE %d to eNB %d", UE_inst, eNB_inst);
|
|
fl_show_form (form_enb[UE_inst]->lte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef PRINT_STATS
|
|
|
|
for (UE_inst=0; UE_inst<NB_UE_INST; UE_inst++) {
|
|
sprintf(UE_stats_filename,"UE_stats%d.txt",UE_inst);
|
|
UE_stats[UE_inst] = fopen (UE_stats_filename, "w");
|
|
}
|
|
|
|
for (eNB_inst=0; eNB_inst<NB_eNB_INST; eNB_inst++) {
|
|
sprintf(eNB_stats_filename,"eNB_stats%d.txt",eNB_inst);
|
|
eNB_stats[eNB_inst] = fopen (eNB_stats_filename, "w");
|
|
}
|
|
|
|
if(abstraction_flag==0) {
|
|
for (UE_inst=0; UE_inst<NB_UE_INST; UE_inst++) {
|
|
/* TODO: transmission_mode is defined per CC, we set 0 for now */
|
|
sprintf(UE_stats_th_filename,"UE_stats_th%d_tx%d.txt",UE_inst,oai_emulation.info.transmission_mode[0]);
|
|
UE_stats_th[UE_inst] = fopen (UE_stats_th_filename, "w");
|
|
}
|
|
|
|
/* TODO: transmission_mode is defined per CC, we set 0 for now */
|
|
sprintf(eNB_stats_th_filename,"eNB_stats_th_tx%d.txt",oai_emulation.info.transmission_mode[0]);
|
|
eNB_avg_thr = fopen (eNB_stats_th_filename, "w");
|
|
} else {
|
|
for (UE_inst=0; UE_inst<NB_UE_INST; UE_inst++) {
|
|
/* TODO: transmission_mode is defined per CC, we set 0 for now */
|
|
sprintf(UE_stats_th_filename,"UE_stats_abs_th%d_tx%d.txt",UE_inst,oai_emulation.info.transmission_mode[0]);
|
|
UE_stats_th[UE_inst] = fopen (UE_stats_th_filename, "w");
|
|
}
|
|
|
|
/* TODO: transmission_mode is defined per CC, we set 0 for now */
|
|
sprintf(eNB_stats_th_filename,"eNB_stats_abs_th_tx%d.txt",oai_emulation.info.transmission_mode[0]);
|
|
eNB_avg_thr = fopen (eNB_stats_th_filename, "w");
|
|
}
|
|
|
|
#ifdef OPENAIR2
|
|
eNB_l2_stats = fopen ("eNB_l2_stats.txt", "w");
|
|
LOG_I(EMU,"eNB_l2_stats=%p\n", eNB_l2_stats);
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#if defined(ENABLE_ITTI)
|
|
MessageDef *message_p = NULL;
|
|
const char *msg_name = NULL;
|
|
int result;
|
|
|
|
itti_mark_task_ready (TASK_L2L1);
|
|
LOG_I(EMU, "TASK_L2L1 is READY\n");
|
|
|
|
if ((oai_emulation.info.nb_enb_local > 0) &&
|
|
(oai_emulation.info.node_function[0] < NGFI_RAU_IF4p5)) {
|
|
/* Wait for the initialize message */
|
|
do {
|
|
if (message_p != NULL) {
|
|
result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
|
|
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
|
}
|
|
|
|
itti_receive_msg (TASK_L2L1, &message_p);
|
|
msg_name = ITTI_MSG_NAME (message_p);
|
|
LOG_I(EMU, "TASK_L2L1 received %s in state L2L1_WAITTING\n", msg_name);
|
|
|
|
switch (ITTI_MSG_ID(message_p)) {
|
|
case INITIALIZE_MESSAGE:
|
|
l2l1_state = L2L1_RUNNING;
|
|
start_eNB = 1;
|
|
break;
|
|
|
|
case ACTIVATE_MESSAGE:
|
|
set_cli_start(ITTI_MSG_INSTANCE (message_p), 1);
|
|
break;
|
|
|
|
case DEACTIVATE_MESSAGE:
|
|
set_cli_start(ITTI_MSG_INSTANCE (message_p), 0);
|
|
break;
|
|
|
|
case TERMINATE_MESSAGE:
|
|
l2l1_state = L2L1_TERMINATED;
|
|
break;
|
|
|
|
default:
|
|
LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
|
|
break;
|
|
}
|
|
} while (l2l1_state == L2L1_WAITTING);
|
|
|
|
result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
|
|
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
|
}
|
|
|
|
#endif
|
|
module_id_t enb_id;
|
|
module_id_t UE_id;
|
|
for (enb_id = 0; enb_id < NB_eNB_INST; enb_id++)
|
|
mac_xface->mrbch_phy_sync_failure (enb_id, 0, enb_id);
|
|
|
|
if (abstraction_flag == 1) {
|
|
for (UE_id = 0; UE_id < NB_UE_INST; UE_id++)
|
|
mac_xface->dl_phy_sync_success (UE_id, 0, 0,1); //UE_id%NB_eNB_INST);
|
|
}
|
|
|
|
start_meas (&oaisim_stats);
|
|
|
|
for (frame = 0;
|
|
(l2l1_state != L2L1_TERMINATED) &&
|
|
((oai_emulation.info.n_frames_flag == 0) ||
|
|
(frame < oai_emulation.info.n_frames));
|
|
frame++) {
|
|
|
|
#if defined(ENABLE_ITTI)
|
|
|
|
do {
|
|
// Checks if a message has been sent to L2L1 task
|
|
itti_poll_msg (TASK_L2L1, &message_p);
|
|
|
|
if (message_p != NULL) {
|
|
msg_name = ITTI_MSG_NAME (message_p);
|
|
LOG_I(EMU, "TASK_L2L1 received %s\n", msg_name);
|
|
|
|
switch (ITTI_MSG_ID(message_p)) {
|
|
case ACTIVATE_MESSAGE:
|
|
set_cli_start(ITTI_MSG_INSTANCE (message_p), 1);
|
|
break;
|
|
|
|
case DEACTIVATE_MESSAGE:
|
|
set_cli_start(ITTI_MSG_INSTANCE (message_p), 0);
|
|
break;
|
|
|
|
case TERMINATE_MESSAGE:
|
|
l2l1_state = L2L1_TERMINATED;
|
|
break;
|
|
|
|
case MESSAGE_TEST:
|
|
break;
|
|
|
|
default:
|
|
LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
|
|
break;
|
|
}
|
|
|
|
result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
|
|
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
|
}
|
|
} while(message_p != NULL);
|
|
|
|
#endif
|
|
|
|
//Run the aperiodic user-defined events
|
|
if (oai_emulation.info.oeh_enabled == 1)
|
|
execute_events (frame);
|
|
|
|
if (ue_connection_test == 1) {
|
|
if ((frame % 20) == 0) {
|
|
snr_dB += snr_direction;
|
|
sinr_dB -= snr_direction;
|
|
}
|
|
|
|
if (snr_dB == -20) {
|
|
snr_direction = snr_step;
|
|
} else if (snr_dB == 20) {
|
|
snr_direction = -snr_step;
|
|
}
|
|
}
|
|
|
|
oai_emulation.info.frame = frame;
|
|
//oai_emulation.info.time_ms += 1;
|
|
oai_emulation.info.time_s += 0.01; // emu time in s, each frame lasts for 10 ms // JNote: TODO check the coherency of the time and frame (I corrected it to 10 (instead of 0.01)
|
|
|
|
update_omg (frame); // frequency is defined in the omg_global params configurable by the user
|
|
update_omg_ocm ();
|
|
|
|
#ifdef OPENAIR2
|
|
|
|
// check if pipe is still open
|
|
if ((oai_emulation.info.omv_enabled == 1)) {
|
|
omv_write (pfd[1], enb_node_list, ue_node_list, omv_data);
|
|
}
|
|
|
|
#endif
|
|
|
|
update_ocm ();
|
|
|
|
for (sf = 0; sf < 10; sf++) {
|
|
LOG_D(EMU,"************************* Subframe %d\n",sf);
|
|
|
|
start_meas (&oaisim_stats_f);
|
|
|
|
wait_for_slot_isr ();
|
|
|
|
#if defined(ENABLE_ITTI)
|
|
itti_update_lte_time(frame % MAX_FRAME_NUMBER, sf<<1);
|
|
#endif
|
|
|
|
oai_emulation.info.time_ms = frame * 10 + sf;
|
|
|
|
#ifdef PROC
|
|
|
|
if(Channel_Flag==1)
|
|
Channel_Func(s_re2,s_im2,r_re2,r_im2,r_re02,r_im02,r_re0_d,r_im0_d,r_re0_u,r_im0_u,eNB2UE,UE2eNB,enb_data,ue_data,abstraction_flag,frame_parms,sf<<1);
|
|
|
|
if(Channel_Flag==0)
|
|
#endif
|
|
{ // SUBFRAME INNER PART
|
|
#if defined(ENABLE_ITTI)
|
|
log_set_instance_type (LOG_INSTANCE_ENB);
|
|
#endif
|
|
|
|
clear_eNB_transport_info (oai_emulation.info.nb_enb_local);
|
|
|
|
int all_done=0;
|
|
while (all_done==0) {
|
|
int i;
|
|
all_done = 1;
|
|
for (i = oai_emulation.info.first_enb_local;
|
|
i < oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local;
|
|
i++)
|
|
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++)
|
|
if (last_eNB_rx_timestamp[i][CC_id] != current_eNB_rx_timestamp[i][CC_id]) {
|
|
all_done = 0;
|
|
break;
|
|
}
|
|
if (all_done == 1)
|
|
for (i = 0; i < NB_UE_INST; i++)
|
|
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++)
|
|
if (last_UE_rx_timestamp[i][CC_id] != current_UE_rx_timestamp[i][CC_id]) {
|
|
all_done = 0;
|
|
break;
|
|
}
|
|
if (all_done == 0)
|
|
usleep(500);
|
|
}
|
|
|
|
// increment timestamps
|
|
for (eNB_inst = oai_emulation.info.first_enb_local;
|
|
(eNB_inst
|
|
< (oai_emulation.info.first_enb_local
|
|
+ oai_emulation.info.nb_enb_local));
|
|
eNB_inst++) {
|
|
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++)
|
|
current_eNB_rx_timestamp[eNB_inst][CC_id] += PHY_vars_eNB_g[eNB_inst][CC_id]->frame_parms.samples_per_tti;
|
|
}
|
|
for (UE_inst = 0; UE_inst<NB_UE_INST;UE_inst++) {
|
|
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++)
|
|
current_UE_rx_timestamp[UE_inst][CC_id] += PHY_vars_UE_g[UE_inst][CC_id]->frame_parms.samples_per_tti;
|
|
}
|
|
|
|
for (eNB_inst = oai_emulation.info.first_enb_local;
|
|
(eNB_inst
|
|
< (oai_emulation.info.first_enb_local
|
|
+ oai_emulation.info.nb_enb_local));
|
|
eNB_inst++) {
|
|
if (oai_emulation.info.cli_start_enb[eNB_inst] != 0) {
|
|
|
|
/*
|
|
LOG_D(EMU,
|
|
"PHY procedures eNB %d for frame %d, subframe %d TDD %d/%d Nid_cell %d\n",
|
|
eNB_inst,
|
|
frame % MAX_FRAME_NUMBER,
|
|
sf,
|
|
PHY_vars_eNB_g[eNB_inst][0]->frame_parms.frame_type,
|
|
PHY_vars_eNB_g[eNB_inst][0]->frame_parms.tdd_config,
|
|
PHY_vars_eNB_g[eNB_inst][0]->frame_parms.Nid_cell);
|
|
|
|
*/
|
|
#ifdef OPENAIR2
|
|
//Application: traffic gen
|
|
update_otg_eNB (eNB_inst, oai_emulation.info.time_ms);
|
|
|
|
//IP/OTG to PDCP and PDCP to IP operation
|
|
// pdcp_run (frame, 1, 0, eNB_inst); //PHY_vars_eNB_g[eNB_id]->Mod_id
|
|
#endif
|
|
|
|
|
|
#ifdef PRINT_STATS
|
|
|
|
if((sf==9) && frame%10==0)
|
|
if(eNB_avg_thr)
|
|
fprintf(eNB_avg_thr,"%d %d\n",PHY_vars_eNB_g[eNB_inst][0]->proc.proc_rxtx[sf&1].frame_tx,
|
|
(PHY_vars_eNB_g[eNB_inst][0]->total_system_throughput)/((PHY_vars_eNB_g[eNB_inst][0]->proc.proc_rxtx[sf&1].frame_tx+1)*10));
|
|
|
|
if (eNB_stats[eNB_inst]) {
|
|
len = dump_eNB_stats(PHY_vars_eNB_g[eNB_inst][0], stats_buffer, 0);
|
|
rewind (eNB_stats[eNB_inst]);
|
|
fwrite (stats_buffer, 1, len, eNB_stats[eNB_inst]);
|
|
fflush(eNB_stats[eNB_inst]);
|
|
}
|
|
|
|
#ifdef OPENAIR2
|
|
|
|
if (eNB_l2_stats) {
|
|
len = dump_eNB_l2_stats (stats_buffer, 0);
|
|
rewind (eNB_l2_stats);
|
|
fwrite (stats_buffer, 1, len, eNB_l2_stats);
|
|
fflush(eNB_l2_stats);
|
|
}
|
|
|
|
#endif
|
|
#endif
|
|
}
|
|
}// eNB_inst loop
|
|
|
|
// Call ETHERNET emulation here
|
|
//emu_transport (frame, last_slot, next_slot, direction, oai_emulation.info.frame_type, ethernet_flag);
|
|
|
|
#if defined(ENABLE_ITTI)
|
|
log_set_instance_type (LOG_INSTANCE_UE);
|
|
#endif
|
|
|
|
|
|
/*
|
|
clear_UE_transport_info (oai_emulation.info.nb_ue_local);
|
|
clear_UE_transport_info (oai_emulation.info.nb_ue_local);
|
|
|
|
for (UE_inst = oai_emulation.info.first_ue_local;
|
|
(UE_inst < (oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local));
|
|
UE_inst++) {
|
|
if (oai_emulation.info.cli_start_ue[UE_inst] != 0) {
|
|
#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
|
|
|
|
#else
|
|
|
|
if (frame >= (UE_inst * 20)) // activate UE only after 20*UE_id frames so that different UEs turn on separately
|
|
#endif
|
|
{
|
|
LOG_D(EMU,
|
|
"PHY procedures UE %d for frame %d, slot %d (subframe TX %d, RX %d)\n",
|
|
UE_inst, frame % MAX_FRAME_NUMBER, slot, next_slot >> 1,
|
|
last_slot >> 1);
|
|
|
|
if (PHY_vars_UE_g[UE_inst][0]->UE_mode[0]
|
|
!= NOT_SYNCHED) {
|
|
if (frame > 0) {
|
|
PHY_vars_UE_g[UE_inst][0]->frame_rx = frame % MAX_FRAME_NUMBER;
|
|
PHY_vars_UE_g[UE_inst][0]->slot_rx = last_slot;
|
|
PHY_vars_UE_g[UE_inst][0]->slot_tx = next_slot;
|
|
|
|
if (next_slot > 1)
|
|
PHY_vars_UE_g[UE_inst][0]->frame_tx = frame % MAX_FRAME_NUMBER;
|
|
else
|
|
PHY_vars_UE_g[UE_inst][0]->frame_tx = (frame + 1) % MAX_FRAME_NUMBER;
|
|
#ifdef OPENAIR2
|
|
//Application
|
|
update_otg_UE (UE_inst, oai_emulation.info.time_ms);
|
|
|
|
//Access layer
|
|
// PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE_inst, ENB_FLAG_NO, NOT_A_RNTI, frame, next_slot>>1, 0);
|
|
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE_inst, 0, ENB_FLAG_NO, NOT_A_RNTI, frame % MAX_FRAME_NUMBER, next_slot);
|
|
pdcp_run (&ctxt);
|
|
#endif
|
|
|
|
for (CC_id = 0; CC_id < MAX_NUM_CCs;
|
|
CC_id++) {
|
|
phy_procedures_UE_lte (
|
|
PHY_vars_UE_g[UE_inst][CC_id],
|
|
0, abstraction_flag,
|
|
normal_txrx, no_relay,
|
|
NULL);
|
|
}
|
|
|
|
ue_data[UE_inst]->tx_power_dBm =
|
|
PHY_vars_UE_g[UE_inst][0]->tx_power_dBm;
|
|
}
|
|
} else {
|
|
if (abstraction_flag == 1) {
|
|
LOG_E(EMU,
|
|
"sync not supported in abstraction mode (UE%d,mode%d)\n",
|
|
UE_inst,
|
|
PHY_vars_UE_g[UE_inst][0]->UE_mode[0]);
|
|
exit (-1);
|
|
}
|
|
|
|
if ((frame > 0)
|
|
&& (last_slot
|
|
== (LTE_SLOTS_PER_FRAME
|
|
- 2))) {
|
|
initial_sync (PHY_vars_UE_g[UE_inst][0],
|
|
normal_txrx);
|
|
|
|
}
|
|
}
|
|
|
|
#ifdef PRINT_STATS
|
|
|
|
if(last_slot==2 && frame%10==0) {
|
|
if (UE_stats_th[UE_inst]) {
|
|
fprintf(UE_stats_th[UE_inst],"%d %d\n",frame%MAX_FRAME_NUMBER, PHY_vars_UE_g[UE_inst][0]->bitrate[0]/1000);
|
|
}
|
|
}
|
|
|
|
if (UE_stats[UE_inst]) {
|
|
len = dump_ue_stats (PHY_vars_UE_g[UE_inst][0], stats_buffer, 0, normal_txrx, 0);
|
|
rewind (UE_stats[UE_inst]);
|
|
fwrite (stats_buffer, 1, len, UE_stats[UE_inst]);
|
|
fflush(UE_stats[UE_inst]);
|
|
}
|
|
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef Rel10
|
|
|
|
for (RN_id=oai_emulation.info.first_rn_local;
|
|
RN_id<oai_emulation.info.first_rn_local+oai_emulation.info.nb_rn_local;
|
|
RN_id++) {
|
|
// UE id and eNB id of the RN
|
|
UE_inst= oai_emulation.info.first_ue_local+oai_emulation.info.nb_ue_local + RN_id;// NB_UE_INST + RN_id
|
|
eNB_inst= oai_emulation.info.first_enb_local+oai_emulation.info.nb_enb_local + RN_id;// NB_eNB_INST + RN_id
|
|
|
|
// currently only works in FDD
|
|
if (oai_emulation.info.eMBMS_active_state == 4) {
|
|
r_type = multicast_relay;
|
|
//LOG_I(EMU,"Activating the multicast relaying\n");
|
|
} else {
|
|
LOG_E(EMU,"Not supported eMBMS option when relaying is enabled %d\n", r_type);
|
|
exit(-1);
|
|
}
|
|
|
|
PHY_vars_RN_g[RN_id]->frame = frame % MAX_FRAME_NUMBER;
|
|
|
|
if ( oai_emulation.info.frame_type == 0) {
|
|
// RN == UE
|
|
if (frame>0) {
|
|
if (PHY_vars_UE_g[UE_inst][0]->UE_mode[0] != NOT_SYNCHED) {
|
|
LOG_D(EMU,"[RN %d] PHY procedures UE %d for frame %d, slot %d (subframe TX %d, RX %d)\n",
|
|
RN_id, UE_inst, frame, slot, next_slot >> 1,last_slot>>1);
|
|
PHY_vars_UE_g[UE_inst][0]->frame_rx = frame % MAX_FRAME_NUMBER;
|
|
PHY_vars_UE_g[UE_inst][0]->slot_rx = last_slot;
|
|
PHY_vars_UE_g[UE_inst][0]->slot_tx = next_slot;
|
|
|
|
if (next_slot>1) PHY_vars_UE_g[UE_inst][0]->frame_tx = frame % MAX_FRAME_NUMBER;
|
|
else PHY_vars_UE_g[UE_inst][0]->frame_tx = (frame+1) % MAX_FRAME_NUMBER;
|
|
|
|
phy_procedures_UE_lte (PHY_vars_UE_g[UE_inst][0], 0, abstraction_flag,normal_txrx,
|
|
r_type, PHY_vars_RN_g[RN_id]);
|
|
} else if (last_slot == (LTE_SLOTS_PER_FRAME-2)) {
|
|
initial_sync(PHY_vars_UE_g[UE_inst][0],normal_txrx);
|
|
}
|
|
}
|
|
|
|
emu_transport (frame % MAX_FRAME_NUMBER, sf<<1, ((sf+4)%10)<<1, subframe_select(&PHY_vars_eNB_g[0][0]->frame_parms,sf),
|
|
oai_emulation.info.frame_type[0], ethernet_flag);
|
|
|
|
start_meas (&dl_chan_stats);
|
|
|
|
for (UE_inst = 0; UE_inst < NB_UE_INST; UE_inst++)
|
|
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
|
//#warning figure out what to do with UE frame_parms during initial_sync
|
|
do_DL_sig (r_re0,
|
|
r_im0,
|
|
r_re,
|
|
r_im,
|
|
s_re,
|
|
s_im,
|
|
eNB2UE,
|
|
enb_data,
|
|
ue_data,
|
|
PHY_vars_eNB_g[0][CC_id]->proc.proc_rxtx[sf&1].subframe_tx<<1,
|
|
abstraction_flag,
|
|
&PHY_vars_eNB_g[0][CC_id]->frame_parms,
|
|
UE_inst, CC_id);
|
|
do_DL_sig (r_re0,
|
|
r_im0,
|
|
r_re,
|
|
r_im,n
|
|
|
|
s_re,
|
|
s_im,
|
|
eNB2UE,
|
|
enb_data,
|
|
ue_data,
|
|
(PHY_vars_eNB_g[0][CC_id]->proc.proc_rxtx[sf&1].subframe_tx<<1)+1,
|
|
abstraction_flag,
|
|
&PHY_vars_eNB_g[0][CC_id]->frame_parms,
|
|
UE_inst, CC_id);
|
|
}
|
|
|
|
stop_meas (&dl_chan_stats);
|
|
|
|
|
|
start_meas (&ul_chan_stats);
|
|
|
|
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
|
//#warning figure out what to do with UE frame_parms during initial_sync
|
|
do_UL_sig (r_re0, r_im0, r_re, r_im, s_re, s_im, UE2eNB,
|
|
enb_data, ue_data,
|
|
PHY_vars_UE_g[0][CC_id]->proc.proc_rxtx[sf&1].subframe_tx<<1,
|
|
abstraction_flag,
|
|
&PHY_vars_eNB_g[0][CC_id]->frame_parms,
|
|
frame % MAX_FRAME_NUMBER, CC_id);
|
|
do_UL_sig (r_re0, r_im0, r_re, r_im, s_re, s_im, UE2eNB,
|
|
enb_data, ue_data,
|
|
(PHY_vars_UE_g[0][CC_id]->proc.proc_rxtx[sf&1].subframe_tx<<1)+1,
|
|
abstraction_flag,
|
|
&PHY_vars_eNB_g[0][CC_id]->frame_parms,
|
|
frame % MAX_FRAME_NUMBER, CC_id);
|
|
}
|
|
|
|
stop_meas (&ul_chan_stats);
|
|
|
|
*/
|
|
|
|
if ((sf == 0) && ((frame % MAX_FRAME_NUMBER) == 0) && (abstraction_flag == 0)
|
|
&& (oai_emulation.info.n_frames == 1)) {
|
|
|
|
write_output ("dlchan0.m",
|
|
"dlch0",
|
|
&(PHY_vars_UE_g[0][0]->common_vars.common_vars_rx_data_per_thread[0].dl_ch_estimates[0][0][0]),
|
|
(6
|
|
* (PHY_vars_UE_g[0][0]->frame_parms.ofdm_symbol_size)),
|
|
1, 1);
|
|
write_output ("dlchan1.m",
|
|
"dlch1",
|
|
&(PHY_vars_UE_g[0][0]->common_vars.common_vars_rx_data_per_thread[0].dl_ch_estimates[1][0][0]),
|
|
(6
|
|
* (PHY_vars_UE_g[0][0]->frame_parms.ofdm_symbol_size)),
|
|
1, 1);
|
|
write_output ("dlchan2.m",
|
|
"dlch2",
|
|
&(PHY_vars_UE_g[0][0]->common_vars.common_vars_rx_data_per_thread[0].dl_ch_estimates[2][0][0]),
|
|
(6
|
|
* (PHY_vars_UE_g[0][0]->frame_parms.ofdm_symbol_size)),
|
|
1, 1);
|
|
write_output ("pbch_rxF_comp0.m",
|
|
"pbch_comp0",
|
|
PHY_vars_UE_g[0][0]->pbch_vars[0]->rxdataF_comp[0],
|
|
6 * 12 * 4, 1, 1);
|
|
write_output ("pbch_rxF_llr.m", "pbch_llr",
|
|
PHY_vars_UE_g[0][0]->pbch_vars[0]->llr,
|
|
(frame_parms[0]->Ncp == 0) ? 1920 : 1728, 1,
|
|
4);
|
|
}
|
|
|
|
stop_meas (&oaisim_stats_f);
|
|
} // SUBFRAME INNER PART
|
|
|
|
|
|
}
|
|
/*
|
|
if ((frame >= 10) && (frame <= 11) && (abstraction_flag == 0)
|
|
#ifdef PROC
|
|
&&(Channel_Flag==0)
|
|
#endif
|
|
) {
|
|
sprintf (fname, "UEtxsig%d.m", frame % MAX_FRAME_NUMBER);
|
|
sprintf (vname, "txs%d", frame % MAX_FRAME_NUMBER);
|
|
write_output (fname,
|
|
vname,
|
|
PHY_vars_UE_g[0][0]->common_vars.txdata[0],
|
|
PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti
|
|
* 10,
|
|
1, 1);
|
|
sprintf (fname, "eNBtxsig%d.m", frame % MAX_FRAME_NUMBER);
|
|
sprintf (vname, "txs%d", frame % MAX_FRAME_NUMBER);
|
|
write_output (fname,
|
|
vname,
|
|
PHY_vars_eNB_g[0][0]->common_vars.txdata[0][0],
|
|
PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti
|
|
* 10,
|
|
1, 1);
|
|
sprintf (fname, "eNBtxsigF%d.m", frame % MAX_FRAME_NUMBER);
|
|
sprintf (vname, "txsF%d", frame % MAX_FRAME_NUMBER);
|
|
write_output (fname,
|
|
vname,
|
|
PHY_vars_eNB_g[0][0]->common_vars.txdataF[0][0],
|
|
PHY_vars_eNB_g[0][0]->frame_parms.symbols_per_tti
|
|
* PHY_vars_eNB_g[0][0]->frame_parms.ofdm_symbol_size,
|
|
1, 1);
|
|
sprintf (fname, "UErxsig%d.m", frame % MAX_FRAME_NUMBER);
|
|
sprintf (vname, "rxs%d", frame % MAX_FRAME_NUMBER);
|
|
write_output (fname,
|
|
vname,
|
|
PHY_vars_UE_g[0][0]->common_vars.rxdata[0],
|
|
PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti
|
|
* 10,
|
|
1, 1);
|
|
sprintf (fname, "eNBrxsig%d.m", frame % MAX_FRAME_NUMBER);
|
|
sprintf (vname, "rxs%d", frame % MAX_FRAME_NUMBER);
|
|
write_output (fname,
|
|
vname,
|
|
PHY_vars_eNB_g[0][0]->common_vars.rxdata[0][0],
|
|
PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti
|
|
* 10,
|
|
1, 1);
|
|
}
|
|
*/
|
|
|
|
//#ifdef XFORMS
|
|
if (xforms==1) {
|
|
eNB_inst = 0;
|
|
|
|
for (UE_inst = 0; UE_inst < NB_UE_INST; UE_inst++) {
|
|
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
|
|
phy_scope_UE(form_ue[CC_id][UE_inst],
|
|
PHY_vars_UE_g[UE_inst][CC_id],
|
|
eNB_inst,
|
|
UE_inst,
|
|
7);
|
|
}
|
|
|
|
phy_scope_eNB(form_enb[UE_inst],
|
|
PHY_vars_eNB_g[eNB_inst][0],
|
|
UE_inst);
|
|
|
|
}
|
|
}
|
|
//#endif
|
|
|
|
#ifdef SMBV
|
|
|
|
// Rohde&Schwarz SMBV100A vector signal generator
|
|
if ((frame % MAX_FRAME_NUMBER == config_frames[0]) || (frame % MAX_FRAME_NUMBER == config_frames[1]) || (frame % MAX_FRAME_NUMBER == config_frames[2]) || (frame % MAX_FRAME_NUMBER == config_frames[3])) {
|
|
smbv_frame_cnt++;
|
|
}
|
|
|
|
#endif
|
|
|
|
} // frame loop
|
|
|
|
stop_meas (&oaisim_stats);
|
|
oai_shutdown ();
|
|
|
|
#ifdef PRINT_STATS
|
|
|
|
for (UE_inst=0; UE_inst<NB_UE_INST; UE_inst++) {
|
|
if (UE_stats[UE_inst])
|
|
fclose (UE_stats[UE_inst]);
|
|
|
|
if(UE_stats_th[UE_inst])
|
|
fclose (UE_stats_th[UE_inst]);
|
|
}
|
|
|
|
for (eNB_inst=0; eNB_inst<NB_eNB_INST; eNB_inst++) {
|
|
if (eNB_stats[eNB_inst])
|
|
fclose (eNB_stats[eNB_inst]);
|
|
}
|
|
|
|
if (eNB_avg_thr)
|
|
fclose (eNB_avg_thr);
|
|
|
|
if (eNB_l2_stats)
|
|
fclose (eNB_l2_stats);
|
|
|
|
#endif
|
|
|
|
#if defined(ENABLE_ITTI)
|
|
itti_terminate_tasks(TASK_L2L1);
|
|
#endif
|
|
|
|
return NULL;
|
|
}
|
|
|
|
#if T_TRACER
|
|
int T_wait = 1; /* by default we wait for the tracer */
|
|
int T_port = 2021; /* default port to listen to to wait for the tracer */
|
|
int T_dont_fork = 0; /* default is to fork, see 'T_init' to understand */
|
|
#endif
|
|
|
|
/*------------------------------------------------------------------------------*/
|
|
int
|
|
main (int argc, char **argv)
|
|
{
|
|
|
|
clock_t t;
|
|
|
|
start_background_system();
|
|
|
|
#ifdef SMBV
|
|
// Rohde&Schwarz SMBV100A vector signal generator
|
|
strcpy(smbv_ip,DEFAULT_SMBV_IP);
|
|
#endif
|
|
|
|
#ifdef PROC
|
|
int node_id;
|
|
int port,Process_Flag=0,wgt,Channel_Flag=0,temp;
|
|
#endif
|
|
|
|
//default parameters
|
|
oai_emulation.info.n_frames = MAX_FRAME_NUMBER; //1024; //10;
|
|
oai_emulation.info.n_frames_flag = 0; //fixme
|
|
snr_dB = 30;
|
|
|
|
//Default values if not changed by the user in get_simulation_options();
|
|
pdcp_period = 1;
|
|
omg_period = 1;
|
|
//Clean ip rule table
|
|
for(int i =0; i<NUMBER_OF_UE_MAX; i++){
|
|
char command_line[100];
|
|
sprintf(command_line, "while ip rule del table %d; do true; done",i+201);
|
|
system(command_line);
|
|
}
|
|
// start thread for log gen
|
|
log_thread_init ();
|
|
|
|
init_oai_emulation (); // to initialize everything !!!
|
|
|
|
// get command-line options
|
|
get_simulation_options (argc, argv); //Command-line options
|
|
|
|
#if T_TRACER
|
|
T_init(T_port, T_wait, T_dont_fork);
|
|
#endif
|
|
|
|
// Initialize VCD LOG module
|
|
VCD_SIGNAL_DUMPER_INIT (oai_emulation.info.vcd_file);
|
|
|
|
#if !defined(ENABLE_ITTI)
|
|
pthread_t tid;
|
|
int err;
|
|
sigset_t sigblock;
|
|
sigemptyset (&sigblock);
|
|
sigaddset (&sigblock, SIGHUP);
|
|
sigaddset (&sigblock, SIGINT);
|
|
sigaddset (&sigblock, SIGTERM);
|
|
sigaddset (&sigblock, SIGQUIT);
|
|
//sigaddset(&sigblock, SIGKILL);
|
|
|
|
if ((err = pthread_sigmask (SIG_BLOCK, &sigblock, NULL)) != 0) {
|
|
printf ("SIG_BLOCK error\n");
|
|
return -1;
|
|
}
|
|
|
|
if (pthread_create (&tid, NULL, sigh, NULL)) {
|
|
printf ("Pthread for tracing Signals is not created!\n");
|
|
return -1;
|
|
} else {
|
|
printf ("Pthread for tracing Signals is created!\n");
|
|
}
|
|
|
|
#endif
|
|
// configure oaisim with OCG
|
|
oaisim_config (); // config OMG and OCG, OPT, OTG, OLG
|
|
|
|
if (ue_connection_test == 1) {
|
|
snr_direction = -snr_step;
|
|
snr_dB = 20;
|
|
sinr_dB = -20;
|
|
}
|
|
|
|
pthread_cond_init(&sync_cond,NULL);
|
|
pthread_mutex_init(&sync_mutex, NULL);
|
|
pthread_mutex_init(&subframe_mutex, NULL);
|
|
|
|
#ifdef OPENAIR2
|
|
init_omv ();
|
|
#endif
|
|
//Before this call, NB_UE_INST and NB_eNB_INST are not set correctly
|
|
check_and_adjust_params ();
|
|
|
|
set_seed = oai_emulation.emulation_config.seed.value;
|
|
|
|
init_otg_pdcp_buffer ();
|
|
|
|
init_seed (set_seed);
|
|
|
|
init_openair1 ();
|
|
|
|
init_openair2 ();
|
|
|
|
init_openair0();
|
|
|
|
init_ocm ();
|
|
|
|
#if defined(ENABLE_ITTI)
|
|
// Note: Cannot handle both RRU/RAU and eNB at the same time, if the first "eNB" is an RRU/RAU, no NAS
|
|
if (oai_emulation.info.node_function[0] < NGFI_RAU_IF4p5) {
|
|
if (create_tasks(oai_emulation.info.nb_enb_local,
|
|
oai_emulation.info.nb_ue_local) < 0)
|
|
exit(-1); // need a softer mode
|
|
}
|
|
else {
|
|
if (create_tasks(0,
|
|
oai_emulation.info.nb_ue_local) < 0)
|
|
exit(-1); // need a softer mode
|
|
}
|
|
#endif
|
|
|
|
// wait for all threads to startup
|
|
sleep(3);
|
|
printf("Sending sync to all threads\n");
|
|
|
|
pthread_mutex_lock(&sync_mutex);
|
|
sync_var=0;
|
|
pthread_cond_broadcast(&sync_cond);
|
|
pthread_mutex_unlock(&sync_mutex);
|
|
|
|
#ifdef SMBV
|
|
// Rohde&Schwarz SMBV100A vector signal generator
|
|
smbv_init_config(smbv_fname, smbv_nframes);
|
|
smbv_write_config_from_frame_parms(smbv_fname, &PHY_vars_eNB_g[0][0]->frame_parms);
|
|
#endif
|
|
|
|
/* #if defined (FLEXRAN_AGENT_SB_IF)
|
|
flexran_agent_start();
|
|
#endif */
|
|
|
|
// add events to future event list: Currently not used
|
|
//oai_emulation.info.oeh_enabled = 1;
|
|
if (oai_emulation.info.oeh_enabled == 1)
|
|
schedule_events ();
|
|
|
|
// oai performance profiler is enabled
|
|
if (oai_emulation.info.opp_enabled == 1)
|
|
reset_opp_meas_oaisim ();
|
|
|
|
cpuf=get_cpu_freq_GHz();
|
|
|
|
init_time ();
|
|
|
|
init_slot_isr ();
|
|
|
|
t = clock ();
|
|
|
|
LOG_N(EMU,
|
|
">>>>>>>>>>>>>>>>>>>>>>>>>>> OAIEMU initialization done <<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");
|
|
|
|
#if defined(ENABLE_ITTI)
|
|
|
|
// Handle signals until all tasks are terminated
|
|
itti_wait_tasks_end();
|
|
|
|
#else
|
|
|
|
if (oai_emulation.info.nb_enb_local > 0) {
|
|
eNB_app_task (NULL); // do nothing for the moment
|
|
}
|
|
|
|
l2l1_task (NULL);
|
|
#endif
|
|
t = clock () - t;
|
|
LOG_I(EMU, "Duration of the simulation: %f seconds\n",
|
|
((float) t) / CLOCKS_PER_SEC);
|
|
|
|
LOG_N(EMU,
|
|
">>>>>>>>>>>>>>>>>>>>>>>>>>> OAIEMU Ending <<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");
|
|
|
|
raise (SIGINT);
|
|
// oai_shutdown ();
|
|
|
|
return (0);
|
|
}
|
|
|
|
void
|
|
reset_opp_meas_oaisim (void)
|
|
{
|
|
uint8_t eNB_id = 0, UE_id = 0;
|
|
|
|
reset_meas (&oaisim_stats);
|
|
reset_meas (&oaisim_stats_f); // frame
|
|
|
|
// init time stats here (including channel)
|
|
reset_meas (&dl_chan_stats);
|
|
reset_meas (&ul_chan_stats);
|
|
|
|
for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) {
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_tx);
|
|
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->ofdm_demod_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->rx_dft_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_channel_estimation_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_freq_offset_estimation_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_decoding_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_rate_unmatching_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_turbo_decoding_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_deinterleaving_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_llr_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_unscrambling_stats);
|
|
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_tc_init_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_tc_alpha_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_tc_beta_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_tc_gamma_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_tc_ext_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_tc_intl1_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_tc_intl2_stats);
|
|
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->tx_prach);
|
|
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->ofdm_mod_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->ulsch_encoding_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->ulsch_modulation_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->ulsch_segmentation_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->ulsch_rate_matching_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->ulsch_turbo_encoding_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->ulsch_interleaving_stats);
|
|
reset_meas (&PHY_vars_UE_g[UE_id][0]->ulsch_multiplexing_stats);
|
|
/*
|
|
* L2 functions
|
|
*/
|
|
|
|
// UE MAC
|
|
reset_meas (&UE_mac_inst[UE_id].ue_scheduler); // total
|
|
reset_meas (&UE_mac_inst[UE_id].tx_ulsch_sdu); // inlcude rlc_data_req + mac header gen
|
|
reset_meas (&UE_mac_inst[UE_id].rx_dlsch_sdu); // include mac_rrc_data_ind or mac_rlc_status_ind+mac_rlc_data_ind and mac header parser
|
|
reset_meas (&UE_mac_inst[UE_id].ue_query_mch);
|
|
reset_meas (&UE_mac_inst[UE_id].rx_mch_sdu); // include rld_data_ind+ parse mch header
|
|
reset_meas (&UE_mac_inst[UE_id].rx_si); // include rlc_data_ind + mac header parser
|
|
|
|
reset_meas (&UE_pdcp_stats[UE_id].pdcp_run);
|
|
reset_meas (&UE_pdcp_stats[UE_id].data_req);
|
|
reset_meas (&UE_pdcp_stats[UE_id].data_ind);
|
|
reset_meas (&UE_pdcp_stats[UE_id].apply_security);
|
|
reset_meas (&UE_pdcp_stats[UE_id].validate_security);
|
|
reset_meas (&UE_pdcp_stats[UE_id].pdcp_ip);
|
|
reset_meas (&UE_pdcp_stats[UE_id].ip_pdcp);
|
|
|
|
}
|
|
|
|
for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++) {
|
|
|
|
for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) {
|
|
reset_meas (&eNB2UE[eNB_id][UE_id][0]->random_channel);
|
|
reset_meas (&eNB2UE[eNB_id][UE_id][0]->interp_time);
|
|
reset_meas (&eNB2UE[eNB_id][UE_id][0]->interp_freq);
|
|
reset_meas (&eNB2UE[eNB_id][UE_id][0]->convolution);
|
|
reset_meas (&UE2eNB[UE_id][eNB_id][0]->random_channel);
|
|
reset_meas (&UE2eNB[UE_id][eNB_id][0]->interp_time);
|
|
reset_meas (&UE2eNB[UE_id][eNB_id][0]->interp_freq);
|
|
reset_meas (&UE2eNB[UE_id][eNB_id][0]->convolution);
|
|
}
|
|
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->phy_proc);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->phy_proc_rx);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->phy_proc_tx);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->rx_prach);
|
|
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->ofdm_mod_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->dlsch_encoding_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->dlsch_modulation_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->dlsch_scrambling_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->dlsch_rate_matching_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->dlsch_turbo_encoding_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->dlsch_interleaving_stats);
|
|
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->ofdm_demod_stats);
|
|
//reset_meas(&PHY_vars_eNB_g[eNB_id]->rx_dft_stats);
|
|
//reset_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_channel_estimation_stats);
|
|
//reset_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_freq_offset_estimation_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_decoding_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_demodulation_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_rate_unmatching_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_turbo_decoding_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_deinterleaving_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_demultiplexing_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_llr_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_tc_init_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_tc_alpha_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_tc_beta_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_tc_gamma_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_tc_ext_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_tc_intl1_stats);
|
|
reset_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_tc_intl2_stats);
|
|
#ifdef LOCALIZATION
|
|
reset_meas(&PHY_vars_eNB_g[eNB_id][0]->localization_stats);
|
|
#endif
|
|
|
|
/*
|
|
* L2 functions
|
|
*/
|
|
// eNB MAC
|
|
reset_meas (&eNB_mac_inst[eNB_id].eNB_scheduler); // total
|
|
reset_meas (&eNB_mac_inst[eNB_id].schedule_si); // only schedule + tx
|
|
reset_meas (&eNB_mac_inst[eNB_id].schedule_ra); // only ra
|
|
reset_meas (&eNB_mac_inst[eNB_id].schedule_ulsch); // onlu ulsch
|
|
reset_meas (&eNB_mac_inst[eNB_id].fill_DLSCH_dci); // only dci
|
|
reset_meas (&eNB_mac_inst[eNB_id].schedule_dlsch_preprocessor); // include rlc_data_req + MAC header gen
|
|
reset_meas (&eNB_mac_inst[eNB_id].schedule_dlsch); // include rlc_data_req + MAC header gen + pre-processor
|
|
reset_meas (&eNB_mac_inst[eNB_id].schedule_mch); // only embms
|
|
reset_meas (&eNB_mac_inst[eNB_id].rx_ulsch_sdu); // include rlc_data_ind + mac header parser
|
|
|
|
reset_meas (&eNB_pdcp_stats[eNB_id].pdcp_run);
|
|
reset_meas (&eNB_pdcp_stats[eNB_id].data_req);
|
|
reset_meas (&eNB_pdcp_stats[eNB_id].data_ind);
|
|
reset_meas (&eNB_pdcp_stats[eNB_id].apply_security);
|
|
reset_meas (&eNB_pdcp_stats[eNB_id].validate_security);
|
|
reset_meas (&eNB_pdcp_stats[eNB_id].pdcp_ip);
|
|
reset_meas (&eNB_pdcp_stats[eNB_id].ip_pdcp);
|
|
|
|
}
|
|
}
|
|
|
|
void
|
|
print_opp_meas_oaisim (void)
|
|
{
|
|
|
|
uint8_t eNB_id = 0, UE_id = 0;
|
|
|
|
print_meas (&oaisim_stats, "[OAI][total_exec_time]", &oaisim_stats,
|
|
&oaisim_stats);
|
|
print_meas (&oaisim_stats_f, "[OAI][SF_exec_time]", &oaisim_stats,
|
|
&oaisim_stats_f);
|
|
|
|
print_meas (&dl_chan_stats, "[DL][chan_stats]", &oaisim_stats,
|
|
&oaisim_stats_f);
|
|
print_meas (&ul_chan_stats, "[UL][chan_stats]", &oaisim_stats,
|
|
&oaisim_stats_f);
|
|
|
|
for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) {
|
|
for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++) {
|
|
print_meas (&eNB2UE[eNB_id][UE_id][0]->random_channel,
|
|
"[DL][random_channel]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&eNB2UE[eNB_id][UE_id][0]->interp_time,
|
|
"[DL][interp_time]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&eNB2UE[eNB_id][UE_id][0]->interp_freq,
|
|
"[DL][interp_freq]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&eNB2UE[eNB_id][UE_id][0]->convolution,
|
|
"[DL][convolution]", &oaisim_stats, &oaisim_stats_f);
|
|
|
|
print_meas (&UE2eNB[UE_id][eNB_id][0]->random_channel,
|
|
"[UL][random_channel]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&UE2eNB[UE_id][eNB_id][0]->interp_time,
|
|
"[UL][interp_time]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&UE2eNB[UE_id][eNB_id][0]->interp_freq,
|
|
"[UL][interp_freq]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&UE2eNB[UE_id][eNB_id][0]->convolution,
|
|
"[UL][convolution]", &oaisim_stats, &oaisim_stats_f);
|
|
}
|
|
}
|
|
|
|
for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) {
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc, "[UE][total_phy_proc]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx,
|
|
"[UE][total_phy_proc_rx]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->ofdm_demod_stats,
|
|
"[UE][ofdm_demod]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->rx_dft_stats, "[UE][rx_dft]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_channel_estimation_stats,
|
|
"[UE][channel_est]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_freq_offset_estimation_stats,
|
|
"[UE][freq_offset]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_llr_stats, "[UE][llr]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_unscrambling_stats,
|
|
"[UE][unscrambling]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_decoding_stats,
|
|
"[UE][decoding]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_rate_unmatching_stats,
|
|
"[UE][rate_unmatching]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_deinterleaving_stats,
|
|
"[UE][deinterleaving]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_turbo_decoding_stats,
|
|
"[UE][turbo_decoding]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_tc_init_stats,
|
|
"[UE][ |_tc_init]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_tc_alpha_stats,
|
|
"[UE][ |_tc_alpha]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_tc_beta_stats,
|
|
"[UE][ |_tc_beta]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_tc_gamma_stats,
|
|
"[UE][ |_tc_gamma]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_tc_ext_stats,
|
|
"[UE][ |_tc_ext]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_tc_intl1_stats,
|
|
"[UE][ |_tc_intl1]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_tc_intl2_stats,
|
|
"[UE][ |_tc_intl2]", &oaisim_stats, &oaisim_stats_f);
|
|
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_tx,
|
|
"[UE][total_phy_proc_tx]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->ofdm_mod_stats, "[UE][ofdm_mod]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->ulsch_modulation_stats,
|
|
"[UE][modulation]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->ulsch_encoding_stats,
|
|
"[UE][encoding]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->ulsch_segmentation_stats,
|
|
"[UE][segmentation]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->ulsch_rate_matching_stats,
|
|
"[UE][rate_matching]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->ulsch_turbo_encoding_stats,
|
|
"[UE][turbo_encoding]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->ulsch_interleaving_stats,
|
|
"[UE][interleaving]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_UE_g[UE_id][0]->ulsch_multiplexing_stats,
|
|
"[UE][multiplexing]", &oaisim_stats, &oaisim_stats_f);
|
|
|
|
}
|
|
|
|
for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++) {
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->phy_proc,
|
|
"[eNB][total_phy_proc]", &oaisim_stats, &oaisim_stats_f);
|
|
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->phy_proc_tx,
|
|
"[eNB][total_phy_proc_tx]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->ofdm_mod_stats,
|
|
"[eNB][ofdm_mod]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->dlsch_modulation_stats,
|
|
"[eNB][modulation]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->dlsch_scrambling_stats,
|
|
"[eNB][scrambling]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->dlsch_encoding_stats,
|
|
"[eNB][encoding]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->dlsch_interleaving_stats,
|
|
"[eNB][|_interleaving]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->dlsch_rate_matching_stats,
|
|
"[eNB][|_rate_matching]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->dlsch_turbo_encoding_stats,
|
|
"[eNB][|_turbo_encoding]", &oaisim_stats, &oaisim_stats_f);
|
|
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->phy_proc_rx,
|
|
"[eNB][total_phy_proc_rx]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->ofdm_demod_stats,
|
|
"[eNB][ofdm_demod]", &oaisim_stats, &oaisim_stats_f);
|
|
//print_meas(&PHY_vars_eNB_g[eNB_id][0]->ulsch_channel_estimation_stats,"[eNB][channel_est]");
|
|
//print_meas(&PHY_vars_eNB_g[eNB_id][0]->ulsch_freq_offset_estimation_stats,"[eNB][freq_offset]");
|
|
//print_meas(&PHY_vars_eNB_g[eNB_id][0]->rx_dft_stats,"[eNB][rx_dft]");
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_demodulation_stats,
|
|
"[eNB][demodulation]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_decoding_stats,
|
|
"[eNB][decoding]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_deinterleaving_stats,
|
|
"[eNB][|_deinterleaving]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_demultiplexing_stats,
|
|
"[eNB][|_demultiplexing]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_rate_unmatching_stats,
|
|
"[eNB][|_rate_unmatching]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_turbo_decoding_stats,
|
|
"[eNB][|_turbo_decoding]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_tc_init_stats,
|
|
"[eNB][ |_tc_init]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_tc_alpha_stats,
|
|
"[eNB][ |_tc_alpha]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_tc_beta_stats,
|
|
"[eNB][ |_tc_beta]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_tc_gamma_stats,
|
|
"[eNB][ |_tc_gamma]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_tc_ext_stats,
|
|
"[eNB][ |_tc_ext]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_tc_intl1_stats,
|
|
"[eNB][ |_tc_intl1]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->ulsch_tc_intl2_stats,
|
|
"[eNB][ |_tc_intl2]", &oaisim_stats, &oaisim_stats_f);
|
|
|
|
print_meas (&PHY_vars_eNB_g[eNB_id][0]->rx_prach, "[eNB][rx_prach]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
|
|
#ifdef LOCALIZATION
|
|
print_meas(&PHY_vars_eNB_g[eNB_id][0]->localization_stats, "[eNB][LOCALIZATION]",&oaisim_stats,&oaisim_stats_f);
|
|
#endif
|
|
}
|
|
|
|
for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) {
|
|
|
|
print_meas (&UE_mac_inst[UE_id].ue_scheduler, "[UE][mac_scheduler]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&UE_mac_inst[UE_id].tx_ulsch_sdu, "[UE][tx_ulsch_sdu]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&UE_mac_inst[UE_id].rx_dlsch_sdu, "[UE][rx_dlsch_sdu]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&UE_mac_inst[UE_id].ue_query_mch, "[UE][query_MCH]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&UE_mac_inst[UE_id].rx_mch_sdu, "[UE][rx_mch_sdu]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&UE_mac_inst[UE_id].rx_si, "[UE][rx_si]", &oaisim_stats,
|
|
&oaisim_stats_f);
|
|
|
|
print_meas (&UE_pdcp_stats[UE_id].pdcp_run, "[UE][total_pdcp_run]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&UE_pdcp_stats[UE_id].data_req, "[UE][DL][pdcp_data_req]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&UE_pdcp_stats[UE_id].data_ind, "[UE][UL][pdcp_data_ind]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
|
|
print_meas (&UE_pdcp_stats[UE_id].apply_security,
|
|
"[UE][DL][apply_security]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&UE_pdcp_stats[UE_id].validate_security,
|
|
"[UE][UL][validate_security]", &oaisim_stats,
|
|
&oaisim_stats_f);
|
|
print_meas (&UE_pdcp_stats[UE_id].ip_pdcp, "[UE][DL][ip_pdcp]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&UE_pdcp_stats[UE_id].pdcp_ip, "[UE][UL][pdcp_ip]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
|
|
}
|
|
|
|
for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++) {
|
|
|
|
print_meas (&eNB_mac_inst[eNB_id].eNB_scheduler, "[eNB][mac_scheduler]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&eNB_mac_inst[eNB_id].schedule_si, "[eNB][DL][SI]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&eNB_mac_inst[eNB_id].schedule_ra, "[eNB][DL][RA]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&eNB_mac_inst[eNB_id].fill_DLSCH_dci,
|
|
"[eNB][DL/UL][fill_DCI]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&eNB_mac_inst[eNB_id].schedule_dlsch_preprocessor,
|
|
"[eNB][DL][preprocessor]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&eNB_mac_inst[eNB_id].schedule_dlsch,
|
|
"[eNB][DL][schedule_tx_dlsch]", &oaisim_stats,
|
|
&oaisim_stats_f);
|
|
print_meas (&eNB_mac_inst[eNB_id].schedule_mch, "[eNB][DL][mch]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&eNB_mac_inst[eNB_id].schedule_ulsch, "[eNB][UL][ULSCH]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&eNB_mac_inst[eNB_id].rx_ulsch_sdu,
|
|
"[eNB][UL][rx_ulsch_sdu]", &oaisim_stats, &oaisim_stats_f);
|
|
|
|
print_meas (&eNB_pdcp_stats[eNB_id].pdcp_run, "[eNB][pdcp_run]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&eNB_pdcp_stats[eNB_id].data_req,
|
|
"[eNB][DL][pdcp_data_req]", &oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&eNB_pdcp_stats[eNB_id].data_ind,
|
|
"[eNB][UL][pdcp_data_ind]", &oaisim_stats, &oaisim_stats_f);
|
|
|
|
print_meas (&eNB_pdcp_stats[eNB_id].apply_security,
|
|
"[eNB][DL][apply_security]", &oaisim_stats,
|
|
&oaisim_stats_f);
|
|
print_meas (&eNB_pdcp_stats[eNB_id].validate_security,
|
|
"[eNB][UL][validate_security]", &oaisim_stats,
|
|
&oaisim_stats_f);
|
|
print_meas (&eNB_pdcp_stats[eNB_id].ip_pdcp, "[eNB][DL][ip_pdcp]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
print_meas (&eNB_pdcp_stats[eNB_id].pdcp_ip, "[eNB][UL][pdcp_ip]",
|
|
&oaisim_stats, &oaisim_stats_f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#if !defined(ENABLE_ITTI)
|
|
static void *
|
|
sigh (void *arg)
|
|
{
|
|
|
|
int signum;
|
|
sigset_t sigcatch;
|
|
sigemptyset (&sigcatch);
|
|
sigaddset (&sigcatch, SIGHUP);
|
|
sigaddset (&sigcatch, SIGINT);
|
|
sigaddset (&sigcatch, SIGTERM);
|
|
sigaddset (&sigcatch, SIGQUIT);
|
|
|
|
for (;;) {
|
|
sigwait (&sigcatch, &signum);
|
|
|
|
//sigwait(&sigblock, &signum);
|
|
switch (signum) {
|
|
case SIGHUP:
|
|
case SIGINT:
|
|
case SIGTERM:
|
|
case SIGQUIT:
|
|
fprintf (stderr, "received signal %d \n", signum);
|
|
// no need for mutx: when ITTI not used, this variable is only accessed by this function
|
|
l2l1_state = L2L1_TERMINATED;
|
|
break;
|
|
|
|
default:
|
|
fprintf (stderr, "Unexpected signal %d \n", signum);
|
|
exit (-1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
pthread_exit (NULL);
|
|
}
|
|
#endif /* !defined(ENABLE_ITTI) */
|
|
|
|
void
|
|
oai_shutdown (void)
|
|
{
|
|
static int done = 0;
|
|
|
|
if (done)
|
|
return;
|
|
|
|
free (otg_pdcp_buffer);
|
|
otg_pdcp_buffer = 0;
|
|
|
|
#ifdef SMBV
|
|
|
|
// Rohde&Schwarz SMBV100A vector signal generator
|
|
if (config_smbv) {
|
|
smbv_send_config (smbv_fname,smbv_ip);
|
|
}
|
|
|
|
#endif
|
|
|
|
//Perform KPI measurements
|
|
if (oai_emulation.info.otg_enabled == 1){
|
|
LOG_N(EMU,"calling OTG kpi gen .... \n");
|
|
kpi_gen ();
|
|
}
|
|
if (oai_emulation.info.opp_enabled == 1)
|
|
print_opp_meas_oaisim ();
|
|
|
|
// relase all rx state
|
|
if (ethernet_flag == 1) {
|
|
emu_transport_release ();
|
|
}
|
|
|
|
#ifdef PROC
|
|
|
|
if (abstraction_flag == 0 && Channel_Flag==0 && Process_Flag==0)
|
|
#else
|
|
if (abstraction_flag == 0)
|
|
#endif
|
|
{
|
|
/*
|
|
#ifdef IFFT_FPGA
|
|
free(txdataF2[0]);
|
|
free(txdataF2[1]);
|
|
free(txdataF2);
|
|
free(txdata[0]);
|
|
free(txdata[1]);
|
|
free(txdata);
|
|
#endif
|
|
*/
|
|
/*
|
|
for (int i = 0; i < 2; i++) {
|
|
free (s_re[i]);
|
|
free (s_im[i]);
|
|
free (r_re[i]);
|
|
free (r_im[i]);
|
|
}
|
|
|
|
free (s_re);
|
|
free (s_im);
|
|
free (r_re);
|
|
free (r_im);
|
|
s_re = 0;
|
|
s_im = 0;
|
|
r_re = 0;
|
|
r_im = 0;*/
|
|
|
|
lte_sync_time_free ();
|
|
}
|
|
|
|
// added for PHY abstraction
|
|
if (oai_emulation.info.ocm_enabled == 1) {
|
|
for (eNB_inst = 0; eNB_inst < NUMBER_OF_eNB_MAX; eNB_inst++) {
|
|
free (enb_data[eNB_inst]);
|
|
enb_data[eNB_inst] = 0;
|
|
}
|
|
|
|
for (UE_inst = 0; UE_inst < NUMBER_OF_UE_MAX; UE_inst++) {
|
|
free (ue_data[UE_inst]);
|
|
ue_data[UE_inst] = 0;
|
|
}
|
|
} //End of PHY abstraction changes
|
|
|
|
#ifdef OPENAIR2
|
|
mac_top_cleanup ();
|
|
#endif
|
|
|
|
// stop OMG
|
|
stop_mobility_generator (omg_param_list); //omg_param_list.mobility_type
|
|
#ifdef OPENAIR2
|
|
|
|
if (oai_emulation.info.omv_enabled == 1)
|
|
omv_end (pfd[1], omv_data);
|
|
|
|
#endif
|
|
|
|
if ((oai_emulation.info.ocm_enabled == 1) && (ethernet_flag == 0)
|
|
&& (ShaF != NULL)) {
|
|
destroyMat (ShaF, map1, map2);
|
|
ShaF = 0;
|
|
}
|
|
|
|
if (opt_enabled == 1)
|
|
terminate_opt ();
|
|
|
|
if (oai_emulation.info.cli_enabled)
|
|
cli_server_cleanup ();
|
|
|
|
for (int i = 0; i < NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX; i++)
|
|
if (oai_emulation.info.oai_ifup[i] == 1) {
|
|
char interfaceName[8];
|
|
snprintf (interfaceName, sizeof(interfaceName), "oai%d", i);
|
|
bringInterfaceUp (interfaceName, 0);
|
|
}
|
|
|
|
log_thread_finalize ();
|
|
logClean ();
|
|
VCD_SIGNAL_DUMPER_CLOSE ();
|
|
|
|
done = 1; // prevent next invokation of this function
|
|
|
|
LOG_N(EMU,
|
|
">>>>>>>>>>>>>>>>>>>>>>>>>>> OAIEMU shutdown <<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");
|
|
}
|
|
|
|
eNB_MAC_INST*
|
|
get_eNB_mac_inst (module_id_t module_idP)
|
|
{
|
|
return (&eNB_mac_inst[module_idP]);
|
|
}
|
|
|
|
OAI_Emulation*
|
|
get_OAI_emulation ()
|
|
{
|
|
return &oai_emulation;
|
|
}
|
|
|
|
|