/******************************************************************************* Eurecom OpenAirInterface Copyright(c) 1999 - 2014 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, 2229, route des crĂȘtes, 06560 Valbonne Sophia Antipolis, France *******************************************************************************/ #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 "MAC_INTERFACE/vars.h" #include "SIMULATION/ETH_TRANSPORT/proto.h" //#ifdef OPENAIR2 #include "LAYER2/MAC/defs.h" #include "LAYER2/MAC/vars.h" #include "pdcp.h" #ifndef CELLULAR #include "RRC/LITE/vars.h" #endif #include "PHY_INTERFACE/vars.h" //#endif #include "RRC/NAS/nas_config.h" #include "ARCH/CBMIMO1/DEVICE_DRIVER/vars.h" #ifdef IFFT_FPGA //#include "PHY/LTE_REFSIG/mod_table.h" #endif //IFFT_FPGA #include "SCHED/defs.h" #include "SCHED/vars.h" #ifdef XFORMS #include "PHY/TOOLS/lte_phy_scope.h" #endif #ifdef SMBV #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 #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" //#ifdef PROC #include "../PROC/interface.h" #include "../PROC/channel_sim_proc.h" #include "../PROC/Tsync.h" #include "../PROC/Process.h" //#endif #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 #define RF 1 #define MCS_COUNT 24 /*added for PHY abstraction */ #define N_TRIALS 1 /* 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 */ frame_t frame = 0; char stats_buffer[16384]; channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX]; channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX]; //Added for PHY abstraction node_desc_t *enb_data[NUMBER_OF_eNB_MAX]; node_desc_t *ue_data[NUMBER_OF_UE_MAX]; // 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; uint8_t cooperation_flag; // for cooperative communication extern uint8_t target_dl_mcs; extern uint8_t target_ul_mcs; uint8_t rate_adaptation_flag; extern uint8_t abstraction_flag; extern uint8_t ethernet_flag; extern uint16_t Nid_cell; extern LTE_DL_FRAME_PARMS *frame_parms; #ifdef XFORMS int otg_enabled; #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 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: cbr, scbr, mcbr, bcbr, mscbr\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"); printf ("-W IP address to connect to SMBV and configure SMBV from config file. Requires compilation with SMBV=1, -W0 uses default IP 192.168.12.201\n"); printf ("-x Set the transmission mode (1,2,5,6 supported for now)\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"); } pthread_t log_thread; void log_thread_init() { //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() { 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; #ifdef Rel10 static module_id_t RN_id = 0; #endif 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; /*------------------------------------------------------------------------------*/ void *l2l1_task(void *args_p) { clock_t t; // Framing variables int32_t slot, last_slot, next_slot; #ifdef Rel10 relaying_type_t r_type = no_relay; // no relaying #endif lte_subframe_t direction; 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[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 #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 #ifdef XFORMS xargv[0] = xname; fl_initialize (&xargc, xargv, NULL, 0, 0); eNB_inst = 0; for (UE_inst = 0; UE_inst < NB_UE_INST; UE_inst++) { // DL scope at UEs form_ue[UE_inst] = create_lte_phy_scope_ue(); sprintf (title, "LTE DL SCOPE eNB %d to UE %d", eNB_inst, UE_inst); fl_show_form (form_ue[UE_inst]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); // 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); if (openair_daq_vars.use_ia_receiver == 1) { fl_set_button(form_ue[UE_inst]->button_0,1); fl_set_object_label(form_ue[UE_inst]->button_0, "IA Receiver ON"); fl_set_object_color(form_ue[UE_inst]->button_0, FL_GREEN, FL_GREEN); } } #endif #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++) { sprintf(UE_stats_th_filename,"UE_stats_th%d_tx%d.txt",UE_inst,oai_emulation.info.transmission_mode); UE_stats_th[UE_inst] = fopen (UE_stats_th_filename, "w"); } sprintf(eNB_stats_th_filename,"eNB_stats_th_tx%d.txt",oai_emulation.info.transmission_mode); eNB_avg_thr = fopen (eNB_stats_th_filename, "w"); } else { for (UE_inst=0;UE_inst<NB_UE_INST;UE_inst++) { sprintf(UE_stats_th_filename,"UE_stats_abs_th%d_tx%d.txt",UE_inst,oai_emulation.info.transmission_mode); UE_stats_th[UE_inst] = fopen (UE_stats_th_filename, "w"); } sprintf(eNB_stats_th_filename,"eNB_stats_abs_th_tx%d.txt",oai_emulation.info.transmission_mode); 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; int result; itti_mark_task_ready (TASK_L2L1); LOG_I(EMU, "TASK_L2L1 is READY\n"); if (oai_emulation.info.nb_enb_local > 0) { /* 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); switch (ITTI_MSG_ID(message_p)) { case INITIALIZE_MESSAGE: l2l1_state = L2L1_RUNNING; 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 start_meas(&oaisim_stats); for (frame = 0; (l2l1_state != L2L1_TERMINATED) && (frame < oai_emulation.info.n_frames); frame++) { start_meas(&oaisim_stats_f); #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) { 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: LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p)); 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); /* // Handling the cooperation Flag if (cooperation_flag == 2) { if ((PHY_vars_eNB_g[0]->eNB_UE_stats[0].mode == PUSCH) && (PHY_vars_eNB_g[0]->eNB_UE_stats[1].mode == PUSCH)) PHY_vars_eNB_g[0]->cooperation_flag = 2; } */ 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.1; // 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) // if n_frames not set by the user or is greater than max num frame then set adjust the frame counter if ((oai_emulation.info.n_frames_flag == 0) || (oai_emulation.info.n_frames >= 0xffff)) { frame %= (oai_emulation.info.n_frames - 1); } 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 #ifdef DEBUG_OMG if ((((int) oai_emulation.info.time_s) % 100) == 0) { 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++) { get_node_position (UE, UE_inst); } } #endif update_ocm (); for (slot = 0; slot < 20; slot++) { wait_for_slot_isr (); #if defined(ENABLE_ITTI) itti_update_lte_time(frame, slot); #endif last_slot = (slot - 1) % 20; if (last_slot < 0) last_slot += 20; next_slot = (slot + 1) % 20; oai_emulation.info.time_ms = frame * 10 + (slot >> 1); direction = subframe_select (frame_parms, next_slot >> 1); #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,slot); if(Channel_Flag==0) #endif { #if defined(ENABLE_ITTI) log_set_instance_type (LOG_INSTANCE_ENB); #endif if ((next_slot % 2) == 0) clear_eNB_transport_info (oai_emulation.info.nb_enb_local); 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, slot %d (subframe TX %d, RX %d) TDD %d/%d Nid_cell %d\n", eNB_inst, frame, slot, next_slot >> 1, last_slot>>1, PHY_vars_eNB_g[eNB_inst]->lte_frame_parms.frame_type, PHY_vars_eNB_g[eNB_inst]->lte_frame_parms.tdd_config, PHY_vars_eNB_g[eNB_inst]->lte_frame_parms.Nid_cell); #ifdef OPENAIR2 //Appliation: 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 // PHY_vars_eNB_g[eNB_id]->frame = frame; phy_procedures_eNB_lte (last_slot, next_slot, PHY_vars_eNB_g[eNB_inst], abstraction_flag, no_relay, NULL); #ifdef PRINT_STATS if(last_slot==9 && frame%10==0) if(eNB_avg_thr) fprintf(eNB_avg_thr,"%d %d\n",PHY_vars_eNB_g[eNB_inst]->frame,(PHY_vars_eNB_g[eNB_inst]->total_system_throughput)/((PHY_vars_eNB_g[eNB_inst]->frame+1)*10)); if (eNB_stats[eNB_inst]) { len = dump_eNB_stats(PHY_vars_eNB_g[eNB_inst], 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 } } // 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 if ((next_slot % 2) == 0) 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, slot, next_slot >> 1, last_slot>>1); if (PHY_vars_UE_g[UE_inst]->UE_mode[0] != NOT_SYNCHED) { if (frame > 0) { PHY_vars_UE_g[UE_inst]->frame = frame; #ifdef OPENAIR2 //Application update_otg_UE (UE_inst, oai_emulation.info.time_ms); //Access layer pdcp_run (frame, 0, UE_inst, 0); #endif phy_procedures_UE_lte (last_slot, next_slot, PHY_vars_UE_g[UE_inst], 0, abstraction_flag, normal_txrx, no_relay, NULL); ue_data[UE_inst]->tx_power_dBm = PHY_vars_UE_g[UE_inst]->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]->UE_mode[0]); exit (-1); } if ((frame > 0) && (last_slot == (LTE_SLOTS_PER_FRAME - 2))) { initial_sync (PHY_vars_UE_g[UE_inst], normal_txrx); /* write_output("dlchan00.m","dlch00",&(PHY_vars_UE_g[0]->lte_ue_common_vars.dl_ch_estimates[0][0][0]),(6*(PHY_vars_UE_g[0]->lte_frame_parms.ofdm_symbol_size)),1,1); if (PHY_vars_UE_g[0]->lte_frame_parms.nb_antennas_rx>1) write_output("dlchan01.m","dlch01",&(PHY_vars_UE_g[0]->lte_ue_common_vars.dl_ch_estimates[0][1][0]),(6*(PHY_vars_UE_g[0]->lte_frame_parms.ofdm_symbol_size)),1,1); write_output("dlchan10.m","dlch10",&(PHY_vars_UE_g[0]->lte_ue_common_vars.dl_ch_estimates[0][2][0]),(6*(PHY_vars_UE_g[0]->lte_frame_parms.ofdm_symbol_size)),1,1); if (PHY_vars_UE_g[0]->lte_frame_parms.nb_antennas_rx>1) write_output("dlchan11.m","dlch11",&(PHY_vars_UE_g[0]->lte_ue_common_vars.dl_ch_estimates[0][3][0]),(6*(PHY_vars_UE_g[0]->lte_frame_parms.ofdm_symbol_size)),1,1); write_output("rxsig.m","rxs",PHY_vars_UE_g[0]->lte_ue_common_vars.rxdata[0],PHY_vars_UE_g[0]->lte_frame_parms.samples_per_tti*10,1,1); write_output("rxsigF.m","rxsF",PHY_vars_UE_g[0]->lte_ue_common_vars.rxdataF[0],2*PHY_vars_UE_g[0]->lte_frame_parms.symbols_per_tti*PHY_vars_UE_g[0]->lte_frame_parms.ofdm_symbol_size,2,1); write_output("pbch_rxF_ext0.m","pbch_ext0",PHY_vars_UE_g[0]->lte_ue_pbch_vars[0]->rxdataF_ext[0],6*12*4,1,1); write_output("pbch_rxF_comp0.m","pbch_comp0",PHY_vars_UE_g[0]->lte_ue_pbch_vars[0]->rxdataF_comp[0],6*12*4,1,1); write_output("pbch_rxF_llr.m","pbch_llr",PHY_vars_UE_g[0]->lte_ue_pbch_vars[0]->llr,(frame_parms->Ncp==0) ? 1920 : 1728,1,4); */ } } #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, PHY_vars_UE_g[UE_inst]->bitrate[0]/1000); } } if (UE_stats[UE_inst]) { len = dump_ue_stats (PHY_vars_UE_g[UE_inst], 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; if ( oai_emulation.info.frame_type == 0) { // RN == UE if (frame>0) { if (PHY_vars_UE_g[UE_inst]->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]->frame = frame; phy_procedures_UE_lte (last_slot, next_slot, PHY_vars_UE_g[UE_inst], 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],normal_txrx); } } // RN == eNB LOG_D(EMU,"[RN %d] PHY procedures eNB %d for frame %d, slot %d (subframe TX %d, RX %d)\n", RN_id, eNB_inst, frame, slot, next_slot >> 1,last_slot>>1); phy_procedures_eNB_lte (last_slot, next_slot, PHY_vars_eNB_g[eNB_inst], abstraction_flag, r_type, PHY_vars_RN_g[RN_id]); } else { LOG_E(EMU,"TDD is not supported for multicast relaying %d\n", r_type); exit(-1); } } #endif emu_transport (frame, last_slot, next_slot, direction, oai_emulation.info.frame_type, ethernet_flag); if ((direction == SF_DL) || (frame_parms->frame_type == 0)) { // consider only sec id 0 /* for (eNB_id=0;eNB_id<NB_eNB_INST;eNB_id++) { if (abstraction_flag == 0) { do_OFDM_mod(PHY_vars_eNB_g[eNB_id]->lte_eNB_common_vars.txdataF[0], PHY_vars_eNB_g[eNB_id]->lte_eNB_common_vars.txdata[0], frame,next_slot, frame_parms); } }*/ start_meas(&dl_chan_stats); for (UE_inst = 0; UE_inst < NB_UE_INST; UE_inst++) { do_DL_sig (r_re0, r_im0, r_re, r_im, s_re, s_im, eNB2UE, enb_data, ue_data, next_slot, abstraction_flag,frame_parms, UE_inst); } stop_meas(&dl_chan_stats); } if ((direction == SF_UL) || (frame_parms->frame_type == 0)) { //if ((subframe<2) || (subframe>4)) start_meas(&ul_chan_stats); do_UL_sig (r_re0, r_im0, r_re, r_im, s_re, s_im, UE2eNB, enb_data, ue_data, next_slot, abstraction_flag,frame_parms, frame); stop_meas(&ul_chan_stats); /* int ccc; fprintf(SINRpost,"SINRdb For eNB New Subframe : \n "); for(ccc = 0 ; ccc<301; ccc++) { fprintf(SINRpost,"_ %f ", SINRpost_eff[ccc]); } fprintf(SINRpost,"SINRdb For eNB : %f \n ", SINRpost_eff[ccc]); */ } if ((direction == SF_S)) { //it must be a special subframe if (next_slot % 2 == 0) { //DL part /* for (eNB_id=0;eNB_id<NB_eNB_INST;eNB_id++) { if (abstraction_flag == 0) { do_OFDM_mod(PHY_vars_eNB_g[eNB_id]->lte_eNB_common_vars.txdataF[0], PHY_vars_eNB_g[eNB_id]->lte_eNB_common_vars.txdata[0], frame,next_slot, frame_parms); } }*/ start_meas(&dl_chan_stats); for (UE_inst = 0; UE_inst < NB_UE_INST; UE_inst++) { do_DL_sig (r_re0, r_im0, r_re, r_im, s_re, s_im, eNB2UE, enb_data, ue_data, next_slot, abstraction_flag,frame_parms, UE_inst); } stop_meas(&dl_chan_stats); /* for (aarx=0;aarx<UE2eNB[1][0]->nb_rx;aarx++) for (aatx=0;aatx<UE2eNB[1][0]->nb_tx;aatx++) for (k=0;k<UE2eNB[1][0]->channel_length;k++) printf("SB(%d,%d,%d)->(%f,%f)\n",k,aarx,aatx,UE2eNB[1][0]->ch[aarx+(aatx*UE2eNB[1][0]->nb_rx)][k].r,UE2eNB[1][0]->ch[aarx+(aatx*UE2eNB[1][0]->nb_rx)][k].i); */ } else { // UL part start_meas(&ul_chan_stats); do_UL_sig (r_re0, r_im0, r_re, r_im, s_re, s_im, UE2eNB, enb_data, ue_data, next_slot, abstraction_flag,frame_parms, frame); stop_meas(&ul_chan_stats); /* int ccc; fprintf(SINRpost,"SINRdb For eNB New Subframe : \n "); for(ccc = 0 ; ccc<301; ccc++) { fprintf(SINRpost,"_ %f ", SINRpost_eff[ccc]); } fprintf(SINRpost,"SINRdb For eNB : %f \n ", SINRpost_eff[ccc]); } */} } if ((last_slot == 1) && (frame == 0) && (abstraction_flag == 0) && (oai_emulation.info.n_frames == 1)) { write_output ("dlchan0.m", "dlch0", &(PHY_vars_UE_g[0]->lte_ue_common_vars.dl_ch_estimates[0][0][0]), (6 * (PHY_vars_UE_g[0]->lte_frame_parms.ofdm_symbol_size)), 1, 1); write_output ("dlchan1.m", "dlch1", &(PHY_vars_UE_g[0]->lte_ue_common_vars.dl_ch_estimates[1][0][0]), (6 * (PHY_vars_UE_g[0]->lte_frame_parms.ofdm_symbol_size)), 1, 1); write_output ("dlchan2.m", "dlch2", &(PHY_vars_UE_g[0]->lte_ue_common_vars.dl_ch_estimates[2][0][0]), (6 * (PHY_vars_UE_g[0]->lte_frame_parms.ofdm_symbol_size)), 1, 1); write_output ("pbch_rxF_comp0.m", "pbch_comp0", PHY_vars_UE_g[0]->lte_ue_pbch_vars[0]->rxdataF_comp[0], 6 * 12 * 4, 1, 1); write_output ("pbch_rxF_llr.m", "pbch_llr", PHY_vars_UE_g[0]->lte_ue_pbch_vars[0]->llr, (frame_parms->Ncp == 0) ? 1920 : 1728, 1, 4); } /* if ((last_slot==1) && (frame==1)) { write_output("dlsch_rxF_comp0.m","dlsch0_rxF_comp0",PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp[0],300*(-(PHY_vars_UE->lte_frame_parms.Ncp*2)+14),1,1); write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->rxdataF_comp[0],4*300,1,1); } */ } // if Channel_Flag==0 } //end of slot if ((frame >= 1) && (frame <= 9) && (abstraction_flag == 0) #ifdef PROC &&(Channel_Flag==0) #endif ) { write_output ("UEtxsig0.m", "txs0", PHY_vars_UE_g[0]->lte_ue_common_vars.txdata[0], FRAME_LENGTH_COMPLEX_SAMPLES, 1, 1); sprintf (fname, "eNBtxsig%d.m", frame); sprintf (vname, "txs%d", frame); write_output (fname, vname, PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][0], FRAME_LENGTH_COMPLEX_SAMPLES, 1, 1); write_output ( "eNBtxsigF0.m", "txsF0", PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdataF[0][0], PHY_vars_eNB_g[0]->lte_frame_parms.symbols_per_tti * PHY_vars_eNB_g[0]->lte_frame_parms.ofdm_symbol_size, 1, 1); write_output ("UErxsig0.m", "rxs0", PHY_vars_UE_g[0]->lte_ue_common_vars.rxdata[0], FRAME_LENGTH_COMPLEX_SAMPLES, 1, 1); write_output ("eNBrxsig0.m", "rxs0", PHY_vars_eNB_g[0]->lte_eNB_common_vars.rxdata[0][0], FRAME_LENGTH_COMPLEX_SAMPLES, 1, 1); } #ifdef XFORMS eNB_inst = 0; for (UE_inst = 0; UE_inst < NB_UE_INST; UE_inst++) { phy_scope_UE(form_ue[UE_inst], PHY_vars_UE_g[UE_inst], eNB_inst, UE_inst, 7); phy_scope_eNB(form_enb[UE_inst], PHY_vars_eNB_g[eNB_inst], UE_inst); } #endif #ifdef SMBV if ((frame == config_frames[0]) || (frame == config_frames[1]) || (frame == config_frames[2]) || (frame == config_frames[3])) { smbv_frame_cnt++; } #endif stop_meas(&oaisim_stats_f); } //end of frame stop_meas(&oaisim_stats); #if defined(ENABLE_ITTI) itti_terminate_tasks(TASK_L2L1); #endif #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 return NULL; } /*------------------------------------------------------------------------------*/ int main(int argc, char **argv) { int32_t i; // pointers signal buffers (s = transmit, r,r0 = receive) clock_t t; //FILE *SINRpost; //char SINRpost_fname[512]; // sprintf(SINRpost_fname,"postprocSINR.m"); //SINRpost = fopen(SINRpost_fname,"w"); // variables/flags which are set by user on command-line #ifdef SMBV strcpy(smbv_ip,DEFAULT_SMBV_IP); #endif // time calibration for soft realtime mode char pbch_file_path[512]; FILE *pbch_file_fd; #ifdef PROC int node_id; int port,Process_Flag=0,wgt,Channel_Flag=0,temp; #endif //double **s_re2[MAX_eNB+MAX_UE], **s_im2[MAX_eNB+MAX_UE], **r_re2[MAX_eNB+MAX_UE], **r_im2[MAX_eNB+MAX_UE], **r_re02, **r_im02; //double **r_re0_d[MAX_UE][MAX_eNB], **r_im0_d[MAX_UE][MAX_eNB], **r_re0_u[MAX_eNB][MAX_UE],**r_im0_u[MAX_eNB][MAX_UE]; //default parameters rate_adaptation_flag = 0; oai_emulation.info.n_frames = 0xffff; //1024; //10; oai_emulation.info.n_frames_flag = 0; //fixme snr_dB = 30; cooperation_flag = 0; // default value 0 for no cooperation, 1 for Delay diversity, 2 for Distributed Alamouti //Default values if not changed by the user in get_simulation_options(); pdcp_period = 1; omg_period = 1; // 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 // 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; } #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_ocm (); #ifdef SMBV smbv_init_config(smbv_fname, smbv_nframes); smbv_write_config_from_frame_parms(smbv_fname, &PHY_vars_eNB_g[0]->lte_frame_parms); #endif // add events to future event list: Currently not used if (oai_emulation.info.oeh_enabled == 1) schedule_events(); // oai performance profiler is enabled if (oai_emulation.info.opp_enabled == 1) reset_opp_meas(); 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 if (create_tasks(oai_emulation.info.nb_enb_local, oai_emulation.info.nb_ue_local) >= 0) { itti_wait_tasks_end(); } else { exit(-1); // need a softer mode } #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); // fclose(SINRpost); LOG_N(EMU, ">>>>>>>>>>>>>>>>>>>>>>>>>>> OAIEMU Ending <<<<<<<<<<<<<<<<<<<<<<<<<<\n\n"); raise(SIGINT); oai_shutdown(); return (0); } void reset_opp_meas(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]->phy_proc); reset_meas(&PHY_vars_UE_g[UE_id]->phy_proc_rx); reset_meas(&PHY_vars_UE_g[UE_id]->phy_proc_tx); reset_meas(&PHY_vars_UE_g[UE_id]->ofdm_demod_stats); reset_meas(&PHY_vars_UE_g[UE_id]->rx_dft_stats); reset_meas(&PHY_vars_UE_g[UE_id]->dlsch_channel_estimation_stats); reset_meas(&PHY_vars_UE_g[UE_id]->dlsch_freq_offset_estimation_stats); reset_meas(&PHY_vars_UE_g[UE_id]->dlsch_decoding_stats); reset_meas(&PHY_vars_UE_g[UE_id]->dlsch_rate_unmatching_stats); reset_meas(&PHY_vars_UE_g[UE_id]->dlsch_turbo_decoding_stats); reset_meas(&PHY_vars_UE_g[UE_id]->dlsch_deinterleaving_stats); reset_meas(&PHY_vars_UE_g[UE_id]->dlsch_llr_stats); reset_meas(&PHY_vars_UE_g[UE_id]->dlsch_unscrambling_stats); reset_meas(&PHY_vars_UE_g[UE_id]->dlsch_tc_init_stats); reset_meas(&PHY_vars_UE_g[UE_id]->dlsch_tc_alpha_stats); reset_meas(&PHY_vars_UE_g[UE_id]->dlsch_tc_beta_stats); reset_meas(&PHY_vars_UE_g[UE_id]->dlsch_tc_gamma_stats); reset_meas(&PHY_vars_UE_g[UE_id]->dlsch_tc_ext_stats); reset_meas(&PHY_vars_UE_g[UE_id]->dlsch_tc_intl1_stats); reset_meas(&PHY_vars_UE_g[UE_id]->dlsch_tc_intl2_stats); reset_meas(&PHY_vars_UE_g[UE_id]->tx_prach); reset_meas(&PHY_vars_UE_g[UE_id]->ofdm_mod_stats); reset_meas(&PHY_vars_UE_g[UE_id]->ulsch_encoding_stats); reset_meas(&PHY_vars_UE_g[UE_id]->ulsch_modulation_stats); reset_meas(&PHY_vars_UE_g[UE_id]->ulsch_segmentation_stats); reset_meas(&PHY_vars_UE_g[UE_id]->ulsch_rate_matching_stats); reset_meas(&PHY_vars_UE_g[UE_id]->ulsch_turbo_encoding_stats); reset_meas(&PHY_vars_UE_g[UE_id]->ulsch_interleaving_stats); reset_meas(&PHY_vars_UE_g[UE_id]->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++) { reset_meas(&PHY_vars_eNB_g[eNB_id]->phy_proc); reset_meas(&PHY_vars_eNB_g[eNB_id]->phy_proc_rx); reset_meas(&PHY_vars_eNB_g[eNB_id]->phy_proc_tx); reset_meas(&PHY_vars_eNB_g[eNB_id]->rx_prach); reset_meas(&PHY_vars_eNB_g[eNB_id]->ofdm_mod_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->dlsch_encoding_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->dlsch_modulation_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->dlsch_scrambling_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->dlsch_rate_matching_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->dlsch_turbo_encoding_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->dlsch_interleaving_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->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]->ulsch_decoding_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_demodulation_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_rate_unmatching_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_turbo_decoding_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_deinterleaving_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_demultiplexing_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_llr_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_tc_init_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_tc_alpha_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_tc_beta_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_tc_gamma_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_tc_ext_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_tc_intl1_stats); reset_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_tc_intl2_stats); reset_meas(&eNB2UE[eNB_id][UE_id]->random_channel); reset_meas(&eNB2UE[eNB_id][UE_id]->interp_time); reset_meas(&eNB2UE[eNB_id][UE_id]->interp_freq); reset_meas(&eNB2UE[eNB_id][UE_id]->convolution); reset_meas(&UE2eNB[UE_id][eNB_id]->random_channel); reset_meas(&UE2eNB[UE_id][eNB_id]->interp_time); reset_meas(&UE2eNB[UE_id][eNB_id]->interp_freq); reset_meas(&UE2eNB[UE_id][eNB_id]->convolution); /* * 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(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]->random_channel,"[DL][random_channel]",&oaisim_stats,&oaisim_stats_f); print_meas(&eNB2UE[eNB_id][UE_id]->interp_time,"[DL][interp_time]",&oaisim_stats,&oaisim_stats_f); print_meas(&eNB2UE[eNB_id][UE_id]->interp_freq,"[DL][interp_freq]",&oaisim_stats,&oaisim_stats_f); print_meas(&eNB2UE[eNB_id][UE_id]->convolution,"[DL][convolution]",&oaisim_stats,&oaisim_stats_f); print_meas(&UE2eNB[UE_id][eNB_id]->random_channel,"[UL][random_channel]",&oaisim_stats,&oaisim_stats_f); print_meas(&UE2eNB[UE_id][eNB_id]->interp_time,"[UL][interp_time]",&oaisim_stats,&oaisim_stats_f); print_meas(&UE2eNB[UE_id][eNB_id]->interp_freq,"[UL][interp_freq]",&oaisim_stats,&oaisim_stats_f); print_meas(&UE2eNB[UE_id][eNB_id]->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]->phy_proc,"[UE][total_phy_proc]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->phy_proc_rx,"[UE][total_phy_proc_rx]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->ofdm_demod_stats,"[UE][ofdm_demod]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->rx_dft_stats,"[UE][rx_dft]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->dlsch_channel_estimation_stats,"[UE][channel_est]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->dlsch_freq_offset_estimation_stats,"[UE][freq_offset]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->dlsch_llr_stats,"[UE][llr]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->dlsch_unscrambling_stats,"[UE][unscrambling]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->dlsch_decoding_stats,"[UE][decoding]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->dlsch_rate_unmatching_stats,"[UE][rate_unmatching]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->dlsch_deinterleaving_stats,"[UE][deinterleaving]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->dlsch_turbo_decoding_stats,"[UE][turbo_decoding]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->dlsch_tc_init_stats,"[UE][ |_tc_init]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->dlsch_tc_alpha_stats,"[UE][ |_tc_alpha]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->dlsch_tc_beta_stats,"[UE][ |_tc_beta]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->dlsch_tc_gamma_stats,"[UE][ |_tc_gamma]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->dlsch_tc_ext_stats,"[UE][ |_tc_ext]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->dlsch_tc_intl1_stats,"[UE][ |_tc_intl1]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->dlsch_tc_intl2_stats,"[UE][ |_tc_intl2]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->phy_proc_tx,"[UE][total_phy_proc_tx]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->ofdm_mod_stats,"[UE][ofdm_mod]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->ulsch_modulation_stats,"[UE][modulation]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->ulsch_encoding_stats,"[UE][encoding]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->ulsch_segmentation_stats,"[UE][segmentation]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->ulsch_rate_matching_stats,"[UE][rate_matching]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->ulsch_turbo_encoding_stats,"[UE][turbo_encoding]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->ulsch_interleaving_stats,"[UE][interleaving]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_UE_g[UE_id]->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]->phy_proc,"[eNB][total_phy_proc]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->phy_proc_tx,"[eNB][total_phy_proc_tx]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->ofdm_mod_stats,"[eNB][ofdm_mod]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->dlsch_modulation_stats,"[eNB][modulation]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->dlsch_scrambling_stats,"[eNB][scrambling]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->dlsch_encoding_stats,"[eNB][encoding]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->dlsch_interleaving_stats,"[eNB][|_interleaving]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->dlsch_rate_matching_stats,"[eNB][|_rate_matching]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->dlsch_turbo_encoding_stats,"[eNB][|_turbo_encoding]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->phy_proc_rx,"[eNB][total_phy_proc_rx]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->ofdm_demod_stats,"[eNB][ofdm_demod]",&oaisim_stats,&oaisim_stats_f); //print_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_channel_estimation_stats,"[eNB][channel_est]"); //print_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_freq_offset_estimation_stats,"[eNB][freq_offset]"); //print_meas(&PHY_vars_eNB_g[eNB_id]->rx_dft_stats,"[eNB][rx_dft]"); print_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_demodulation_stats,"[eNB][demodulation]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_decoding_stats,"[eNB][decoding]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_deinterleaving_stats,"[eNB][|_deinterleaving]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_demultiplexing_stats,"[eNB][|_demultiplexing]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_rate_unmatching_stats,"[eNB][|_rate_unmatching]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_turbo_decoding_stats,"[eNB][|_turbo_decoding]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_tc_init_stats,"[eNB][ |_tc_init]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_tc_alpha_stats,"[eNB][ |_tc_alpha]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_tc_beta_stats,"[eNB][ |_tc_beta]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_tc_gamma_stats,"[eNB][ |_tc_gamma]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_tc_ext_stats,"[eNB][ |_tc_ext]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_tc_intl1_stats,"[eNB][ |_tc_intl1]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->ulsch_tc_intl2_stats,"[eNB][ |_tc_intl2]",&oaisim_stats,&oaisim_stats_f); print_meas(&PHY_vars_eNB_g[eNB_id]->rx_prach,"[eNB][rx_prach]",&oaisim_stats,&oaisim_stats_f); } 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); } } 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); } void oai_shutdown(void) { static int done=0; int i; char interfaceName[8]; if (done) return; free (otg_pdcp_buffer); #ifdef SMBV if (config_smbv) { smbv_send_config (smbv_fname,smbv_ip); } #endif //Perform KPI measurements if (oai_emulation.info.otg_enabled == 1) kpi_gen (); if (oai_emulation.info.opp_enabled == 1) print_opp_meas(); // 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 (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); 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]); } for (UE_inst = 0; UE_inst < NUMBER_OF_UE_MAX; UE_inst++) { free (ue_data[UE_inst]); } } //End of PHY abstraction changes #ifdef OPENAIR2 mac_top_cleanup (); #endif // stop OMG stop_mobility_generator (oai_emulation.info.omg_model_ue); //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); if ((oai_emulation.info.opt_enabled == 1)) terminate_opt (); if (oai_emulation.info.cli_enabled) cli_server_cleanup (); for (i = 0; i < NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX; i++) if (oai_emulation.info.oai_ifup[i] == 1) { sprintf (interfaceName, "oai%d", i); bringInterfaceUp (interfaceName, 0); } log_thread_finalize (); logClean (); vcd_signal_dumper_close (); done =1; LOG_N(EMU, ">>>>>>>>>>>>>>>>>>>>>>>>>>> OAIEMU shutdown <<<<<<<<<<<<<<<<<<<<<<<<<<\n\n"); }