From 2276996f74302c6b5a44b279fb4ca96d7ce125f7 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 27 Aug 2018 17:28:50 +0200 Subject: [PATCH 1/4] basic simulator: minor bugfix: clear memory before use --- targets/ARCH/tcp_bridge/tcp_bridge_oai.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/ARCH/tcp_bridge/tcp_bridge_oai.c b/targets/ARCH/tcp_bridge/tcp_bridge_oai.c index ba6d96db93..4d7d49d9c7 100644 --- a/targets/ARCH/tcp_bridge/tcp_bridge_oai.c +++ b/targets/ARCH/tcp_bridge/tcp_bridge_oai.c @@ -253,7 +253,7 @@ int tcp_bridge_ue_first_read(openair0_device *device, openair0_timestamp *timest tcp_bridge_state_t *t = device->priv; uint32_t b[t->samples_per_subframe * 12]; - memset(b, 0, nsamps * 4); + memset(b, 0, t->samples_per_subframe * 12 * 4); int n = fullwrite(t->sock, b, t->samples_per_subframe * 12 * 4); if (n != t->samples_per_subframe * 12 * 4) { printf("tcp_bridge: write error ret %d error %s\n", n, strerror(errno)); From 97ddf5ea28e6bac5a2ff037f34a3a568dd067913 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 27 Aug 2018 17:32:00 +0200 Subject: [PATCH 2/4] basic simulator: bugfix: wait for synch ready at the right time Before this commit we were checking for UE->is_synchronized == 0 then we were waiting for a potentially active synch routine to finish and then we were starting the synch routine again but the synch routine that was running may have set UE->is_synchronized to 1. This was leading to various problems, most notably the following message repeated over and over in the UE log and the UE unable to connect properly: [RRC] [UE 0] Frame 377: OUT OF SYNC FROM eNB 0 (T310 active 0 : T310 0, N310 345, N311 0) So let's wait for a potentially active synch routine to finish before anything else. --- targets/RT/USER/lte-ue.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index ab84249f9f..fbf0eff1cd 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -1459,18 +1459,19 @@ void *UE_thread(void *arg) { while (!oai_exit) { +#if BASIC_SIMULATOR + while (!(UE->proc.instance_cnt_synch < 0)) { + printf("ue sync not ready\n"); + usleep(500*1000); + } +#endif + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); int instance_cnt_synch = UE->proc.instance_cnt_synch; int is_synchronized = UE->is_synchronized; AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); if (is_synchronized == 0) { -#if BASIC_SIMULATOR - while (!((instance_cnt_synch = UE->proc.instance_cnt_synch) < 0)) { - printf("ue sync not ready\n"); - usleep(500*1000); - } -#endif if (instance_cnt_synch < 0) { // we can invoke the synch // grab 10 ms of signal and wakeup synch thread for (int i=0; iframe_parms.nb_antennas_rx; i++) From 164bbc65eba44b37d15207a5c39e631a06023145 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 27 Aug 2018 17:38:47 +0200 Subject: [PATCH 3/4] basic simulator: bugfix: do not put random data in DCI when not used With 50 RBs and 100 RBs the UE crashes in the basic simulator because of false detection of DCIs. Putting nothing in the unused REs in the DCI instead of random bits solves this issue and let the basic simulator run with 50 RBs and 100 RBs. Note that in the real UE the problem needs to be solved because the channel may lead to false DCI detection and the consequent crashes have to be solved. This commit sort of "hides" the issue to have the basic simulator functional. Note also that putting nothing in the unused REs in the DCI should be the normal general case. But it has not been tested with anything but the basic simulator so the previous code is left. --- openair1/PHY/LTE_TRANSPORT/dci.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c index 1c015b1c84..520488664d 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -346,6 +346,13 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, y[0] = &yseq0[0]; y[1] = &yseq1[0]; +#if BASIC_SIMULATOR + /* this should be the normal case + * but it has to be validated for all the various cases + * so let's just do it for the basic simulator + */ + memset(e, 2, DCI_BITS_MAX); +#else #if 1 // reset all bits to , here we set elements as 2 // memset(e, 2, DCI_BITS_MAX); @@ -358,6 +365,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, * (not sure about this, to be checked somehow) */ //memset(e, 0, DCI_BITS_MAX); +#endif /* BASIC_SIMULATOR */ e_ptr = e; From a48c36582ffa93f38b2b9cd18b16b4b1e3e831ca Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 27 Aug 2018 17:46:03 +0200 Subject: [PATCH 4/4] bugfix: fix threading in the UE Various problems were found with the basic simulator. Variables used by various threads for synchronization need to be initialized properly. That is before the various threads start using them. This goes for: - UE->is_synchronized - UE->proc.instance_cnt_synch - UE->proc.instance_cnt_rxtx The function "UE->rfdevice.trx_start_func" was called in "UE_thread_synch" but should be called in "UE_thread" because "UE_thread" is the one that calls "UE->rfdevice.trx_read_func" and there is no guaranty that the call to "UE->rfdevice.trx_start_func" is done before as it has to (it's in another thread). And finally "pthread_cond_signal(&proc->cond_rxtx)" was called twice, which may not be a problem but was certainly not intended. Plus removing one call simplifies the code by removing some "if" logic, which is a good thing per se. This commit was not tested with a real UE and may thus introduce some issues. Hopefully not! --- targets/RT/USER/lte-ue.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index fbf0eff1cd..66107d79a4 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -446,7 +446,6 @@ static void *UE_thread_synch(void *arg) int freq_offset=0; char threadname[128]; - UE->is_synchronized = 0; printf("UE_thread_sync in with PHY_vars_UE %p\n",arg); cpu_set_t cpuset; @@ -522,11 +521,6 @@ static void *UE_thread_synch(void *arg) printf("Started device, unlocked sync_mutex (UE_sync_thread)\n"); - if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { - LOG_E(HW,"Could not start the device\n"); - oai_exit=1; - } - while (oai_exit==0) { AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); while (UE->proc.instance_cnt_synch < 0) @@ -755,7 +749,6 @@ static void *UE_thread_rxn_txnp4(void *arg) { UE_rxtx_proc_t *proc = rtd->proc; PHY_VARS_UE *UE = rtd->UE; - proc->instance_cnt_rxtx=-1; proc->subframe_rx=proc->sub_frame_start; char threadname[256]; @@ -1457,6 +1450,10 @@ void *UE_thread(void *arg) { int sub_frame=-1; //int cumulated_shift=0; + if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { + LOG_E(HW,"Could not start the device\n"); + oai_exit=1; + } while (!oai_exit) { #if BASIC_SIMULATOR @@ -1662,12 +1659,7 @@ void *UE_thread(void *arg) { proc->instance_cnt_rxtx++; LOG_D( PHY, "[SCHED][UE %d] UE RX instance_cnt_rxtx %d subframe %d !!\n", UE->Mod_id, proc->instance_cnt_rxtx,proc->subframe_rx); - if (proc->instance_cnt_rxtx == 0) { - if (pthread_cond_signal(&proc->cond_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id); - exit_fun("nothing to add"); - } - } else { + if (proc->instance_cnt_rxtx != 0) { LOG_E( PHY, "[SCHED][UE %d] UE RX thread busy (IC %d)!!\n", UE->Mod_id, proc->instance_cnt_rxtx); if (proc->instance_cnt_rxtx > 2) exit_fun("instance_cnt_rxtx > 2"); @@ -1718,6 +1710,8 @@ void init_UE_threads(int inst) { pthread_mutex_init(&UE->proc.mutex_synch,NULL); pthread_cond_init(&UE->proc.cond_synch,NULL); + UE->proc.instance_cnt_synch = -1; + UE->is_synchronized = 0; // the threads are not yet active, therefore access is allowed without locking int nb_threads=RX_NB_TH; @@ -1729,6 +1723,7 @@ void init_UE_threads(int inst) { pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL); pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); + UE->proc.proc_rxtx[i].instance_cnt_rxtx = -1; UE->proc.proc_rxtx[i].sub_frame_start=i; UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i);