diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index a39cf35f6a8bdbf1fcae472ed430c418b0e1c0c2..56ff74b8d3e85cd60838a1b4baa4ac21f72ef1c1 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1736,6 +1736,9 @@ add_executable(oaisim ${s1ap_h} ${x2ap_h} ${OPENAIR_BIN_DIR}/messages_xml.h + ${OPENAIR_TARGETS}/RT/USER/lte-ue.c + ${OPENAIR_TARGETS}/RT/USER/lte-enb.c + ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c ${OPENAIR_TARGETS}/SIMU/USER/channel_sim.c ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c ${OPENAIR_TARGETS}/SIMU/USER/oaisim_config.c @@ -1779,6 +1782,9 @@ add_executable(oaisim_nos1 ${s1ap_h} ${x2ap_h} ${OPENAIR_BIN_DIR}/messages_xml.h + ${OPENAIR_TARGETS}/RT/USER/lte-ue.c + ${OPENAIR_TARGETS}/RT/USER/lte-enb.c + ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c ${OPENAIR_TARGETS}/SIMU/USER/channel_sim.c ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c ${OPENAIR_TARGETS}/SIMU/USER/oaisim_config.c diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 4c46674ecb1be7a2f522a51f5a2fd600beb1dcd0..e4386c8fdfe479d8044b1b0dd31ea2bbc5eb826d 100755 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -171,6 +171,7 @@ typedef enum { } eNB_timing_t; + typedef struct UE_SCAN_INFO_s { /// 10 best amplitudes (linear) for each pss signals int32_t amp[3][10]; @@ -310,10 +311,16 @@ typedef struct { uint8_t CC_id; /// Last RX timestamp openair0_timestamp timestamp_rx; + /// pthread attributes for main UE thread + pthread_attr_t attr_ue; + /// scheduling parameters for main UE thread + struct sched_param sched_param_ue; + /// pthread descriptor main UE thread + pthread_t pthread_ue; /// \brief Instance count for synch thread. /// \internal This variable is protected by \ref mutex_synch. int instance_cnt_synch; - /// pthread attributes for prach processing thread + /// pthread attributes for synch processing thread pthread_attr_t attr_synch; /// scheduling parameters for synch thread struct sched_param sched_param_synch; @@ -770,6 +777,9 @@ typedef struct { time_stats_t dlsch_tc_intl2_stats; time_stats_t tx_prach; + /// RF and Interface devices per CC + openair0_device rfdevice; + #if ENABLE_RAL hash_table_t *ral_thresholds_timed; SLIST_HEAD(ral_thresholds_gen_poll_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX]; diff --git a/openair1/PHY/extern.h b/openair1/PHY/extern.h index 4c9e2706c78a6055a72546c6c7d102bf87399b98..2144c4f01d93b80225c1760f4b1020135964e7bc 100755 --- a/openair1/PHY/extern.h +++ b/openair1/PHY/extern.h @@ -111,6 +111,9 @@ extern double p_qam64[8]; extern double beta1_dlsch[6][MCS_COUNT]; extern double beta2_dlsch[6][MCS_COUNT]; +extern char eNB_functions[5][20]; +extern char eNB_timing[2][20]; + #endif /*__PHY_EXTERN_H__ */ diff --git a/openair1/PHY/vars.h b/openair1/PHY/vars.h index 3d940d4a94a2b58b52af104f884783f3fa0beacd..85bfe7a2a65b41b88e6da9c0af695f4106da2667 100755 --- a/openair1/PHY/vars.h +++ b/openair1/PHY/vars.h @@ -139,6 +139,9 @@ double beta2_dlsch[6][MCS_COUNT] = { {2.52163, 0.83231, 0.77472, 1.36536, 1.1682 */ +char eNB_functions[5][20]={"eNodeB_3GPP","eNodeB_3GPP_BBU","NGFI_RRU_IF5","NGFI_RRU_IF4","NGFI_RCC_IF4"}; +char eNB_timing[2][20]={"synch_to_ext_device","synch_to_other"}; + #endif /*__PHY_VARS_H__ */ diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index ecaeb20fa8d36bd75876a59538b29c7760881852..43edfa807d4a6505643e4d83066b2ed8f2c524d0 100755 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -3236,99 +3236,3 @@ int phy_procedures_RN_eNB_TX(unsigned char last_slot, unsigned char next_slot, r return do_proc; } #endif -/* -void phy_procedures_eNB_lte(unsigned char subframe,PHY_VARS_eNB **eNB,uint8_t abstraction_flag, - relaying_type_t r_type, PHY_VARS_RN *rn) -{ -#if defined(ENABLE_ITTI) - MessageDef *msg_p; - const char *msg_name; - instance_t instance; - unsigned int Mod_id; - int result; -#endif - - - int CC_id=0; - - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB, eNB[0]->proc[subframe].frame_tx); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_LTE,1); - start_meas(&eNB[0]->phy_proc); - -#if defined(ENABLE_ITTI) - - do { - // Checks if a message has been sent to PHY sub-task - itti_poll_msg (TASK_PHY_ENB, &msg_p); - - if (msg_p != NULL) { - msg_name = ITTI_MSG_NAME (msg_p); - instance = ITTI_MSG_INSTANCE (msg_p); - Mod_id = instance; - - switch (ITTI_MSG_ID(msg_p)) { - - // Messages from eNB app - case PHY_CONFIGURATION_REQ: - LOG_I(PHY, "[eNB %d] Received %s\n", instance, msg_name); - // TODO - - break; - - default: - LOG_E(PHY, "[ENB %d] Received unexpected message %s\n", Mod_id, msg_name); - break; - } - - result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - } - } while(msg_p != NULL); - -#endif - - - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - if ((((eNB[CC_id]->frame_parms.frame_type == TDD)&& - (subframe_select(&eNB[CC_id]->frame_parms,eNB[CC_id]->proc[0].subframe_tx)==SF_DL))|| - (eNB[CC_id]->frame_parms.frame_type == FDD))) { -#ifdef Rel10 - - if (phy_procedures_RN_eNB_TX(eNB[CC_id]->proc[0].subframe_rx, eNB[CC_id]->proc[0].subframe_tx, r_type) != 0 ) -#endif - phy_procedures_eNB_TX(subframe,eNB[CC_id],abstraction_flag,r_type,rn); - } - - if ((((eNB[CC_id]->frame_parms.frame_type == TDD )&& - (subframe_select(&eNB[CC_id]->frame_parms,eNB[CC_id]->proc[0].subframe_rx)==SF_UL)) || - (eNB[CC_id]->frame_parms.frame_type == FDD))) { - phy_procedures_eNB_RX(subframe,eNB[CC_id],abstraction_flag,r_type); - } - - if (subframe_select(&eNB[CC_id]->frame_parms,eNB[CC_id]->proc[0].subframe_tx)==SF_S) { -#ifdef Rel10 - - if (phy_procedures_RN_eNB_TX(subframe, subframe, r_type) != 0 ) -#endif - phy_procedures_eNB_TX(subframe,eNB[CC_id],abstraction_flag,r_type,rn); - } - - if ((subframe_select(&eNB[CC_id]->frame_parms,eNB[CC_id]->proc[0].subframe_rx)==SF_S)) { - phy_procedures_eNB_S_RX(subframe,eNB[CC_id],abstraction_flag,r_type); - } - - eNB[CC_id]->proc[0].frame_tx++; - eNB[CC_id]->proc[0].frame_rx++; - - if (eNB[CC_id]->proc[0].frame_tx>=MAX_FRAME_NUMBER) // defined in impl_defs_top.h - eNB[CC_id]->proc[0].frame_tx-=MAX_FRAME_NUMBER; - - if (eNB[CC_id]->proc[0].frame_rx>=MAX_FRAME_NUMBER) - eNB[CC_id]->proc[0].frame_rx-=MAX_FRAME_NUMBER; - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_LTE,0); - stop_meas(&eNB[0]->phy_proc); -} -*/ diff --git a/openair2/UTIL/OCG/OCG.h b/openair2/UTIL/OCG/OCG.h index cf96de7963dab64806482a743426538288d9fbd3..c47cc8e8c7a3dde20ba2a7edc5b960471024b410 100644 --- a/openair2/UTIL/OCG/OCG.h +++ b/openair2/UTIL/OCG/OCG.h @@ -707,6 +707,8 @@ typedef struct { // phy related params unsigned int n_frames; unsigned int n_frames_flag; // if set, then let the emulation goes to infinity + node_function_t node_function[MAX_NUM_CCs]; + node_timing_t node_timing[MAX_NUM_CCS]; unsigned char frame_type[MAX_NUM_CCs]; //! LTE frame type (TDD=1, FDD=0). \note this should be converted to \ref lte_frame_type_t (header file reorganization needed) char * frame_type_name[MAX_NUM_CCs]; unsigned char tdd_config[MAX_NUM_CCs]; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_no_mme.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_no_mme.conf index 50cb6747acba76737f576a55e8a36a2aa67a931a..3ec8ea01da7c99e050b0340706a181ad6db6683e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_no_mme.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_no_mme.conf @@ -23,6 +23,8 @@ eNBs = component_carriers = ( { + node_function = "eNodeB_3GPP"; + node_timing = "SYNCH_TO_OTHER"; frame_type = "FDD"; tdd_config = 3; tdd_config_s = 0; diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 3317d289e06512b53e4b6e15597460c043bcefc1..ba7921e4082d678a05c12140b852eb814d25f1ee 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -157,7 +157,7 @@ static struct { void exit_fun(const char* s); -void init_eNB(eNB_func_t node_function); +void init_eNB(eNB_func_t node_function,int nb_inst); void stop_eNB(void); @@ -350,7 +350,7 @@ static void* eNB_thread_rxtx( void* param ) { /* Set affinity mask to include CPUs 1 to MAX_CPUS */ /* CPU 0 is reserved for UHD threads */ - /* CPU 1 is reserved for all TX threads */ + /* CPU 1 is reserved for all RX_TX threads */ /* Enable CPU Affinity only if number of CPUs >2 */ CPU_ZERO(&cpuset); @@ -398,7 +398,7 @@ static void* eNB_thread_rxtx( void* param ) { exit_fun("Error getting thread priority"); } - LOG_I(HW, "[SCHED][eNB] TX thread started on CPU %d TID %ld, sched_policy = %s , priority = %d, CPU Affinity=%s \n",sched_getcpu(),gettid(), + LOG_I(HW, "[SCHED][eNB] RXn_TXnp4 thread started on CPU %d TID %ld, sched_policy = %s , priority = %d, CPU Affinity=%s \n",sched_getcpu(),gettid(), (policy == SCHED_FIFO) ? "SCHED_FIFO" : (policy == SCHED_RR) ? "SCHED_RR" : (policy == SCHED_OTHER) ? "SCHED_OTHER" : @@ -644,12 +644,103 @@ static void* eNB_thread_asynch_rx( void* param ) { LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; openair0_timestamp timestamp_rx; int frame_rx,subframe_rx; - int first_rx = 1; + static int first_rx = 1; uint16_t packet_type; uint32_t symbol_number=0; uint32_t symbol_mask, symbol_mask_full; int prach_rx; +#ifdef DEADLINE_SCHEDULER + struct sched_attr attr; + unsigned int flags = 0; + uint64_t runtime = 870000 ; + uint64_t deadline = 1 * 1000000; + uint64_t period = 1 * 10000000; // each rx thread has a period of 10ms from the starting point + + attr.size = sizeof(attr); + attr.sched_flags = 0; + attr.sched_nice = 0; + attr.sched_priority = 0; + + attr.sched_policy = SCHED_DEADLINE; + attr.sched_runtime = runtime; + attr.sched_deadline = deadline; + attr.sched_period = period; + + if (sched_setattr(0, &attr, flags) < 0 ) { + perror("[SCHED] eNB FH sched_setattr failed\n"); + return &eNB_thread_FH_status; + } + + LOG_I( HW, "[SCHED] eNB asynch RX deadline thread (TID %ld) started on CPU %d\n", gettid(), sched_getcpu() ); +#else // LOW_LATENCY + int policy, s, j; + struct sched_param sparam; + char cpu_affinity[1024]; + cpu_set_t cpuset; + + /* Set affinity mask to include CPUs 1 to MAX_CPUS */ + /* CPU 0 is reserved for UHD */ + /* CPU 1 is reserved for all TX threads */ + /* CPU 2..MAX_CPUS is reserved for all RX threads */ + /* Set CPU Affinity only if number of CPUs >2 */ + CPU_ZERO(&cpuset); +#ifdef CPU_AFFINITY + if (get_nprocs() >2) { + for (j = 1; j < get_nprocs(); j++) + CPU_SET(j, &cpuset); + + s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) { + perror( "pthread_setaffinity_np"); + exit_fun (" Error setting processor affinity :"); + } + } +#endif //CPU_AFFINITY + /* Check the actual affinity mask assigned to the thread */ + + s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) { + perror ("pthread_getaffinity_np"); + exit_fun (" Error getting processor affinity :"); + } + memset(cpu_affinity,0, sizeof(cpu_affinity)); + + for (j = 0; j < CPU_SETSIZE; j++) + if (CPU_ISSET(j, &cpuset)) { + char temp[1024]; + sprintf (temp, " CPU_%d", j); + strcat(cpu_affinity, temp); + } + + memset(&sparam, 0 , sizeof (sparam)); + sparam.sched_priority = sched_get_priority_max(SCHED_FIFO); + + policy = SCHED_FIFO ; + s = pthread_setschedparam(pthread_self(), policy, &sparam); + if (s != 0) { + perror("pthread_setschedparam : "); + exit_fun("Error setting thread priority"); + } + + memset(&sparam, 0 , sizeof (sparam)); + + s = pthread_getschedparam(pthread_self(), &policy, &sparam); + if (s != 0) { + perror("pthread_getschedparam"); + exit_fun("Error getting thread priority"); + } + + LOG_I(HW, "[SCHED][eNB] eNB asynch RX thread started on CPU %d TID %ld, sched_policy = %s, priority = %d, CPU Affinity = %s\n", sched_getcpu(),gettid(), + (policy == SCHED_FIFO) ? "SCHED_FIFO" : + (policy == SCHED_RR) ? "SCHED_RR" : + (policy == SCHED_OTHER) ? "SCHED_OTHER" : + "???", + sparam.sched_priority, cpu_affinity); + + +#endif // DEADLINE_SCHEDULER + if (eNB->node_function == eNodeB_3GPP_BBU) { // acquisition from IF /// **** recv_IF5 of rxdata from RRH **** /// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 ); @@ -772,11 +863,11 @@ static void* eNB_thread_FH( void* param ) { attr.sched_period = period; if (sched_setattr(0, &attr, flags) < 0 ) { - perror("[SCHED] eNB RX sched_setattr failed\n"); + perror("[SCHED] eNB FH sched_setattr failed\n"); return &eNB_thread_FH_status; } - LOG_I( HW, "[SCHED] eNB RX deadline thread (TID %ld) started on CPU %d\n", gettid(), sched_getcpu() ); + LOG_I( HW, "[SCHED] eNB FH deadline thread (TID %ld) started on CPU %d\n", gettid(), sched_getcpu() ); #else // LOW_LATENCY int policy, s, j; struct sched_param sparam; @@ -835,7 +926,7 @@ static void* eNB_thread_FH( void* param ) { exit_fun("Error getting thread priority"); } - LOG_I(HW, "[SCHED][eNB] RX thread started on CPU %d TID %ld, sched_policy = %s, priority = %d, CPU Affinity = %s\n", sched_getcpu(),gettid(), + LOG_I(HW, "[SCHED][eNB] FH thread started on CPU %d TID %ld, sched_policy = %s, priority = %d, CPU Affinity = %s\n", sched_getcpu(),gettid(), (policy == SCHED_FIFO) ? "SCHED_FIFO" : (policy == SCHED_RR) ? "SCHED_RR" : (policy == SCHED_OTHER) ? "SCHED_OTHER" : @@ -848,8 +939,8 @@ static void* eNB_thread_FH( void* param ) { mlockall(MCL_CURRENT | MCL_FUTURE); - // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe of TX and RX threads - printf( "waiting for sync (eNB_thread_rx_common)\n"); + // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe + printf( "waiting for sync (eNB_thread_FH)\n"); pthread_mutex_lock( &sync_mutex ); while (sync_var<0) @@ -1080,8 +1171,8 @@ static void* eNB_thread_FH( void* param ) { break; } } else { - LOG_W( PHY,"[eNB] Frame %d, FH CC_id %d thread busy!! (cnt_rxtx %i)\n",slave_proc->frame_rx,slave_proc->CC_id, cnt_slave); - exit_fun( "TX thread busy" ); + LOG_W( PHY,"[eNB] Frame %d, FH CC_id %d thread busy!! (cnt_FH %i)\n",slave_proc->frame_rx,slave_proc->CC_id, cnt_slave); + exit_fun( "FH thread busy" ); break; } } @@ -1324,91 +1415,94 @@ static void* eNB_thread_prach( void* param ) { } -void init_eNB_proc(void) { +void init_eNB_proc(int nb_inst) { int i; int CC_id; PHY_VARS_eNB *eNB; eNB_proc_t *proc; eNB_rxtx_proc_t *proc_rxtx; - - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - eNB = PHY_vars_eNB_g[0][CC_id]; - - proc = &eNB->proc; - proc_rxtx = proc->proc_rxtx; + int inst; + + for (inst = 0; inst < nb_inst; inst++) { + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + eNB = PHY_vars_eNB_g[inst][CC_id]; + LOG_I(PHY,"Initializing eNB %d CC_id %d (%s,%s),\n",inst,CC_id,eNB_functions[eNB->node_function],eNB_timing[eNB->node_timing]); + proc = &eNB->proc; + proc_rxtx = proc->proc_rxtx; #ifndef DEADLINE_SCHEDULER - /* - pthread_attr_init( &attr_eNB_proc_tx[CC_id][i] ); - if (pthread_attr_setstacksize( &attr_eNB_proc_tx[CC_id][i], 64 *PTHREAD_STACK_MIN ) != 0) - perror("[ENB_PROC_TX] setting thread stack size failed\n"); - - pthread_attr_init( &attr_eNB_proc_rx[CC_id][i] ); - if (pthread_attr_setstacksize( &attr_eNB_proc_rx[CC_id][i], 64 * PTHREAD_STACK_MIN ) != 0) - perror("[ENB_PROC_RX] setting thread stack size failed\n"); - */ - // set the kernel scheduling policy and priority - proc_rxtx[0].sched_param_rxtx.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY; - pthread_attr_setschedparam (&proc_rxtx[0].attr_rxtx, &proc_rxtx[0].sched_param_rxtx); - pthread_attr_setschedpolicy (&proc_rxtx[0].attr_rxtx, SCHED_FIFO); - proc_rxtx[1].sched_param_rxtx.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY; - pthread_attr_setschedparam (&proc_rxtx[1].attr_rxtx, &proc_rxtx[1].sched_param_rxtx); - pthread_attr_setschedpolicy (&proc_rxtx[1].attr_rxtx, SCHED_FIFO); - - proc->sched_param_FH.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY; - pthread_attr_setschedparam (&proc->attr_FH, &proc->sched_param_FH); - pthread_attr_setschedpolicy (&proc->attr_FH, SCHED_FIFO); - - proc->sched_param_prach.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY; - pthread_attr_setschedparam (&proc->attr_prach, &proc->sched_param_prach); - pthread_attr_setschedpolicy (&proc->attr_prach, SCHED_FIFO); - - printf("Setting OS scheduler to SCHED_FIFO for eNB [cc%d][thread%d] \n",CC_id, i); + /* + pthread_attr_init( &attr_eNB_proc_tx[CC_id][i] ); + if (pthread_attr_setstacksize( &attr_eNB_proc_tx[CC_id][i], 64 *PTHREAD_STACK_MIN ) != 0) + perror("[ENB_PROC_TX] setting thread stack size failed\n"); + + pthread_attr_init( &attr_eNB_proc_rx[CC_id][i] ); + if (pthread_attr_setstacksize( &attr_eNB_proc_rx[CC_id][i], 64 * PTHREAD_STACK_MIN ) != 0) + perror("[ENB_PROC_RX] setting thread stack size failed\n"); + */ + // set the kernel scheduling policy and priority + proc_rxtx[0].sched_param_rxtx.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY; + pthread_attr_setschedparam (&proc_rxtx[0].attr_rxtx, &proc_rxtx[0].sched_param_rxtx); + pthread_attr_setschedpolicy (&proc_rxtx[0].attr_rxtx, SCHED_FIFO); + proc_rxtx[1].sched_param_rxtx.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY; + pthread_attr_setschedparam (&proc_rxtx[1].attr_rxtx, &proc_rxtx[1].sched_param_rxtx); + pthread_attr_setschedpolicy (&proc_rxtx[1].attr_rxtx, SCHED_FIFO); + + proc->sched_param_FH.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY; + pthread_attr_setschedparam (&proc->attr_FH, &proc->sched_param_FH); + pthread_attr_setschedpolicy (&proc->attr_FH, SCHED_FIFO); + + proc->sched_param_prach.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY; + pthread_attr_setschedparam (&proc->attr_prach, &proc->sched_param_prach); + pthread_attr_setschedpolicy (&proc->attr_prach, SCHED_FIFO); + + printf("Setting OS scheduler to SCHED_FIFO for eNB [cc%d][thread%d] \n",CC_id, i); #endif - proc_rxtx[0].instance_cnt_rxtx = -1; - proc_rxtx[1].instance_cnt_rxtx = -1; - proc->instance_cnt_prach = -1; - proc->instance_cnt_FH = -1; - proc->CC_id = CC_id; - - proc->first_rx=4; - - pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL); - pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL); - pthread_mutex_init( &proc->mutex_prach, NULL); - pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL); - pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL); - pthread_cond_init( &proc->cond_prach, NULL); - pthread_cond_init( &proc->cond_FH, NULL); + proc_rxtx[0].instance_cnt_rxtx = -1; + proc_rxtx[1].instance_cnt_rxtx = -1; + proc->instance_cnt_prach = -1; + proc->instance_cnt_FH = -1; + proc->CC_id = CC_id; + + proc->first_rx=4; + + pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL); + pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL); + pthread_mutex_init( &proc->mutex_prach, NULL); + pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL); + pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL); + pthread_cond_init( &proc->cond_prach, NULL); + pthread_cond_init( &proc->cond_FH, NULL); #ifndef DEADLINE_SCHEDULER - pthread_create( &proc_rxtx[0].pthread_rxtx, &proc_rxtx[0].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[0] ); - pthread_create( &proc_rxtx[1].pthread_rxtx, &proc_rxtx[1].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[1] ); - pthread_create( &proc->pthread_FH, &proc->attr_FH, eNB_thread_FH, &eNB->proc ); - pthread_create( &proc->pthread_prach, &proc->attr_prach, eNB_thread_prach, &eNB->proc ); - if (eNB->node_timing == synch_to_other) - pthread_create( &proc->pthread_asynch_rx, &proc->attr_asynch_rx, eNB_thread_asynch_rx, &eNB->proc ); + pthread_create( &proc_rxtx[0].pthread_rxtx, &proc_rxtx[0].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[0] ); + pthread_create( &proc_rxtx[1].pthread_rxtx, &proc_rxtx[1].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[1] ); + pthread_create( &proc->pthread_FH, &proc->attr_FH, eNB_thread_FH, &eNB->proc ); + pthread_create( &proc->pthread_prach, &proc->attr_prach, eNB_thread_prach, &eNB->proc ); + if (eNB->node_timing == synch_to_other) + pthread_create( &proc->pthread_asynch_rx, &proc->attr_asynch_rx, eNB_thread_asynch_rx, &eNB->proc ); #else - pthread_create( &proc_rxtx[0].pthread_rxtx, NULL, eNB_thread_rxtx, &eNB->proc_rxtx[0] ); - pthread_create( &proc_rxtx[1].pthread_rxtx, NULL, eNB_thread_rxtx, &eNB->proc_rxtx[1] ); - pthread_create( &proc->pthread_FH, NULL, eNB_thread_FH, &eNB->proc ); - pthread_create( &proc->pthread_prach, NULL, eNB_thread_prach, &eNB->proc ); - if (eNB->node_timing == synch_to_other) - pthread_create( &proc->pthread_asynch_rx, NULL, eNB_thread_asynch_rx, &eNB->proc ); - + pthread_create( &proc_rxtx[0].pthread_rxtx, NULL, eNB_thread_rxtx, &eNB->proc_rxtx[0] ); + pthread_create( &proc_rxtx[1].pthread_rxtx, NULL, eNB_thread_rxtx, &eNB->proc_rxtx[1] ); + pthread_create( &proc->pthread_FH, NULL, eNB_thread_FH, &eNB->proc ); + pthread_create( &proc->pthread_prach, NULL, eNB_thread_prach, &eNB->proc ); + if (eNB->node_timing == synch_to_other) + pthread_create( &proc->pthread_asynch_rx, NULL, eNB_thread_asynch_rx, &eNB->proc ); + #endif - char name[16]; - snprintf( name, sizeof(name), "RXTX0 %d", i ); - pthread_setname_np( proc_rxtx[0].pthread_rxtx, name ); - snprintf( name, sizeof(name), "RXTX1 %d", i ); - pthread_setname_np( proc_rxtx[1].pthread_rxtx, name ); - snprintf( name, sizeof(name), "FH %d", i ); - pthread_setname_np( proc->pthread_FH, name ); + char name[16]; + snprintf( name, sizeof(name), "RXTX0 %d", i ); + pthread_setname_np( proc_rxtx[0].pthread_rxtx, name ); + snprintf( name, sizeof(name), "RXTX1 %d", i ); + pthread_setname_np( proc_rxtx[1].pthread_rxtx, name ); + snprintf( name, sizeof(name), "FH %d", i ); + pthread_setname_np( proc->pthread_FH, name ); + } + + /* setup PHY proc TX sync mechanism */ + pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL); + pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL); + sync_phy_proc.phy_proc_CC_id = 0; } - - /* setup PHY proc TX sync mechanism */ - pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL); - pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL); - sync_phy_proc.phy_proc_CC_id = 0; } @@ -1577,14 +1671,15 @@ void print_opp_meas(void) { } -void init_eNB(eNB_func_t node_function) { + void init_eNB(eNB_func_t node_function,int nb_inst) { int CC_id; - - for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) - PHY_vars_eNB_g[0][CC_id]->node_function = node_function; - - init_eNB_proc(); + int inst; + for (inst=0;inst<nb_inst;inst++) + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) + PHY_vars_eNB_g[0][CC_id]->node_function = node_function; + + init_eNB_proc(nb_inst); sleep(1); LOG_D(HW,"[lte-softmodem.c] eNB threads created\n"); diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index eedc6415747fa4054077a43f02f81f430cc48d29..d17f7b859941fcdbc2ccd6af19e56771e1c71ca8 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -119,14 +119,14 @@ unsigned short config_frames[4] = {2,9,11,13}; // In lte-enb.c extern int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]); -extern void init_eNB(eNB_func_t); +extern void init_eNB(eNB_func_t,int); extern void stop_eNB(void); extern void kill_eNB_proc(void); // In lte-ue.c extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]); extern void fill_ue_band_info(void); -extern void init_UE(void); +extern void init_UE(int); #ifdef XFORMS // current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0) @@ -284,9 +284,6 @@ eth_params_t *eth_params; openair0_config_t openair0_cfg[MAX_CARDS]; -// Change to openair_global to handle UE -openair0_device openair0; - double cpuf; char uecap_xer[1024],uecap_xer_in=0; @@ -1677,40 +1674,15 @@ int main( int argc, char **argv ) } } } - /* device host type is set*/ - openair0.host_type = BBU_HOST; - /* device type is initialized NONE_DEV (no RF device) when the RF device will be initiated device type will be set */ - openair0.type = NONE_DEV; - /* transport type is initialized NONE_TP (no transport protocol) when the transport protocol will be initiated transport protocol type will be set */ - openair0.transp_type = NONE_TP; - - // Legacy BBU - RRH init - //int returns=-1; - ///* BBU can have either a local or a remote radio head */ - //if (local_remote_radio == BBU_LOCAL_RADIO_HEAD) { //local radio head active - load library of radio head and initiate it - //if (mode!=loop_through_memory) { - //returns=openair0_device_load(&openair0, &openair0_cfg[0]); - //printf("openair0_device_init returns %d\n",returns); - //if (returns<0) { - //printf("Exiting, cannot initialize device\n"); - //exit(-1); - //} - //} - //else if (mode==loop_through_memory) { - //} - //} else { //remote radio head active - load library of transport protocol and initiate it - //if (mode!=loop_through_memory) { - //returns=openair0_transport_load(&openair0, &openair0_cfg[0], eth_params); - //printf("openair0_transport_init returns %d\n",returns); - //if (returns<0) { - //printf("Exiting, cannot initialize transport protocol\n"); - //exit(-1); - //} - //} - //else if (mode==loop_through_memory) { - //} - //} - + else { + /* device host type is set*/ + PHY_vars_UE_g[0][0]->rfdevice.host_type = BBU_HOST; + /* device type is initialized NONE_DEV (no RF device) when the RF device will be initiated device type will be set */ + PHY_vars_UE_g[0][0]->rfdevice.type = NONE_DEV; + /* transport type is initialized NONE_TP (no transport protocol) when the transport protocol will be initiated transport protocol type will be set */ + PHY_vars_UE_g[0][0]->rfdevice.transp_type = NONE_TP; + } + int returns=-1; // Handle spatially distributed MIMO antenna ports @@ -1720,7 +1692,7 @@ int main( int argc, char **argv ) if (mode!=loop_through_memory) { returns= (UE_flag == 0) ? openair0_device_load(&(PHY_vars_eNB_g[0][CC_id]->rfdevice), &openair0_cfg[0]) : - openair0_device_load(&openair0, &openair0_cfg[0]); + openair0_device_load(&(PHY_vars_UE_g[0][CC_id]->rfdevice), &openair0_cfg[0]); printf("openair0_device_init returns %d for CC_id %d\n",returns,CC_id); if (returns<0) { @@ -1904,8 +1876,8 @@ int main( int argc, char **argv ) // start the main thread - if (UE_flag == 1) init_UE(); - else init_eNB(node_function); + if (UE_flag == 1) init_UE(1); + else init_eNB(node_function,1); // Sleep to allow all threads to setup sleep(3); @@ -1978,16 +1950,18 @@ int main( int argc, char **argv ) pthread_mutex_destroy(&sync_mutex); // *** Handle per CC_id openair0 - if (UE_flag==1) - openair0.trx_end_func(&openair0); - - for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - if (PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func) - PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->rfdevice); - if (PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func) - PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->ifdevice); + if (UE_flag==1) { + if (PHY_vars_UE_g[0][0]->rfdevice.trx_end_func) + PHY_vars_UE_g[0][0]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][0]->rfdevice); + } + else { + for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + if (PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func) + PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->rfdevice); + if (PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func) + PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->ifdevice); + } } - if (ouput_vcd) VCD_SIGNAL_DUMPER_CLOSE(); diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 4fa06f1bc81b4e65b6ca98c2185277ae131a30ff..73e919758837d45ba92de12ac285b574047f4fee 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -92,9 +92,9 @@ typedef enum { si=2 } sync_mode_t; -void init_UE_threads(void); +void init_UE_threads(int nb_inst); void *UE_thread(void *arg); -void init_UE(void); +void init_UE(int nb_inst); extern pthread_cond_t sync_cond; extern pthread_mutex_t sync_mutex; @@ -105,8 +105,6 @@ extern openair0_config_t openair0_cfg[MAX_CARDS]; extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; extern openair0_rf_map rf_map[MAX_NUM_CCs]; - -extern openair0_device openair0; extern int oai_exit; extern int32_t **rxdata; @@ -176,21 +174,26 @@ pthread_t main_ue_thread; pthread_attr_t attr_UE_thread; struct sched_param sched_param_UE_thread; -void init_UE() { +void init_UE(int nb_inst) { int error_code; - - printf("Intializing UE Threads ...\n"); - init_UE_threads(); - sleep(1); - error_code = pthread_create(&main_ue_thread, &attr_UE_thread, UE_thread, NULL); - - if (error_code!= 0) { - LOG_D(HW,"[lte-softmodem.c] Could not allocate UE_thread, error %d\n",error_code); - return; - } else { - LOG_D( HW, "[lte-softmodem.c] Allocate UE_thread successful\n" ); - pthread_setname_np( main_ue_thread, "main UE" ); + int inst; + PHY_VARS_UE *UE; + + for (inst=0;inst<nb_inst;inst++) { + printf("Intializing UE Threads for instance %d ...\n",inst); + init_UE_threads(inst); + sleep(1); + UE = PHY_vars_UE_g[inst][0]; + error_code = pthread_create(&UE->proc.pthread_ue, &UE->proc.attr_ue, UE_thread, NULL); + + if (error_code!= 0) { + LOG_D(HW,"[lte-softmodem.c] Could not allocate UE_thread, error %d\n",error_code); + return; + } else { + LOG_D(HW, "[lte-softmodem.c] Allocate UE_thread successful\n" ); + pthread_setname_np( UE->proc.pthread_ue, "main UE" ); + } } printf("UE threads created\n"); @@ -362,7 +365,7 @@ static void *UE_thread_synch(void *arg) } - if (openair0.trx_start_func(&openair0) != 0 ) { + if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { LOG_E(HW,"Could not start the device\n"); oai_exit=1; } @@ -484,12 +487,12 @@ static void *UE_thread_synch(void *arg) break; } - //openair0.trx_set_freq_func(&openair0,&openair0_cfg[0],0); - //openair0.trx_set_gains_func(&openair0,&openair0_cfg[0]); - openair0.trx_stop_func(&openair0); + //UE->rfdevice.trx_set_freq_func(&openair0,&openair0_cfg[0],0); + //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]); + UE->rfdevice.trx_stop_func(&UE->rfdevice); sleep(1); init_frame_parms(&UE->frame_parms,1); - if (openair0.trx_start_func(&openair0) != 0 ) { + if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { LOG_E(HW,"Could not start the device\n"); oai_exit=1; } @@ -568,7 +571,7 @@ static void *UE_thread_synch(void *arg) } } - // openair0.trx_set_freq_func(&openair0,&openair0_cfg[0],0); + // UE->rfdevice.trx_set_freq_func(&openair0,&openair0_cfg[0],0); if (UE->UE_scan_carrier==1) { for (i=0;i<openair0_cfg[0].rx_num_channels;i++) { @@ -606,192 +609,6 @@ static void *UE_thread_synch(void *arg) return &UE_thread_synch_retval; } -/*! - * \brief This is the UE transmit thread. - * This thread performs the phy_procedures_UE_TX() on every transmit slot. - * \param arg is a pointer to a \ref PHY_VARS_UE structure. - * \returns a pointer to an int. The storage is not on the heap and must not be freed. - */ -/* -static void *UE_thread_tx(void *arg) -{ - static int UE_thread_tx_retval; - //int ret; - - PHY_VARS_UE *UE = (PHY_VARS_UE*)arg; - - UE->instance_cnt_tx=-1; - -#ifdef DEADLINE_SCHEDULER - - struct sched_attr attr; - unsigned int flags = 0; - - attr.size = sizeof(attr); - attr.sched_flags = 0; - attr.sched_nice = 0; - attr.sched_priority = 0; - - // This creates a 1ms reservation every 10ms period - attr.sched_policy = SCHED_DEADLINE; - attr.sched_runtime = 900000; // each tx thread requires .5ms to finish its job - attr.sched_deadline = 1000000; // each tx thread will finish within 1ms - attr.sched_period = 1000000; // each tx thread has a period of 1ms from the starting point - - - if (sched_setattr(0, &attr, flags) < 0 ) { - perror("[SCHED] UE_thread_tx thread: sched_setattr failed\n"); - return &UE_thread_tx_retval; - } - -#else - int policy, s, j; - struct sched_param sparam; - char cpu_affinity[1024]; - cpu_set_t cpuset; - - // Set affinity mask to include CPUs 1 to MAX_CPUS - // CPU 0 is reserved for UHD threads - CPU_ZERO(&cpuset); - - #ifdef CPU_AFFINITY - if (get_nprocs() >2) - { - for (j = 1; j < get_nprocs(); j++) - CPU_SET(j, &cpuset); - - s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) - { - perror( "pthread_setaffinity_np"); - exit_fun("Error setting processor affinity"); - } - } -#endif - - // Check the actual affinity mask assigned to the thread - - s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) - { - perror( "pthread_getaffinity_np"); - exit_fun("Error getting processor affinity "); - } - memset(cpu_affinity, 0 , sizeof(cpu_affinity)); - for (j = 0; j < CPU_SETSIZE; j++) - if (CPU_ISSET(j, &cpuset)) - { - char temp[1024]; - sprintf(temp, " CPU_%d ", j); - strcat(cpu_affinity, temp); - } - - memset(&sparam, 0 , sizeof (sparam)); - sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; - policy = SCHED_FIFO ; - - s = pthread_setschedparam(pthread_self(), policy, &sparam); - if (s != 0) - { - perror("pthread_setschedparam : "); - exit_fun("Error setting thread priority"); - } - s = pthread_getschedparam(pthread_self(), &policy, &sparam); - if (s != 0) - { - perror("pthread_getschedparam : "); - exit_fun("Error getting thread priority"); - - } - - LOG_I( HW, "[SCHED][UE] Started UE thread TX on CPU %d TID %ld , sched_policy = %s, priority = %d, CPU Affinity = %s \n", (int)sched_getcpu(), gettid(), - (policy == SCHED_FIFO) ? "SCHED_FIFO" : - (policy == SCHED_RR) ? "SCHED_RR" : - (policy == SCHED_OTHER) ? "SCHED_OTHER" : - "???", - (int) sparam.sched_priority, cpu_affinity); - - -#endif - - printf("waiting for sync (UE_thread_tx)\n"); - - pthread_mutex_lock(&sync_mutex); - printf("Locked sync_mutex, waiting (UE_thread_tx)\n"); - - while (sync_var<0) - pthread_cond_wait(&sync_cond, &sync_mutex); - - pthread_mutex_unlock(&sync_mutex); - printf("unlocked sync_mutex, waiting (UE_thread_tx)\n"); - - printf("Starting UE TX thread\n"); - - // Lock memory from swapping. This is a process wide call (not constraint to this thread). - mlockall(MCL_CURRENT | MCL_FUTURE); - - while (!oai_exit) { - - if (pthread_mutex_lock(&UE->mutex_tx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE TX\n" ); - exit_fun("nothing to add"); - return &UE_thread_tx_retval; - } - - while (UE->instance_cnt_tx < 0) { - // most of the time, the thread is waiting here - pthread_cond_wait( &UE->cond_tx, &UE->mutex_tx ); - } - - if (pthread_mutex_unlock(&UE->mutex_tx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE TX\n" ); - exit_fun("nothing to add"); - return &UE_thread_tx_retval; - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_TX, 1 ); - - if ((subframe_select( &UE->frame_parms, UE->slot_tx>>1 ) == SF_UL) || - (UE->frame_parms.frame_type == FDD)) { - phy_procedures_UE_TX( UE, 0, 0, UE->mode, no_relay ); - } - - if ((subframe_select( &UE->frame_parms, UE->slot_tx>>1 ) == SF_S) && - ((UE->slot_tx&1) == 1)) { - phy_procedures_UE_S_TX( UE, 0, 0, no_relay ); - } - - UE->slot_tx += 2; - - if (UE->slot_tx >= 20) { - UE->slot_tx -= 20; - UE->frame_tx++; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_UE, UE->frame_tx ); - } - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX_UE, UE->slot_tx>>1 ); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_TX, 0 ); - - if (pthread_mutex_lock(&UE->mutex_tx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE TX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_tx_retval; - } - - UE->instance_cnt_tx--; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_TX, UE->instance_cnt_tx); - - if (pthread_mutex_unlock(&UE->mutex_tx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE TX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_tx_retval; - } - - } - - return &UE_thread_tx_retval; -} -*/ /*! @@ -804,7 +621,7 @@ static void *UE_thread_tx(void *arg) static void *UE_thread_rxn_txnp4(void *arg) { - static int UE_thread_rx_retval; + static int UE_thread_rxtx_retval; UE_rxtx_proc_t *proc = (UE_rxtx_proc_t *)arg; int ret; PHY_VARS_UE *UE=PHY_vars_UE_g[0][proc->CC_id]; @@ -828,8 +645,8 @@ static void *UE_thread_rxn_txnp4(void *arg) attr.sched_period = 1000000; // each rx thread has a period of 1ms from the starting point if (sched_setattr(0, &attr, flags) < 0 ) { - perror("[SCHED] UE_thread_rx : sched_setattr failed\n"); - return &UE_thread_rx_retval; + perror("[SCHED] UE_thread_rxtx : sched_setattr failed\n"); + return &UE_thread_rxtx_retval; } #else @@ -914,15 +731,15 @@ static void *UE_thread_rxn_txnp4(void *arg) pthread_cond_wait(&sync_cond, &sync_mutex); pthread_mutex_unlock(&sync_mutex); - printf("unlocked sync_mutex, waiting (UE_thread_rx)\n"); + printf("unlocked sync_mutex, waiting (UE_thread_rxtx)\n"); printf("Starting UE RXN_TXNP4 thread\n"); while (!oai_exit) { if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RX\n" ); + LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); exit_fun("nothing to add"); - return &UE_thread_rx_retval; + return &UE_thread_rxtx_retval; } while (proc->instance_cnt_rxtx < 0) { @@ -933,7 +750,7 @@ static void *UE_thread_rxn_txnp4(void *arg) if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); exit_fun("nothing to add"); - return &UE_thread_rx_retval; + return &UE_thread_rxtx_retval; } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_RXTX0+(proc->subframe_rx&1), 1 ); @@ -976,23 +793,23 @@ static void *UE_thread_rxn_txnp4(void *arg) if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RX\n" ); + LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); exit_fun("noting to add"); - return &UE_thread_rx_retval; + return &UE_thread_rxtx_retval; } proc->instance_cnt_rxtx--; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_RX, proc->instance_cnt_rxtx); if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RX\n" ); + LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXTX\n" ); exit_fun("noting to add"); - return &UE_thread_rx_retval; + return &UE_thread_rxtx_retval; } } // thread finished - return &UE_thread_rx_retval; + return &UE_thread_rxtx_retval; } @@ -1105,11 +922,11 @@ void *UE_thread(void *arg) { rxp[i] = (void*)&rxdata[i][0]; if (UE->mode != loop_through_memory) { - rxs = openair0.trx_read_func(&openair0, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti*10, - UE->frame_parms.nb_antennas_rx); + rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + UE->frame_parms.samples_per_tti*10, + UE->frame_parms.nb_antennas_rx); } instance_cnt_synch = ++UE->proc.instance_cnt_synch; if (instance_cnt_synch == 0) { @@ -1132,11 +949,11 @@ void *UE_thread(void *arg) { rxp[i] = (void*)&dummy_rx[i][0]; for (int sf=0;sf<10;sf++) { // printf("Reading dummy sf %d\n",sf); - rxs = openair0.trx_read_func(&openair0, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti, - UE->frame_parms.nb_antennas_rx); + rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + UE->frame_parms.samples_per_tti, + UE->frame_parms.nb_antennas_rx); } } } @@ -1147,11 +964,11 @@ void *UE_thread(void *arg) { start_rx_stream=1; if (UE->mode != loop_through_memory) { LOG_I(PHY,"Resynchronizing RX by %d samples\n",UE->rx_offset); - rxs = openair0.trx_read_func(&openair0, - ×tamp, - (void**)rxdata, - UE->rx_offset, - UE->frame_parms.nb_antennas_rx); + rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + (void**)rxdata, + UE->rx_offset, + UE->frame_parms.nb_antennas_rx); if (rxs != UE->rx_offset) { exit_fun("problem in rx"); return &UE_thread_retval; @@ -1161,11 +978,11 @@ void *UE_thread(void *arg) { UE->proc.proc_rxtx[1].frame_rx++; // read in first symbol - rxs = openair0.trx_read_func(&openair0, - ×tamp, - (void**)rxdata, - UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, - UE->frame_parms.nb_antennas_rx); + rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + (void**)rxdata, + UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, + UE->frame_parms.nb_antennas_rx); slot_fep(UE, 0, 0, @@ -1192,21 +1009,21 @@ void *UE_thread(void *arg) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); if (UE->mode != loop_through_memory) { if (sf<9) { - rxs = openair0.trx_read_func(&openair0, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti, - UE->frame_parms.nb_antennas_rx); + rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + UE->frame_parms.samples_per_tti, + UE->frame_parms.nb_antennas_rx); } else { - rxs = openair0.trx_read_func(&openair0, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0, - UE->frame_parms.nb_antennas_rx); + rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + UE->frame_parms.samples_per_tti-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0, + UE->frame_parms.nb_antennas_rx); // read in first symbol of next frame and adjust for timing drift - rxs = openair0.trx_read_func(&openair0, + rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, ×tamp1, (void**)rxdata, UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 - rx_off_diff, @@ -1383,7 +1200,7 @@ void *UE_thread_old(void *arg) if (UE->mode != loop_through_memory) { - rxs = openair0.trx_read_func(&openair0, + rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, ×tamp, rxp, spp - ((first_rx==1) ? rx_off_diff : 0), @@ -1413,7 +1230,7 @@ void *UE_thread_old(void *arg) for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++) txp[i] = (void*)&txdata[i][txpos]; - openair0.trx_write_func(&openair0, + UE->rfdevice.trx_write_func(&openair0, (timestamp+openair0_cfg[0].tx_scheduling_advance-openair0_cfg[0].tx_sample_advance), txp, spp - ((first_rx==1) ? rx_off_diff : 0), @@ -1612,7 +1429,7 @@ void *UE_thread_old(void *arg) #ifndef USRP_DEBUG if (UE->mode != loop_through_memory) { LOG_I(PHY,"Resynchronizing RX by %d samples\n",UE->rx_offset); - rxs = openair0.trx_read_func(&openair0, + rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, ×tamp, (void**)rxdata, UE->rx_offset, @@ -1673,16 +1490,18 @@ void *UE_thread_old(void *arg) * - UE_thread_synch * and the locking between them. */ -void init_UE_threads(void) +void init_UE_threads(int inst) { - PHY_VARS_UE *UE = PHY_vars_UE_g[0][0]; - - pthread_attr_init (&attr_UE_thread); - pthread_attr_setstacksize(&attr_UE_thread,8192);//5*PTHREAD_STACK_MIN); + PHY_VARS_UE *UE; + + UE = PHY_vars_UE_g[inst][0]; + pthread_attr_init (&UE->proc.attr_ue); + pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); + #ifndef LOWLATENCY - sched_param_UE_thread.sched_priority = sched_get_priority_max(SCHED_FIFO); - pthread_attr_setschedparam(&attr_UE_thread,&sched_param_UE_thread); + UE->proc.sched_param_ue.sched_priority = sched_get_priority_max(SCHED_FIFO); + pthread_attr_setschedparam(&UE->proc.attr_ue,&sched_param_UE_thread); #endif // the threads are not yet active, therefore access is allowed without locking diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 2472328c76beea3154ab10655225f4e14f6bdcb5..f59c7d7f544feee8594e51e990f49a456e307743 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -61,22 +61,15 @@ #include "LAYER2/MAC/proto.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" -#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 // Rohde&Schwarz SMBV100A vector signal generator @@ -143,6 +136,28 @@ 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; + + +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; @@ -164,6 +179,9 @@ extern uint16_t Nid_cell; extern LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; +extern Enb_properties_array_t enb_properties; + + //#ifdef XFORMS int otg_enabled; int xforms=0; @@ -728,23 +746,32 @@ l2l1_task (void *args_p) #endif CC_id=0; - PHY_vars_eNB_g[eNB_inst][CC_id]->proc.frame_rx = frame; - PHY_vars_eNB_g[eNB_inst][CC_id]->proc.subframe_rx = sf; - PHY_vars_eNB_g[eNB_inst][CC_id]->proc.proc_rxtx[sf&1].frame_rx = frame; - PHY_vars_eNB_g[eNB_inst][CC_id]->proc.proc_rxtx[sf&1].subframe_rx = sf; - PHY_vars_eNB_g[eNB_inst][CC_id]->proc.proc_rxtx[sf&1].subframe_tx = (sf+4)%10; - PHY_vars_eNB_g[eNB_inst][CC_id]->proc.proc_rxtx[sf&1].frame_tx = (sf<6) ? frame : frame+1; - phy_procedures_eNB_common_RX(PHY_vars_eNB_g[eNB_inst][CC_id], - abstraction_flag); - phy_procedures_eNB_uespec_RX(PHY_vars_eNB_g[eNB_inst][CC_id], - &PHY_vars_eNB_g[eNB_inst][CC_id]->proc.proc_rxtx[sf&1], - abstraction_flag, - no_relay); - phy_procedures_eNB_TX(PHY_vars_eNB_g[eNB_inst][CC_id], - &PHY_vars_eNB_g[eNB_inst][CC_id]->proc.proc_rxtx[sf&1], - 0,no_relay,NULL); - - + // trigger synch event to RAN FH thread for CC_id + eNB_proc_t *proc = &PHY_vars_eNB_g[eNB_inst][CC_id]->proc; + + + if (pthread_mutex_lock(&proc->mutex_FH) != 0) { + LOG_E( PHY, "error locking mutex for FH\n"); + exit_fun( "error locking mutex" ); + break; + } + int cnt_FH = ++proc->instance_cnt_FH; + proc->frame_rx = frame; + proc->subframe_rx = sf; + proc->timestamp_rx += PHY_vars_eNB_g[eNB_inst][CC_id]->frame_parms.samples_per_tti; + + if (proc->instance_cnt_FH == 0) { + if (pthread_cond_signal(&proc->cond_FH) != 0) { + LOG_E(PHY,"ERROR pthread_cond_signal for eNB FH CCid %d\n",proc->CC_id); + exit_fun("ERROR pthread_cond_signal"); + break; + } + } + else { + LOG_W(PHY,"[eNB] Frame %d, FH CC_id %d thread busy!! (cnt_FH %d)\n",proc->instance_cnt_FH); + exit_fun("FH thread busy"); + break; + } #ifdef PRINT_STATS if((sf==9) && frame%10==0) @@ -780,109 +807,9 @@ l2l1_task (void *args_p) log_set_instance_type (LOG_INSTANCE_UE); #endif + /* 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 - { // UE_PROCEDURES - LOG_D(EMU, - "PHY procedures UE %d for frame %d, subframe %d\n", - UE_inst, frame % MAX_FRAME_NUMBER, sf); - - if (PHY_vars_UE_g[UE_inst][0]->UE_mode[0] - != NOT_SYNCHED) { - if (frame > 0) { - PHY_vars_UE_g[UE_inst][0]->proc.proc_rxtx[sf&1].frame_rx = frame % MAX_FRAME_NUMBER; - PHY_vars_UE_g[UE_inst][0]->proc.proc_rxtx[sf&1].subframe_rx = sf; - PHY_vars_UE_g[UE_inst][0]->proc.proc_rxtx[sf&1].frame_tx = ((sf<6) ? frame : frame+1)% MAX_FRAME_NUMBER; - PHY_vars_UE_g[UE_inst][0]->proc.proc_rxtx[sf&1].subframe_tx = (sf+4)%10; - -#ifdef OPENAIR2 - //Application - update_otg_UE (UE_inst, oai_emulation.info.time_ms); - - //Access layer - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE_inst, 0, ENB_FLAG_NO, NOT_A_RNTI, frame % MAX_FRAME_NUMBER, sf); - pdcp_run (&ctxt); -#endif - - for (CC_id = 0; CC_id < MAX_NUM_CCs; - CC_id++) { - phy_procedures_UE_RX(PHY_vars_UE_g[UE_inst][CC_id], - &PHY_vars_UE_g[UE_inst][CC_id]->proc.proc_rxtx[sf&1], - 0, abstraction_flag, - normal_txrx, no_relay, - NULL); - phy_procedures_UE_TX(PHY_vars_UE_g[UE_inst][CC_id], - &PHY_vars_UE_g[UE_inst][CC_id]->proc.proc_rxtx[sf&1], - 0, - abstraction_flag, - normal_txrx, - no_relay); - } - - 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) - && (sf==9)){ - - initial_sync (PHY_vars_UE_g[UE_inst][0], - normal_txrx); - - /* - write_output("dlchan00.m","dlch00",&(PHY_vars_UE_g[0]->common_vars.dl_ch_estimates[0][0][0]),(6*(PHY_vars_UE_g[0]->frame_parms.ofdm_symbol_size)),1,1); - if (PHY_vars_UE_g[0]->frame_parms.nb_antennas_rx>1) - write_output("dlchan01.m","dlch01",&(PHY_vars_UE_g[0]->common_vars.dl_ch_estimates[0][1][0]),(6*(PHY_vars_UE_g[0]->frame_parms.ofdm_symbol_size)),1,1); - write_output("dlchan10.m","dlch10",&(PHY_vars_UE_g[0]->common_vars.dl_ch_estimates[0][2][0]),(6*(PHY_vars_UE_g[0]->frame_parms.ofdm_symbol_size)),1,1); - if (PHY_vars_UE_g[0]->frame_parms.nb_antennas_rx>1) - write_output("dlchan11.m","dlch11",&(PHY_vars_UE_g[0]->common_vars.dl_ch_estimates[0][3][0]),(6*(PHY_vars_UE_g[0]->frame_parms.ofdm_symbol_size)),1,1); - write_output("rxsig.m","rxs",PHY_vars_UE_g[0]->common_vars.rxdata[0],PHY_vars_UE_g[0]->frame_parms.samples_per_tti*10,1,1); - write_output("rxsigF.m","rxsF",PHY_vars_UE_g[0]->common_vars.rxdataF[0],2*PHY_vars_UE_g[0]->frame_parms.symbols_per_tti*PHY_vars_UE_g[0]->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((sf==1) && 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], &PHY_vars_UE_g[UE_inst][0]->proc.proc_rxtx[sf&1],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 - } // UE_PROCEDURES - } - } // UE_inst - 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); @@ -942,6 +869,7 @@ l2l1_task (void *args_p) stop_meas (&ul_chan_stats); + */ if ((sf == 0) && ((frame % MAX_FRAME_NUMBER) == 0) && (abstraction_flag == 0) && (oai_emulation.info.n_frames == 1)) { @@ -1200,7 +1128,7 @@ main (int argc, char **argv) // oai performance profiler is enabled if (oai_emulation.info.opp_enabled == 1) - reset_opp_meas (); + reset_opp_meas_oaisim (); init_time (); @@ -1242,7 +1170,7 @@ main (int argc, char **argv) } void -reset_opp_meas (void) +reset_opp_meas_oaisim (void) { uint8_t eNB_id = 0, UE_id = 0; @@ -1383,7 +1311,7 @@ reset_opp_meas (void) } void -print_opp_meas (void) +print_opp_meas_oaisim (void) { uint8_t eNB_id = 0, UE_id = 0; @@ -1687,7 +1615,7 @@ oai_shutdown (void) kpi_gen (); } if (oai_emulation.info.opp_enabled == 1) - print_opp_meas (); + print_opp_meas_oaisim (); // relase all rx state if (ethernet_flag == 1) { diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index 867d578ce918f335fcc5b1150e76f85651aad478..c8f42dfdd89a6bf8dc20639550b33b5a54d28386 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -772,12 +772,13 @@ void get_simulation_options(int argc, char *argv[]) AssertFatal (oai_emulation.info.nb_enb_local <= enb_properties->number, "Number of eNB is greater than eNB defined in configuration file %s (%d/%d)!", conf_config_file_name, oai_emulation.info.nb_enb_local, enb_properties->number); - + /* Update some simulation parameters */ oai_emulation.info.frame_type[0] = enb_properties->properties[0]->frame_type[0]; oai_emulation.info.tdd_config[0] = enb_properties->properties[0]->tdd_config[0]; oai_emulation.info.tdd_config_S[0] = enb_properties->properties[0]->tdd_config_s[0]; oai_emulation.info.extended_prefix_flag[0] = enb_properties->properties[0]->prefix_type[0]; + } free(conf_config_file_name); @@ -1016,23 +1017,26 @@ void init_openair1(void) } else { PHY_vars_eNB_g[eNB_id][CC_id]->N_TA_offset = 0; } - } - } + } // eNB_id + } // CC_id - for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++) + for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++) { for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { if (phy_test==1) PHY_vars_eNB_g[eNB_id][CC_id]->mac_enabled=0; else PHY_vars_eNB_g[eNB_id][CC_id]->mac_enabled=1; } + } + + init_eNB(eNodeB_3GPP,NB_eNB_INST); // init_ue_status(); - for (UE_id=0; UE_id<NB_UE_INST; UE_id++) + for (UE_id=0; UE_id<NB_UE_INST; UE_id++) { for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - + PHY_vars_UE_g[UE_id][CC_id]->tx_power_max_dBm=23; - + PHY_vars_UE_g[UE_id][CC_id]->rx_total_gain_dB=100; // update UE_mode for each eNB_id not just 0 @@ -1065,8 +1069,10 @@ void init_openair1(void) #endif + } // CC_id + } // UE_id + init_UE(NB_UE_INST); } -} void init_openair2(void) {