From ab7515e2804bc416df6f16e285590eb90628bf6a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 14 Sep 2018 14:58:15 +0200 Subject: [PATCH 1/2] basic simulator: handle discontinuities in output In TDD mode the eNB does not output data all the time, only in downlink and special subframes. The basic simulator needs a continuous stream of samples. So let's fill the blank with silence. --- targets/ARCH/tcp_bridge/tcp_bridge_oai.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/targets/ARCH/tcp_bridge/tcp_bridge_oai.c b/targets/ARCH/tcp_bridge/tcp_bridge_oai.c index 4d7d49d9c7..32fddb9c2d 100644 --- a/targets/ARCH/tcp_bridge/tcp_bridge_oai.c +++ b/targets/ARCH/tcp_bridge/tcp_bridge_oai.c @@ -44,6 +44,7 @@ typedef struct { int sock; int samples_per_subframe; uint64_t timestamp; + uint64_t next_tx_timestamp; int is_enb; } tcp_bridge_state_t; @@ -141,11 +142,27 @@ int tcp_bridge_write(openair0_device *device, openair0_timestamp timestamp, void { if (cc != 1) { printf("tcp_bridge: only 1 antenna supported\n"); exit(1); } tcp_bridge_state_t *t = device->priv; + /* deal with discontinuities in output (think: eNB in TDD mode) */ + if (t->next_tx_timestamp && timestamp != t->next_tx_timestamp) { + uint32_t b[4096]; + uint64_t to_send = timestamp - t->next_tx_timestamp; + memset(b, 0, 4096 * sizeof(uint32_t)); + while (to_send) { + int len = to_send > 4096 ? 4096 : to_send; + int n = fullwrite(t->sock, b, len * 4); + if (n != len * 4) { + printf("tcp_bridge: write error ret %d error %s\n", n, strerror(errno)); + abort(); + } + to_send -= len; + } + } int n = fullwrite(t->sock, buff[0], nsamps * 4); if (n != nsamps * 4) { printf("tcp_bridge: write error ret %d (wanted %d) error %s\n", n, nsamps*4, strerror(errno)); abort(); } + t->next_tx_timestamp = timestamp + nsamps; return nsamps; } From 824f62d8bfa8949dfa550245bdb3e26be36ddcd5 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 14 Sep 2018 15:01:55 +0200 Subject: [PATCH 2/2] basic simulator: support TDD mode For whatever reason we need N_TA_offset to be 0 for the basic simulator to function properly. This is more a hack than a proper solution. More analysis is needed to understand what happens and what should be really done. --- openair1/PHY/INIT/lte_param_init.c | 7 +++++++ targets/RT/USER/lte-ru.c | 6 ++++++ targets/RT/USER/lte-ue.c | 7 +++++++ 3 files changed, 20 insertions(+) diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c index 0830058a8f..dd8c2e54db 100644 --- a/openair1/PHY/INIT/lte_param_init.c +++ b/openair1/PHY/INIT/lte_param_init.c @@ -169,6 +169,13 @@ void lte_param_init(PHY_VARS_eNB **eNBp, } else ru->N_TA_offset=0; +#if BASIC_SIMULATOR + /* this is required for the basic simulator in TDD mode + * TODO: find a proper cleaner solution + */ + UE->N_TA_offset = 0; +#endif + printf("Done lte_param_init\n"); diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index d20b614ad7..1ff97386ac 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1456,6 +1456,12 @@ int setup_RU_buffers(RU_t *ru) { if (frame_parms->N_RB_DL == 100) ru->N_TA_offset = 624; else if (frame_parms->N_RB_DL == 50) ru->N_TA_offset = 624/2; else if (frame_parms->N_RB_DL == 25) ru->N_TA_offset = 624/4; +#if BASIC_SIMULATOR + /* this is required for the basic simulator in TDD mode + * TODO: find a proper cleaner solution + */ + ru->N_TA_offset = 0; +#endif } if (ru->openair0_cfg.mmapped_dma == 1) { // replace RX signal buffers with mmaped HW versions diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 66107d79a4..c49a54b98a 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -333,6 +333,13 @@ void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correcti } else UE->N_TA_offset = 0; +#if BASIC_SIMULATOR + /* this is required for the basic simulator in TDD mode + * TODO: find a proper cleaner solution + */ + UE->N_TA_offset = 0; +#endif + if (simL1flag == 1) init_ue_devices(UE); LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]); init_UE_threads(inst);