From 96786e96da7ff74f5decdac10fe4a5f56c4cc297 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 9 Jul 2018 13:15:35 +0100 Subject: [PATCH 01/88] Splitting the lib debug into phy and common debug. --- lib/include/srslte/common/debug.h | 43 ++++++++++++++ lib/include/srslte/phy/utils/debug.h | 2 - lib/src/common/debug.c | 89 ++++++++++++++++++++++++++++ lib/src/phy/utils/debug.c | 54 ----------------- 4 files changed, 132 insertions(+), 56 deletions(-) create mode 100644 lib/include/srslte/common/debug.h create mode 100644 lib/src/common/debug.c diff --git a/lib/include/srslte/common/debug.h b/lib/include/srslte/common/debug.h new file mode 100644 index 000000000..350d1336b --- /dev/null +++ b/lib/include/srslte/common/debug.h @@ -0,0 +1,43 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of the srsLTE library. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +/****************************************************************************** + * File: debug.h + * + * Description: Debug output utilities. + * + * Reference: + *****************************************************************************/ + +#ifndef SRSLTE_COMMON_DEBUG_H +#define SRSLTE_COMMON_DEBUG_H + +#include +#include "srslte/config.h" + +void srslte_debug_handle_crash(int argc, char **argv); + +#endif // SRSLTE_COMMON_DEBUG diff --git a/lib/include/srslte/phy/utils/debug.h b/lib/include/srslte/phy/utils/debug.h index 9a07272b6..7fe532eb4 100644 --- a/lib/include/srslte/phy/utils/debug.h +++ b/lib/include/srslte/phy/utils/debug.h @@ -78,6 +78,4 @@ SRSLTE_API extern int handler_registered; else{srslte_phy_log_print(LOG_LEVEL_ERROR, _fmt, ##__VA_ARGS__);} // #endif /* CMAKE_BUILD_TYPE==Debug */ -void srslte_debug_handle_crash(int argc, char **argv); - #endif // SRSLTE_DEBUG_H diff --git a/lib/src/common/debug.c b/lib/src/common/debug.c new file mode 100644 index 000000000..5eeda27bc --- /dev/null +++ b/lib/src/common/debug.c @@ -0,0 +1,89 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of the srsLTE library. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +#include +#include +#include +#include +#include + +#include "srslte/version.h" +#include "srslte/common/debug.h" + +const static char crash_file_name[] = "./srsLTE.backtrace.crash"; +static int bt_argc; +static char **bt_argv; + +static void crash_handler(int sig) { + void *array[128]; + int size; + + /* Get all stack traces */ + size = backtrace(array, 128); + + FILE *f = fopen(crash_file_name, "a"); + if (!f) { + printf("srsLTE crashed... we could not save backtrace in '%s'...\n", crash_file_name); + } else { + char **symbols = backtrace_symbols(array, size); + + time_t lnTime; + struct tm *stTime; + char strdate[32]; + + time(&lnTime); + stTime = localtime(&lnTime); + + strftime(strdate, 32, "%d/%m/%Y %H:%M:%S", stTime); + + fprintf(f, "--- command='"); + for (int i = 0; i < bt_argc; i++) { + fprintf(f, "%s%s", (i == 0) ? "" : " ", bt_argv[i]); + } + fprintf(f, "' version=%s signal=%d date='%s' ---\n", SRSLTE_VERSION_STRING, sig, strdate); + + for (int i = 0; i < size; i++) { + fprintf(f, "\t%s\n", symbols[i]); + } + fprintf(f, "\n"); + + printf("srsLTE crashed... backtrace saved in '%s'...\n", crash_file_name); + fclose(f); + } + printf("--- exiting ---\n"); + exit(1); +} + +void srslte_debug_handle_crash(int argc, char **argv) { + bt_argc = argc; + bt_argv = argv; + + signal(SIGSEGV, crash_handler); + signal(SIGABRT, crash_handler); + signal(SIGILL, crash_handler); + signal(SIGFPE, crash_handler); + signal(SIGPIPE, crash_handler); +} diff --git a/lib/src/phy/utils/debug.c b/lib/src/phy/utils/debug.c index 4b65e8d6d..17d6a79c2 100644 --- a/lib/src/phy/utils/debug.c +++ b/lib/src/phy/utils/debug.c @@ -45,57 +45,3 @@ void get_time_interval(struct timeval * tdata) { tdata[0].tv_usec += 1000000; } } - -const static char crash_file_name[] = "./srsLTE.backtrace.crash"; -static int bt_argc; -static char **bt_argv; - -static void crash_handler(int sig) { - void *array[128]; - int size; - - /* Get all stack traces */ - size = backtrace(array, 128); - - FILE *f = fopen(crash_file_name, "a"); - if (!f) { - printf("srsLTE crashed... we could not save backtrace in '%s'...\n", crash_file_name); - } else { - char **symbols = backtrace_symbols(array, size); - - time_t lnTime; - struct tm *stTime; - char strdate[32]; - - time(&lnTime); - stTime = localtime(&lnTime); - - strftime(strdate, 32, "%d/%m/%Y %H:%M:%S", stTime); - - fprintf(f, "--- command='"); - for (int i = 0; i < bt_argc; i++) { - fprintf(f, "%s%s", (i == 0) ? "" : " ", bt_argv[i]); - } - fprintf(f, "' version=%s signal=%d date='%s' ---\n", SRSLTE_VERSION_STRING, sig, strdate); - - for (int i = 0; i < size; i++) { - fprintf(f, "\t%s\n", symbols[i]); - } - fprintf(f, "\n"); - - printf("srsLTE crashed... backtrace saved in '%s'...\n", crash_file_name); - fclose(f); - } - printf("--- exiting ---\n"); - exit(1); -} - -void srslte_debug_handle_crash(int argc, char **argv) { - bt_argc = argc; - bt_argv = argv; - - signal(SIGSEGV, crash_handler); - signal(SIGABRT, crash_handler); - signal(SIGILL, crash_handler); - signal(SIGFPE, crash_handler); -} From 7aaa9a178932905f8ee8d335d1fea3e5c0963e9e Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 9 Jul 2018 14:33:50 +0100 Subject: [PATCH 02/88] Moved srslte_debug_handle_crash to common/debug.c --- lib/examples/CMakeLists.txt | 4 ++-- lib/examples/cell_measurement.c | 1 + lib/examples/pdsch_enodeb.c | 1 + lib/examples/pdsch_ue.c | 1 + lib/include/srslte/phy/utils/debug.h | 4 ++-- lib/include/srslte/srslte.h | 7 ++++--- lib/src/common/debug.c | 1 + lib/src/phy/utils/debug.c | 6 ------ srsenb/src/main.cc | 1 + srsue/src/main.cc | 1 + 10 files changed, 14 insertions(+), 13 deletions(-) diff --git a/lib/examples/CMakeLists.txt b/lib/examples/CMakeLists.txt index 3577af08e..2ab3d45fa 100644 --- a/lib/examples/CMakeLists.txt +++ b/lib/examples/CMakeLists.txt @@ -63,10 +63,10 @@ endif(SRSGUI_FOUND) if(RF_FOUND) add_executable(cell_search cell_search.c) - target_link_libraries(cell_search srslte_phy srslte_rf) + target_link_libraries(cell_search srslte_phy srslte_common srslte_rf) add_executable(cell_measurement cell_measurement.c) - target_link_libraries(cell_measurement srslte_phy srslte_rf) + target_link_libraries(cell_measurement srslte_phy srslte_common srslte_rf) add_executable(usrp_capture usrp_capture.c) target_link_libraries(usrp_capture srslte_phy srslte_rf) diff --git a/lib/examples/cell_measurement.c b/lib/examples/cell_measurement.c index 3185b74f1..d21716776 100644 --- a/lib/examples/cell_measurement.c +++ b/lib/examples/cell_measurement.c @@ -40,6 +40,7 @@ #include "srslte/srslte.h" #include "srslte/phy/rf/rf.h" #include "srslte/phy/rf/rf_utils.h" +#include "srslte/common/debug.h" cell_search_cfg_t cell_detect_config = { SRSLTE_DEFAULT_MAX_FRAMES_PBCH, diff --git a/lib/examples/pdsch_enodeb.c b/lib/examples/pdsch_enodeb.c index 2ecfee771..122067176 100644 --- a/lib/examples/pdsch_enodeb.c +++ b/lib/examples/pdsch_enodeb.c @@ -33,6 +33,7 @@ #include #include #include +#include "srslte/common/debug.h" #include #include #include "srslte/common/gen_mch_tables.h" diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index 3b84afb71..4918a52d7 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -37,6 +37,7 @@ #include #include #include "srslte/common/gen_mch_tables.h" +#include "srslte/common/debug.h" #include #include "srslte/phy/io/filesink.h" #include "srslte/srslte.h" diff --git a/lib/include/srslte/phy/utils/debug.h b/lib/include/srslte/phy/utils/debug.h index 7fe532eb4..748134284 100644 --- a/lib/include/srslte/phy/utils/debug.h +++ b/lib/include/srslte/phy/utils/debug.h @@ -32,8 +32,8 @@ * Reference: *****************************************************************************/ -#ifndef SRSLTE_DEBUG_H -#define SRSLTE_DEBUG_H +#ifndef SRSLTE_PHY_DEBUG_H +#define SRSLTE_PHY_DEBUG_H #include #include "srslte/config.h" diff --git a/lib/include/srslte/srslte.h b/lib/include/srslte/srslte.h index f87a1bf2c..0304e34ca 100644 --- a/lib/include/srslte/srslte.h +++ b/lib/include/srslte/srslte.h @@ -31,7 +31,7 @@ #ifdef __cplusplus extern "C" { #endif - + #include #include @@ -49,7 +49,8 @@ #include "srslte/phy/common/sequence.h" #include "srslte/phy/common/phy_common.h" #include "srslte/phy/common/phy_logger.h" - +#include "srslte/common/debug.h" + #include "srslte/phy/ch_estimation/chest_ul.h" #include "srslte/phy/ch_estimation/chest_dl.h" #include "srslte/phy/ch_estimation/refsignal_dl.h" @@ -104,7 +105,7 @@ #include "srslte/phy/phch/regs.h" #include "srslte/phy/phch/sch.h" #include "srslte/phy/phch/uci.h" - + #include "srslte/phy/ue/ue_sync.h" #include "srslte/phy/ue/ue_mib.h" #include "srslte/phy/ue/ue_cell_search.h" diff --git a/lib/src/common/debug.c b/lib/src/common/debug.c index 5eeda27bc..e577c8740 100644 --- a/lib/src/common/debug.c +++ b/lib/src/common/debug.c @@ -41,6 +41,7 @@ static void crash_handler(int sig) { void *array[128]; int size; + /* Get all stack traces */ size = backtrace(array, 128); diff --git a/lib/src/phy/utils/debug.c b/lib/src/phy/utils/debug.c index 17d6a79c2..dc37800cd 100644 --- a/lib/src/phy/utils/debug.c +++ b/lib/src/phy/utils/debug.c @@ -24,14 +24,8 @@ * */ -#include -#include -#include -#include #include - #include "srslte/phy/utils/debug.h" -#include "srslte/version.h" int srslte_verbose = 0; int handler_registered = 0; diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index eab5d4bcf..5c86570d8 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -31,6 +31,7 @@ #include #include "srslte/common/config_file.h" +#include "srslte/common/debug.h" #include #include diff --git a/srsue/src/main.cc b/srsue/src/main.cc index f71f9ac6f..4279c8286 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -38,6 +38,7 @@ #include "srsue/hdr/ue.h" #include "srslte/common/config_file.h" +#include "srslte/common/debug.h" #include "srslte/srslte.h" #include "srsue/hdr/metrics_stdout.h" #include "srsue/hdr/metrics_csv.h" From d00662708fc37939d4337768940dfb171081652f Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 9 Jul 2018 14:39:19 +0100 Subject: [PATCH 03/88] Added srslte_debug_handle_crash to EPC. --- srsepc/src/main.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index beed67709..24e507f6f 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -278,12 +278,14 @@ level(std::string l) int main (int argc,char * argv[] ) -{ - cout << endl <<"--- Software Radio Systems EPC ---" << endl << endl; +{ signal(SIGINT, sig_int_handler); signal(SIGTERM, sig_int_handler); signal(SIGKILL, sig_int_handler); + cout << endl <<"--- Software Radio Systems EPC ---" << endl << endl; + srslte_debug_handle_crash(argc, argv); + all_args_t args; parse_args(&args, argc, argv); From 1a7e746a067f1b6989cea0edcd673a139f95d1ee Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 11 Jul 2018 15:42:51 +0200 Subject: [PATCH 04/88] Minor cleanup --- lib/src/upper/rlc_um.cc | 2 +- srsue/src/phy/phch_recv.cc | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 3ba471724..4ddf4b2b0 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -204,7 +204,7 @@ void rlc_um::write_sdu_nb(byte_buffer_t *sdu) } if (sdu) { if (tx_sdu_queue.try_write(sdu)) { - log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B,tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes); + log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B,tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes, tx_sdu_queue.size()); } else { log->debug_hex(sdu->msg, sdu->N_bytes, "[Dropped SDU] %s Tx SDU (%d B,tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes, tx_sdu_queue.size()); pool->deallocate(sdu); diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 8ab51d90c..9f9ef945d 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -26,8 +26,6 @@ #include #include -#include -#include #include "srslte/srslte.h" #include "srslte/common/log.h" #include "srsue/hdr/phy/phch_worker.h" From 229569cd76da2900f813790a46da5762989dcac4 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 11 Jul 2018 14:49:39 +0200 Subject: [PATCH 05/88] Fix Aperiodic CQI retx when TBS=0 --- srsue/hdr/mac/ul_harq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/hdr/mac/ul_harq.h b/srsue/hdr/mac/ul_harq.h index 6fb27be8a..d62a94aba 100644 --- a/srsue/hdr/mac/ul_harq.h +++ b/srsue/hdr/mac/ul_harq.h @@ -227,7 +227,7 @@ private: if (grant->has_cqi_request && grant->phy_grant.ul.mcs.tbs == 0) { /* Only CQI reporting (without SCH) */ memcpy(&action->phy_grant.ul, &grant->phy_grant.ul, sizeof(srslte_ra_ul_grant_t)); - memcpy(&cur_grant, grant, sizeof(Tgrant)); + //memcpy(&cur_grant, grant, sizeof(Tgrant)); action->tx_enabled = true; action->rnti = grant->rnti; } else if ((!(grant->rnti_type == SRSLTE_RNTI_TEMP) && grant->ndi[0] != get_ndi() && harq_feedback) || From d95d0e2e7a9c7f49694215c54040837b93ac9fd7 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sat, 7 Jul 2018 11:12:28 +0200 Subject: [PATCH 06/88] Fix issue #179 in master --- srsenb/src/upper/rrc.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/srsenb/src/upper/rrc.cc b/srsenb/src/upper/rrc.cc index 3a9bbd0f2..2e481ce6e 100644 --- a/srsenb/src/upper/rrc.cc +++ b/srsenb/src/upper/rrc.cc @@ -1853,11 +1853,7 @@ int rrc::ue::sr_allocate(uint32_t period, uint32_t *I_sr, uint32_t *N_pucch_sr) return -1; } if (parent->cfg.sr_cfg.sf_mapping[j_min] < period) { - if (period > 5) { - *I_sr = period - 5 + parent->cfg.sr_cfg.sf_mapping[j_min]; - } else { - *I_sr = period + parent->cfg.sr_cfg.sf_mapping[j_min]; - } + *I_sr = period - 5 + parent->cfg.sr_cfg.sf_mapping[j_min]; } else { parent->rrc_log->error("Allocating SR: invalid sf_idx=%d for period=%d\n", parent->cfg.sr_cfg.sf_mapping[j_min], period); return -1; From 30dd539220842c0647e7dcf1d134f7cf40e7a969 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sat, 7 Jul 2018 12:17:55 +0200 Subject: [PATCH 07/88] Add rwlock to sched class --- srsenb/hdr/mac/scheduler.h | 6 +- srsenb/src/enb.cc | 14 +++++ srsenb/src/mac/scheduler.cc | 112 ++++++++++++++++++++++++++++-------- 3 files changed, 106 insertions(+), 26 deletions(-) diff --git a/srsenb/hdr/mac/scheduler.h b/srsenb/hdr/mac/scheduler.h index 0c69bcbef..519343097 100644 --- a/srsenb/hdr/mac/scheduler.h +++ b/srsenb/hdr/mac/scheduler.h @@ -151,8 +151,10 @@ private: metric_ul *ul_metric; srslte::log *log_h; rrc_interface_mac *rrc; - - cell_cfg_t cfg; + + pthread_rwlock_t rwlock; + + cell_cfg_t cfg; sched_args_t sched_cfg; const static int MAX_PRB = 100; diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index f1e237568..c5660e0f0 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -205,6 +205,20 @@ bool enb::init(all_args_t *args_) fprintf(stderr, "Error parsing DRB configuration\n"); return false; } + + uint32_t prach_freq_offset = rrc_cfg.sibs[1].sib.sib2.rr_config_common_sib.prach_cnfg.prach_cnfg_info.prach_freq_offset; + + if (prach_freq_offset + 6 > cell_cfg.nof_prb) { + fprintf(stderr, "Invalid PRACH configuration: frequency offset=%d outside bandwidth limits\n", prach_freq_offset); + return false; + } + + if (prach_freq_offset < rrc_cfg.cqi_cfg.nof_prb || prach_freq_offset < rrc_cfg.sr_cfg.nof_prb ) { + fprintf(stderr, "Invalid PRACH configuration: frequency offset=%d lower than CQI offset: %d or SR offset: %d\n", + prach_freq_offset, rrc_cfg.cqi_cfg.nof_prb, rrc_cfg.sr_cfg.nof_prb); + return false; + } + rrc_cfg.inactivity_timeout_ms = args->expert.rrc_inactivity_timer; rrc_cfg.enable_mbsfn = args->expert.enable_mbsfn; diff --git a/srsenb/src/mac/scheduler.cc b/srsenb/src/mac/scheduler.cc index 4bebfb3d9..8737d9168 100644 --- a/srsenb/src/mac/scheduler.cc +++ b/srsenb/src/mac/scheduler.cc @@ -62,11 +62,16 @@ sched::sched() : bc_aggr_level(0), rar_aggr_level(0), avail_rbg(0), P(0), start_ bzero(rar_locations[i], sizeof(sched_ue::sched_dci_cce_t) * 10); } reset(); + + pthread_rwlock_init(&rwlock, NULL); } sched::~sched() { srslte_regs_free(®s); + pthread_rwlock_wrlock(&rwlock); + pthread_rwlock_unlock(&rwlock); + pthread_rwlock_destroy(&rwlock); } void sched::init(rrc_interface_mac *rrc_, srslte::log* log) @@ -86,9 +91,11 @@ int sched::reset() bzero(pending_msg3, sizeof(pending_msg3_t)*10); bzero(pending_rar, sizeof(sched_rar_t)*SCHED_MAX_PENDING_RAR); bzero(pending_sibs, sizeof(sched_sib_t)*MAX_SIBS); + configured = false; + pthread_rwlock_wrlock(&rwlock); ue_db.clear(); - configured = false; - return 0; + pthread_rwlock_unlock(&rwlock); + return 0; } void sched::set_sched_cfg(sched_interface::sched_args_t* sched_cfg_) @@ -152,9 +159,11 @@ int sched::cell_cfg(sched_interface::cell_cfg_t* cell_cfg) int sched::ue_cfg(uint16_t rnti, sched_interface::ue_cfg_t *ue_cfg) { // Add or config user - ue_db[rnti].set_cfg(rnti, ue_cfg, &cfg, ®s, log_h); + pthread_rwlock_rdlock(&rwlock); + ue_db[rnti].set_cfg(rnti, ue_cfg, &cfg, ®s, log_h); ue_db[rnti].set_max_mcs(sched_cfg.pusch_max_mcs, sched_cfg.pdsch_max_mcs); ue_db[rnti].set_fixed_mcs(sched_cfg.pusch_mcs, sched_cfg.pdsch_mcs); + pthread_rwlock_unlock(&rwlock); return 0; } @@ -162,167 +171,198 @@ int sched::ue_cfg(uint16_t rnti, sched_interface::ue_cfg_t *ue_cfg) int sched::ue_rem(uint16_t rnti) { int ret = 0; + pthread_rwlock_wrlock(&rwlock); if (ue_db.count(rnti)) { ue_db.erase(rnti); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_rwlock_unlock(&rwlock); return ret; } bool sched::ue_exists(uint16_t rnti) { - return (ue_db.count(rnti) == 1); + pthread_rwlock_rdlock(&rwlock); + bool ret = (ue_db.count(rnti) == 1); + pthread_rwlock_unlock(&rwlock); + return ret; } void sched::phy_config_enabled(uint16_t rnti, bool enabled) { + pthread_rwlock_rdlock(&rwlock); if (ue_db.count(rnti)) { ue_db[rnti].phy_config_enabled(current_tti, enabled); } else { Error("User rnti=0x%x not found\n", rnti); } + pthread_rwlock_unlock(&rwlock); } int sched::bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, sched_interface::ue_bearer_cfg_t *cfg) { int ret = 0; - if (ue_db.count(rnti)) { + pthread_rwlock_rdlock(&rwlock); + if (ue_db.count(rnti)) { ue_db[rnti].set_bearer_cfg(lc_id, cfg); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_rwlock_unlock(&rwlock); return ret; } int sched::bearer_ue_rem(uint16_t rnti, uint32_t lc_id) { int ret = 0; - if (ue_db.count(rnti)) { + pthread_rwlock_rdlock(&rwlock); + if (ue_db.count(rnti)) { ue_db[rnti].rem_bearer(lc_id); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_rwlock_unlock(&rwlock); return ret; } uint32_t sched::get_dl_buffer(uint16_t rnti) { uint32_t ret = 0; - if (ue_db.count(rnti)) { + pthread_rwlock_rdlock(&rwlock); + if (ue_db.count(rnti)) { ret = ue_db[rnti].get_pending_dl_new_data(current_tti); } else { Error("User rnti=0x%x not found\n", rnti); } + pthread_rwlock_unlock(&rwlock); return ret; } uint32_t sched::get_ul_buffer(uint16_t rnti) { uint32_t ret = 0; - if (ue_db.count(rnti)) { + pthread_rwlock_rdlock(&rwlock); + if (ue_db.count(rnti)) { ret = ue_db[rnti].get_pending_ul_new_data(current_tti); } else { Error("User rnti=0x%x not found\n", rnti); } + pthread_rwlock_unlock(&rwlock); return ret; } int sched::dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) { int ret = 0; + pthread_rwlock_rdlock(&rwlock); if (ue_db.count(rnti)) { ue_db[rnti].dl_buffer_state(lc_id, tx_queue, retx_queue); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_rwlock_unlock(&rwlock); return ret; } int sched::dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code) { int ret = 0; - if (ue_db.count(rnti)) { + pthread_rwlock_rdlock(&rwlock); + if (ue_db.count(rnti)) { ue_db[rnti].mac_buffer_state(ce_code); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_rwlock_unlock(&rwlock); return ret; } int sched::dl_ant_info(uint16_t rnti, LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT *dl_ant_info) { int ret = 0; + pthread_rwlock_rdlock(&rwlock); if (ue_db.count(rnti)) { ue_db[rnti].set_dl_ant_info(dl_ant_info); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_rwlock_unlock(&rwlock); return ret; } int sched::dl_ack_info(uint32_t tti, uint16_t rnti, uint32_t tb_idx, bool ack) { int ret = 0; - if (ue_db.count(rnti)) { + pthread_rwlock_rdlock(&rwlock); + if (ue_db.count(rnti)) { ret = ue_db[rnti].set_ack_info(tti, tb_idx, ack); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_rwlock_unlock(&rwlock); return ret; } int sched::ul_crc_info(uint32_t tti, uint16_t rnti, bool crc) { int ret = 0; - if (ue_db.count(rnti)) { + pthread_rwlock_rdlock(&rwlock); + if (ue_db.count(rnti)) { ue_db[rnti].set_ul_crc(tti, crc); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_rwlock_unlock(&rwlock); return ret; } int sched::dl_ri_info(uint32_t tti, uint16_t rnti, uint32_t cqi_value) { int ret = 0; - if (ue_db.count(rnti)) { + pthread_rwlock_rdlock(&rwlock); + if (ue_db.count(rnti)) { ue_db[rnti].set_dl_ri(tti, cqi_value); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_rwlock_unlock(&rwlock); return ret; } int sched::dl_pmi_info(uint32_t tti, uint16_t rnti, uint32_t pmi_value) { int ret = 0; + pthread_rwlock_rdlock(&rwlock); if (ue_db.count(rnti)) { ue_db[rnti].set_dl_pmi(tti, pmi_value); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_rwlock_unlock(&rwlock); return ret; } int sched::dl_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi_value) { int ret = 0; + pthread_rwlock_rdlock(&rwlock); if (ue_db.count(rnti)) { ue_db[rnti].set_dl_cqi(tti, cqi_value); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_rwlock_unlock(&rwlock); return ret; } @@ -345,79 +385,93 @@ int sched::dl_rach_info(uint32_t tti, uint32_t ra_id, uint16_t rnti, uint32_t es int sched::ul_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi, uint32_t ul_ch_code) { int ret = 0; - if (ue_db.count(rnti)) { + pthread_rwlock_rdlock(&rwlock); + if (ue_db.count(rnti)) { ue_db[rnti].set_ul_cqi(tti, cqi, ul_ch_code); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_rwlock_unlock(&rwlock); return ret; } int sched::ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr, bool set_value) { int ret = 0; - if (ue_db.count(rnti)) { + pthread_rwlock_rdlock(&rwlock); + if (ue_db.count(rnti)) { ue_db[rnti].ul_buffer_state(lcid, bsr, set_value); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_rwlock_unlock(&rwlock); return ret; } int sched::ul_recv_len(uint16_t rnti, uint32_t lcid, uint32_t len) { int ret = 0; - if (ue_db.count(rnti)) { + pthread_rwlock_rdlock(&rwlock); + if (ue_db.count(rnti)) { ue_db[rnti].ul_recv_len(lcid, len); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_rwlock_unlock(&rwlock); return ret; } int sched::ul_phr(uint16_t rnti, int phr) { int ret = 0; - if (ue_db.count(rnti)) { + pthread_rwlock_rdlock(&rwlock); + if (ue_db.count(rnti)) { ue_db[rnti].ul_phr(phr); } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_rwlock_unlock(&rwlock); return ret; } int sched::ul_sr_info(uint32_t tti, uint16_t rnti) { int ret = 0; - if (ue_db.count(rnti)) { + pthread_rwlock_rdlock(&rwlock); + if (ue_db.count(rnti)) { ue_db[rnti].set_sr();; } else { Error("User rnti=0x%x not found\n", rnti); ret = -1; } + pthread_rwlock_unlock(&rwlock); return ret; } void sched::tpc_inc(uint16_t rnti) { - if (ue_db.count(rnti)) { + pthread_rwlock_rdlock(&rwlock); + if (ue_db.count(rnti)) { ue_db[rnti].tpc_inc(); } else { Error("User rnti=0x%x not found\n", rnti); } + pthread_rwlock_unlock(&rwlock); } void sched::tpc_dec(uint16_t rnti) { - if (ue_db.count(rnti)) { + pthread_rwlock_rdlock(&rwlock); + if (ue_db.count(rnti)) { ue_db[rnti].tpc_dec(); } else { Error("User rnti=0x%x not found\n", rnti); } + pthread_rwlock_unlock(&rwlock); } /******************************************************* @@ -714,6 +768,8 @@ int sched::dl_sched(uint32_t tti, sched_interface::dl_sched_res_t* sched_result) rar_aggr_level = 2; bzero(sched_result, sizeof(sched_interface::dl_sched_res_t)); + pthread_rwlock_rdlock(&rwlock); + /* Schedule Broadcast data */ sched_result->nof_bc_elems += dl_sched_bc(sched_result->bc); @@ -722,7 +778,9 @@ int sched::dl_sched(uint32_t tti, sched_interface::dl_sched_res_t* sched_result) /* Schedule pending RLC data */ sched_result->nof_data_elems += dl_sched_data(sched_result->data); - + + pthread_rwlock_unlock(&rwlock); + /* Set CFI */ sched_result->cfi = current_cfi; @@ -733,10 +791,16 @@ int sched::dl_sched(uint32_t tti, sched_interface::dl_sched_res_t* sched_result) int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched_result) { typedef std::map::iterator it_t; + if (!configured) { return 0; } + if (cfg.prach_freq_offset + 6 > cfg.cell.nof_prb) { + fprintf(stderr, "Invalid PRACH configuration: frequency offset=%d outside bandwidth limits\n", cfg.prach_freq_offset); + return -1; + } + /* If dl_sched() not yet called this tti (this tti is +4ms advanced), reset CCE state */ if (TTI_TX(current_tti) != tti) { bzero(used_cce, MAX_CCE*sizeof(bool)); @@ -757,6 +821,8 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched bzero(sched_result, sizeof(sched_interface::ul_sched_res_t)); ul_metric->reset_allocation(cfg.cell.nof_prb); + pthread_rwlock_rdlock(&rwlock); + // Get HARQ process for this TTI for(it_t iter=ue_db.begin(); iter!=ue_db.end(); ++iter) { sched_ue *user = (sched_ue*) &iter->second; @@ -819,10 +885,6 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched ul_harq_proc::ul_alloc_t prach = {cfg.prach_freq_offset, 6}; if(!ul_metric->update_allocation(prach)) { log_h->warning("SCHED: Failed to allocate PRACH RBs within (%d,%d)\n", prach.RB_start, prach.RB_start + prach.L); - if (prach.RB_start + prach.L > cfg.cell.nof_prb) { - fprintf(stderr, "Invalid PRACH configuration: frequency offset=%d outside bandwidth limits\n", cfg.prach_freq_offset); - return -1; - } } else { log_h->debug("SCHED: Allocated PRACH RBs within (%d,%d)\n", prach.RB_start, prach.RB_start + prach.L); @@ -931,6 +993,8 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched user->get_ul_harq(current_tti)->reset_pending_data(); } + pthread_rwlock_unlock(&rwlock); + sched_result->nof_dci_elems = nof_dci_elems; sched_result->nof_phich_elems = nof_phich_elems; From 3122d8e95970b8b6531f1fa9da0cf9af626157ac Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 9 Jul 2018 00:26:58 +0200 Subject: [PATCH 08/88] RLC reestablish to re-enable tx_enabled --- lib/include/srslte/upper/rlc_common.h | 1 + lib/include/srslte/upper/rlc_tm.h | 1 + lib/include/srslte/upper/rlc_um.h | 1 + lib/src/upper/rlc.cc | 6 +----- lib/src/upper/rlc_am.cc | 6 ++++++ lib/src/upper/rlc_entity.cc | 2 +- lib/src/upper/rlc_tm.cc | 6 ++++++ lib/src/upper/rlc_um.cc | 6 ++++++ 8 files changed, 23 insertions(+), 6 deletions(-) diff --git a/lib/include/srslte/upper/rlc_common.h b/lib/include/srslte/upper/rlc_common.h index a5b2e0403..c9655efae 100644 --- a/lib/include/srslte/upper/rlc_common.h +++ b/lib/include/srslte/upper/rlc_common.h @@ -163,6 +163,7 @@ public: srslte::mac_interface_timers *mac_timers_) = 0; virtual void configure(srslte_rlc_config_t cnfg) = 0; virtual void stop() = 0; + virtual void reestablish() = 0; virtual void empty_queue() = 0; virtual rlc_mode_t get_mode() = 0; diff --git a/lib/include/srslte/upper/rlc_tm.h b/lib/include/srslte/upper/rlc_tm.h index 774011292..d78ab59c4 100644 --- a/lib/include/srslte/upper/rlc_tm.h +++ b/lib/include/srslte/upper/rlc_tm.h @@ -49,6 +49,7 @@ public: mac_interface_timers *mac_timers); void configure(srslte_rlc_config_t cnfg); void stop(); + void reestablish(); void empty_queue(); rlc_mode_t get_mode(); diff --git a/lib/include/srslte/upper/rlc_um.h b/lib/include/srslte/upper/rlc_um.h index 864edaded..f099f60cf 100644 --- a/lib/include/srslte/upper/rlc_um.h +++ b/lib/include/srslte/upper/rlc_um.h @@ -57,6 +57,7 @@ public: srsue::rrc_interface_rlc *rrc_, mac_interface_timers *mac_timers_); void configure(srslte_rlc_config_t cnfg); + void reestablish(); void stop(); void empty_queue(); bool is_mrb(); diff --git a/lib/src/upper/rlc.cc b/lib/src/upper/rlc.cc index 7fa514e08..c24f0076b 100644 --- a/lib/src/upper/rlc.cc +++ b/lib/src/upper/rlc.cc @@ -130,11 +130,7 @@ void rlc::reestablish() { // defaul lcid=0 is created void rlc::reset() { - for(uint32_t i=0; ideallocate(buf); } + tx_sdu_queue.reset(); +} + +void rlc_am::reestablish() { + stop(); + tx_enabled = true; } void rlc_am::stop() diff --git a/lib/src/upper/rlc_entity.cc b/lib/src/upper/rlc_entity.cc index 4d0573043..783a14982 100644 --- a/lib/src/upper/rlc_entity.cc +++ b/lib/src/upper/rlc_entity.cc @@ -87,7 +87,7 @@ void rlc_entity::configure(srslte_rlc_config_t cnfg) // Reestablishment stops the entity but does not destroy it. Mode will not change void rlc_entity::reestablish() { - rlc->stop(); + rlc->reestablish(); } // A call to stop() stops the entity and clears deletes the instance. Next time this entity can be used for other mode. diff --git a/lib/src/upper/rlc_tm.cc b/lib/src/upper/rlc_tm.cc index c24c1ce29..988acf2af 100644 --- a/lib/src/upper/rlc_tm.cc +++ b/lib/src/upper/rlc_tm.cc @@ -68,6 +68,12 @@ void rlc_tm::empty_queue() while(ul_queue.try_read(&buf)) { pool->deallocate(buf); } + ul_queue.reset(); +} + +void rlc_tm::reestablish() { + stop(); + tx_enabled = true; } void rlc_tm::stop() diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 4ddf4b2b0..f0466c9e1 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -122,6 +122,7 @@ void rlc_um::empty_queue() { while(tx_sdu_queue.try_read(&buf)) { pool->deallocate(buf); } + tx_sdu_queue.reset(); } bool rlc_um::is_mrb() @@ -129,6 +130,11 @@ bool rlc_um::is_mrb() return cfg.is_mrb; } +void rlc_um::reestablish() { + stop(); + tx_enabled = true; +} + void rlc_um::stop() { // Empty tx_sdu_queue before locking the mutex From 08f7dda0f3f3c33be35d5bc4c20bfa9e3b7541f9 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 12 Jul 2018 11:32:26 +0200 Subject: [PATCH 09/88] Consider the case of calling gtpu::add_bearer() before initialization --- srsenb/src/upper/gtpu.cc | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/srsenb/src/upper/gtpu.cc b/srsenb/src/upper/gtpu.cc index 0f8bc3325..ba5d0a598 100644 --- a/srsenb/src/upper/gtpu.cc +++ b/srsenb/src/upper/gtpu.cc @@ -35,6 +35,14 @@ namespace srsenb { gtpu::gtpu():mchthread() { + pdcp = NULL; + gtpu_log = NULL; + gtp_bind_addr = NULL; + mme_addr = NULL; + pool = NULL; + + pthread_mutex_init(&mutex, NULL); + } bool gtpu::init(std::string gtp_bind_addr_, std::string mme_addr_, srsenb::pdcp_interface_gtpu* pdcp_, srslte::log* gtpu_log_, bool enable_mbsfn) @@ -44,8 +52,6 @@ bool gtpu::init(std::string gtp_bind_addr_, std::string mme_addr_, srsenb::pdcp_ gtp_bind_addr = gtp_bind_addr_; mme_addr = mme_addr_; - pthread_mutex_init(&mutex, NULL); - pool = byte_buffer_pool::get_instance(); // Set up sink socket @@ -155,12 +161,17 @@ void gtpu::write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t* pdu) pool->deallocate(pdu); } -// gtpu_interface_rrc +/* Warning: This function is called before calling gtpu::init() during MCCH initialization. + * If access to any element created in init (such as gtpu_log) is required, it must be considered + * the case of it being NULL. + */ void gtpu::add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out, uint32_t *teid_in) { // Allocate a TEID for the incoming tunnel rntilcid_to_teidin(rnti, lcid, teid_in); - //gtpu_log->info("Adding bearer for rnti: 0x%x, lcid: %d, addr: 0x%x, teid_out: 0x%x, teid_in: 0x%x\n", rnti, lcid, addr, teid_out, *teid_in); + if (gtpu_log) { + gtpu_log->info("Adding bearer for rnti: 0x%x, lcid: %d, addr: 0x%x, teid_out: 0x%x, teid_in: 0x%x\n", rnti, lcid, addr, teid_out, *teid_in); + } // Initialize maps if it's a new RNTI if(rnti_bearers.count(rnti) == 0) { @@ -178,6 +189,7 @@ void gtpu::add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid void gtpu::rem_bearer(uint16_t rnti, uint32_t lcid) { + pthread_mutex_lock(&mutex); gtpu_log->info("Removing bearer for rnti: 0x%x, lcid: %d\n", rnti, lcid); rnti_bearers[rnti].teids_in[lcid] = 0; @@ -193,6 +205,7 @@ void gtpu::rem_bearer(uint16_t rnti, uint32_t lcid) if(rem) { rnti_bearers.erase(rnti); } + pthread_mutex_unlock(&mutex); } void gtpu::rem_user(uint16_t rnti) From 7df91e12833e2d5bfff713bc64a725f837f1287e Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 12 Jul 2018 11:49:56 +0200 Subject: [PATCH 10/88] Fix compilation error in previous commit --- srsenb/src/upper/gtpu.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/srsenb/src/upper/gtpu.cc b/srsenb/src/upper/gtpu.cc index ba5d0a598..1d90fd388 100644 --- a/srsenb/src/upper/gtpu.cc +++ b/srsenb/src/upper/gtpu.cc @@ -37,8 +37,6 @@ gtpu::gtpu():mchthread() { pdcp = NULL; gtpu_log = NULL; - gtp_bind_addr = NULL; - mme_addr = NULL; pool = NULL; pthread_mutex_init(&mutex, NULL); From a9b023258cfdc7c4d4d77c4923d57a772987e7de Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 19 Jun 2018 11:44:54 +0200 Subject: [PATCH 11/88] refactor RLC UM to have separate tx/rx objects --- lib/include/srslte/upper/rlc_um.h | 191 ++++++--- lib/src/upper/rlc_um.cc | 649 ++++++++++++++++++------------ 2 files changed, 518 insertions(+), 322 deletions(-) diff --git a/lib/include/srslte/upper/rlc_um.h b/lib/include/srslte/upper/rlc_um.h index f099f60cf..8a3c2eb60 100644 --- a/lib/include/srslte/upper/rlc_um.h +++ b/lib/include/srslte/upper/rlc_um.h @@ -45,8 +45,7 @@ struct rlc_umd_pdu_t{ }; class rlc_um - :public timer_callback - ,public rlc_common + :public rlc_common { public: rlc_um(uint32_t queue_len = 32); @@ -59,7 +58,7 @@ public: void configure(srslte_rlc_config_t cnfg); void reestablish(); void stop(); - void empty_queue(); + void empty_queue(); bool is_mrb(); rlc_mode_t get_mode(); @@ -75,72 +74,132 @@ public: int read_pdu(uint8_t *payload, uint32_t nof_bytes); void write_pdu(uint8_t *payload, uint32_t nof_bytes); int get_increment_sequence_num(); - // Timeout callback interface - void timer_expired(uint32_t timeout_id); - - bool reordering_timeout_running(); private: - byte_buffer_pool *pool; - srslte::log *log; - uint32_t lcid; - srsue::pdcp_interface_rlc *pdcp; - srsue::rrc_interface_rlc *rrc; - mac_interface_timers *mac_timers; - - // TX SDU buffers - rlc_tx_queue tx_sdu_queue; - byte_buffer_t *tx_sdu; - byte_buffer_t tx_sdu_temp; - - // Rx window - std::map rx_window; - - // RX SDU buffers - byte_buffer_t *rx_sdu; - uint32_t vr_ur_in_rx_sdu; - - // Mutexes - pthread_mutex_t mutex; - - /**************************************************************************** - * Configurable parameters - * Ref: 3GPP TS 36.322 v10.0.0 Section 7 - ***************************************************************************/ - - srslte_rlc_um_config_t cfg; - - /**************************************************************************** - * State variables and counters - * Ref: 3GPP TS 36.322 v10.0.0 Section 7 - ***************************************************************************/ - - // Tx state variables - uint32_t vt_us; // Send state. SN to be assigned for next PDU. - - // Rx state variables - uint32_t vr_ur; // Receive state. SN of earliest PDU still considered for reordering. - uint32_t vr_ux; // t_reordering state. SN following PDU which triggered t_reordering. - uint32_t vr_uh; // Highest rx state. SN following PDU with highest SN among rxed PDUs. - - /**************************************************************************** - * Timers - * Ref: 3GPP TS 36.322 v10.0.0 Section 7 - ***************************************************************************/ - srslte::timers::timer *reordering_timer; - uint32_t reordering_timer_id; - - bool tx_enabled; - bool pdu_lost; - - int build_data_pdu(uint8_t *payload, uint32_t nof_bytes); - void handle_data_pdu(uint8_t *payload, uint32_t nof_bytes); - void reassemble_rx_sdus(); - bool inside_reordering_window(uint16_t sn); - void debug_state(); - - std::string rb_name(); + // Transmitter sub-class + class rlc_um_tx + { + public: + rlc_um_tx(uint32_t queue_len); + ~rlc_um_tx(); + void init(srslte::log *log_); + void configure(srslte_rlc_config_t cfg, std::string rb_name); + int build_data_pdu(uint8_t *payload, uint32_t nof_bytes); + void stop(); + void reestablish(); + void empty_queue(); + void write_sdu(byte_buffer_t *sdu); + void try_write_sdu(byte_buffer_t *sdu); + uint32_t get_buffer_size_bytes(); + + private: + byte_buffer_pool *pool; + srslte::log *log; + std::string rb_name; + + /**************************************************************************** + * Configurable parameters + * Ref: 3GPP TS 36.322 v10.0.0 Section 7 + ***************************************************************************/ + srslte_rlc_um_config_t cfg; + + // TX SDU buffers + rlc_tx_queue tx_sdu_queue; + byte_buffer_t *tx_sdu; + + /**************************************************************************** + * State variables and counters + * Ref: 3GPP TS 36.322 v10.0.0 Section 7 + ***************************************************************************/ + uint32_t vt_us; // Send state. SN to be assigned for next PDU. + + // Mutexes + pthread_mutex_t mutex; + + bool tx_enabled; + + // helper functions + void debug_state(); + const char* get_rb_name(); + }; + + // Receiver sub-class + class rlc_um_rx : public timer_callback { + public: + rlc_um_rx(); + ~rlc_um_rx(); + void init(srslte::log *log_, + uint32_t lcid_, + srsue::pdcp_interface_rlc *pdcp_, + srsue::rrc_interface_rlc *rrc_, + srslte::mac_interface_timers *mac_timers_); + void stop(); + void configure(srslte_rlc_config_t cfg, std::string rb_name); + void handle_data_pdu(uint8_t *payload, uint32_t nof_bytes); + void reassemble_rx_sdus(); + bool inside_reordering_window(uint16_t sn); + + // Timeout callback interface + void timer_expired(uint32_t timeout_id); + + private: + byte_buffer_pool *pool; + srslte::log *log; + mac_interface_timers *mac_timers; + std::string rb_name; + + /**************************************************************************** + * Configurable parameters + * Ref: 3GPP TS 36.322 v10.0.0 Section 7 + ***************************************************************************/ + srslte_rlc_um_config_t cfg; + + // Rx window + std::map rx_window; + + // RX SDU buffers + byte_buffer_t *rx_sdu; + uint32_t vr_ur_in_rx_sdu; + + // Rx state variables + uint32_t vr_ur; // Receive state. SN of earliest PDU still considered for reordering. + uint32_t vr_ux; // t_reordering state. SN following PDU which triggered t_reordering. + uint32_t vr_uh; // Highest rx state. SN following PDU with highest SN among rxed PDUs. + bool pdu_lost; + + // Upper layer handles and variables + srsue::pdcp_interface_rlc *pdcp; + srsue::rrc_interface_rlc *rrc; + uint32_t lcid; + + // Mutexes + pthread_mutex_t mutex; + + /**************************************************************************** + * Timers + * Ref: 3GPP TS 36.322 v10.0.0 Section 7 + ***************************************************************************/ + srslte::timers::timer *reordering_timer; + uint32_t reordering_timer_id; + + // helper functions + void debug_state(); + bool reordering_timeout_running(); + const char* get_rb_name(); + }; + + // Rx and Tx objects + rlc_um_tx tx; + rlc_um_rx rx; + + // Common variables needed by parent class + srsue::rrc_interface_rlc *rrc; + uint32_t lcid; + srslte_rlc_um_config_t cfg; + std::string rb_name; + + std::string get_rb_name(srsue::rrc_interface_rlc *rrc, uint32_t lcid, bool is_mrb); }; /**************************************************************************** diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index f0466c9e1..32c696cdc 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -33,40 +33,18 @@ namespace srslte { -rlc_um::rlc_um(uint32_t queue_len) : tx_sdu_queue(queue_len) -{ - log = NULL; - pdcp = NULL; - rrc = NULL; - reordering_timer = NULL; - lcid = 0; - reordering_timer_id = 0; +rlc_um::rlc_um(uint32_t queue_len) + :lcid(0) + ,tx(queue_len) + ,rrc(NULL) +{ bzero(&cfg, sizeof(srslte_rlc_um_config_t)); - - tx_sdu = NULL; - - rx_sdu = NULL; - pool = byte_buffer_pool::get_instance(); - - pthread_mutex_init(&mutex, NULL); - - vt_us = 0; - vr_ur = 0; - vr_ux = 0; - vr_uh = 0; - - vr_ur_in_rx_sdu = 0; - - mac_timers = NULL; - - pdu_lost = false; } // Warning: must call stop() to properly deallocate all buffers rlc_um::~rlc_um() { - pthread_mutex_destroy(&mutex); - pool = NULL; + stop(); } void rlc_um::init(srslte::log *log_, @@ -75,106 +53,81 @@ void rlc_um::init(srslte::log *log_, srsue::rrc_interface_rlc *rrc_, srslte::mac_interface_timers *mac_timers_) { - log = log_; - lcid = lcid_; - pdcp = pdcp_; - rrc = rrc_; - mac_timers = mac_timers_; - reordering_timer_id = mac_timers->timer_get_unique_id(); - reordering_timer = mac_timers->timer_get(reordering_timer_id); - tx_enabled = true; + tx.init(log_); + rx.init(log_, lcid_, pdcp_, rrc_, mac_timers_); + lcid = lcid_; + rrc = rrc_; // needed to determine bearer name during configuration } + void rlc_um::configure(srslte_rlc_config_t cnfg_) { + // determine bearer name and configure Rx/Tx objects + rb_name = get_rb_name(rrc, lcid, cnfg_.um.is_mrb); + + rx.configure(cnfg_, rb_name); + tx.configure(cnfg_, rb_name); + + // store config cfg = cnfg_.um; - if(cnfg_.um.is_mrb){ - tx_sdu_queue.resize(512); - } - switch(cnfg_.rlc_mode) - { - case LIBLTE_RRC_RLC_MODE_UM_BI: - log->warning("%s configured in %s mode: " - "t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits\n", - rb_name().c_str(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode], - cfg.t_reordering, rlc_umd_sn_size_num[cfg.rx_sn_field_length], rlc_umd_sn_size_num[cfg.rx_sn_field_length]); - break; - case LIBLTE_RRC_RLC_MODE_UM_UNI_UL: - log->warning("%s configured in %s mode: tx_sn_field_length=%u bits\n", - rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode], - - rlc_umd_sn_size_num[cfg.rx_sn_field_length]); - break; - case LIBLTE_RRC_RLC_MODE_UM_UNI_DL: - log->warning("%s configured in %s mode: " - "t_reordering=%d ms, rx_sn_field_length=%u bits\n", - rb_name().c_str(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode], - cfg.t_reordering, rlc_umd_sn_size_num[cfg.rx_sn_field_length]); - break; - default: - log->error("RLC configuration mode not recognized\n"); +} + + +void rlc_um::rlc_um_rx::configure(srslte_rlc_config_t cnfg_, std::string rb_name_) +{ + cfg = cnfg_.um; + rb_name = rb_name_; + switch(cnfg_.rlc_mode) { + case LIBLTE_RRC_RLC_MODE_UM_BI: + log->warning("%s configured in %s mode: " + "t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits\n", + get_rb_name(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode], + cfg.t_reordering, rlc_umd_sn_size_num[cfg.rx_sn_field_length], rlc_umd_sn_size_num[cfg.rx_sn_field_length]); + break; + case LIBLTE_RRC_RLC_MODE_UM_UNI_UL: + log->warning("%s configured in %s mode: tx_sn_field_length=%u bits\n", + get_rb_name(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode], + + rlc_umd_sn_size_num[cfg.rx_sn_field_length]); + break; + case LIBLTE_RRC_RLC_MODE_UM_UNI_DL: + log->warning("%s configured in %s mode: " + "t_reordering=%d ms, rx_sn_field_length=%u bits\n", + get_rb_name(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode], + cfg.t_reordering, rlc_umd_sn_size_num[cfg.rx_sn_field_length]); + break; + default: + log->error("RLC configuration mode not recognized\n"); } } + void rlc_um::empty_queue() { // Drop all messages in TX SDU queue - byte_buffer_t *buf; - while(tx_sdu_queue.try_read(&buf)) { - pool->deallocate(buf); - } - tx_sdu_queue.reset(); + tx.empty_queue(); } + bool rlc_um::is_mrb() { return cfg.is_mrb; } -void rlc_um::reestablish() { - stop(); - tx_enabled = true; -} -void rlc_um::stop() +void rlc_um::reestablish() { - // Empty tx_sdu_queue before locking the mutex - tx_enabled = false; - empty_queue(); - - pthread_mutex_lock(&mutex); - vt_us = 0; - vr_ur = 0; - vr_ux = 0; - vr_uh = 0; - pdu_lost = false; - if(rx_sdu) { - pool->deallocate(rx_sdu); - rx_sdu = NULL; - } + tx.reestablish(); // calls stop and enables tx again + rx.stop(); // nothing else needed +} - if(tx_sdu) { - pool->deallocate(tx_sdu); - tx_sdu = NULL; - } - if(reordering_timer) { - reordering_timer->stop(); - } - - // Drop all messages in RX window - std::map::iterator it; - for(it = rx_window.begin(); it != rx_window.end(); it++) { - pool->deallocate(it->second.buf); - } - rx_window.clear(); - pthread_mutex_unlock(&mutex); - - if (mac_timers && reordering_timer) { - mac_timers->timer_release_id(reordering_timer_id); - reordering_timer = NULL; - } +void rlc_um::stop() +{ + tx.stop(); + rx.stop(); } + rlc_mode_t rlc_um::get_mode() { return RLC_MODE_UM; @@ -190,34 +143,12 @@ uint32_t rlc_um::get_bearer() ***************************************************************************/ void rlc_um::write_sdu(byte_buffer_t *sdu) { - if (!tx_enabled) { - byte_buffer_pool::get_instance()->deallocate(sdu); - return; - } - if (sdu) { - tx_sdu_queue.write(sdu); - log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B ,tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes, tx_sdu_queue.size()); - } else { - log->warning("NULL SDU pointer in write_sdu()\n"); - } + tx.write_sdu(sdu); } void rlc_um::write_sdu_nb(byte_buffer_t *sdu) { - if (!tx_enabled) { - byte_buffer_pool::get_instance()->deallocate(sdu); - return; - } - if (sdu) { - if (tx_sdu_queue.try_write(sdu)) { - log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B,tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes, tx_sdu_queue.size()); - } else { - log->debug_hex(sdu->msg, sdu->N_bytes, "[Dropped SDU] %s Tx SDU (%d B,tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes, tx_sdu_queue.size()); - pool->deallocate(sdu); - } - } else { - log->warning("NULL SDU pointer in write_sdu()\n"); - } + tx.try_write_sdu(sdu); } /**************************************************************************** @@ -226,109 +157,191 @@ void rlc_um::write_sdu_nb(byte_buffer_t *sdu) uint32_t rlc_um::get_buffer_state() { - // Bytes needed for tx SDUs - uint32_t n_sdus = tx_sdu_queue.size(); + return tx.get_buffer_size_bytes(); +} - uint32_t n_bytes = tx_sdu_queue.size_bytes(); - if(tx_sdu) - { - n_sdus++; - n_bytes += tx_sdu->N_bytes; +uint32_t rlc_um::get_total_buffer_state() +{ + return get_buffer_state(); +} + +int rlc_um::read_pdu(uint8_t *payload, uint32_t nof_bytes) +{ + return tx.build_data_pdu(payload, nof_bytes); +} + +void rlc_um::write_pdu(uint8_t *payload, uint32_t nof_bytes) +{ + rx.handle_data_pdu(payload, nof_bytes); +} + + +/**************************************************************************** + * Helper functions + ***************************************************************************/ + +std::string rlc_um::get_rb_name(srsue::rrc_interface_rlc *rrc, uint32_t lcid, bool is_mrb) +{ + if(is_mrb) { + std::stringstream ss; + ss << "MRB" << lcid; + return ss.str(); + } else { + return rrc->get_rb_name(lcid); } +} - // Room needed for header extensions? (integer rounding) - if(n_sdus > 1) - n_bytes += ((n_sdus-1)*1.5)+0.5; - // Room needed for fixed header? - if(n_bytes > 0) - n_bytes += (cfg.is_mrb)?2:3; +/**************************************************************************** + * Tx subclass implementation + ***************************************************************************/ - return n_bytes; +rlc_um::rlc_um_tx::rlc_um_tx(uint32_t queue_len) + :tx_sdu_queue(queue_len) + ,pool(byte_buffer_pool::get_instance()) + ,log(NULL) + ,tx_sdu(NULL) + ,vt_us(0) + ,tx_enabled(false) +{ + pthread_mutex_init(&mutex, NULL); } -uint32_t rlc_um::get_total_buffer_state() + +rlc_um::rlc_um_tx::~rlc_um_tx() { - return get_buffer_state(); + pthread_mutex_destroy(&mutex); } -int rlc_um::read_pdu(uint8_t *payload, uint32_t nof_bytes) + +void rlc_um::rlc_um_tx::init(srslte::log *log_) { - int r; - log->debug("MAC opportunity - %d bytes\n", nof_bytes); - pthread_mutex_lock(&mutex); - r = build_data_pdu(payload, nof_bytes); - pthread_mutex_unlock(&mutex); - return r; + log = log_; + tx_enabled = true; } -void rlc_um::write_pdu(uint8_t *payload, uint32_t nof_bytes) + +void rlc_um::rlc_um_tx::configure(srslte_rlc_config_t cnfg_, std::string rb_name_) +{ + cfg = cnfg_.um; + if(cfg.is_mrb){ + tx_sdu_queue.resize(512); + } + rb_name = rb_name_; +} + + +void rlc_um::rlc_um_tx::stop() +{ + tx_enabled = false; + empty_queue(); +} + + +void rlc_um::rlc_um_tx::reestablish() +{ + stop(); + tx_enabled = true; +} + + +void rlc_um::rlc_um_tx::empty_queue() { pthread_mutex_lock(&mutex); - handle_data_pdu(payload, nof_bytes); + + // deallocate all SDUs in transmit queue + while(tx_sdu_queue.size() > 0) { + byte_buffer_t *buf; + tx_sdu_queue.read(&buf); + pool->deallocate(buf); + } + + // deallocate SDU that is currently processed + if(tx_sdu) { + pool->deallocate(tx_sdu); + tx_sdu = NULL; + } + pthread_mutex_unlock(&mutex); } -/**************************************************************************** - * Timeout callback interface - ***************************************************************************/ -void rlc_um::timer_expired(uint32_t timeout_id) +uint32_t rlc_um::rlc_um_tx::get_buffer_size_bytes() { - if(reordering_timer_id == timeout_id) - { - pthread_mutex_lock(&mutex); + // Bytes needed for tx SDUs + uint32_t n_sdus = tx_sdu_queue.size(); + uint32_t n_bytes = tx_sdu_queue.size_bytes(); + if(tx_sdu) { + n_sdus++; + n_bytes += tx_sdu->N_bytes; + } - // 36.322 v10 Section 5.1.2.2.4 - log->info("%s reordering timeout expiry - updating vr_ur and reassembling\n", - rb_name().c_str()); + // Room needed for header extensions? (integer rounding) + if(n_sdus > 1) { + n_bytes += ((n_sdus-1)*1.5)+0.5; + } - log->warning("Lost PDU SN: %d\n", vr_ur); - pdu_lost = true; - rx_sdu->reset(); - while(RX_MOD_BASE(vr_ur) < RX_MOD_BASE(vr_ux)) - { - vr_ur = (vr_ur + 1)%cfg.rx_mod; - log->debug("Entering Reassemble from timeout id=%d\n", timeout_id); - reassemble_rx_sdus(); - log->debug("Finished reassemble from timeout id=%d\n", timeout_id); - } - reordering_timer->stop(); - if(RX_MOD_BASE(vr_uh) > RX_MOD_BASE(vr_ur)) - { - reordering_timer->set(this, cfg.t_reordering); - reordering_timer->run(); - vr_ux = vr_uh; - } + // Room needed for fixed header? + if(n_bytes > 0) + n_bytes += (cfg.is_mrb)?2:3; - debug_state(); - pthread_mutex_unlock(&mutex); + return n_bytes; +} + + +void rlc_um::rlc_um_tx::write_sdu(byte_buffer_t *sdu) +{ + if (!tx_enabled) { + byte_buffer_pool::get_instance()->deallocate(sdu); + return; + } + + if (sdu) { + tx_sdu_queue.write(sdu); + log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B ,tx_sdu_queue_len=%d)", get_rb_name(), sdu->N_bytes, tx_sdu_queue.size()); + } else { + log->warning("NULL SDU pointer in write_sdu()\n"); } } -bool rlc_um::reordering_timeout_running() + +void rlc_um::rlc_um_tx::try_write_sdu(byte_buffer_t *sdu) { - return reordering_timer->is_running(); + if (!tx_enabled) { + byte_buffer_pool::get_instance()->deallocate(sdu); + return; + } + + if (sdu) { + if (tx_sdu_queue.try_write(sdu)) { + log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B ,tx_sdu_queue_len=%d)", get_rb_name(), sdu->N_bytes, tx_sdu_queue.size()); + } else { + log->warning_hex(sdu->msg, sdu->N_bytes, "[Dropped SDU] %s Tx SDU (%d B ,tx_sdu_queue_len=%d)", get_rb_name(), sdu->N_bytes, tx_sdu_queue.size()); + pool->deallocate(sdu); + } + } else { + log->warning("NULL SDU pointer in write_sdu()\n"); + } } -/**************************************************************************** - * Helpers - ***************************************************************************/ -int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) +int rlc_um::rlc_um_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) { - if(!tx_sdu && tx_sdu_queue.size() == 0) - { + pthread_mutex_lock(&mutex); + log->debug("MAC opportunity - %d bytes\n", nof_bytes); + if(!tx_sdu && tx_sdu_queue.size() == 0) { log->info("No data available to be sent\n"); + pthread_mutex_unlock(&mutex); return 0; } byte_buffer_t *pdu = pool_allocate; - if(!pdu || pdu->N_bytes != 0) - { + if(!pdu || pdu->N_bytes != 0) { log->error("Failed to allocate PDU buffer\n"); - return -1; + pthread_mutex_unlock(&mutex); + return 0; } + rlc_umd_pdu_header_t header; header.fi = RLC_FI_FIELD_START_AND_END_ALIGNED; header.sn = vt_us; @@ -346,17 +359,17 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) { pool->deallocate(pdu); log->warning("%s Cannot build a PDU - %d bytes available, %d bytes required for header\n", - rb_name().c_str(), nof_bytes, head_len); + get_rb_name(), nof_bytes, head_len); + pthread_mutex_unlock(&mutex); return 0; } // Check for SDU segment - if(tx_sdu) - { + if(tx_sdu) { uint32_t space = pdu_space-head_len; to_move = space >= tx_sdu->N_bytes ? tx_sdu->N_bytes : space; log->debug("%s adding remainder of SDU segment - %d bytes of %d remaining\n", - rb_name().c_str(), to_move, tx_sdu->N_bytes); + get_rb_name(), to_move, tx_sdu->N_bytes); memcpy(pdu_ptr, tx_sdu->msg, to_move); last_li = to_move; pdu_ptr += to_move; @@ -366,7 +379,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) if(tx_sdu->N_bytes == 0) { log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", - rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us()); + get_rb_name(), tx_sdu->get_latency_us()); pool->deallocate(tx_sdu); tx_sdu = NULL; @@ -376,8 +389,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) } // Pull SDUs from queue - while(pdu_space > head_len + 1 && tx_sdu_queue.size() > 0) - { + while(pdu_space > head_len + 1 && tx_sdu_queue.size() > 0) { log->debug("pdu_space=%d, head_len=%d\n", pdu_space, head_len); if(last_li > 0) header.li[header.N_li++] = last_li; @@ -386,17 +398,16 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) uint32_t space = pdu_space-head_len; to_move = space >= tx_sdu->N_bytes ? tx_sdu->N_bytes : space; log->debug("%s adding new SDU segment - %d bytes of %d remaining\n", - rb_name().c_str(), to_move, tx_sdu->N_bytes); + get_rb_name(), to_move, tx_sdu->N_bytes); memcpy(pdu_ptr, tx_sdu->msg, to_move); last_li = to_move; pdu_ptr += to_move; pdu->N_bytes += to_move; tx_sdu->N_bytes -= to_move; tx_sdu->msg += to_move; - if(tx_sdu->N_bytes == 0) - { + if(tx_sdu->N_bytes == 0) { log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", - rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us()); + get_rb_name(), tx_sdu->get_latency_us()); pool->deallocate(tx_sdu); tx_sdu = NULL; @@ -404,89 +415,173 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) pdu_space -= to_move; } - if(tx_sdu) + if(tx_sdu) { header.fi |= RLC_FI_FIELD_NOT_END_ALIGNED; // Last byte does not correspond to last byte of SDU + } // Set SN - header.sn = vt_us; vt_us = (vt_us + 1)%cfg.tx_mod; // Add header and TX - log->debug("%s packing PDU with length %d\n", rb_name().c_str(), pdu->N_bytes); + log->debug("%s packing PDU with length %d\n", get_rb_name(), pdu->N_bytes); rlc_um_write_data_pdu_header(&header, pdu); memcpy(payload, pdu->msg, pdu->N_bytes); uint32_t ret = pdu->N_bytes; - log->debug("%s returning length %d\n", rrc->get_rb_name(lcid).c_str(), pdu->N_bytes); + log->debug("%s returning length %d\n", get_rb_name(), pdu->N_bytes); pool->deallocate(pdu); debug_state(); + + pthread_mutex_unlock(&mutex); return ret; } -void rlc_um::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes) + +const char* rlc_um::rlc_um_tx::get_rb_name() +{ + return rb_name.c_str(); +} + + +void rlc_um::rlc_um_tx::debug_state() +{ + log->debug("%s vt_us = %d\n", get_rb_name(), vt_us); +} + +/**************************************************************************** + * Rx subclass implementation + ***************************************************************************/ + +rlc_um::rlc_um_rx::rlc_um_rx() + :reordering_timer(NULL) + ,reordering_timer_id(0) + ,pool(byte_buffer_pool::get_instance()) + ,log(NULL) + ,pdcp(NULL) + ,rrc(NULL) + ,rx_sdu(NULL) + ,vr_ur(0) + ,vr_ux (0) + ,vr_uh(0) + ,vr_ur_in_rx_sdu(0) + ,pdu_lost(false) + ,mac_timers(NULL) + ,lcid(0) +{ + pthread_mutex_init(&mutex, NULL); +} + + +rlc_um::rlc_um_rx::~rlc_um_rx() +{ + pthread_mutex_destroy(&mutex); +} + + +void rlc_um::rlc_um_rx::init(srslte::log *log_, uint32_t lcid_, srsue::pdcp_interface_rlc *pdcp_, srsue::rrc_interface_rlc *rrc_, srslte::mac_interface_timers *mac_timers_) { + log = log_; + lcid = lcid_; + pdcp = pdcp_; + rrc = rrc_; + mac_timers = mac_timers_; + reordering_timer_id = mac_timers->timer_get_unique_id(); + reordering_timer = mac_timers->timer_get(reordering_timer_id); +} + + +void rlc_um::rlc_um_rx::stop() +{ + pthread_mutex_lock(&mutex); + if(reordering_timer) { + reordering_timer->stop(); + } + vr_ur = 0; + vr_ux = 0; + vr_uh = 0; + pdu_lost = false; + if(rx_sdu) { + pool->deallocate(rx_sdu); + rx_sdu = NULL; + } + + if (mac_timers && reordering_timer) { + mac_timers->timer_release_id(reordering_timer_id); + reordering_timer = NULL; + } + + // Drop all messages in RX window + std::map::iterator it; + for(it = rx_window.begin(); it != rx_window.end(); it++) { + pool->deallocate(it->second.buf); + } + rx_window.clear(); + pthread_mutex_unlock(&mutex); +} + + +void rlc_um::rlc_um_rx::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes) +{ + pthread_mutex_lock(&mutex); + rlc_umd_pdu_t pdu; + int header_len = 0; std::map::iterator it; rlc_umd_pdu_header_t header; rlc_um_read_data_pdu_header(payload, nof_bytes, cfg.rx_sn_field_length, &header); - log->info_hex(payload, nof_bytes, "RX %s Rx data PDU SN: %d", - rb_name().c_str(), header.sn); + log->info_hex(payload, nof_bytes, "RX %s Rx data PDU SN: %d", get_rb_name(), header.sn); if(RX_MOD_BASE(header.sn) >= RX_MOD_BASE(vr_uh-cfg.rx_window_size) && RX_MOD_BASE(header.sn) < RX_MOD_BASE(vr_ur)) { log->info("%s SN: %d outside rx window [%d:%d] - discarding\n", - rb_name().c_str(), header.sn, vr_ur, vr_uh); - return; + get_rb_name(), header.sn, vr_ur, vr_uh); + goto unlock_and_exit; } it = rx_window.find(header.sn); if(rx_window.end() != it) { - log->info("%s Discarding duplicate SN: %d\n", - rb_name().c_str(), header.sn); - return; + log->info("%s Discarding duplicate SN: %d\n", get_rb_name(), header.sn); + goto unlock_and_exit; } // Write to rx window - rlc_umd_pdu_t pdu; pdu.buf = pool_allocate; if (!pdu.buf) { log->error("Discarting packet: no space in buffer pool\n"); - return; + goto unlock_and_exit; } memcpy(pdu.buf->msg, payload, nof_bytes); pdu.buf->N_bytes = nof_bytes; //Strip header from PDU - int header_len = rlc_um_packed_length(&header); + header_len = rlc_um_packed_length(&header); pdu.buf->msg += header_len; pdu.buf->N_bytes -= header_len; pdu.header = header; rx_window[header.sn] = pdu; - + // Update vr_uh - if(!inside_reordering_window(header.sn)) + if(!inside_reordering_window(header.sn)) { vr_uh = (header.sn + 1)%cfg.rx_mod; + } // Reassemble and deliver SDUs, while updating vr_ur log->debug("Entering Reassemble from received PDU\n"); reassemble_rx_sdus(); log->debug("Finished reassemble from received PDU\n"); - + // Update reordering variables and timers - if(reordering_timer->is_running()) - { + if(reordering_timer->is_running()) { if(RX_MOD_BASE(vr_ux) <= RX_MOD_BASE(vr_ur) || (!inside_reordering_window(vr_ux) && vr_ux != vr_uh)) { reordering_timer->stop(); } } - if(!reordering_timer->is_running()) - { - if(RX_MOD_BASE(vr_uh) > RX_MOD_BASE(vr_ur)) - { + if(!reordering_timer->is_running()) { + if(RX_MOD_BASE(vr_uh) > RX_MOD_BASE(vr_ur)) { reordering_timer->set(this, cfg.t_reordering); reordering_timer->run(); vr_ux = vr_uh; @@ -494,9 +589,14 @@ void rlc_um::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes) } debug_state(); + + unlock_and_exit: + pthread_mutex_unlock(&mutex); } -void rlc_um::reassemble_rx_sdus() + +// No locking required as only called from within handle_data_pdu and timer_expired which lock +void rlc_um::rlc_um_rx::reassemble_rx_sdus() { if(!rx_sdu) { rx_sdu = pool_allocate; @@ -536,7 +636,7 @@ void rlc_um::reassemble_rx_sdus() log->warning("Dropping remainder of lost PDU (lower edge middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)\n", vr_ur, vr_ur_in_rx_sdu); rx_sdu->reset(); } else { - log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d, i=%d (lower edge middle segments)", rb_name().c_str(), vr_ur, i); + log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d, i=%d (lower edge middle segments)", get_rb_name(), vr_ur, i); rx_sdu->set_timestamp(); if(cfg.is_mrb){ pdcp->write_pdu_mch(lcid, rx_sdu); @@ -553,7 +653,6 @@ void rlc_um::reassemble_rx_sdus() } // Handle last segment - if (rx_sdu->N_bytes > 0 || rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { log->debug("Writing last segment in SDU buffer. Lower edge vr_ur=%d, Buffer size=%d, segment size=%d\n", vr_ur, rx_sdu->N_bytes, rx_window[vr_ur].buf->N_bytes); @@ -567,7 +666,7 @@ void rlc_um::reassemble_rx_sdus() log->warning("Dropping remainder of lost PDU (lower edge last segments)\n"); rx_sdu->reset(); } else { - log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (lower edge last segments)", rrc->get_rb_name(lcid).c_str(), vr_ur); + log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (lower edge last segments)", get_rb_name(), vr_ur); rx_sdu->set_timestamp(); if(cfg.is_mrb){ pdcp->write_pdu_mch(lcid, rx_sdu); @@ -592,13 +691,10 @@ void rlc_um::reassemble_rx_sdus() vr_ur = (vr_ur + 1)%cfg.rx_mod; } - // Now update vr_ur until we reach an SN we haven't yet received - while(rx_window.end() != rx_window.find(vr_ur)) - { + while(rx_window.end() != rx_window.find(vr_ur)) { // Handle any SDU segments - for(uint32_t i=0; idebug("Concatenating %d bytes in to current length %d. rx_window remaining bytes=%d, vr_ur_in_rx_sdu=%d, vr_ur=%d, rx_mod=%d, last_mod=%d\n", - len, rx_sdu->N_bytes, rx_window[vr_ur].buf->N_bytes, vr_ur_in_rx_sdu, vr_ur, cfg.rx_mod, (vr_ur_in_rx_sdu+1)%cfg.rx_mod); + len, rx_sdu->N_bytes, rx_window[vr_ur].buf->N_bytes, vr_ur_in_rx_sdu, vr_ur, cfg.rx_mod, (vr_ur_in_rx_sdu+1)%cfg.rx_mod); memcpy(&rx_sdu->msg[rx_sdu->N_bytes], rx_window[vr_ur].buf->msg, len); rx_sdu->N_bytes += len; rx_window[vr_ur].buf->msg += len; @@ -628,7 +724,7 @@ void rlc_um::reassemble_rx_sdus() log->warning("Dropping remainder of lost PDU (update vr_ur middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)\n", vr_ur, vr_ur_in_rx_sdu); rx_sdu->reset(); } else { - log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d, i=%d, (update vr_ur middle segments)", rb_name().c_str(), vr_ur, i); + log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d, i=%d, (update vr_ur middle segments)", get_rb_name(), vr_ur, i); rx_sdu->set_timestamp(); if(cfg.is_mrb){ pdcp->write_pdu_mch(lcid, rx_sdu); @@ -665,13 +761,12 @@ void rlc_um::reassemble_rx_sdus() rx_sdu->N_bytes, rx_window[vr_ur].buf->N_bytes, vr_ur); } vr_ur_in_rx_sdu = vr_ur; - if(rlc_um_end_aligned(rx_window[vr_ur].header.fi)) - { + if(rlc_um_end_aligned(rx_window[vr_ur].header.fi)) { if(pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { log->warning("Dropping remainder of lost PDU (update vr_ur last segments)\n"); rx_sdu->reset(); } else { - log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (update vr_ur last segments)", rb_name().c_str(), vr_ur); + log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (update vr_ur last segments)", get_rb_name(), vr_ur); rx_sdu->set_timestamp(); if(cfg.is_mrb){ pdcp->write_pdu_mch(lcid, rx_sdu); @@ -687,7 +782,7 @@ void rlc_um::reassemble_rx_sdus() pdu_lost = false; } -clean_up_rx_window: + clean_up_rx_window: // Clean up rx_window pool->deallocate(rx_window[vr_ur].buf); @@ -697,7 +792,8 @@ clean_up_rx_window: } } -bool rlc_um::inside_reordering_window(uint16_t sn) +// Only called when lock is hold +bool rlc_um::rlc_um_rx::inside_reordering_window(uint16_t sn) { if(cfg.rx_window_size == 0) { return true; @@ -711,23 +807,64 @@ bool rlc_um::inside_reordering_window(uint16_t sn) } } -void rlc_um::debug_state() + +/**************************************************************************** + * Timeout callback interface + ***************************************************************************/ + +void rlc_um::rlc_um_rx::timer_expired(uint32_t timeout_id) { - log->debug("%s vt_us = %d, vr_ur = %d, vr_ux = %d, vr_uh = %d \n", - rb_name().c_str(), vt_us, vr_ur, vr_ux, vr_uh); + if(reordering_timer_id == timeout_id) + { + pthread_mutex_lock(&mutex); -} + // 36.322 v10 Section 5.1.2.2.4 + log->info("%s reordering timeout expiry - updating vr_ur and reassembling\n", + get_rb_name()); -std::string rlc_um::rb_name() { - if(cfg.is_mrb) { - std::stringstream ss; - ss << "MRB" << lcid; - return ss.str(); - } else { - return rrc->get_rb_name(lcid); + log->warning("Lost PDU SN: %d\n", vr_ur); + pdu_lost = true; + rx_sdu->reset(); + while(RX_MOD_BASE(vr_ur) < RX_MOD_BASE(vr_ux)) + { + vr_ur = (vr_ur + 1)%cfg.rx_mod; + log->debug("Entering Reassemble from timeout id=%d\n", timeout_id); + reassemble_rx_sdus(); + log->debug("Finished reassemble from timeout id=%d\n", timeout_id); + } + reordering_timer->stop(); + if(RX_MOD_BASE(vr_uh) > RX_MOD_BASE(vr_ur)) + { + reordering_timer->set(this, cfg.t_reordering); + reordering_timer->run(); + vr_ux = vr_uh; + } + + debug_state(); + pthread_mutex_unlock(&mutex); } } +bool rlc_um::rlc_um_rx::reordering_timeout_running() +{ + return reordering_timer->is_running(); +} + +/**************************************************************************** + * Helper functions + ***************************************************************************/ + +void rlc_um::rlc_um_rx::debug_state() +{ + log->debug("%s vr_ur = %d, vr_ux = %d, vr_uh = %d\n", get_rb_name(), vr_ur, vr_ux, vr_uh); +} + +const char* rlc_um::rlc_um_rx::get_rb_name() +{ + return rb_name.c_str(); +} + + /**************************************************************************** * Header pack/unpack helper functions * Ref: 3GPP TS 36.322 v10.0.0 Section 6.2.1 From 936001aaf5123889cb81526022b61c5c2379d843 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 29 Jun 2018 15:52:10 +0200 Subject: [PATCH 12/88] add blocking allocation to buffer_pool --- lib/include/srslte/common/buffer_pool.h | 47 ++++++++++++++++--------- lib/include/srslte/common/common.h | 1 + 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index 0a87c0df1..283501ff4 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -63,6 +63,7 @@ public: nof_buffers = (uint32_t) capacity_; } pthread_mutex_init(&mutex, NULL); + pthread_cond_init(&cv_not_empty, NULL); for(uint32_t i=0;i 0) - { + if (available.size() > 0) { b = available.top(); used.push_back(b); available.pop(); - + if (is_almost_empty()) { - printf("Warning buffer pool capacity is %f %%\n", (float) 100*available.size()/capacity); + printf("Warning buffer pool capacity is %f %%\n", (float) 100 * available.size() / capacity); } #ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED - if (debug_name) { - strncpy(b->debug_name, debug_name, SRSLTE_BUFFER_POOL_LOG_NAME_LEN); - b->debug_name[SRSLTE_BUFFER_POOL_LOG_NAME_LEN-1] = 0; - } + if (debug_name) { + strncpy(b->debug_name, debug_name, SRSLTE_BUFFER_POOL_LOG_NAME_LEN); + b->debug_name[SRSLTE_BUFFER_POOL_LOG_NAME_LEN - 1] = 0; + } #endif - - } else { + } else if (blocking) { + // blocking allocation + while(available.size() == 0) { + pthread_cond_wait(&cv_not_empty, &mutex); + } + + // retrieve the new buffer + b = available.top(); + used.push_back(b); + available.pop(); + + // do not print any warning + } + else { printf("Error - buffer pool is empty\n"); #ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED @@ -148,6 +161,7 @@ public: available.push(b); ret = true; } + pthread_cond_signal(&cv_not_empty); pthread_mutex_unlock(&mutex); return ret; } @@ -157,7 +171,8 @@ private: static const int POOL_SIZE = 2048; std::stack available; std::vector used; - pthread_mutex_t mutex; + pthread_mutex_t mutex; + pthread_cond_t cv_not_empty; uint32_t capacity; }; @@ -174,8 +189,8 @@ public: ~byte_buffer_pool() { delete pool; } - byte_buffer_t* allocate(const char *debug_name = NULL) { - return pool->allocate(debug_name); + byte_buffer_t* allocate(const char *debug_name = NULL, bool blocking = false) { + return pool->allocate(debug_name, blocking); } void deallocate(byte_buffer_t *b) { if(!b) { diff --git a/lib/include/srslte/common/common.h b/lib/include/srslte/common/common.h index 3313d0eb4..ed5c9acc1 100644 --- a/lib/include/srslte/common/common.h +++ b/lib/include/srslte/common/common.h @@ -69,6 +69,7 @@ #ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED #define pool_allocate (pool->allocate(__PRETTY_FUNCTION__)) +#define pool_allocate_blocking (pool->allocate(__PRETTY_FUNCTION__, true)) #define SRSLTE_BUFFER_POOL_LOG_NAME_LEN 128 #else #define pool_allocate (pool->allocate()) From 1f7e9187906c824b2092c71374291042e571d631 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 29 Jun 2018 16:03:27 +0200 Subject: [PATCH 13/88] use blocking pool_allocate for all NAS messages --- srsue/src/upper/nas.cc | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 5601896b5..df581e21a 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -209,7 +209,12 @@ bool nas::rrc_connect() { } // Generate service request or attach request message - byte_buffer_t *dedicatedInfoNAS = pool_allocate; + byte_buffer_t *dedicatedInfoNAS = pool_allocate_blocking; + if (!dedicatedInfoNAS) { + nas_log->error("Fatal Error: Couldn't allocate PDU in rrc_connect().\n"); + return false; + } + if (state == EMM_STATE_REGISTERED) { gen_service_request(dedicatedInfoNAS); } else { @@ -1111,7 +1116,7 @@ void nas::gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg) { } void nas::send_security_mode_reject(uint8_t cause) { - byte_buffer_t *msg = pool_allocate; + byte_buffer_t *msg = pool_allocate_blocking; if (!msg) { nas_log->error("Fatal Error: Couldn't allocate PDU in send_security_mode_reject().\n"); return; @@ -1129,7 +1134,7 @@ void nas::send_security_mode_reject(uint8_t cause) { void nas::send_authentication_response(const uint8_t* res, const size_t res_len, const uint8_t sec_hdr_type) { - byte_buffer_t *pdu = pool_allocate; + byte_buffer_t *pdu = pool_allocate_blocking; if (!pdu) { nas_log->error("Fatal Error: Couldn't allocate PDU in send_authentication_response().\n"); return; @@ -1164,7 +1169,7 @@ void nas::send_authentication_response(const uint8_t* res, const size_t res_len, void nas::send_authentication_failure(const uint8_t cause, const uint8_t* auth_fail_param) { - byte_buffer_t *msg = pool_allocate; + byte_buffer_t *msg = pool_allocate_blocking; if (!msg) { nas_log->error("Fatal Error: Couldn't allocate PDU in send_authentication_failure().\n"); return; @@ -1192,7 +1197,7 @@ void nas::send_authentication_failure(const uint8_t cause, const uint8_t* auth_f void nas::send_identity_response() {} void nas::send_service_request() { - byte_buffer_t *msg = pool_allocate; + byte_buffer_t *msg = pool_allocate_blocking; if (!msg) { nas_log->error("Fatal Error: Couldn't allocate PDU in send_service_request().\n"); return; From a0d4650c2ce9aa81189d089c8b301579b6039137 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 12 Jul 2018 18:07:13 +0200 Subject: [PATCH 14/88] Fix reestablish UM --- lib/src/upper/rlc_um.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index f0466c9e1..77c40aa36 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -67,6 +67,10 @@ rlc_um::~rlc_um() { pthread_mutex_destroy(&mutex); pool = NULL; + if (mac_timers && reordering_timer) { + mac_timers->timer_release_id(reordering_timer_id); + reordering_timer = NULL; + } } void rlc_um::init(srslte::log *log_, @@ -169,10 +173,6 @@ void rlc_um::stop() rx_window.clear(); pthread_mutex_unlock(&mutex); - if (mac_timers && reordering_timer) { - mac_timers->timer_release_id(reordering_timer_id); - reordering_timer = NULL; - } } rlc_mode_t rlc_um::get_mode() From b6f84c2a1ff984bcfebe520b4a319363d38423f7 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 12 Jul 2018 18:07:13 +0200 Subject: [PATCH 15/88] Fix reestablish UM --- lib/src/upper/rlc_um.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index f0466c9e1..77c40aa36 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -67,6 +67,10 @@ rlc_um::~rlc_um() { pthread_mutex_destroy(&mutex); pool = NULL; + if (mac_timers && reordering_timer) { + mac_timers->timer_release_id(reordering_timer_id); + reordering_timer = NULL; + } } void rlc_um::init(srslte::log *log_, @@ -169,10 +173,6 @@ void rlc_um::stop() rx_window.clear(); pthread_mutex_unlock(&mutex); - if (mac_timers && reordering_timer) { - mac_timers->timer_release_id(reordering_timer_id); - reordering_timer = NULL; - } } rlc_mode_t rlc_um::get_mode() From 5474f6d55faf9405319a1bb90b0ef34d3aa90456 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 12 Jul 2018 16:57:22 +0200 Subject: [PATCH 16/88] Add log to pool deallocate --- lib/include/srslte/common/buffer_pool.h | 12 +++++++++++- srsenb/hdr/enb.h | 1 + srsenb/src/enb.cc | 4 ++++ srsue/hdr/ue.h | 1 + srsue/src/ue.cc | 4 ++++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index 283501ff4..54708b3e1 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -38,6 +38,7 @@ INCLUDES *******************************************************************************/ +#include "srslte/common/log.h" #include "srslte/common/common.h" namespace srslte { @@ -184,6 +185,7 @@ public: static byte_buffer_pool* get_instance(int capacity = -1); static void cleanup(void); byte_buffer_pool(int capacity = -1) { + log = NULL; pool = new buffer_pool(capacity); } ~byte_buffer_pool() { @@ -192,13 +194,20 @@ public: byte_buffer_t* allocate(const char *debug_name = NULL, bool blocking = false) { return pool->allocate(debug_name, blocking); } + void set_log(srslte::log *log) { + this->log = log; + } void deallocate(byte_buffer_t *b) { if(!b) { return; } b->reset(); if (!pool->deallocate(b)) { - printf("Error deallocating PDU: Addr=0x%lx not found in pool\n", (uint64_t) b); + if (log) { + log->error("Deallocating PDU: Addr=0x%lx, name=%s not found in pool\n", (uint64_t) b, b->debug_name); + } else { + printf("Error deallocating PDU: Addr=0x%lx, name=%s not found in pool\n", (uint64_t) b, b->debug_name); + } } b = NULL; } @@ -206,6 +215,7 @@ public: pool->print_all_buffers(); } private: + srslte::log *log; buffer_pool *pool; }; diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index b483d021b..08f75bc1e 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -201,6 +201,7 @@ private: srslte::log_filter rrc_log; srslte::log_filter gtpu_log; srslte::log_filter s1ap_log; + srslte::log_filter pool_log; srslte::byte_buffer_pool *pool; diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index c5660e0f0..911fb1d48 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -99,6 +99,10 @@ bool enb::init(all_args_t *args_) gtpu_log.init("GTPU", logger); s1ap_log.init("S1AP", logger); + pool_log.init("POOL", logger); + pool_log.set_level(srslte::LOG_LEVEL_ERROR); + pool->set_log(&pool_log); + // Init logs rf_log.set_level(srslte::LOG_LEVEL_INFO); for (int i=0;iexpert.phy.nof_phy_threads;i++) { diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index 7d33749b1..b45c079c5 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -115,6 +115,7 @@ private: srslte::log_filter nas_log; srslte::log_filter gw_log; srslte::log_filter usim_log; + srslte::log_filter pool_log; all_args_t *args; bool started; diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 1218a322c..d75b2f941 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -89,6 +89,10 @@ bool ue::init(all_args_t *args_) { gw_log.init("GW ", logger); usim_log.init("USIM", logger); + pool_log.init("POOL", logger); + pool_log.set_level(srslte::LOG_LEVEL_ERROR); + byte_buffer_pool::get_instance()->set_log(&pool_log); + // Init logs rf_log.set_level(srslte::LOG_LEVEL_INFO); rf_log.info("Starting UE\n"); From 2d5cdc4f35c3ad1c9eabdb94de9bbba6b210ad73 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 12 Jul 2018 16:57:22 +0200 Subject: [PATCH 17/88] Add log to pool deallocate --- lib/include/srslte/common/buffer_pool.h | 12 +++++++++++- srsenb/hdr/enb.h | 1 + srsenb/src/enb.cc | 4 ++++ srsue/hdr/ue.h | 1 + srsue/src/ue.cc | 4 ++++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index 0a87c0df1..1a7241797 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -38,6 +38,7 @@ INCLUDES *******************************************************************************/ +#include "srslte/common/log.h" #include "srslte/common/common.h" namespace srslte { @@ -169,6 +170,7 @@ public: static byte_buffer_pool* get_instance(int capacity = -1); static void cleanup(void); byte_buffer_pool(int capacity = -1) { + log = NULL; pool = new buffer_pool(capacity); } ~byte_buffer_pool() { @@ -177,13 +179,20 @@ public: byte_buffer_t* allocate(const char *debug_name = NULL) { return pool->allocate(debug_name); } + void set_log(srslte::log *log) { + this->log = log; + } void deallocate(byte_buffer_t *b) { if(!b) { return; } b->reset(); if (!pool->deallocate(b)) { - printf("Error deallocating PDU: Addr=0x%lx not found in pool\n", (uint64_t) b); + if (log) { + log->error("Deallocating PDU: Addr=0x%lx, name=%s not found in pool\n", (uint64_t) b, b->debug_name); + } else { + printf("Error deallocating PDU: Addr=0x%lx, name=%s not found in pool\n", (uint64_t) b, b->debug_name); + } } b = NULL; } @@ -191,6 +200,7 @@ public: pool->print_all_buffers(); } private: + srslte::log *log; buffer_pool *pool; }; diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index b483d021b..08f75bc1e 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -201,6 +201,7 @@ private: srslte::log_filter rrc_log; srslte::log_filter gtpu_log; srslte::log_filter s1ap_log; + srslte::log_filter pool_log; srslte::byte_buffer_pool *pool; diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index c5660e0f0..911fb1d48 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -99,6 +99,10 @@ bool enb::init(all_args_t *args_) gtpu_log.init("GTPU", logger); s1ap_log.init("S1AP", logger); + pool_log.init("POOL", logger); + pool_log.set_level(srslte::LOG_LEVEL_ERROR); + pool->set_log(&pool_log); + // Init logs rf_log.set_level(srslte::LOG_LEVEL_INFO); for (int i=0;iexpert.phy.nof_phy_threads;i++) { diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index 7d33749b1..b45c079c5 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -115,6 +115,7 @@ private: srslte::log_filter nas_log; srslte::log_filter gw_log; srslte::log_filter usim_log; + srslte::log_filter pool_log; all_args_t *args; bool started; diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 1218a322c..d75b2f941 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -89,6 +89,10 @@ bool ue::init(all_args_t *args_) { gw_log.init("GW ", logger); usim_log.init("USIM", logger); + pool_log.init("POOL", logger); + pool_log.set_level(srslte::LOG_LEVEL_ERROR); + byte_buffer_pool::get_instance()->set_log(&pool_log); + // Init logs rf_log.set_level(srslte::LOG_LEVEL_INFO); rf_log.info("Starting UE\n"); From 3f38165827d12e0e281e015ac5963678be042620 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 12 Jul 2018 16:57:22 +0200 Subject: [PATCH 18/88] Add log to pool deallocate --- lib/include/srslte/common/buffer_pool.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index 54708b3e1..0ffe00cdf 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -197,6 +197,9 @@ public: void set_log(srslte::log *log) { this->log = log; } + void set_log(srslte::log *log) { + this->log = log; + } void deallocate(byte_buffer_t *b) { if(!b) { return; From 291d80119c9acdf93cc7c1e2ba4202a1cefb027b Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 13 Jul 2018 12:42:54 +0200 Subject: [PATCH 19/88] fix conflicts after merging --- lib/include/srslte/common/buffer_pool.h | 3 --- lib/src/upper/rlc_um.cc | 9 --------- 2 files changed, 12 deletions(-) diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index 0ffe00cdf..54708b3e1 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -197,9 +197,6 @@ public: void set_log(srslte::log *log) { this->log = log; } - void set_log(srslte::log *log) { - this->log = log; - } void deallocate(byte_buffer_t *b) { if(!b) { return; diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index f676bdfc8..f2f6d65ef 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -44,16 +44,7 @@ rlc_um::rlc_um(uint32_t queue_len) // Warning: must call stop() to properly deallocate all buffers rlc_um::~rlc_um() { -<<<<<<< HEAD - pthread_mutex_destroy(&mutex); - pool = NULL; - if (mac_timers && reordering_timer) { - mac_timers->timer_release_id(reordering_timer_id); - reordering_timer = NULL; - } -======= stop(); ->>>>>>> 1f7e9187906c824b2092c71374291042e571d631 } void rlc_um::init(srslte::log *log_, From 3d3f98b21e34e165d333ba5b7ca99d5f8732bb62 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 2 Jul 2018 12:29:52 +0200 Subject: [PATCH 20/88] Fixed posible interleaver segfault --- lib/src/phy/fec/rm_turbo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/phy/fec/rm_turbo.c b/lib/src/phy/fec/rm_turbo.c index b327500c8..3e06a9de2 100644 --- a/lib/src/phy/fec/rm_turbo.c +++ b/lib/src/phy/fec/rm_turbo.c @@ -259,6 +259,7 @@ void srslte_rm_turbo_free_tables () { } rm_turbo_tables_generated = false; } + rm_turbo_tables_generated = false; } /** From c012a6ea83c0b7d4d97493a2b4bd2ddb6412a91e Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 12 Jul 2018 18:55:19 +0200 Subject: [PATCH 21/88] Mutex more operations in worker to fix segfault when HO. Protect pdsch/pusch from regenerating sequence --- lib/src/phy/phch/pdsch.c | 2 ++ lib/src/phy/phch/pusch.c | 1 + srsue/src/phy/phch_worker.cc | 7 ++++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/src/phy/phch/pdsch.c b/lib/src/phy/phch/pdsch.c index b38cfdbd8..e6dd9f52b 100644 --- a/lib/src/phy/phch/pdsch.c +++ b/lib/src/phy/phch/pdsch.c @@ -427,6 +427,8 @@ int srslte_pdsch_set_rnti(srslte_pdsch_t *q, uint16_t rnti) { return -1; } } + q->users[rnti_idx]->sequence_generated = false; + for (int i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { for (int j = 0; j < SRSLTE_MAX_CODEWORDS; j++) { if (srslte_sequence_pdsch(&q->users[rnti_idx]->seq[j][i], rnti, j, 2 * i, q->cell.id, diff --git a/lib/src/phy/phch/pusch.c b/lib/src/phy/phch/pusch.c index aa049f7c0..43bd08537 100644 --- a/lib/src/phy/phch/pusch.c +++ b/lib/src/phy/phch/pusch.c @@ -444,6 +444,7 @@ int srslte_pusch_set_rnti(srslte_pusch_t *q, uint16_t rnti) { return -1; } } + q->users[rnti_idx]->sequence_generated = false; for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { if (srslte_sequence_pusch(&q->users[rnti_idx]->seq[i], rnti, 2 * i, q->cell.id, q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 7f83ac731..7c1f8329a 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -86,6 +86,7 @@ phch_worker::~phch_worker() void phch_worker::reset() { + pthread_mutex_lock(&mutex); bzero(&dl_metrics, sizeof(dl_metrics_t)); bzero(&ul_metrics, sizeof(ul_metrics_t)); bzero(&dmrs_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t)); @@ -101,6 +102,7 @@ void phch_worker::reset() I_sr = 0; cfi = 0; rssi_read_cnt = 0; + pthread_mutex_unlock(&mutex); } void phch_worker::enable_pdsch_coworker() { @@ -1402,6 +1404,7 @@ void phch_worker::enable_pregen_signals(bool enabled) void phch_worker::set_ul_params(bool pregen_disabled) { + pthread_mutex_lock(&mutex); phy_interface_rrc::phy_cfg_common_t *common = &phy->config->common; LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT *dedicated = &phy->config->dedicated; @@ -1504,7 +1507,9 @@ void phch_worker::set_ul_params(bool pregen_disabled) /* SR configuration */ I_sr = dedicated->sched_request_cnfg.sr_cnfg_idx; sr_configured = true; - + + pthread_mutex_unlock(&mutex); + if (pregen_enabled && !pregen_disabled) { Info("Pre-generating UL signals worker=%d\n", get_id()); srslte_ue_ul_pregen_signals(&ue_ul); From 597cf18b9d3f60cc680f919d1d8e62b29a1bdd9d Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 13 Jul 2018 11:57:15 +0100 Subject: [PATCH 22/88] Changing common/debug.h to crash_handler.h --- lib/examples/cell_search.c | 1 + .../common/{debug.h => crash_handler.h} | 11 ++++++++-- lib/include/srslte/srslte.h | 1 - lib/src/common/{debug.c => crash_handler.c} | 2 +- srsenb/src/main.cc | 2 +- srsepc/src/CMakeLists.txt | 22 +++++++++---------- srsepc/src/main.cc | 3 ++- srsue/src/main.cc | 2 +- 8 files changed, 26 insertions(+), 18 deletions(-) rename lib/include/srslte/common/{debug.h => crash_handler.h} (88%) rename lib/src/common/{debug.c => crash_handler.c} (98%) diff --git a/lib/examples/cell_search.c b/lib/examples/cell_search.c index 025be3c59..7e1a056c7 100644 --- a/lib/examples/cell_search.c +++ b/lib/examples/cell_search.c @@ -38,6 +38,7 @@ #include "srslte/srslte.h" #include "srslte/phy/rf/rf_utils.h" +#include "srslte/common/crash_handler.h" #ifndef DISABLE_RF diff --git a/lib/include/srslte/common/debug.h b/lib/include/srslte/common/crash_handler.h similarity index 88% rename from lib/include/srslte/common/debug.h rename to lib/include/srslte/common/crash_handler.h index 350d1336b..02db08ba2 100644 --- a/lib/include/srslte/common/debug.h +++ b/lib/include/srslte/common/crash_handler.h @@ -32,12 +32,19 @@ * Reference: *****************************************************************************/ -#ifndef SRSLTE_COMMON_DEBUG_H -#define SRSLTE_COMMON_DEBUG_H +#ifndef SRSLTE_CRASH_HANDLER_H +#define SRSLTE_CRASH_HANDLER_H #include #include "srslte/config.h" +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + void srslte_debug_handle_crash(int argc, char **argv); +#ifdef __cplusplus +} +#endif // __cplusplus #endif // SRSLTE_COMMON_DEBUG diff --git a/lib/include/srslte/srslte.h b/lib/include/srslte/srslte.h index 0304e34ca..c675e0fe7 100644 --- a/lib/include/srslte/srslte.h +++ b/lib/include/srslte/srslte.h @@ -49,7 +49,6 @@ #include "srslte/phy/common/sequence.h" #include "srslte/phy/common/phy_common.h" #include "srslte/phy/common/phy_logger.h" -#include "srslte/common/debug.h" #include "srslte/phy/ch_estimation/chest_ul.h" #include "srslte/phy/ch_estimation/chest_dl.h" diff --git a/lib/src/common/debug.c b/lib/src/common/crash_handler.c similarity index 98% rename from lib/src/common/debug.c rename to lib/src/common/crash_handler.c index e577c8740..658f70181 100644 --- a/lib/src/common/debug.c +++ b/lib/src/common/crash_handler.c @@ -31,7 +31,7 @@ #include #include "srslte/version.h" -#include "srslte/common/debug.h" +#include "srslte/common/crash_handler.h" const static char crash_file_name[] = "./srsLTE.backtrace.crash"; static int bt_argc; diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 6926eb23f..9c15ef25c 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -31,7 +31,7 @@ #include #include "srslte/common/config_file.h" -#include "srslte/common/debug.h" +#include "srslte/common/crash_handler.h" #include #include diff --git a/srsepc/src/CMakeLists.txt b/srsepc/src/CMakeLists.txt index 9fb56ce30..f411eace5 100644 --- a/srsepc/src/CMakeLists.txt +++ b/srsepc/src/CMakeLists.txt @@ -34,17 +34,17 @@ if (RPATH) endif (RPATH) -add_executable(srsepc main.cc ) -target_link_libraries(srsepc srsepc_mme - srsepc_hss - srsepc_sgw - srslte_upper - srslte_common - ${CMAKE_THREAD_LIBS_INIT} - ${Boost_LIBRARIES} - ${SEC_LIBRARIES} - ${LIBCONFIGPP_LIBRARIES} - ${SCTP_LIBRARIES}) +add_executable(srsepc main.cc) +target_link_libraries( srsepc srsepc_mme + srsepc_hss + srsepc_sgw + srslte_upper + srslte_common + ${CMAKE_THREAD_LIBS_INIT} + ${Boost_LIBRARIES} + ${SEC_LIBRARIES} + ${LIBCONFIGPP_LIBRARIES} + ${SCTP_LIBRARIES}) add_executable(srsmbms mbms-gw/main.cc ) target_link_libraries(srsmbms srsepc_mbms_gw diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index 2255d9e4c..95883cd44 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -27,6 +27,7 @@ #include #include #include +#include "srslte/common/crash_handler.h" #include "srslte/common/bcd_helpers.h" #include "srslte/common/config_file.h" #include "srsepc/hdr/mme/mme.h" @@ -39,7 +40,7 @@ namespace bpo = boost::program_options; bool running = true; -void +void sig_int_handler(int signo){ running = false; } diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 4279c8286..d0dd59f3e 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -38,7 +38,7 @@ #include "srsue/hdr/ue.h" #include "srslte/common/config_file.h" -#include "srslte/common/debug.h" +#include "srslte/common/crash_handler.h" #include "srslte/srslte.h" #include "srsue/hdr/metrics_stdout.h" #include "srsue/hdr/metrics_csv.h" From 8017b792cf05dda94b28cba897b0e11424997403 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 13 Jul 2018 11:59:03 +0100 Subject: [PATCH 23/88] Changing SRSLTE_PHY_DEBUG back to SRSLTE_DEBUG. --- lib/include/srslte/phy/utils/debug.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/include/srslte/phy/utils/debug.h b/lib/include/srslte/phy/utils/debug.h index 748134284..7fe532eb4 100644 --- a/lib/include/srslte/phy/utils/debug.h +++ b/lib/include/srslte/phy/utils/debug.h @@ -32,8 +32,8 @@ * Reference: *****************************************************************************/ -#ifndef SRSLTE_PHY_DEBUG_H -#define SRSLTE_PHY_DEBUG_H +#ifndef SRSLTE_DEBUG_H +#define SRSLTE_DEBUG_H #include #include "srslte/config.h" From 84e7925f6925241b1a9cbf4050f44bafd5a17f4a Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 13 Jul 2018 12:06:27 +0100 Subject: [PATCH 24/88] Fixed up a comment. --- lib/include/srslte/common/crash_handler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/include/srslte/common/crash_handler.h b/lib/include/srslte/common/crash_handler.h index 02db08ba2..dec3940e1 100644 --- a/lib/include/srslte/common/crash_handler.h +++ b/lib/include/srslte/common/crash_handler.h @@ -47,4 +47,4 @@ void srslte_debug_handle_crash(int argc, char **argv); #ifdef __cplusplus } #endif // __cplusplus -#endif // SRSLTE_COMMON_DEBUG +#endif // SRSLTE_CRASH_HANDLER_H From bd59d72b9fbcea8c30665eddbb341b8ce9eacfcb Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 13 Jul 2018 13:09:16 +0200 Subject: [PATCH 25/88] set RRC args by-value --- srsue/hdr/upper/rrc.h | 2 +- srsue/src/ue.cc | 5 ++++- srsue/src/upper/rrc.cc | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index dfef5e723..e56db9e9e 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -280,7 +280,7 @@ public: void stop(); rrc_state_t get_state(); - void set_args(rrc_args_t *args); + void set_args(rrc_args_t args); // Timeout callback interface void timer_expired(uint32_t timeout_id); diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index d75b2f941..1bd3e5669 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -232,7 +232,10 @@ bool ue::init(all_args_t *args_) { args->rrc.supported_bands[0] = srslte_band_get_band(args->rf.dl_earfcn); args->rrc.nof_supported_bands = 1; args->rrc.ue_category = atoi(args->ue_category_str.c_str()); - rrc.set_args(&args->rrc); + + // set args and initialize RRC + rrc.set_args(args->rrc); + rrc.init(&phy, &mac, &rlc, &pdcp, &nas, usim, &gw, &mac, &rrc_log); // Currently EARFCN list is set to only one frequency as indicated in ue.conf std::vector earfcn_list; diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 440b4a318..856aeedf9 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -237,8 +237,8 @@ bool rrc::have_drb() { return drb_up; } -void rrc::set_args(rrc_args_t *args) { - memcpy(&this->args, args, sizeof(rrc_args_t)); +void rrc::set_args(rrc_args_t args_) { + args = args_; } /* From 788dc7bd7a10595f7779b82e4ef54d2c2bc1c7a7 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 13 Jul 2018 19:17:59 +0100 Subject: [PATCH 26/88] Fixed compilation issues introduced from the changes in the crash_handler. --- lib/examples/cell_measurement.c | 2 +- lib/examples/pdsch_enodeb.c | 2 +- lib/examples/pdsch_ue.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/examples/cell_measurement.c b/lib/examples/cell_measurement.c index d21716776..421be629c 100644 --- a/lib/examples/cell_measurement.c +++ b/lib/examples/cell_measurement.c @@ -40,7 +40,7 @@ #include "srslte/srslte.h" #include "srslte/phy/rf/rf.h" #include "srslte/phy/rf/rf_utils.h" -#include "srslte/common/debug.h" +#include "srslte/common/crash_handler.h" cell_search_cfg_t cell_detect_config = { SRSLTE_DEFAULT_MAX_FRAMES_PBCH, diff --git a/lib/examples/pdsch_enodeb.c b/lib/examples/pdsch_enodeb.c index 122067176..882273ac2 100644 --- a/lib/examples/pdsch_enodeb.c +++ b/lib/examples/pdsch_enodeb.c @@ -33,7 +33,7 @@ #include #include #include -#include "srslte/common/debug.h" +#include "srslte/common/crash_handler.h" #include #include #include "srslte/common/gen_mch_tables.h" diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index 4918a52d7..fcc3addeb 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -37,7 +37,7 @@ #include #include #include "srslte/common/gen_mch_tables.h" -#include "srslte/common/debug.h" +#include "srslte/common/crash_handler.h" #include #include "srslte/phy/io/filesink.h" #include "srslte/srslte.h" From f1c58351335b9372104862e0d9086e0d4495ce1a Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 16 Jul 2018 10:06:33 +0200 Subject: [PATCH 27/88] fix eNB default config help text --- srsenb/enb.conf.example | 1 + 1 file changed, 1 insertion(+) diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index 1c7c93214..b0694b4e8 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -12,6 +12,7 @@ # mnc: Mobile Network Code # mme_addr: IP address of MME for S1 connnection # gtp_bind_addr: Local IP address to bind for GTP connection +# s1c_bind_addr: Local IP address to bind for S1AP connection # n_prb: Number of Physical Resource Blocks (6,15,25,50,75,100) # tm: Transmission mode 1-4 (TM1 default) # nof_ports: Number of Tx ports (1 port default, set to 2 for TM2/3/4) From ac94b531ae0fd3f5f5e2fbce4393eaebea00c469 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 16 Jul 2018 10:11:53 +0200 Subject: [PATCH 28/88] only print build-info when string is filled --- srsue/src/ue_base.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/srsue/src/ue_base.cc b/srsue/src/ue_base.cc index b3fc56132..daab53936 100644 --- a/srsue/src/ue_base.cc +++ b/srsue/src/ue_base.cc @@ -139,7 +139,9 @@ std::string ue_base::get_build_info() std::string ue_base::get_build_string() { std::stringstream ss; - ss << "Built in " << get_build_mode() << " mode using " << get_build_info() << "." << std::endl; + if (get_build_mode() != "" && get_build_info() != "") { + ss << "Built in " << get_build_mode() << " mode using " << get_build_info() << "." << std::endl; + } return ss.str(); } From fda4c39590c9646a138eb463a39d9b57c2721dcd Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 16 Jul 2018 15:16:52 +0200 Subject: [PATCH 29/88] pdsch_ue RSRP in dBm. Fix default rx_gain_offset in ue.conf differs from code --- lib/examples/pdsch_ue.c | 2 +- srsue/ue.conf.example | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index 3b84afb71..b8b4ad1a7 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -821,7 +821,7 @@ int main(int argc, char **argv) { PRINT_LINE(" nof layers: %d", ue_dl.pdsch_cfg.nof_layers); PRINT_LINE("nof codewords: %d", SRSLTE_RA_DL_GRANT_NOF_TB(&ue_dl.pdsch_cfg.grant)); PRINT_LINE(" CFO: %+7.2f Hz", srslte_ue_sync_get_cfo(&ue_sync)); - PRINT_LINE(" RSRP: %+5.1f dBm | %+5.1f dBm", 10 * log10(rsrp0), 10 * log10(rsrp1)); + PRINT_LINE(" RSRP: %+5.1f dBm | %+5.1f dBm", 10 * log10(rsrp0)+30, 10 * log10(rsrp1)+30); PRINT_LINE(" SNR: %+5.1f dB | %+5.1f dB", 10 * log10(rsrp0 / noise), 10 * log10(rsrp1 / noise)); PRINT_LINE(" Rb: %6.2f / %6.2f / %6.2f Mbps (net/maximum/processing)", uerate, enodebrate, procrate); PRINT_LINE(" PDCCH-Miss: %5.2f%%", 100 * (1 - (float) ue_dl.nof_detected / nof_trials)); diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index 3d56d19fb..d1a81b0d9 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -209,7 +209,7 @@ enable = false #ip_netmask = 255.255.255.0 #mbms_service = -1 #rssi_sensor_enabled = false -#rx_gain_offset = 72 +#rx_gain_offset = 62 #prach_gain = 30 #cqi_max = 15 #cqi_fixed = 10 From 1bb471673d4a2d03f600e82bf86f79d3945e9f9a Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 16 Jul 2018 18:14:42 +0200 Subject: [PATCH 30/88] update debian files --- debian/control | 15 +++++++-------- debian/rules | 5 ++++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/debian/control b/debian/control index a20f8df6f..e69e54d61 100644 --- a/debian/control +++ b/debian/control @@ -22,14 +22,13 @@ Vcs-Browser: https://github.com/srsLTE/srsLTE/ Package: srslte Architecture: any Depends: - libfftw3-3 (>= 3.3.3-1), - libboost-program-options1.62.0 (>= 1.62.0), - libmbedcrypto1 (>= 2.8.0-1), - libconfig++9v5 (>= 1.5-0.2), - libsctp1 (>= 1.0.16+dfsg-3), - uhd-host (>= 3.9.2-1), - libuhd003.010.003 (>= 3.10.3.0-2), - ${shlibs:Depends}, + libfftw3-3, + libboost-program-options1.55.0 | libboost-program-options1.62.0, + libmbedcrypto0 | libmbedcrypto1, + libconfig++9v5, + libsctp1, + uhd-host, + libuhd003 | libuhd003.010.003, ${misc:Depends} Description: This is srsLTE, a free and open-source LTE software suite. This software allows you to run a full end-to-end, open-source LTE system. diff --git a/debian/rules b/debian/rules index 3b7e3ced4..b1a2e7f2b 100644 --- a/debian/rules +++ b/debian/rules @@ -8,8 +8,11 @@ export DH_OPTIONS %: dh $@ --parallel +override_dh_shlibdeps: + dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info + override_dh_auto_configure: - dh_auto_configure --buildsystem=cmake -- $(extraopts) $(CEPH_EXTRA_CMAKE_ARGS) -DCMAKE_BUILD_TYPE=Release + dh_auto_configure --buildsystem=cmake -- $(extraopts) $(CEPH_EXTRA_CMAKE_ARGS) -DCMAKE_BUILD_TYPE=RelWithDebInfo override_dh_auto_test: # skip executing tests From f6f47f0320c5a18b57f1b1704a2b7c74f018bcef Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 17 Jul 2018 09:43:05 +0200 Subject: [PATCH 31/88] print srsLTE version name if no git details are found --- srsue/src/ue_base.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/srsue/src/ue_base.cc b/srsue/src/ue_base.cc index daab53936..ed3bd4ee9 100644 --- a/srsue/src/ue_base.cc +++ b/srsue/src/ue_base.cc @@ -133,15 +133,16 @@ std::string ue_base::get_build_mode() std::string ue_base::get_build_info() { + if (std::string(srslte_get_build_info()) == "") { + return std::string(srslte_get_version()); + } return std::string(srslte_get_build_info()); } std::string ue_base::get_build_string() { std::stringstream ss; - if (get_build_mode() != "" && get_build_info() != "") { - ss << "Built in " << get_build_mode() << " mode using " << get_build_info() << "." << std::endl; - } + ss << "Built in " << get_build_mode() << " mode using " << get_build_info() << "." << std::endl; return ss.str(); } From ccf58a63ce65a5520376f4b4c41578fe8610b643 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 17 Jul 2018 09:43:30 +0200 Subject: [PATCH 32/88] reduce default log-level to warning --- srsenb/enb.conf.example | 2 +- srsue/ue.conf.example | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index b0694b4e8..0eb65bd92 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -113,7 +113,7 @@ filename = /tmp/enb.pcap # If set to negative, a single log file will be created. ##################################################################### [log] -all_level = info +all_level = warning all_hex_limit = 32 filename = /tmp/enb.log file_max_size = -1 diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index eeef5531b..bee96c31a 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -77,7 +77,7 @@ nas_filename = /tmp/nas.pcap # If set to negative, a single log file will be created. ##################################################################### [log] -all_level = info +all_level = warning phy_lib_level = none all_hex_limit = 32 filename = /tmp/ue.log From a604fbcc664c95beb2e8da096b61fa748edffc1e Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 17 Jul 2018 12:17:00 +0200 Subject: [PATCH 33/88] fix double RRC init bug in UE --- srsue/src/ue.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 1bd3e5669..a12a66d65 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -226,7 +226,6 @@ bool ue::init(all_args_t *args_) { nas.init(usim, &rrc, &gw, &nas_log, nas_cfg); gw.init(&pdcp, &nas, &gw_log, 3 /* RB_ID_DRB1 */); gw.set_netmask(args->expert.ip_netmask); - rrc.init(&phy, &mac, &rlc, &pdcp, &nas, usim, &gw, &mac, &rrc_log); // Get current band from provided EARFCN args->rrc.supported_bands[0] = srslte_band_get_band(args->rf.dl_earfcn); From 31ba175b37d6447b020c3221d10eec551292b8c3 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 16 Jul 2018 17:34:24 +0200 Subject: [PATCH 34/88] add public PDCP entity interface --- lib/include/srslte/upper/pdcp_interface.h | 72 +++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 lib/include/srslte/upper/pdcp_interface.h diff --git a/lib/include/srslte/upper/pdcp_interface.h b/lib/include/srslte/upper/pdcp_interface.h new file mode 100644 index 000000000..d978651cf --- /dev/null +++ b/lib/include/srslte/upper/pdcp_interface.h @@ -0,0 +1,72 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of the srsUE library. + * + * srsUE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsUE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +#ifndef SRSLTE_PDCP_INTERFACE_H +#define SRSLTE_PDCP_INTERFACE_H + +#include "srslte/common/buffer_pool.h" +#include "srslte/common/log.h" +#include "srslte/common/common.h" +#include "srslte/interfaces/ue_interfaces.h" +#include "srslte/common/security.h" +#include "srslte/common/threads.h" + + +namespace srslte { + +/**************************************************************************** + * Virtual PDCP interface common for all PDCP entities + ***************************************************************************/ +class pdcp_entity_interface +{ +public: + virtual void init(srsue::rlc_interface_pdcp *rlc_, + srsue::rrc_interface_pdcp *rrc_, + srsue::gw_interface_pdcp *gw_, + srslte::log *log_, + uint32_t lcid_, + srslte_pdcp_config_t cfg_) = 0; + virtual void reset() = 0; + virtual void reestablish() = 0; + virtual bool is_active() = 0; + + // RRC interface + virtual void write_sdu(byte_buffer_t *sdu) = 0; + virtual void config_security(uint8_t *k_enc_, + uint8_t *k_int_, + CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, + INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) = 0; + virtual void enable_integrity() = 0; + virtual void enable_encryption() = 0; + + // RLC interface + void write_pdu(byte_buffer_t *pdu); +}; + +} // namespace srslte + + +#endif // SRSLTE_PDCP_INTERFACE_H From b2572044713fe0c4f8374c1b23912643b98d6d30 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 17 Jul 2018 09:53:33 +0200 Subject: [PATCH 35/88] fix public PDCP interface --- lib/include/srslte/upper/pdcp_interface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/include/srslte/upper/pdcp_interface.h b/lib/include/srslte/upper/pdcp_interface.h index d978651cf..9182c74ea 100644 --- a/lib/include/srslte/upper/pdcp_interface.h +++ b/lib/include/srslte/upper/pdcp_interface.h @@ -63,7 +63,7 @@ public: virtual void enable_encryption() = 0; // RLC interface - void write_pdu(byte_buffer_t *pdu); + virtual void write_pdu(byte_buffer_t *pdu) = 0; }; } // namespace srslte From 93c11e44168e7e5e3558a334974aea400d3a5a73 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 16 Jul 2018 21:17:01 +0200 Subject: [PATCH 36/88] turn PDCP array into map --- lib/include/srslte/upper/pdcp.h | 17 +-- lib/include/srslte/upper/pdcp_entity.h | 3 +- lib/include/srslte/upper/pdcp_interface.h | 1 + lib/src/upper/pdcp.cc | 133 ++++++++++++++-------- 4 files changed, 100 insertions(+), 54 deletions(-) diff --git a/lib/include/srslte/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index d4cca957a..84ddc5b5c 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -41,7 +41,7 @@ class pdcp { public: pdcp(); - virtual ~pdcp(){} + ~pdcp(); void init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_, srsue::gw_interface_pdcp *gw_, @@ -79,17 +79,20 @@ public: void write_pdu_bcch_dlsch(byte_buffer_t *sdu); void write_pdu_pcch(byte_buffer_t *sdu); - private: srsue::rlc_interface_pdcp *rlc; srsue::rrc_interface_pdcp *rrc; srsue::gw_interface_pdcp *gw; - log *pdcp_log; - pdcp_entity pdcp_array[SRSLTE_N_RADIO_BEARERS]; - pdcp_entity pdcp_array_mrb[SRSLTE_N_MCH_LCIDS]; - uint32_t lcid; // default LCID that is maintained active by PDCP instance - uint8_t direction; + typedef std::map pdcp_map_t; + typedef std::pair pdcp_map_pair_t; + + log *pdcp_log; + pdcp_map_t pdcp_array, pdcp_array_mrb; + + // default PDCP entity that is maintained active by PDCP instance + srslte_pdcp_config_t default_cnfg; + uint32_t default_lcid; bool valid_lcid(uint32_t lcid); bool valid_mch_lcid(uint32_t lcid); diff --git a/lib/include/srslte/upper/pdcp_entity.h b/lib/include/srslte/upper/pdcp_entity.h index de51ed1de..6586becc0 100644 --- a/lib/include/srslte/upper/pdcp_entity.h +++ b/lib/include/srslte/upper/pdcp_entity.h @@ -33,6 +33,7 @@ #include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/security.h" #include "srslte/common/threads.h" +#include "pdcp_interface.h" namespace srslte { @@ -59,7 +60,7 @@ static const char pdcp_d_c_text[PDCP_D_C_N_ITEMS][20] = {"Control PDU", * PDCP Entity interface * Common interface for all PDCP entities ***************************************************************************/ -class pdcp_entity +class pdcp_entity : public pdcp_entity_interface { public: pdcp_entity(); diff --git a/lib/include/srslte/upper/pdcp_interface.h b/lib/include/srslte/upper/pdcp_interface.h index 9182c74ea..915fbe420 100644 --- a/lib/include/srslte/upper/pdcp_interface.h +++ b/lib/include/srslte/upper/pdcp_interface.h @@ -43,6 +43,7 @@ namespace srslte { class pdcp_entity_interface { public: + virtual ~pdcp_entity_interface() {}; virtual void init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_, srsue::gw_interface_pdcp *gw_, diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index e577a12ce..2d056f631 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -35,47 +35,69 @@ pdcp::pdcp() rrc = NULL; gw = NULL; pdcp_log = NULL; - lcid = 0; - direction = 0; + default_lcid = 0; +} + +pdcp::~pdcp() +{ + // destroy all remaining entities + for (pdcp_map_t::iterator it = pdcp_array.begin(); it != pdcp_array.end(); ++it) { + delete(it->second); + } + pdcp_array.clear(); } void pdcp::init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_, srsue::gw_interface_pdcp *gw_, log *pdcp_log_, uint32_t lcid_, uint8_t direction_) { - rlc = rlc_; - rrc = rrc_; - gw = gw_; - pdcp_log = pdcp_log_; - lcid = lcid_; - direction = direction_; + rlc = rlc_; + rrc = rrc_; + gw = gw_; + pdcp_log = pdcp_log_; + default_lcid = lcid_; // Default config - srslte_pdcp_config_t cnfg; - cnfg.is_control = false; - cnfg.is_data = false; - cnfg.direction = direction_; + default_cnfg.is_control = false; + default_cnfg.is_data = false; + default_cnfg.direction = direction_; - pdcp_array[0].init(rlc, rrc, gw, pdcp_log, lcid, cnfg); + // create default PDCP entity for SRB0 + if (not pdcp_array.insert(pdcp_map_pair_t(0, new pdcp_entity())).second) { + pdcp_log->error("Error inserting PDCP entity in to array\n."); + return; + } + pdcp_array.at(0)->init(rlc, rrc, gw, pdcp_log, default_lcid, default_cnfg); } void pdcp::stop() { + // destroy default entity + if (valid_lcid(0)) { + pdcp_map_t::iterator it; + it = pdcp_array.find(0); + delete(it->second); + pdcp_array.erase(it); + } } void pdcp::reestablish() { - for(uint32_t i=0;ireestablish(); } } } void pdcp::reset() { - for(uint32_t i=0;ireset(); + } } - pdcp_array[0].init(rlc, rrc, gw, pdcp_log, lcid, direction); + if (valid_lcid(0)) { + pdcp_array.at(0)->init(rlc, rrc, gw, pdcp_log, default_lcid, default_cnfg); + } } /******************************************************************************* @@ -83,17 +105,20 @@ void pdcp::reset() *******************************************************************************/ bool pdcp::is_drb_enabled(uint32_t lcid) { - if(lcid >= SRSLTE_N_RADIO_BEARERS) { + if (lcid >= SRSLTE_N_RADIO_BEARERS) { pdcp_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid); return false; } - return pdcp_array[lcid].is_active(); + if (pdcp_array.find(lcid) == pdcp_array.end()) { + return false; + } + return pdcp_array.at(lcid)->is_active(); } void pdcp::write_sdu(uint32_t lcid, byte_buffer_t *sdu) { - if(valid_lcid(lcid)) { - pdcp_array[lcid].write_sdu(sdu); + if (valid_lcid(lcid)) { + pdcp_array.at(lcid)->write_sdu(sdu); } else { pdcp_log->warning("Writing sdu: lcid=%d. Deallocating sdu\n", lcid); byte_buffer_pool::get_instance()->deallocate(sdu); @@ -102,18 +127,23 @@ void pdcp::write_sdu(uint32_t lcid, byte_buffer_t *sdu) void pdcp::write_sdu_mch(uint32_t lcid, byte_buffer_t *sdu) { - if(valid_mch_lcid(lcid)){ - pdcp_array_mrb[lcid].write_sdu(sdu); + if (valid_mch_lcid(lcid)){ + pdcp_array_mrb.at(lcid)->write_sdu(sdu); } } void pdcp::add_bearer(uint32_t lcid, srslte_pdcp_config_t cfg) { - if(lcid >= SRSLTE_N_RADIO_BEARERS) { + if (lcid >= SRSLTE_N_RADIO_BEARERS) { pdcp_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid); return; } - if (!pdcp_array[lcid].is_active()) { - pdcp_array[lcid].init(rlc, rrc, gw, pdcp_log, lcid, cfg); + + if (not valid_lcid(lcid)) { + if (not pdcp_array.insert(pdcp_map_pair_t(lcid, new pdcp_entity())).second) { + pdcp_log->error("Error inserting PDCP entity in to array\n."); + return; + } + pdcp_array.at(lcid)->init(rlc, rrc, gw, pdcp_log, lcid, cfg); pdcp_log->info("Added bearer %s\n", rrc->get_rb_name(lcid).c_str()); } else { pdcp_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rrc->get_rb_name(lcid).c_str()); @@ -123,12 +153,16 @@ void pdcp::add_bearer(uint32_t lcid, srslte_pdcp_config_t cfg) void pdcp::add_bearer_mrb(uint32_t lcid, srslte_pdcp_config_t cfg) { - if(lcid >= SRSLTE_N_RADIO_BEARERS) { + if (lcid >= SRSLTE_N_RADIO_BEARERS) { pdcp_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid); return; } - if (!pdcp_array_mrb[lcid].is_active()) { - pdcp_array_mrb[lcid].init(rlc, rrc, gw, pdcp_log, lcid, cfg); + if (not valid_mch_lcid(lcid)) { + if (pdcp_array_mrb.insert(pdcp_map_pair_t(lcid, new pdcp_entity())).second) { + pdcp_log->error("Error inserting PDCP entity in to array\n."); + return; + } + pdcp_array_mrb.at(lcid)->init(rlc, rrc, gw, pdcp_log, lcid, cfg); pdcp_log->info("Added bearer %s\n", rrc->get_rb_name(lcid).c_str()); } else { pdcp_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rrc->get_rb_name(lcid).c_str()); @@ -141,8 +175,9 @@ void pdcp::config_security(uint32_t lcid, CIPHERING_ALGORITHM_ID_ENUM cipher_algo, INTEGRITY_ALGORITHM_ID_ENUM integ_algo) { - if(valid_lcid(lcid)) - pdcp_array[lcid].config_security(k_enc, k_int, cipher_algo, integ_algo); + if (valid_lcid(lcid)) { + pdcp_array.at(lcid)->config_security(k_enc, k_int, cipher_algo, integ_algo); + } } void pdcp::config_security_all(uint8_t *k_enc, @@ -151,22 +186,24 @@ void pdcp::config_security_all(uint8_t *k_enc, INTEGRITY_ALGORITHM_ID_ENUM integ_algo) { for(uint32_t i=0;iis_active()) { + pdcp_array.at(i)->config_security(k_enc, k_int, cipher_algo, integ_algo); } } } void pdcp::enable_integrity(uint32_t lcid) { - if(valid_lcid(lcid)) - pdcp_array[lcid].enable_integrity(); + if (valid_lcid(lcid)) { + pdcp_array.at(lcid)->enable_integrity(); + } } void pdcp::enable_encryption(uint32_t lcid) { - if(valid_lcid(lcid)) - pdcp_array[lcid].enable_encryption(); + if (valid_lcid(lcid)) { + pdcp_array.at(lcid)->enable_encryption(); + } } /******************************************************************************* @@ -174,8 +211,8 @@ void pdcp::enable_encryption(uint32_t lcid) *******************************************************************************/ void pdcp::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { - if(valid_lcid(lcid)) { - pdcp_array[lcid].write_pdu(pdu); + if (valid_lcid(lcid)) { + pdcp_array.at(lcid)->write_pdu(pdu); } else { pdcp_log->warning("Writing pdu: lcid=%d. Deallocating pdu\n", lcid); byte_buffer_pool::get_instance()->deallocate(pdu); @@ -198,7 +235,7 @@ void pdcp::write_pdu_pcch(byte_buffer_t *sdu) void pdcp::write_pdu_mch(uint32_t lcid, byte_buffer_t *sdu) { - if(0 == lcid) { + if (0 == lcid) { rrc->write_pdu_mch(lcid, sdu); } else { gw->write_pdu_mch(lcid, sdu); @@ -210,27 +247,31 @@ void pdcp::write_pdu_mch(uint32_t lcid, byte_buffer_t *sdu) *******************************************************************************/ bool pdcp::valid_lcid(uint32_t lcid) { - if(lcid >= SRSLTE_N_RADIO_BEARERS) { + if (lcid >= SRSLTE_N_RADIO_BEARERS) { pdcp_log->error("Radio bearer id must be in [0:%d] - %d", SRSLTE_N_RADIO_BEARERS, lcid); return false; } - if(!pdcp_array[lcid].is_active()) { + + if (pdcp_array.find(lcid) == pdcp_array.end()) { pdcp_log->error("PDCP entity for logical channel %d has not been activated\n", lcid); return false; } + return true; } bool pdcp::valid_mch_lcid(uint32_t lcid) { - if(lcid >= SRSLTE_N_MCH_LCIDS) { + if (lcid >= SRSLTE_N_MCH_LCIDS) { pdcp_log->error("Radio bearer id must be in [0:%d] - %d", SRSLTE_N_RADIO_BEARERS, lcid); return false; } - if(!pdcp_array_mrb[lcid].is_active()) { + + if (pdcp_array_mrb.find(lcid) == pdcp_array_mrb.end()) { pdcp_log->error("PDCP entity for logical channel %d has not been activated\n", lcid); return false; } + return true; } From 47a8b1343f6a7677c877823ba5443d3b775c3741 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 17 Jul 2018 15:27:04 +0200 Subject: [PATCH 37/88] add rwlock to PDCP --- lib/include/srslte/upper/pdcp.h | 5 ++- lib/src/upper/pdcp.cc | 65 ++++++++++++++++++++++----------- srsenb/hdr/upper/pdcp.h | 2 +- srsenb/src/upper/pdcp.cc | 2 +- 4 files changed, 49 insertions(+), 25 deletions(-) diff --git a/lib/include/srslte/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index 84ddc5b5c..cd284619f 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -41,7 +41,7 @@ class pdcp { public: pdcp(); - ~pdcp(); + virtual ~pdcp(); void init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_, srsue::gw_interface_pdcp *gw_, @@ -78,7 +78,7 @@ public: void write_pdu_bcch_bch(byte_buffer_t *sdu); void write_pdu_bcch_dlsch(byte_buffer_t *sdu); void write_pdu_pcch(byte_buffer_t *sdu); - + private: srsue::rlc_interface_pdcp *rlc; srsue::rrc_interface_pdcp *rrc; @@ -89,6 +89,7 @@ private: log *pdcp_log; pdcp_map_t pdcp_array, pdcp_array_mrb; + pthread_rwlock_t rwlock; // default PDCP entity that is maintained active by PDCP instance srslte_pdcp_config_t default_cnfg; diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index 2d056f631..3f934f73d 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -36,15 +36,20 @@ pdcp::pdcp() gw = NULL; pdcp_log = NULL; default_lcid = 0; + pthread_rwlock_init(&rwlock, NULL); } pdcp::~pdcp() { // destroy all remaining entities + pthread_rwlock_wrlock(&rwlock); for (pdcp_map_t::iterator it = pdcp_array.begin(); it != pdcp_array.end(); ++it) { delete(it->second); } pdcp_array.clear(); + + pthread_rwlock_unlock(&rwlock); + pthread_rwlock_destroy(&rwlock); } void pdcp::init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_, srsue::gw_interface_pdcp *gw_, log *pdcp_log_, uint32_t lcid_, uint8_t direction_) @@ -61,34 +66,34 @@ void pdcp::init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_ default_cnfg.direction = direction_; // create default PDCP entity for SRB0 - if (not pdcp_array.insert(pdcp_map_pair_t(0, new pdcp_entity())).second) { - pdcp_log->error("Error inserting PDCP entity in to array\n."); - return; - } - pdcp_array.at(0)->init(rlc, rrc, gw, pdcp_log, default_lcid, default_cnfg); + add_bearer(0, default_cnfg); } void pdcp::stop() { // destroy default entity + pthread_rwlock_wrlock(&rwlock); if (valid_lcid(0)) { - pdcp_map_t::iterator it; - it = pdcp_array.find(0); + pdcp_map_t::iterator it = pdcp_array.find(0); delete(it->second); pdcp_array.erase(it); } + pthread_rwlock_unlock(&rwlock); } void pdcp::reestablish() { + pthread_rwlock_rdlock(&rwlock); for (uint32_t i = 0; i < SRSLTE_N_RADIO_BEARERS; i++) { if (valid_lcid(i)) { pdcp_array.at(i)->reestablish(); } } + pthread_rwlock_unlock(&rwlock); } void pdcp::reset() { + pthread_rwlock_rdlock(&rwlock); for (uint32_t i = 0; i < SRSLTE_N_RADIO_BEARERS; i++) { if (valid_lcid(i)) { pdcp_array.at(i)->reset(); @@ -98,6 +103,7 @@ void pdcp::reset() if (valid_lcid(0)) { pdcp_array.at(0)->init(rlc, rrc, gw, pdcp_log, default_lcid, default_cnfg); } + pthread_rwlock_unlock(&rwlock); } /******************************************************************************* @@ -105,39 +111,46 @@ void pdcp::reset() *******************************************************************************/ bool pdcp::is_drb_enabled(uint32_t lcid) { + pthread_rwlock_rdlock(&rwlock); + bool ret = false; + if (lcid >= SRSLTE_N_RADIO_BEARERS) { pdcp_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid); - return false; + goto unlock_and_exit; } if (pdcp_array.find(lcid) == pdcp_array.end()) { - return false; + goto unlock_and_exit; } - return pdcp_array.at(lcid)->is_active(); + ret = pdcp_array.at(lcid)->is_active(); + +unlock_and_exit: + pthread_rwlock_unlock(&rwlock); + return ret; } void pdcp::write_sdu(uint32_t lcid, byte_buffer_t *sdu) { + pthread_rwlock_rdlock(&rwlock); if (valid_lcid(lcid)) { pdcp_array.at(lcid)->write_sdu(sdu); } else { pdcp_log->warning("Writing sdu: lcid=%d. Deallocating sdu\n", lcid); byte_buffer_pool::get_instance()->deallocate(sdu); } + pthread_rwlock_unlock(&rwlock); } void pdcp::write_sdu_mch(uint32_t lcid, byte_buffer_t *sdu) { + pthread_rwlock_rdlock(&rwlock); if (valid_mch_lcid(lcid)){ pdcp_array_mrb.at(lcid)->write_sdu(sdu); } + pthread_rwlock_unlock(&rwlock); } void pdcp::add_bearer(uint32_t lcid, srslte_pdcp_config_t cfg) { - if (lcid >= SRSLTE_N_RADIO_BEARERS) { - pdcp_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid); - return; - } - + pthread_rwlock_rdlock(&rwlock); if (not valid_lcid(lcid)) { if (not pdcp_array.insert(pdcp_map_pair_t(lcid, new pdcp_entity())).second) { pdcp_log->error("Error inserting PDCP entity in to array\n."); @@ -148,17 +161,15 @@ void pdcp::add_bearer(uint32_t lcid, srslte_pdcp_config_t cfg) } else { pdcp_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rrc->get_rb_name(lcid).c_str()); } + pthread_rwlock_unlock(&rwlock); } void pdcp::add_bearer_mrb(uint32_t lcid, srslte_pdcp_config_t cfg) { - if (lcid >= SRSLTE_N_RADIO_BEARERS) { - pdcp_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid); - return; - } + pthread_rwlock_rdlock(&rwlock); if (not valid_mch_lcid(lcid)) { - if (pdcp_array_mrb.insert(pdcp_map_pair_t(lcid, new pdcp_entity())).second) { + if (not pdcp_array_mrb.insert(pdcp_map_pair_t(lcid, new pdcp_entity())).second) { pdcp_log->error("Error inserting PDCP entity in to array\n."); return; } @@ -167,6 +178,7 @@ void pdcp::add_bearer_mrb(uint32_t lcid, srslte_pdcp_config_t cfg) } else { pdcp_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rrc->get_rb_name(lcid).c_str()); } + pthread_rwlock_unlock(&rwlock); } void pdcp::config_security(uint32_t lcid, @@ -175,9 +187,11 @@ void pdcp::config_security(uint32_t lcid, CIPHERING_ALGORITHM_ID_ENUM cipher_algo, INTEGRITY_ALGORITHM_ID_ENUM integ_algo) { + pthread_rwlock_rdlock(&rwlock); if (valid_lcid(lcid)) { pdcp_array.at(lcid)->config_security(k_enc, k_int, cipher_algo, integ_algo); } + pthread_rwlock_unlock(&rwlock); } void pdcp::config_security_all(uint8_t *k_enc, @@ -185,25 +199,31 @@ void pdcp::config_security_all(uint8_t *k_enc, CIPHERING_ALGORITHM_ID_ENUM cipher_algo, INTEGRITY_ALGORITHM_ID_ENUM integ_algo) { + pthread_rwlock_rdlock(&rwlock); for(uint32_t i=0;iis_active()) { pdcp_array.at(i)->config_security(k_enc, k_int, cipher_algo, integ_algo); } } + pthread_rwlock_unlock(&rwlock); } void pdcp::enable_integrity(uint32_t lcid) { + pthread_rwlock_rdlock(&rwlock); if (valid_lcid(lcid)) { pdcp_array.at(lcid)->enable_integrity(); } + pthread_rwlock_unlock(&rwlock); } void pdcp::enable_encryption(uint32_t lcid) { + pthread_rwlock_rdlock(&rwlock); if (valid_lcid(lcid)) { pdcp_array.at(lcid)->enable_encryption(); } + pthread_rwlock_unlock(&rwlock); } /******************************************************************************* @@ -211,18 +231,21 @@ void pdcp::enable_encryption(uint32_t lcid) *******************************************************************************/ void pdcp::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { + pthread_rwlock_rdlock(&rwlock); if (valid_lcid(lcid)) { pdcp_array.at(lcid)->write_pdu(pdu); } else { pdcp_log->warning("Writing pdu: lcid=%d. Deallocating pdu\n", lcid); byte_buffer_pool::get_instance()->deallocate(pdu); } + pthread_rwlock_unlock(&rwlock); } void pdcp::write_pdu_bcch_bch(byte_buffer_t *sdu) { rrc->write_pdu_bcch_bch(sdu); } + void pdcp::write_pdu_bcch_dlsch(byte_buffer_t *sdu) { rrc->write_pdu_bcch_dlsch(sdu); @@ -243,7 +266,7 @@ void pdcp::write_pdu_mch(uint32_t lcid, byte_buffer_t *sdu) } /******************************************************************************* - Helpers + Helpers (Lock must be hold when calling those) *******************************************************************************/ bool pdcp::valid_lcid(uint32_t lcid) { diff --git a/srsenb/hdr/upper/pdcp.h b/srsenb/hdr/upper/pdcp.h index 9624958e4..ce6b01ca6 100644 --- a/srsenb/hdr/upper/pdcp.h +++ b/srsenb/hdr/upper/pdcp.h @@ -39,7 +39,7 @@ class pdcp : public pdcp_interface_rlc, public pdcp_interface_rrc { public: - + virtual ~pdcp() {}; void init(rlc_interface_pdcp *rlc_, rrc_interface_pdcp *rrc_, gtpu_interface_pdcp *gtpu_, srslte::log *pdcp_log_); void stop(); diff --git a/srsenb/src/upper/pdcp.cc b/srsenb/src/upper/pdcp.cc index 6f07e4ece..7f62477f9 100644 --- a/srsenb/src/upper/pdcp.cc +++ b/srsenb/src/upper/pdcp.cc @@ -56,7 +56,7 @@ void pdcp::add_user(uint16_t rnti) { pthread_rwlock_rdlock(&rwlock); if (users.count(rnti) == 0) { - srslte::pdcp *obj = new srslte::pdcp; + srslte::pdcp *obj = new srslte::pdcp; obj->init(&users[rnti].rlc_itf, &users[rnti].rrc_itf, &users[rnti].gtpu_itf, log_h, RB_ID_SRB0, SECURITY_DIRECTION_DOWNLINK); users[rnti].rlc_itf.rnti = rnti; users[rnti].gtpu_itf.rnti = rnti; From c1a0b17c408bd1f12aa5dc36c7b879d882ed3d26 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 17 Jul 2018 15:31:54 +0200 Subject: [PATCH 38/88] Improved phy_dl_test --- lib/test/phy/phy_dl_test.c | 184 ++++++++++++++++++++++++++----------- 1 file changed, 128 insertions(+), 56 deletions(-) diff --git a/lib/test/phy/phy_dl_test.c b/lib/test/phy/phy_dl_test.c index 8c400c3b4..50ea25a1e 100644 --- a/lib/test/phy/phy_dl_test.c +++ b/lib/test/phy/phy_dl_test.c @@ -30,6 +30,8 @@ #include "srslte/srslte.h" +#define MAX_DATABUFFER_SIZE (6144 * 16 * 3 / 8) + srslte_cell_t cell = { .nof_prb = 100, .nof_ports = 1, @@ -39,14 +41,14 @@ srslte_cell_t cell = { .phich_length = SRSLTE_PHICH_NORM }; -uint32_t tm = 0; +uint32_t transmission_mode = 1; srslte_mimo_type_t mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA; -uint32_t sf_idx = 5; -uint32_t cfi = 3; +uint32_t cfi = 1; uint32_t nof_rx_ant = 1; -uint32_t nof_subframes = 10; +uint32_t nof_subframes = 100; uint16_t rnti = 0x1234; bool print_dci_table; +uint32_t mcs = 28; void usage(char *prog) { printf("Usage: %s [cfpndvs]\n", prog); @@ -56,12 +58,13 @@ void usage(char *prog) { printf("\t-s number of subframes to simulate [Default %d]\n", nof_subframes); printf("\t-d Print DCI table [Default %s]\n", print_dci_table ? "yes" : "no"); printf("\t-x MIMO Type: single, diversity, cdd, multiplex [Default %s]\n", srslte_mimotype2str(mimo_type)); + printf("\t-m mcs [Default %d]\n", mcs); printf("\t-v [set srslte_verbose to debug, default none]\n"); } void parse_args(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "cfpndvsx")) != -1) { + while ((opt = getopt(argc, argv, "cfpndvsxm")) != -1) { switch (opt) { case 'x': if (srslte_str2mimotype(argv[optind], &mimo_type)) { @@ -72,18 +75,25 @@ void parse_args(int argc, char **argv) { if (mimo_type == SRSLTE_MIMO_TYPE_SINGLE_ANTENNA) { cell.nof_ports = 1; nof_rx_ant = 1; - tm = 0; + transmission_mode = 1; } else { cell.nof_ports = 2; nof_rx_ant = 2; if (mimo_type == SRSLTE_MIMO_TYPE_TX_DIVERSITY) { - tm = 2; + transmission_mode = 2; + } else if (mimo_type == SRSLTE_MIMO_TYPE_CDD) { + transmission_mode = 3; + } else { + transmission_mode = 4; } } break; case 'f': cfi = (uint32_t) atoi(argv[optind]); break; + case 'm': + mcs = (uint32_t) atoi(argv[optind]); + break; case 'p': cell.nof_prb = (uint32_t) atoi(argv[optind]); break; @@ -109,6 +119,53 @@ void parse_args(int argc, char **argv) { int prbset_num = 1, last_prbset_num = 1; int prbset_orig = 0; +int work_enb(srslte_enb_dl_t *enb_dl, + srslte_dci_format_t dci_format, + srslte_ra_dl_dci_t *dci, + srslte_ra_dl_grant_t *grant, + srslte_softbuffer_tx_t **softbuffer_tx, + uint32_t sf_idx, uint8_t **data_tx) { + int ret = SRSLTE_ERROR; + + srslte_dci_location_t location = { + .ncce = 8, + .L = 3 + }; + + srslte_enb_dl_clear_sf(enb_dl); + + srslte_enb_dl_put_base(enb_dl, sf_idx); + + if (srslte_enb_dl_put_pdcch_dl(enb_dl, + dci, + dci_format, + location, + rnti, + sf_idx % 10) < 0) { + fprintf(stderr, "Error putting PDCCH\n"); + goto quit; + } + + if (srslte_enb_dl_put_pdsch(enb_dl, + grant, + softbuffer_tx, + rnti, + (int[SRSLTE_MAX_CODEWORDS]) {dci->rv_idx, dci->rv_idx_1}, + sf_idx % 10, + data_tx, + mimo_type) < 0) { + fprintf(stderr, "Error putting PDSCH\n"); + goto quit; + } + + srslte_enb_dl_gen_signal(enb_dl); + + ret = SRSLTE_SUCCESS; + + quit: + return ret; +} + unsigned int reverse(register unsigned int x) { x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1)); @@ -131,13 +188,17 @@ uint32_t prbset_to_bitmask() { } int main(int argc, char **argv) { + struct timeval t[3] = {}; + size_t tx_nof_bits = 0, rx_nof_bits = 0; srslte_enb_dl_t enb_dl = {}; srslte_ue_dl_t ue_dl = {}; srslte_softbuffer_tx_t *softbuffer_tx[SRSLTE_MAX_TB] = {}; srslte_softbuffer_rx_t *softbuffer_rx[SRSLTE_MAX_TB] = {}; uint8_t *data_tx[SRSLTE_MAX_TB] = {}; uint8_t *data_rx[SRSLTE_MAX_TB] = {}; - uint32_t count_failures = 0; + uint32_t count_failures = 0, count_tbs = 0; + size_t pdsch_decode_us = 0; + size_t pdsch_encode_us = 0; int ret = -1; @@ -179,13 +240,13 @@ int main(int argc, char **argv) { goto quit; } - data_tx[i] = srslte_vec_malloc(sizeof(uint8_t) * 150000); + data_tx[i] = srslte_vec_malloc(sizeof(uint8_t) * MAX_DATABUFFER_SIZE); if (!data_tx[i]) { fprintf(stderr, "Error allocating data tx\n"); goto quit; } - data_rx[i] = srslte_vec_malloc(sizeof(uint8_t) * 150000); + data_rx[i] = srslte_vec_malloc(sizeof(uint8_t) * MAX_DATABUFFER_SIZE); if (!data_rx[i]) { fprintf(stderr, "Error allocating data tx\n"); goto quit; @@ -223,42 +284,53 @@ int main(int argc, char **argv) { srslte_ue_dl_set_rnti(&ue_dl, rnti); + srslte_chest_dl_average_subframe(&ue_dl.chest, true); + //srslte_chest_dl_set_smooth_filter_gauss(&ue_dl.chest, 4, 1.0f); + /* * Loop */ + INFO("--- Starting test ---\n"); for (uint32_t sf_idx = 0; sf_idx < nof_subframes; sf_idx++) { bool acks[SRSLTE_MAX_TB] = {}; - /* Run eNodeB */ - srslte_enb_dl_clear_sf(&enb_dl); - - srslte_enb_dl_put_base(&enb_dl, sf_idx); + /* Generate random data */ + for (int t = 0; t < SRSLTE_MAX_TB; t++) { + for (int i = 0; i < MAX_DATABUFFER_SIZE; i++) { + data_tx[t][i] = (uint8_t) (rand() & 0xff); + } + } + /* + * Run eNodeB + */ srslte_ra_dl_dci_t dci = {}; srslte_dci_format_t dci_format = SRSLTE_DCI_FORMAT1A; srslte_ra_dl_grant_t grant = {}; + prbset_num = (int) ceilf((float) cell.nof_prb / srslte_ra_type0_P(cell.nof_prb)); + last_prbset_num = prbset_num; + /* Pupulate TB Common */ dci.harq_process = 0; /* Pupulate TB0 */ - dci.mcs_idx = 0; + dci.mcs_idx = mcs; dci.ndi = 0; dci.rv_idx = 0; dci.tb_en[0] = true; if (mimo_type == SRSLTE_MIMO_TYPE_CDD || mimo_type == SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX) { - dci_format = SRSLTE_DCI_FORMAT2B; + dci_format = (transmission_mode == 3) ? SRSLTE_DCI_FORMAT2A : SRSLTE_DCI_FORMAT2; /* Pupulate TB1 */ - dci.mcs_idx_1 = 0; + dci.mcs_idx_1 = mcs; dci.ndi_1 = 0; dci.rv_idx_1 = 0; dci.tb_en[1] = true; /* Pupulate Allocation */ dci.alloc_type = SRSLTE_RA_ALLOC_TYPE0; - dci.alloc_type = SRSLTE_RA_ALLOC_TYPE0; dci.type0_alloc.rbg_bitmask = prbset_to_bitmask(); } else { dci_format = SRSLTE_DCI_FORMAT1A; @@ -275,62 +347,62 @@ int main(int argc, char **argv) { dci.dci_is_1c = (dci_format == SRSLTE_DCI_FORMAT1C); srslte_ra_dl_dci_to_grant(&dci, cell.nof_prb, rnti, &grant); + INFO("--- Process Uplink ---\n"); - srslte_dci_location_t location = { - .ncce = 0, - .L = 2 - }; - - for (int t = 0; t < SRSLTE_RA_DL_GRANT_NOF_TB(&grant); t++) { - for (int i = 0; i < grant.mcs->tbs; i++) { - data_tx[t][i] = (uint8_t) (rand() & 0xff); - } - } - - if (srslte_enb_dl_put_pdcch_dl(&enb_dl, - &dci, - dci_format, - location, - rnti, - sf_idx % 10) < 0) { - fprintf(stderr, "Error putting PDCCH\n"); + gettimeofday(&t[1], NULL); + if (work_enb(&enb_dl, dci_format, &dci, &grant, softbuffer_tx, sf_idx, data_tx)) { goto quit; } - - if (srslte_enb_dl_put_pdsch(&enb_dl, - &grant, - softbuffer_tx, - rnti, - (int[SRSLTE_MAX_CODEWORDS]) {dci.rv_idx, dci.rv_idx_1}, - sf_idx % 10, - data_tx, - mimo_type) < 0) { - fprintf(stderr, "Error putting PDSCH\n"); - goto quit; - } - - srslte_enb_dl_gen_signal(&enb_dl); - - /* Run UE */ - int n = srslte_ue_dl_decode(&ue_dl, data_rx, tm, sf_idx, acks); + gettimeofday(&t[2], NULL); + get_time_interval(t); + pdsch_encode_us += t[0].tv_sec * 1e6 + t[0].tv_usec; + + /* + * Run UE + */ + INFO("--- Process Downlink ---\n"); + gettimeofday(&t[1], NULL); + int n = srslte_ue_dl_decode(&ue_dl, data_rx, transmission_mode - 1, sf_idx, acks); if (n < 0) { fprintf(stderr, "Error decoding PDSCH\n"); goto quit; } + gettimeofday(&t[2], NULL); + get_time_interval(t); + pdsch_decode_us += t[0].tv_sec * 1e6 + t[0].tv_usec; for (int i = 0; i < SRSLTE_RA_DL_GRANT_NOF_TB(&grant); i++) { - if (!acks[i]) { - INFO("UE Failed decoding subframe %d\n", sf_idx); + if (!acks[i] || memcmp(data_tx[i], data_rx[i], grant.mcs[i].tbs / 8) != 0) { + printf("UE Failed decoding tb %d in subframe %d\n", i, sf_idx); + srslte_vec_fprint_hex(stdout, data_tx[i], grant.mcs[i].tbs / 8); + srslte_vec_fprint_hex(stdout, data_rx[i], grant.mcs[i].tbs / 8); count_failures++; } + count_tbs++; } + + tx_nof_bits += (enb_dl.pdsch_cfg.grant.tb_en[0] ? enb_dl.pdsch_cfg.grant.mcs[0].tbs : 0); + tx_nof_bits += (enb_dl.pdsch_cfg.grant.tb_en[1] ? enb_dl.pdsch_cfg.grant.mcs[1].tbs : 0); + rx_nof_bits += (acks[0] ? ue_dl.pdsch_cfg.grant.mcs[0].tbs : 0); + rx_nof_bits += (acks[1] ? ue_dl.pdsch_cfg.grant.mcs[1].tbs : 0); } - printf("Finished! The UE failed decoding %d of %d.\n", count_failures, nof_subframes); + printf("Finished! The UE failed decoding %d of %d transport blocks.\n", count_failures, count_tbs); if (!count_failures) { ret = SRSLTE_SUCCESS; } + printf("%ld were transmitted, %ld bits were received.\n", tx_nof_bits, rx_nof_bits); + printf("[Rates in Mbps] Granted Processed\n"); + printf(" eNb: %5.1f %5.1f\n", + (float) tx_nof_bits / (float) nof_subframes / 1000.0f, + (float) rx_nof_bits / pdsch_encode_us); + printf(" UE: %5.1f %5.1f\n", + (float) rx_nof_bits / (float) nof_subframes / 1000.0f, + (float) rx_nof_bits / pdsch_decode_us); + + printf("BLER: %5.1f%%\n", (float) count_failures / (float) count_tbs * 100.0f); + quit: srslte_enb_dl_free(&enb_dl); srslte_ue_dl_free(&ue_dl); From a21db86a786443290fa1688ebc7a6bcbec47491f Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 17 Jul 2018 15:33:00 +0200 Subject: [PATCH 39/88] SCH Codeblock CRC is computed at same time than parity 0 --- lib/include/srslte/phy/fec/crc.h | 16 +++++- lib/include/srslte/phy/fec/turbocoder.h | 4 +- lib/src/phy/fec/crc.c | 17 ++---- lib/src/phy/fec/test/turbocoder_test.c | 2 +- lib/src/phy/fec/turbocoder.c | 76 +++++++++++++++++++------ lib/src/phy/phch/sch.c | 11 ++-- 6 files changed, 86 insertions(+), 40 deletions(-) diff --git a/lib/include/srslte/phy/fec/crc.h b/lib/include/srslte/phy/fec/crc.h index 030e7c6bb..9bc864831 100644 --- a/lib/include/srslte/phy/fec/crc.h +++ b/lib/include/srslte/phy/fec/crc.h @@ -63,7 +63,21 @@ SRSLTE_API uint32_t srslte_crc_attach(srslte_crc_t *h, SRSLTE_API uint32_t srslte_crc_attach_byte(srslte_crc_t *h, uint8_t *data, - int len); + int len); + +static inline void srslte_crc_checksum_put_byte(srslte_crc_t *h, uint8_t byte) { + + // Polynom order 8, 16, 24 or 32 only. + int ord = h->order - 8; + uint64_t crc = h->crcinit; + + crc = (crc << 8) ^ h->table[((crc >> (ord)) & 0xff) ^ byte]; + h->crcinit = crc; +} + +static inline uint64_t srslte_crc_checksum_get(srslte_crc_t *h) { + return (h->crcinit & h->crcmask); +} SRSLTE_API uint32_t srslte_crc_checksum_byte(srslte_crc_t *h, uint8_t *data, diff --git a/lib/include/srslte/phy/fec/turbocoder.h b/lib/include/srslte/phy/fec/turbocoder.h index 485e83ff3..4da697461 100644 --- a/lib/include/srslte/phy/fec/turbocoder.h +++ b/lib/include/srslte/phy/fec/turbocoder.h @@ -40,6 +40,7 @@ #include "srslte/config.h" #include "srslte/phy/fec/tc_interl.h" +#include "srslte/phy/fec/crc.h" #define SRSLTE_TCOD_MAX_LEN_CB_BYTES (6144/8) @@ -68,7 +69,8 @@ SRSLTE_API int srslte_tcod_encode(srslte_tcod_t *h, uint8_t *output, uint32_t long_cb); -SRSLTE_API int srslte_tcod_encode_lut(srslte_tcod_t *h, +SRSLTE_API int srslte_tcod_encode_lut(srslte_tcod_t *h, + srslte_crc_t *crc, uint8_t *input, uint8_t *parity, uint32_t cblen_idx); diff --git a/lib/src/phy/fec/crc.c b/lib/src/phy/fec/crc.c index a2f6d7931..c97bdd6f9 100644 --- a/lib/src/phy/fec/crc.c +++ b/lib/src/phy/fec/crc.c @@ -48,17 +48,6 @@ void gen_crc_table(srslte_crc_t *h) { } } -uint64_t crctable(srslte_crc_t *h, uint8_t byte) { - - // Polynom order 8, 16, 24 or 32 only. - int ord = h->order - 8; - uint64_t crc = h->crcinit; - - crc = (crc << 8) ^ h->table[((crc >> (ord)) & 0xff) ^ byte]; - h->crcinit = crc; - return (crc & h->crcmask); -} - uint64_t reversecrcbit(uint32_t crc, int nbits, srslte_crc_t *h) { uint64_t m, rmask = 0x1; @@ -137,8 +126,9 @@ uint32_t srslte_crc_checksum(srslte_crc_t *h, uint8_t *data, int len) { } else { byte = (uint8_t) (srslte_bit_pack(&pter, 8) & 0xFF); } - crc = crctable(h, byte); + srslte_crc_checksum_put_byte(h, byte); } + crc = (uint32_t) srslte_crc_checksum_get(h); // Reverse CRC res8 positions if (a == 1) { @@ -159,8 +149,9 @@ uint32_t srslte_crc_checksum_byte(srslte_crc_t *h, uint8_t *data, int len) { // Calculate CRC for (i = 0; i < len/8; i++) { - crc = crctable(h, data[i]); + srslte_crc_checksum_put_byte(h, data[i]); } + crc = (uint32_t) srslte_crc_checksum_get(h); return crc; diff --git a/lib/src/phy/fec/test/turbocoder_test.c b/lib/src/phy/fec/test/turbocoder_test.c index f8219a4e2..59f057919 100644 --- a/lib/src/phy/fec/test/turbocoder_test.c +++ b/lib/src/phy/fec/test/turbocoder_test.c @@ -97,7 +97,7 @@ int main(int argc, char **argv) { } srslte_tcod_encode(&tcod, input_bits, output_bits, long_cb); - srslte_tcod_encode_lut(&tcod, input_bytes, parity, len); + srslte_tcod_encode_lut(&tcod, NULL, input_bytes, parity, len); srslte_bit_unpack_vector(parity, parity_bits, 2*(long_cb+4)); diff --git a/lib/src/phy/fec/turbocoder.c b/lib/src/phy/fec/turbocoder.c index 69f40dd46..c8fd5ffb4 100644 --- a/lib/src/phy/fec/turbocoder.c +++ b/lib/src/phy/fec/turbocoder.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "srslte/phy/fec/cbsegm.h" #include "srslte/phy/fec/turbocoder.h" @@ -40,9 +41,13 @@ #define RATE 3 #define TOTALTAIL 12 -uint8_t tcod_lut_next_state[188][8][256]; -uint8_t tcod_lut_output[188][8][256]; -uint16_t tcod_per_fw[188][6144]; +typedef struct { + uint8_t next_state; + uint8_t output; +} tcod_lut_t; + +static tcod_lut_t tcod_lut[188][8][256]; +static uint16_t tcod_per_fw[188][6144]; static srslte_bit_interleaver_t tcod_interleavers[188]; static bool table_initiated = false; @@ -187,23 +192,59 @@ int srslte_tcod_encode(srslte_tcod_t *h, uint8_t *input, uint8_t *output, uint32 } /* Expects bytes and produces bytes. The systematic and parity bits are interlaced in the output */ -int srslte_tcod_encode_lut(srslte_tcod_t *h, uint8_t *input, uint8_t *parity, uint32_t cblen_idx) +int srslte_tcod_encode_lut(srslte_tcod_t *h, srslte_crc_t *crc, uint8_t *input, uint8_t *parity, uint32_t cblen_idx) { if (cblen_idx < 188) { - uint32_t long_cb = srslte_cbsegm_cbsize(cblen_idx); + uint32_t long_cb = (uint32_t) srslte_cbsegm_cbsize(cblen_idx); if (long_cb % 8) { fprintf(stderr, "Turbo coder LUT implementation long_cb must be multiple of 8\n"); return -1; } - + + /* Reset CRC */ + if (crc) { + srslte_crc_set_init(crc, 0); + } + /* Parity bits for the 1st constituent encoders */ - uint8_t state0 = 0; - for (uint32_t i=0;iorder) / 8; i++) { + uint8_t in = input[i]; + + /* Put byte in CRC and save latest checksum */ + srslte_crc_checksum_put_byte(crc, in); + + /* Run actual encoder */ + tcod_lut_t l = tcod_lut[cblen_idx][state0][in]; + parity[i] = l.output; + state0 = l.next_state; + } + + uint32_t checksum = (uint32_t) srslte_crc_checksum_get(crc); + for (int i = 0; i < crc->order / 8; i++) { + int mask_shift = 8 * (crc->order / 8 - i - 1); + int idx = (long_cb - crc->order) / 8 + i; + uint8_t in = (uint8_t) ((checksum >> mask_shift) & 0xff); + + input[idx] = in; + tcod_lut_t l = tcod_lut[cblen_idx][state0][in]; + parity[idx] = l.output; + state0 = l.next_state; + } + + } else { + /* No CRC given */ + for (uint32_t i = 0; i < long_cb / 8; i++) { + tcod_lut_t l = tcod_lut[cblen_idx][state0][input[i]]; + parity[i] = l.output; + state0 = l.next_state; + } } - parity[long_cb/8] = 0; // will put tail here later + parity[long_cb / 8] = 0; // will put tail here later /* Interleave input */ srslte_bit_interleaver_run(&tcod_interleavers[cblen_idx], input, h->temp, 0); @@ -212,10 +253,11 @@ int srslte_tcod_encode_lut(srslte_tcod_t *h, uint8_t *input, uint8_t *parity, ui /* Parity bits for the 2nd constituent encoders */ uint8_t state1 = 0; for (uint32_t i=0;itemp[i]]; + tcod_lut_t l = tcod_lut[cblen_idx][state1][h->temp[i]]; + uint8_t out = l.output; parity[long_cb/8+i] |= (out&0xf0)>>4; - parity[long_cb/8+i+1] = (out&0xf)<<4; - state1 = tcod_lut_next_state[cblen_idx][state1][h->temp[i]] % 8; + parity[long_cb/8+i+1] = (out&0xf)<<4; + state1 = l.next_state; } /* Tail bits */ @@ -318,7 +360,7 @@ void srslte_tcod_gentable() { reg_1 = (state&2)>>1; reg_2 = state&1; - tcod_lut_output[len][state][data] = 0; + tcod_lut[len][state][data].output = 0; uint8_t bit, in, out; for (uint32_t i = 0; i < 8; i++) { bit = (data&(1<<(7-i)))?1:0; @@ -330,10 +372,10 @@ void srslte_tcod_gentable() { reg_1 = reg_0; reg_0 = in; - tcod_lut_output[len][state][data] |= out<<(7-i); + tcod_lut[len][state][data].output |= out<<(7-i); } - tcod_lut_next_state[len][state][data] = reg_0<<2 | reg_1<<1 | reg_2; + tcod_lut[len][state][data].next_state = (uint8_t) ((reg_0 << 2 | reg_1 << 1 | reg_2) % 8); } } } diff --git a/lib/src/phy/phch/sch.c b/lib/src/phy/phch/sch.c index aa1f297d7..2d7290e9d 100644 --- a/lib/src/phy/phch/sch.c +++ b/lib/src/phy/phch/sch.c @@ -264,15 +264,12 @@ static int encode_tb_off(srslte_sch_t *q, /* Append Transport Block parity bits to the last CB */ memcpy(q->cb_in, &data[rp/8], (rlen - 24) * sizeof(uint8_t)/8); memcpy(&q->cb_in[(rlen - 24)/8], parity, 3 * sizeof(uint8_t)); - } - - /* Attach Codeblock CRC */ - if (cb_segm->C > 1) { - srslte_crc_attach_byte(&q->crc_cb, q->cb_in, rlen); } - /* Turbo Encoding */ - srslte_tcod_encode_lut(&q->encoder, q->cb_in, q->parity_bits, cblen_idx); + /* Turbo Encoding + * If Codeblock CRC is required it is given the CRC instance pointer, otherwise CRC pointer shall be NULL + */ + srslte_tcod_encode_lut(&q->encoder, (cb_segm->C > 1) ? &q->crc_cb : NULL, q->cb_in, q->parity_bits, cblen_idx); } DEBUG("RM cblen_idx=%d, n_e=%d, wp=%d, nof_e_bits=%d\n",cblen_idx, n_e, wp, nof_e_bits); From a0fa2d5b017fcaa0d7344d998d1b5599793f1e30 Mon Sep 17 00:00:00 2001 From: yagoda Date: Tue, 17 Jul 2018 09:35:00 +0100 Subject: [PATCH 40/88] small fix in eMBMS MAC --- srsenb/src/mac/mac.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/srsenb/src/mac/mac.cc b/srsenb/src/mac/mac.cc index d16279f15..fb1a71c4a 100644 --- a/srsenb/src/mac/mac.cc +++ b/srsenb/src/mac/mac.cc @@ -734,7 +734,8 @@ int mac::get_mch_sched(bool is_mcch, dl_sched_t *dl_sched_res) dl_sched_res->sched_grants[0].data[0] = ue_db[SRSLTE_MRNTI]->generate_mch_pdu(mch, 1, mcs_data.tbs/8); } } else { - //TRANSMIT NOTHING + dl_sched_res->sched_grants[0].rnti = 0; + dl_sched_res->sched_grants[0].data[0] = NULL; } mch.current_sf_allocation_num++; } From 190634680cc892ef98ffd20a58be4d1309458812 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 17 Jul 2018 17:08:02 +0200 Subject: [PATCH 41/88] bump version to 18.6.1 --- cmake/modules/SRSLTEVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/SRSLTEVersion.cmake b/cmake/modules/SRSLTEVersion.cmake index db0087290..e79f7f88e 100644 --- a/cmake/modules/SRSLTEVersion.cmake +++ b/cmake/modules/SRSLTEVersion.cmake @@ -20,5 +20,5 @@ SET(SRSLTE_VERSION_MAJOR 18) SET(SRSLTE_VERSION_MINOR 6) -SET(SRSLTE_VERSION_PATCH 0) +SET(SRSLTE_VERSION_PATCH 1) SET(SRSLTE_VERSION_STRING "${SRSLTE_VERSION_MAJOR}.${SRSLTE_VERSION_MINOR}.${SRSLTE_VERSION_PATCH}") From 6d4bb7f6b1d9dfc0eb33f46918b183d325f69d27 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 16 Jul 2018 18:14:42 +0200 Subject: [PATCH 42/88] update debian files --- debian/control | 10 +++++++++- debian/rules | 5 ++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/debian/control b/debian/control index 58720070f..fca5db4ce 100644 --- a/debian/control +++ b/debian/control @@ -8,7 +8,15 @@ Homepage: https://github.com/srsLTE/srsLTE/ Package: srslte Architecture: any -Depends: libfftw3-3 (>= 3.3.3-1), libboost-program-options1.62.0 (>= 1.62.0), libmbedcrypto1 (>= 2.8.0-1), libconfig++9v5 (>= 1.5-0.2), libsctp1 (>= 1.0.16+dfsg-3), uhd-host (>= 3.9.2-1), libuhd003.010.003 (>= 3.10.3.0-2) +Depends: + libfftw3-3, + libboost-program-options1.55.0 | libboost-program-options1.62.0, + libmbedcrypto0 | libmbedcrypto1, + libconfig++9v5, + libsctp1, + uhd-host, + libuhd003 | libuhd003.010.003, + ${misc:Depends} Description: This is srsLTE, a free and open-source LTE software suite. This software allows you to run a full end-to-end, open-source LTE system. It contains a UE, eNB and EPC implementation. diff --git a/debian/rules b/debian/rules index 3b7e3ced4..b1a2e7f2b 100644 --- a/debian/rules +++ b/debian/rules @@ -8,8 +8,11 @@ export DH_OPTIONS %: dh $@ --parallel +override_dh_shlibdeps: + dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info + override_dh_auto_configure: - dh_auto_configure --buildsystem=cmake -- $(extraopts) $(CEPH_EXTRA_CMAKE_ARGS) -DCMAKE_BUILD_TYPE=Release + dh_auto_configure --buildsystem=cmake -- $(extraopts) $(CEPH_EXTRA_CMAKE_ARGS) -DCMAKE_BUILD_TYPE=RelWithDebInfo override_dh_auto_test: # skip executing tests From 3dcddf92e3f19c9b51b9a808edb837f52383c101 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 18 Jul 2018 10:25:27 +0200 Subject: [PATCH 43/88] update debian files (remove obsolete install script) --- debian/srslte.install | 9 --------- 1 file changed, 9 deletions(-) delete mode 100755 debian/srslte.install diff --git a/debian/srslte.install b/debian/srslte.install deleted file mode 100755 index 7ed295542..000000000 --- a/debian/srslte.install +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/dh-exec -srsue/ue.conf.example => usr/share/srslte/config/ue.conf -srsenb/enb.conf.example => usr/share/srslte/config/enb.conf -srsenb/rr.conf.example => usr/share/srslte/config/rr.conf -srsenb/drb.conf.example => usr/share/srslte/config/drb.conf -srsenb/sib.conf.example => usr/share/srslte/config/sib.conf -srsepc/epc.conf.example => usr/share/srslte/config/epc.conf -srsepc/mbms.conf.example => usr/share/srslte/config/mbms.conf -srsepc/user_db.csv.example => usr/share/srslte/config/user_db.csv From eb8a71f85bc6c109fe902401a416b9068b2f725b Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 18 Jul 2018 10:32:10 +0200 Subject: [PATCH 44/88] update debian files --- debian/changelog | 10 +- debian/config | 13 ++ debian/control | 19 +- debian/copyright | 597 +++++++---------------------------------------- debian/postinst | 14 ++ debian/rules | 0 debian/templates | 6 + 7 files changed, 138 insertions(+), 521 deletions(-) create mode 100755 debian/config create mode 100755 debian/postinst mode change 100644 => 100755 debian/rules create mode 100644 debian/templates diff --git a/debian/changelog b/debian/changelog index 036025343..51063a6db 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,11 +1,17 @@ +srslte (18.06.1-0ubuntu1) bionic; urgency=medium + + * Update to srsLTE 18.06.1 + + -- Andre Puschmann Wed, 18 Jul 2018 11:34:00 +0200 + srslte (18.05~SNAPSHOT-0ubuntu2) bionic; urgency=medium * Update pkg deps - -- Andre Puschmann Tue, 01 June 2018 15:10:00 +0200 + -- Andre Puschmann Tue, 01 Jun 2018 15:10:00 +0200 srslte (18.05~SNAPSHOT-0ubuntu1) bionic; urgency=medium * Initial release of deb's - -- Andre Puschmann Tue, 01 June 2018 14:10:00 +0200 + -- Andre Puschmann Tue, 01 Jun 2018 14:10:00 +0200 diff --git a/debian/config b/debian/config new file mode 100755 index 000000000..83d7550e1 --- /dev/null +++ b/debian/config @@ -0,0 +1,13 @@ +#!/bin/sh + +# Exit on error +set -e + +# Source debconf library. +. /usr/share/debconf/confmodule + +# Ask questions +db_input low srslte/install_configs_question || true + +# Show interface +db_go || true diff --git a/debian/control b/debian/control index fca5db4ce..e69e54d61 100644 --- a/debian/control +++ b/debian/control @@ -1,10 +1,23 @@ Source: srslte -Section: misc +Section: universe/misc Priority: optional Maintainer: Andre Puschmann -Build-Depends: debhelper (>= 9), dh-exec, cmake, build-essential, libfftw3-dev, libmbedtls-dev, libboost-program-options-dev, libconfig++-dev, libsctp-dev, libuhd-dev, uhd-host +Build-Depends: + debhelper (>= 9), + dh-exec, + cmake, + build-essential, + libfftw3-dev, + libmbedtls-dev, + libboost-program-options-dev, + libconfig++-dev, + libsctp-dev, + libuhd-dev, + uhd-host Standards-Version: 4.1.1 -Homepage: https://github.com/srsLTE/srsLTE/ +Homepage: http://www.softwareradiosystems.com +Vcs-Git: https://github.com/srsLTE/srsLTE.git +Vcs-Browser: https://github.com/srsLTE/srsLTE/ Package: srslte Architecture: any diff --git a/debian/copyright b/debian/copyright index 592199877..62356443a 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,516 +1,81 @@ -Copyright (C) 2013-2016 Software Radio Systems Limited. All rights reserved. - -The following copyright notices are for libraries used within srsLTE: - ------------------------------------------------------------ -FEC Library - Version 3.0.1 - August 7th, 2007 ------------------------------------------------------------ - -COPYRIGHT - -This package is copyright 2006 by Phil Karn, KA9Q. It may be used -under the terms of the GNU Lesser General Public License (LGPL). - - -GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: srsLTE +Upstream-Contact: srsLTE packaging team +License: AGPL-3+ +Copyright: 2013-2018, Software Radio Systems Limited. +Source: https://www.github.com/srsLTE + +Files: * +Copyright: 2013-2018, Software Radio Systems Limited. +License: AGPL-3+ + +Files: lib/src/phy/fec/viterbi37_port.c + lib/src/phy/fec/viterbi37_sse.c + lib/src/phy/fec/parity.c +Copyright: 2009, Phil Karn, KA9Q +License: LGPL-2.1 + +Files: srsue/src/upper/pcsc_usim.cc + srsue/hdr/upper/pcsc_usim.h +Copyright: 2002-2014, Jouni Malinen +License: BSD-3-clause + + +License: AGPL-3+ + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + . + On Debian systems, the complete text of the AGPL 3 can be found in + /usr/share/doc/srslte/LICENSE + + +License: LGPL-2.1 + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + . + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + . + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +License: BSD-3-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + . + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + . + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + . + 3. Neither the name(s) of the above-listed copyright holder(s) nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/debian/postinst b/debian/postinst new file mode 100755 index 000000000..2009e6847 --- /dev/null +++ b/debian/postinst @@ -0,0 +1,14 @@ +#!/bin/bash + +# Source debconf library. +. /usr/share/debconf/confmodule + +# Fetching configuration from debconf +db_get srslte/install_configs_question +ANSWER1=$RET + +if [ $ANSWER1 == "true" ]; then + srslte_install_configs.sh +fi + +#DEBHELPER# diff --git a/debian/rules b/debian/rules old mode 100644 new mode 100755 diff --git a/debian/templates b/debian/templates new file mode 100644 index 000000000..97127f51a --- /dev/null +++ b/debian/templates @@ -0,0 +1,6 @@ +Template: srslte/install_configs_question +Type: boolean +Default: true +Description: Install configs? + This installs the default srsLTE configuration files to the user's + home directory (~/.srs) but keeps any existing config files. From da387b69302c3b0e82f77681d37c7a63cf2dea01 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 18 Jul 2018 21:24:31 +0200 Subject: [PATCH 45/88] update changelog for 18.06.1 --- CHANGELOG | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 1c4296df6..72831718a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,12 @@ Change Log for Releases ============================== +## 18.06.1 + * Fixed RLC reestablish + * Fixed aperiodic QCI retx + * Fixed eNB instability + * Fixed Debian packaging + ## 18.06 * Added eMBMS support in srsUE/srsENB/srsEPC * Added support for hard SIM cards From 800eea888f22b8bf32ca0bb0eeda1822443565f2 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 19 Jul 2018 10:23:15 +0200 Subject: [PATCH 46/88] fix PDCP security config --- lib/src/upper/pdcp.cc | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index 3f934f73d..e073aeb27 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -83,10 +83,8 @@ void pdcp::stop() void pdcp::reestablish() { pthread_rwlock_rdlock(&rwlock); - for (uint32_t i = 0; i < SRSLTE_N_RADIO_BEARERS; i++) { - if (valid_lcid(i)) { - pdcp_array.at(i)->reestablish(); - } + for (pdcp_map_t::iterator it = pdcp_array.begin(); it != pdcp_array.end(); ++it) { + it->second->reestablish(); } pthread_rwlock_unlock(&rwlock); } @@ -94,12 +92,9 @@ void pdcp::reestablish() { void pdcp::reset() { pthread_rwlock_rdlock(&rwlock); - for (uint32_t i = 0; i < SRSLTE_N_RADIO_BEARERS; i++) { - if (valid_lcid(i)) { - pdcp_array.at(i)->reset(); - } + for (pdcp_map_t::iterator it = pdcp_array.begin(); it != pdcp_array.end(); ++it) { + it->second->reset(); } - if (valid_lcid(0)) { pdcp_array.at(0)->init(rlc, rrc, gw, pdcp_log, default_lcid, default_cnfg); } @@ -113,17 +108,9 @@ bool pdcp::is_drb_enabled(uint32_t lcid) { pthread_rwlock_rdlock(&rwlock); bool ret = false; - - if (lcid >= SRSLTE_N_RADIO_BEARERS) { - pdcp_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid); - goto unlock_and_exit; - } - if (pdcp_array.find(lcid) == pdcp_array.end()) { - goto unlock_and_exit; + if (valid_lcid(lcid)) { + ret = pdcp_array.at(lcid)->is_active(); } - ret = pdcp_array.at(lcid)->is_active(); - -unlock_and_exit: pthread_rwlock_unlock(&rwlock); return ret; } @@ -200,10 +187,8 @@ void pdcp::config_security_all(uint8_t *k_enc, INTEGRITY_ALGORITHM_ID_ENUM integ_algo) { pthread_rwlock_rdlock(&rwlock); - for(uint32_t i=0;iis_active()) { - pdcp_array.at(i)->config_security(k_enc, k_int, cipher_algo, integ_algo); - } + for (pdcp_map_t::iterator it = pdcp_array.begin(); it != pdcp_array.end(); ++it) { + it->second->config_security(k_enc, k_int, cipher_algo, integ_algo); } pthread_rwlock_unlock(&rwlock); } @@ -276,7 +261,6 @@ bool pdcp::valid_lcid(uint32_t lcid) } if (pdcp_array.find(lcid) == pdcp_array.end()) { - pdcp_log->error("PDCP entity for logical channel %d has not been activated\n", lcid); return false; } @@ -291,7 +275,6 @@ bool pdcp::valid_mch_lcid(uint32_t lcid) } if (pdcp_array_mrb.find(lcid) == pdcp_array_mrb.end()) { - pdcp_log->error("PDCP entity for logical channel %d has not been activated\n", lcid); return false; } From 3a9f224f40a25b5551c4a887889b3d1e19b618cb Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 19 Jul 2018 11:53:17 +0200 Subject: [PATCH 47/88] Turbo Coder LUT not a function of CB size --- lib/src/phy/fec/turbocoder.c | 66 ++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/lib/src/phy/fec/turbocoder.c b/lib/src/phy/fec/turbocoder.c index c8fd5ffb4..09d484c58 100644 --- a/lib/src/phy/fec/turbocoder.c +++ b/lib/src/phy/fec/turbocoder.c @@ -46,7 +46,7 @@ typedef struct { uint8_t output; } tcod_lut_t; -static tcod_lut_t tcod_lut[188][8][256]; +static tcod_lut_t tcod_lut[8][256]; static uint16_t tcod_per_fw[188][6144]; static srslte_bit_interleaver_t tcod_interleavers[188]; @@ -219,7 +219,7 @@ int srslte_tcod_encode_lut(srslte_tcod_t *h, srslte_crc_t *crc, uint8_t *input, srslte_crc_checksum_put_byte(crc, in); /* Run actual encoder */ - tcod_lut_t l = tcod_lut[cblen_idx][state0][in]; + tcod_lut_t l = tcod_lut[state0][in]; parity[i] = l.output; state0 = l.next_state; } @@ -231,7 +231,7 @@ int srslte_tcod_encode_lut(srslte_tcod_t *h, srslte_crc_t *crc, uint8_t *input, uint8_t in = (uint8_t) ((checksum >> mask_shift) & 0xff); input[idx] = in; - tcod_lut_t l = tcod_lut[cblen_idx][state0][in]; + tcod_lut_t l = tcod_lut[state0][in]; parity[idx] = l.output; state0 = l.next_state; } @@ -239,7 +239,7 @@ int srslte_tcod_encode_lut(srslte_tcod_t *h, srslte_crc_t *crc, uint8_t *input, } else { /* No CRC given */ for (uint32_t i = 0; i < long_cb / 8; i++) { - tcod_lut_t l = tcod_lut[cblen_idx][state0][input[i]]; + tcod_lut_t l = tcod_lut[state0][input[i]]; parity[i] = l.output; state0 = l.next_state; } @@ -253,7 +253,7 @@ int srslte_tcod_encode_lut(srslte_tcod_t *h, srslte_crc_t *crc, uint8_t *input, /* Parity bits for the 2nd constituent encoders */ uint8_t state1 = 0; for (uint32_t i=0;itemp[i]]; + tcod_lut_t l = tcod_lut[state1][h->temp[i]]; uint8_t out = l.output; parity[long_cb/8+i] |= (out&0xf0)>>4; parity[long_cb/8+i+1] = (out&0xf)<<4; @@ -344,40 +344,40 @@ void srslte_tcod_gentable() { return; } // Save fw/bw permutation tables - for (uint32_t i=0;i>2; - reg_1 = (state&2)>>1; - reg_2 = state&1; - - tcod_lut[len][state][data].output = 0; - uint8_t bit, in, out; - for (uint32_t i = 0; i < 8; i++) { - bit = (data&(1<<(7-i)))?1:0; - - in = bit ^ (reg_2 ^ reg_1); - out = reg_2 ^ (reg_0 ^ in); - - reg_2 = reg_1; - reg_1 = reg_0; - reg_0 = in; - - tcod_lut[len][state][data].output |= out<<(7-i); - - } - tcod_lut[len][state][data].next_state = (uint8_t) ((reg_0 << 2 | reg_1 << 1 | reg_2) % 8); + } + // Compute state transitions + for (uint32_t state=0;state<8;state++) { + for (uint32_t data=0;data<256;data++) { + + uint8_t reg_0, reg_1, reg_2; + reg_0 = (state&4)>>2; + reg_1 = (state&2)>>1; + reg_2 = state&1; + + tcod_lut[state][data].output = 0; + uint8_t bit, in, out; + for (uint32_t i = 0; i < 8; i++) { + bit = (data&(1<<(7-i)))?1:0; + + in = bit ^ (reg_2 ^ reg_1); + out = reg_2 ^ (reg_0 ^ in); + + reg_2 = reg_1; + reg_1 = reg_0; + reg_0 = in; + + tcod_lut[state][data].output |= out<<(7-i); + } - } + tcod_lut[state][data].next_state = (uint8_t) ((reg_0 << 2 | reg_1 << 1 | reg_2) % 8); + } } srslte_tc_interl_free(&interl); From 8e8fab027bbe475699ba614b4ce6b0781b173766 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 20 Jul 2018 10:19:08 +0200 Subject: [PATCH 48/88] refactor RLC base class - add rwlock - put RLC entities into map - general cleanup --- lib/include/srslte/upper/rlc.h | 17 +- lib/include/srslte/upper/rlc_entity.h | 87 ------ lib/src/upper/rlc.cc | 427 +++++++++++++++++--------- lib/src/upper/rlc_entity.cc | 170 ---------- 4 files changed, 300 insertions(+), 401 deletions(-) delete mode 100644 lib/include/srslte/upper/rlc_entity.h delete mode 100644 lib/src/upper/rlc_entity.cc diff --git a/lib/include/srslte/upper/rlc.h b/lib/include/srslte/upper/rlc.h index 8d6eb2fd5..0d8dcad91 100644 --- a/lib/include/srslte/upper/rlc.h +++ b/lib/include/srslte/upper/rlc.h @@ -50,7 +50,7 @@ class rlc { public: rlc(); - virtual ~rlc() {} + virtual ~rlc(); void init(srsue::pdcp_interface_rlc *pdcp_, srsue::rrc_interface_rlc *rrc_, srsue::ue_interface *ue_, @@ -88,7 +88,7 @@ public: void add_bearer(uint32_t lcid); void add_bearer(uint32_t lcid, srslte_rlc_config_t cnfg); void add_bearer_mrb(uint32_t lcid); - void add_bearer_mrb_enb(uint32_t lcid); + private: void reset_metrics(); @@ -98,14 +98,17 @@ private: srsue::rrc_interface_rlc *rrc; srslte::mac_interface_timers *mac_timers; srsue::ue_interface *ue; - srslte::rlc_entity rlc_array[SRSLTE_N_RADIO_BEARERS]; - srslte::rlc_um rlc_array_mrb[SRSLTE_N_MCH_LCIDS]; + + typedef std::map rlc_map_t; + typedef std::pair rlc_map_pair_t; + + rlc_map_t rlc_array, rlc_array_mrb; + pthread_rwlock_t rwlock; + uint32_t default_lcid; int buffer_size; - long ul_tput_bytes[SRSLTE_N_RADIO_BEARERS]; - long dl_tput_bytes[SRSLTE_N_RADIO_BEARERS]; - long dl_tput_bytes_mrb[SRSLTE_N_MCH_LCIDS]; + // Timer needed for metrics calculation struct timeval metrics_time[3]; bool valid_lcid(uint32_t lcid); diff --git a/lib/include/srslte/upper/rlc_entity.h b/lib/include/srslte/upper/rlc_entity.h deleted file mode 100644 index 894572c14..000000000 --- a/lib/include/srslte/upper/rlc_entity.h +++ /dev/null @@ -1,87 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 Software Radio Systems Limited - * - * \section LICENSE - * - * This file is part of the srsUE library. - * - * srsUE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsUE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#ifndef SRSLTE_RLC_ENTITY_H -#define SRSLTE_RLC_ENTITY_H - -#include "srslte/common/log.h" -#include "srslte/common/common.h" -#include "srslte/interfaces/ue_interfaces.h" -#include "srslte/upper/rlc_common.h" -#include "srslte/upper/rlc_tm.h" -#include "srslte/upper/rlc_um.h" -#include "srslte/upper/rlc_am.h" - -namespace srslte { - - - -/**************************************************************************** - * RLC Entity - * Common container for all RLC entities - ***************************************************************************/ -class rlc_entity -{ -public: - rlc_entity(); - void init(rlc_mode_t mode, - log *rlc_entity_log_, - uint32_t lcid_, - srsue::pdcp_interface_rlc *pdcp_, - srsue::rrc_interface_rlc *rrc_, - mac_interface_timers *mac_timers_, - int buffer_size = -1); // use -1 for default buffer sizes - - void configure(srslte_rlc_config_t cnfg); - void reestablish(); - void stop(); - void empty_queue(); - bool active(); - - rlc_mode_t get_mode(); - uint32_t get_bearer(); - - // PDCP interface - void write_sdu(byte_buffer_t *sdu); - void write_sdu_nb(byte_buffer_t *sdu); - - // MAC interface - uint32_t get_buffer_state(); - uint32_t get_total_buffer_state(); - int read_pdu(uint8_t *payload, uint32_t nof_bytes); - void write_pdu(uint8_t *payload, uint32_t nof_bytes); - - -private: - rlc_mode_t mode; - uint32_t lcid; - rlc_common *rlc; -}; - -} // namespace srslte - - -#endif // SRSLTE_RLC_ENTITY_H diff --git a/lib/src/upper/rlc.cc b/lib/src/upper/rlc.cc index c24f0076b..1a602d7c0 100644 --- a/lib/src/upper/rlc.cc +++ b/lib/src/upper/rlc.cc @@ -25,6 +25,7 @@ */ +#include #include "srslte/upper/rlc.h" #include "srslte/upper/rlc_tm.h" #include "srslte/upper/rlc_um.h" @@ -42,8 +43,25 @@ rlc::rlc() ue = NULL; default_lcid = 0; bzero(metrics_time, sizeof(metrics_time)); - bzero(ul_tput_bytes, sizeof(ul_tput_bytes)); - bzero(dl_tput_bytes, sizeof(dl_tput_bytes)); + pthread_rwlock_init(&rwlock, NULL); +} + +rlc::~rlc() +{ + // destroy all remaining entities + pthread_rwlock_wrlock(&rwlock); + for (rlc_map_t::iterator it = rlc_array.begin(); it != rlc_array.end(); ++it) { + delete(it->second); + } + rlc_array.clear(); + + for (rlc_map_t::iterator it = rlc_array_mrb.begin(); it != rlc_array_mrb.end(); ++it) { + delete(it->second); + } + rlc_array_mrb.clear(); + + pthread_rwlock_unlock(&rwlock); + pthread_rwlock_destroy(&rwlock); } void rlc::init(srsue::pdcp_interface_rlc *pdcp_, @@ -63,109 +81,170 @@ void rlc::init(srsue::pdcp_interface_rlc *pdcp_, buffer_size = buffer_size_; gettimeofday(&metrics_time[1], NULL); - reset_metrics(); + reset_metrics(); - rlc_array[0].init(RLC_MODE_TM, rlc_log, default_lcid, pdcp, rrc, mac_timers, buffer_size); // SRB0 + // create default RLC_TM bearer for SRB0 + add_bearer(default_lcid, srslte_rlc_config_t()); } void rlc::reset_metrics() { - bzero(dl_tput_bytes, sizeof(long)*SRSLTE_N_RADIO_BEARERS); - bzero(ul_tput_bytes, sizeof(long)*SRSLTE_N_RADIO_BEARERS); + for (rlc_map_t::iterator it = rlc_array.begin(); it != rlc_array.end(); ++it) { + it->second->reset_metrics(); + } + + for (rlc_map_t::iterator it = rlc_array_mrb.begin(); it != rlc_array_mrb.end(); ++it) { + it->second->reset_metrics(); + } } void rlc::stop() { - for(uint32_t i=0; isecond->stop(); } + for (rlc_map_t::iterator it = rlc_array_mrb.begin(); it != rlc_array_mrb.end(); ++it) { + it->second->stop(); + } + pthread_rwlock_unlock(&rwlock); } void rlc::get_metrics(rlc_metrics_t &m) { - + pthread_rwlock_rdlock(&rwlock); + gettimeofday(&metrics_time[2], NULL); get_time_interval(metrics_time); double secs = (double)metrics_time[0].tv_sec + metrics_time[0].tv_usec*1e-6; m.dl_tput_mbps = 0; - m.ul_tput_mbps = 0; - for (int i=0;iinfo("LCID=%d, RX throughput: %4.6f Mbps. TX throughput: %4.6f Mbps.\n", - i, - (dl_tput_bytes[i]*8/(double)1e6)/secs, - (ul_tput_bytes[i]*8/(double)1e6)/secs); - } + m.ul_tput_mbps = 0; + + for (rlc_map_t::iterator it = rlc_array.begin(); it != rlc_array.end(); ++it) { + m.dl_tput_mbps += (it->second->get_num_rx_bytes()*8/(double)1e6)/secs; + m.ul_tput_mbps += (it->second->get_num_tx_bytes()*8/(double)1e6)/secs; + rlc_log->info("LCID=%d, RX throughput: %4.6f Mbps. TX throughput: %4.6f Mbps.\n", + it->first, + (it->second->get_num_rx_bytes()*8/(double)1e6)/secs, + (it->second->get_num_tx_bytes()*8/(double)1e6)/secs); } // Add multicast metrics - for (int i=0;iinfo("MCH_LCID=%d, RX throughput: %4.6f Mbps.\n", - i, - (dl_tput_bytes_mrb[i]*8/(double)1e6)/secs); - } + for (rlc_map_t::iterator it = rlc_array_mrb.begin(); it != rlc_array_mrb.end(); ++it) { + m.dl_tput_mbps += (it->second->get_num_rx_bytes()*8/(double)1e6)/secs; + rlc_log->info("MCH_LCID=%d, RX throughput: %4.6f Mbps\n", + it->first, + (it->second->get_num_rx_bytes()*8/(double)1e6)/secs); } memcpy(&metrics_time[1], &metrics_time[2], sizeof(struct timeval)); reset_metrics(); + + pthread_rwlock_unlock(&rwlock); } // A call to reestablish stops all lcids but does not delete the instances. The mapping lcid to rlc mode can not change -void rlc::reestablish() { - for(uint32_t i=0; isecond->reestablish(); + } + + for (rlc_map_t::iterator it = rlc_array_mrb.begin(); it != rlc_array_mrb.end(); ++it) { + it->second->reestablish(); } + + pthread_rwlock_unlock(&rwlock); } -// Resetting the RLC layer returns the object to the state after the call to init(): All lcids are stopped and -// defaul lcid=0 is created +// Resetting the RLC layer returns the object to the state after the call to init(): +// All LCIDs are removed, except SRB0 void rlc::reset() { - stop(); - rlc_array[0].init(RLC_MODE_TM, rlc_log, default_lcid, pdcp, rrc, mac_timers, buffer_size); // SRB0 + pthread_rwlock_wrlock(&rwlock); + for (rlc_map_t::iterator it = rlc_array.begin(); it != rlc_array.end(); ++it) { + delete(it->second); + } + rlc_array.clear(); + + for (rlc_map_t::iterator it = rlc_array_mrb.begin(); it != rlc_array_mrb.end(); ++it) { + delete(it->second); + } + rlc_array_mrb.clear(); + + // Add SRB0 again + add_bearer(default_lcid, srslte_rlc_config_t()); + + pthread_rwlock_unlock(&rwlock); } void rlc::empty_queue() { - for(uint32_t i=0; isecond->empty_queue(); } + pthread_rwlock_unlock(&rwlock); } /******************************************************************************* PDCP interface *******************************************************************************/ + void rlc::write_sdu(uint32_t lcid, byte_buffer_t *sdu) { - if(valid_lcid(lcid)) { - rlc_array[lcid].write_sdu(sdu); + pthread_rwlock_rdlock(&rwlock); + if (valid_lcid(lcid)) { + rlc_array.at(lcid)->write_sdu(sdu); + } else { + rlc_log->warning("Writing SDU: lcid=%d. Deallocating sdu\n", lcid); + byte_buffer_pool::get_instance()->deallocate(sdu); } + pthread_rwlock_unlock(&rwlock); } + + void rlc::write_sdu_nb(uint32_t lcid, byte_buffer_t *sdu) { - if(valid_lcid(lcid)) { - rlc_array[lcid].write_sdu_nb(sdu); + pthread_rwlock_rdlock(&rwlock); + if (valid_lcid(lcid)) { + rlc_array.at(lcid)->write_sdu_nb(sdu); + } else { + rlc_log->warning("Writing SDU: lcid=%d. Deallocating sdu\n", lcid); + byte_buffer_pool::get_instance()->deallocate(sdu); } + pthread_rwlock_unlock(&rwlock); } + + void rlc::write_sdu_mch(uint32_t lcid, byte_buffer_t *sdu) { - if(valid_lcid_mrb(lcid)) { - rlc_array_mrb[lcid].write_sdu(sdu); + pthread_rwlock_rdlock(&rwlock); + if (valid_lcid_mrb(lcid)) { + rlc_array_mrb.at(lcid)->write_sdu_nb(sdu); + } else { + rlc_log->warning("Writing SDU: lcid=%d. Deallocating sdu\n", lcid); + byte_buffer_pool::get_instance()->deallocate(sdu); } + pthread_rwlock_unlock(&rwlock); } -bool rlc::rb_is_um(uint32_t lcid) { - return rlc_array[lcid].get_mode()==RLC_MODE_UM; + +bool rlc::rb_is_um(uint32_t lcid) +{ + bool ret = false; + + pthread_rwlock_rdlock(&rwlock); + if (valid_lcid(lcid)) { + ret = rlc_array.at(lcid)->get_mode() == RLC_MODE_UM; + } + pthread_rwlock_unlock(&rwlock); + + return ret; } /******************************************************************************* @@ -173,61 +252,82 @@ bool rlc::rb_is_um(uint32_t lcid) { *******************************************************************************/ uint32_t rlc::get_buffer_state(uint32_t lcid) { - if(valid_lcid(lcid)) { - return rlc_array[lcid].get_buffer_state(); - } else { - return 0; + uint32_t ret = 0; + + pthread_rwlock_rdlock(&rwlock); + if (valid_lcid(lcid)) { + ret = rlc_array.at(lcid)->get_buffer_state(); } + pthread_rwlock_unlock(&rwlock); + + return ret; } uint32_t rlc::get_total_buffer_state(uint32_t lcid) { - if(valid_lcid(lcid)) { - return rlc_array[lcid].get_total_buffer_state(); - } else { - return 0; + uint32_t ret = 0; + + pthread_rwlock_rdlock(&rwlock); + if (valid_lcid(lcid)) { + ret = rlc_array.at(lcid)->get_total_buffer_state(); } + pthread_rwlock_unlock(&rwlock); + + return ret; } uint32_t rlc::get_total_mch_buffer_state(uint32_t lcid) { - if(valid_lcid_mrb(lcid)) { - return rlc_array_mrb[lcid].get_total_buffer_state(); - } else { - return 0; + uint32_t ret = 0; + + pthread_rwlock_rdlock(&rwlock); + if (valid_lcid(lcid)) { + ret = rlc_array_mrb.at(lcid)->get_total_buffer_state(); } + pthread_rwlock_unlock(&rwlock); + + return ret; } int rlc::read_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) { - if(valid_lcid(lcid)) { - ul_tput_bytes[lcid] += nof_bytes; - return rlc_array[lcid].read_pdu(payload, nof_bytes); + uint32_t ret = 0; + + pthread_rwlock_rdlock(&rwlock); + if (valid_lcid(lcid)) { + ret = rlc_array.at(lcid)->read_pdu(payload, nof_bytes); } - return 0; + pthread_rwlock_unlock(&rwlock); + + return ret; } int rlc::read_pdu_mch(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) { - if(valid_lcid_mrb(lcid)) { - ul_tput_bytes[lcid] += nof_bytes; - return rlc_array_mrb[lcid].read_pdu(payload, nof_bytes); + uint32_t ret = 0; + + pthread_rwlock_rdlock(&rwlock); + if (valid_lcid(lcid)) { + ret = rlc_array_mrb.at(lcid)->read_pdu(payload, nof_bytes); } - return 0; + pthread_rwlock_unlock(&rwlock); + + return ret; } void rlc::write_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) { - if(valid_lcid(lcid)) { - dl_tput_bytes[lcid] += nof_bytes; - rlc_array[lcid].write_pdu(payload, nof_bytes); + pthread_rwlock_rdlock(&rwlock); + if (valid_lcid(lcid)) { + rlc_array.at(lcid)->write_pdu(payload, nof_bytes); } + pthread_rwlock_unlock(&rwlock); } +// Pass directly to PDCP, no DL througput counting done void rlc::write_pdu_bcch_bch(uint8_t *payload, uint32_t nof_bytes) { rlc_log->info_hex(payload, nof_bytes, "BCCH BCH message received."); - dl_tput_bytes[0] += nof_bytes; byte_buffer_t *buf = pool_allocate; if (buf) { memcpy(buf->msg, payload, nof_bytes); @@ -239,10 +339,10 @@ void rlc::write_pdu_bcch_bch(uint8_t *payload, uint32_t nof_bytes) } } +// Pass directly to PDCP, no DL througput counting done void rlc::write_pdu_bcch_dlsch(uint8_t *payload, uint32_t nof_bytes) { rlc_log->info_hex(payload, nof_bytes, "BCCH TXSCH message received."); - dl_tput_bytes[0] += nof_bytes; byte_buffer_t *buf = pool_allocate; if (buf) { memcpy(buf->msg, payload, nof_bytes); @@ -254,10 +354,10 @@ void rlc::write_pdu_bcch_dlsch(uint8_t *payload, uint32_t nof_bytes) } } +// Pass directly to PDCP, no DL througput counting done void rlc::write_pdu_pcch(uint8_t *payload, uint32_t nof_bytes) { rlc_log->info_hex(payload, nof_bytes, "PCCH message received."); - dl_tput_bytes[0] += nof_bytes; byte_buffer_t *buf = pool_allocate; if (buf) { memcpy(buf->msg, payload, nof_bytes); @@ -271,117 +371,170 @@ void rlc::write_pdu_pcch(uint8_t *payload, uint32_t nof_bytes) void rlc::write_pdu_mch(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) { - if(valid_lcid_mrb(lcid)) { - dl_tput_bytes_mrb[lcid] += nof_bytes; - rlc_array_mrb[lcid].write_pdu(payload, nof_bytes); + pthread_rwlock_rdlock(&rwlock); + if (valid_lcid_mrb(lcid)) { + rlc_array_mrb.at(lcid)->write_pdu(payload, nof_bytes); } + pthread_rwlock_unlock(&rwlock); } /******************************************************************************* RRC interface *******************************************************************************/ + +// FIXME: Remove function to forbid implicit configuration void rlc::add_bearer(uint32_t lcid) { - // No config provided - use defaults for SRB1 and SRB2 - if(lcid < 3) { - if (!rlc_array[lcid].active()) { - LIBLTE_RRC_RLC_CONFIG_STRUCT cnfg; - cnfg.rlc_mode = LIBLTE_RRC_RLC_MODE_AM; - cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS45; - cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_INFINITY; - cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_INFINITY; - cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4; - cnfg.dl_am_rlc.t_reordering = LIBLTE_RRC_T_REORDERING_MS35; - cnfg.dl_am_rlc.t_status_prohibit = LIBLTE_RRC_T_STATUS_PROHIBIT_MS0; - add_bearer(lcid, srslte_rlc_config_t(&cnfg)); - } else { - rlc_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rrc->get_rb_name(lcid).c_str()); - } - }else{ + if (lcid > 2) { rlc_log->error("Radio bearer %s does not support default RLC configuration.\n", rrc->get_rb_name(lcid).c_str()); + return; + } + + // No config provided - use defaults for SRB0, SRB1, and SRB2 + if (lcid == 0) { + // SRB0 is TM + add_bearer(lcid, srslte_rlc_config_t()); + } else { + // SRB1 and SRB2 are AM + LIBLTE_RRC_RLC_CONFIG_STRUCT cnfg; + cnfg.rlc_mode = LIBLTE_RRC_RLC_MODE_AM; + cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS45; + cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_INFINITY; + cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_INFINITY; + cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4; + cnfg.dl_am_rlc.t_reordering = LIBLTE_RRC_T_REORDERING_MS35; + cnfg.dl_am_rlc.t_status_prohibit = LIBLTE_RRC_T_STATUS_PROHIBIT_MS0; + add_bearer(lcid, srslte_rlc_config_t(&cnfg)); } } + void rlc::add_bearer(uint32_t lcid, srslte_rlc_config_t cnfg) { - if(lcid >= SRSLTE_N_RADIO_BEARERS) { - rlc_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid); - return; - } + pthread_rwlock_wrlock(&rwlock); - if (!rlc_array[lcid].active()) { - rlc_log->warning("Adding radio bearer %s with mode %s\n", - rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg.rlc_mode]); + rlc_common *rlc_entity = NULL; + + if (not valid_lcid(lcid)) { switch(cnfg.rlc_mode) { - case LIBLTE_RRC_RLC_MODE_AM: - rlc_array[lcid].init(RLC_MODE_AM, rlc_log, lcid, pdcp, rrc, mac_timers, buffer_size); - break; - case LIBLTE_RRC_RLC_MODE_UM_BI: - rlc_array[lcid].init(RLC_MODE_UM, rlc_log, lcid, pdcp, rrc, mac_timers, buffer_size); - break; - case LIBLTE_RRC_RLC_MODE_UM_UNI_DL: - rlc_array[lcid].init(RLC_MODE_UM, rlc_log, lcid, pdcp, rrc, mac_timers, buffer_size); - break; - case LIBLTE_RRC_RLC_MODE_UM_UNI_UL: - rlc_array[lcid].init(RLC_MODE_UM, rlc_log, lcid, pdcp, rrc, mac_timers, buffer_size); - break; - default: - rlc_log->error("Cannot add RLC entity - invalid mode\n"); - return; + case SRSLTE_RLC_MODE_TM: + rlc_entity = new rlc_tm(); + break; + case SRSLTE_RLC_MODE_AM: + rlc_entity = new rlc_am(); + break; + case SRSLTE_RLC_MODE_UM: + rlc_entity = new rlc_um(); + break; + default: + rlc_log->error("Cannot add RLC entity - invalid mode\n"); + return; + } + + if (rlc_entity) { + // configure and add to array + rlc_entity->init(rlc_log, lcid, pdcp, rrc, mac_timers); + + if (cnfg.rlc_mode != SRSLTE_RLC_MODE_TM) { + if (rlc_entity->configure(cnfg) == false) { + rlc_log->error("Error configuring RLC entity\n."); + goto delete_and_exit; + } + } + + if (not rlc_array.insert(rlc_map_pair_t(lcid, rlc_entity)).second) { + rlc_log->error("Error inserting RLC entity in to array\n."); + goto delete_and_exit; + } + } else { + rlc_log->error("Error instantiating RLC\n"); + goto delete_and_exit; } + rlc_log->warning("Added radio bearer %s with mode %s\n", rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg.rlc_mode]); + goto unlock_and_exit; } else { rlc_log->warning("Bearer %s already created.\n", rrc->get_rb_name(lcid).c_str()); } - rlc_array[lcid].configure(cnfg); +delete_and_exit: + if (rlc_entity) { + delete(rlc_entity); + } + +unlock_and_exit: + pthread_rwlock_unlock(&rwlock); } + void rlc::add_bearer_mrb(uint32_t lcid) { - // 36.321 Table 6.2.1-4 - if(lcid >= SRSLTE_N_MCH_LCIDS) { - rlc_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_MCH_LCIDS, lcid); - return; + pthread_rwlock_wrlock(&rwlock); + rlc_common *rlc_entity = NULL; + + if (not valid_lcid_mrb(lcid)) { + rlc_entity = new rlc_um(); + if (rlc_entity) { + // configure and add to array + rlc_entity->init(rlc_log, lcid, pdcp, rrc, mac_timers); + if (rlc_entity->configure(srslte_rlc_config_t::mch_config()) == false) { + rlc_log->error("Error configuring RLC entity\n."); + goto delete_and_exit; + } + if (not rlc_array_mrb.insert(rlc_map_pair_t(lcid, rlc_entity)).second) { + rlc_log->error("Error inserting RLC entity in to array\n."); + goto delete_and_exit; + } + } else { + rlc_log->error("Error instantiating RLC\n"); + goto delete_and_exit; + } + rlc_log->warning("Added radio bearer %s with mode RLC_UM\n", rrc->get_rb_name(lcid).c_str()); + goto unlock_and_exit; + } else { + rlc_log->warning("Bearer %s already created.\n", rrc->get_rb_name(lcid).c_str()); } - rlc_array_mrb[lcid].init(rlc_log, lcid, pdcp, rrc, mac_timers); - rlc_array_mrb[lcid].configure(srslte_rlc_config_t::mch_config()); -} -void rlc::add_bearer_mrb_enb(uint32_t lcid) -{ - if(lcid >= SRSLTE_N_MCH_LCIDS) { - rlc_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_MCH_LCIDS, lcid); - return; +delete_and_exit: + if (rlc_entity) { + delete(rlc_entity); } - rlc_array_mrb[lcid].init(rlc_log,lcid,pdcp,rrc,mac_timers); - rlc_array_mrb[lcid].configure(srslte_rlc_config_t::mch_config()); + +unlock_and_exit: + pthread_rwlock_unlock(&rwlock); } + /******************************************************************************* - Helpers + Helpers (Lock must be hold when calling those) *******************************************************************************/ + bool rlc::valid_lcid(uint32_t lcid) { - if(lcid >= SRSLTE_N_RADIO_BEARERS) { - rlc_log->warning("Invalid LCID=%d\n", lcid); + if (lcid >= SRSLTE_N_RADIO_BEARERS) { + rlc_log->error("Radio bearer id must be in [0:%d] - %d", SRSLTE_N_RADIO_BEARERS, lcid); return false; - } else if(!rlc_array[lcid].active()) { + } + + if (rlc_array.find(lcid) == rlc_array.end()) { return false; } + return true; } bool rlc::valid_lcid_mrb(uint32_t lcid) { - if(lcid >= SRSLTE_N_MCH_LCIDS) { + if (lcid >= SRSLTE_N_MCH_LCIDS) { + rlc_log->error("Radio bearer id must be in [0:%d] - %d", SRSLTE_N_RADIO_BEARERS, lcid); return false; } - if(!rlc_array_mrb[lcid].is_mrb()) { + + if (rlc_array_mrb.find(lcid) == rlc_array_mrb.end()) { return false; } + return true; } - } // namespace srsue diff --git a/lib/src/upper/rlc_entity.cc b/lib/src/upper/rlc_entity.cc deleted file mode 100644 index 783a14982..000000000 --- a/lib/src/upper/rlc_entity.cc +++ /dev/null @@ -1,170 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 Software Radio Systems Limited - * - * \section LICENSE - * - * This file is part of the srsUE library. - * - * srsUE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsUE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include "srslte/upper/rlc_entity.h" - -namespace srslte { - -rlc_entity::rlc_entity() - :rlc(NULL) -{ -} - -void rlc_entity::init(rlc_mode_t mode_, - log *rlc_entity_log_, - uint32_t lcid_, - srsue::pdcp_interface_rlc *pdcp_, - srsue::rrc_interface_rlc *rrc_, - mac_interface_timers *mac_timers_, - int buffer_size) -{ - - if (buffer_size <= 0) { - buffer_size = rlc_common::RLC_BUFFER_NOF_PDU; - } - // Create the RLC instance the first time init() is called. - // If called to reestablished, the entity is stopped but not destroyed - // Next call to init() must use same mode - if (rlc == NULL) { - switch(mode_) - { - case RLC_MODE_TM: - rlc = new rlc_tm((uint32_t) buffer_size); - break; - case RLC_MODE_UM: - rlc = new rlc_um((uint32_t) buffer_size); - break; - case RLC_MODE_AM: - rlc = new rlc_am((uint32_t) buffer_size); - break; - default: - rlc_entity_log_->error("Invalid RLC mode - defaulting to TM\n"); - rlc = new rlc_tm((uint32_t) buffer_size); - break; - } - lcid = lcid_; - mode = mode_; - } else { - if (lcid != lcid_) { - rlc_entity_log_->warning("Reestablishing RLC instance. LCID changed from %d to %d\n", lcid, lcid_); - lcid = lcid_; - } - if (mode != mode_) { - rlc_entity_log_->console("Error reestablishing RLC instance. Mode changed from %d to %d. \n", mode, mode_); - } - } - rlc->init(rlc_entity_log_, lcid_, pdcp_, rrc_, mac_timers_); -} - -void rlc_entity::configure(srslte_rlc_config_t cnfg) -{ - if(rlc) - rlc->configure(cnfg); -} - -// Reestablishment stops the entity but does not destroy it. Mode will not change -void rlc_entity::reestablish() { - rlc->reestablish(); -} - -// A call to stop() stops the entity and clears deletes the instance. Next time this entity can be used for other mode. -void rlc_entity::stop() -{ - rlc->stop(); - delete rlc; - rlc = NULL; -} - -void rlc_entity::empty_queue() -{ - rlc->empty_queue(); -} - -bool rlc_entity::active() -{ - return (rlc != NULL); -} - -rlc_mode_t rlc_entity::get_mode() -{ - if(rlc) - return rlc->get_mode(); - else - return RLC_MODE_TM; -} - -uint32_t rlc_entity::get_bearer() -{ - if(rlc) - return rlc->get_bearer(); - else - return 0; -} - -// PDCP interface -void rlc_entity::write_sdu(byte_buffer_t *sdu) -{ - if(rlc) - rlc->write_sdu(sdu); -} - -void rlc_entity::write_sdu_nb(byte_buffer_t *sdu) -{ - if(rlc) - rlc->write_sdu_nb(sdu); -} - -// MAC interface -uint32_t rlc_entity::get_buffer_state() -{ - if(rlc) - return rlc->get_buffer_state(); - else - return 0; -} - -uint32_t rlc_entity::get_total_buffer_state() -{ - if(rlc) - return rlc->get_total_buffer_state(); - else - return 0; -} - -int rlc_entity::read_pdu(uint8_t *payload, uint32_t nof_bytes) -{ - if(rlc) - return rlc->read_pdu(payload, nof_bytes); - else - return 0; -} -void rlc_entity::write_pdu(uint8_t *payload, uint32_t nof_bytes) -{ - if(rlc) - rlc->write_pdu(payload, nof_bytes); -} - -} // namespace srsue From 27d3d697df8b5306b2267dc46e231da2df2298d5 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 23 Jul 2018 15:44:50 +0200 Subject: [PATCH 49/88] refactor RLC part#2 - move metrics into entities - make configure interface return true/false on success/failure - add own srslte mode type --- lib/include/srslte/upper/rlc_am.h | 13 ++- lib/include/srslte/upper/rlc_common.h | 6 +- lib/include/srslte/upper/rlc_interface.h | 35 ++++--- lib/include/srslte/upper/rlc_tm.h | 12 ++- lib/include/srslte/upper/rlc_um.h | 23 +++- lib/src/upper/rlc_am.cc | 48 +++++++-- lib/src/upper/rlc_tm.cc | 29 +++++- lib/src/upper/rlc_um.cc | 127 +++++++++++++++++------ lib/test/upper/rlc_am_test.cc | 11 ++ lib/test/upper/rlc_stress_test.cc | 20 ++-- lib/test/upper/rlc_um_test.cc | 4 +- srsenb/src/upper/rlc.cc | 2 +- 12 files changed, 250 insertions(+), 80 deletions(-) diff --git a/lib/include/srslte/upper/rlc_am.h b/lib/include/srslte/upper/rlc_am.h index cfaee6c5c..f57a65b0b 100644 --- a/lib/include/srslte/upper/rlc_am.h +++ b/lib/include/srslte/upper/rlc_am.h @@ -66,8 +66,7 @@ struct rlc_amd_retx_t{ }; -class rlc_am - :public rlc_common +class rlc_am : public rlc_common { public: rlc_am(uint32_t queue_len = 16); @@ -77,7 +76,7 @@ public: srsue::pdcp_interface_rlc *pdcp_, srsue::rrc_interface_rlc *rrc_, mac_interface_timers *mac_timers); - void configure(srslte_rlc_config_t cnfg); + bool configure(srslte_rlc_config_t cnfg); void reestablish(); void stop(); @@ -96,6 +95,10 @@ public: int read_pdu(uint8_t *payload, uint32_t nof_bytes); void write_pdu(uint8_t *payload, uint32_t nof_bytes); + uint32_t get_num_tx_bytes(); + uint32_t get_num_rx_bytes(); + void reset_metrics(); + private: byte_buffer_pool *pool; @@ -128,6 +131,10 @@ private: bool do_status; rlc_status_pdu_t status; + // Metrics + uint32_t num_tx_bytes; + uint32_t num_rx_bytes; + /**************************************************************************** * Configurable parameters * Ref: 3GPP TS 36.322 v10.0.0 Section 7 diff --git a/lib/include/srslte/upper/rlc_common.h b/lib/include/srslte/upper/rlc_common.h index c9655efae..f3fcec12d 100644 --- a/lib/include/srslte/upper/rlc_common.h +++ b/lib/include/srslte/upper/rlc_common.h @@ -161,7 +161,7 @@ public: srsue::pdcp_interface_rlc *pdcp_, srsue::rrc_interface_rlc *rrc_, srslte::mac_interface_timers *mac_timers_) = 0; - virtual void configure(srslte_rlc_config_t cnfg) = 0; + virtual bool configure(srslte_rlc_config_t cnfg) = 0; virtual void stop() = 0; virtual void reestablish() = 0; virtual void empty_queue() = 0; @@ -169,6 +169,10 @@ public: virtual rlc_mode_t get_mode() = 0; virtual uint32_t get_bearer() = 0; + virtual uint32_t get_num_tx_bytes() = 0; + virtual uint32_t get_num_rx_bytes() = 0; + virtual void reset_metrics() = 0; + // PDCP interface virtual void write_sdu(byte_buffer_t *sdu) = 0; virtual void write_sdu_nb(byte_buffer_t *sdu) = 0; diff --git a/lib/include/srslte/upper/rlc_interface.h b/lib/include/srslte/upper/rlc_interface.h index b1d211527..0b2460101 100644 --- a/lib/include/srslte/upper/rlc_interface.h +++ b/lib/include/srslte/upper/rlc_interface.h @@ -28,11 +28,19 @@ #define SRSLTE_RLC_INTERFACE_H // for custom constructors -#include "srslte/asn1/liblte_rrc.h" +#include namespace srslte { +typedef enum{ + SRSLTE_RLC_MODE_TM = 0, + SRSLTE_RLC_MODE_UM, + SRSLTE_RLC_MODE_AM, + SRSLTE_RLC_MODE_N_ITEMS +} srslte_rlc_mode_t; +static const char srslte_rlc_mode_text[SRSLTE_RLC_MODE_N_ITEMS][20] = { "TM", "UM", "AM"}; + typedef enum{ RLC_UMD_SN_SIZE_5_BITS = 0, RLC_UMD_SN_SIZE_10_BITS, @@ -80,19 +88,22 @@ typedef struct { class srslte_rlc_config_t { public: - LIBLTE_RRC_RLC_MODE_ENUM rlc_mode; + srslte_rlc_mode_t rlc_mode; srslte_rlc_am_config_t am; srslte_rlc_um_config_t um; // Default ctor - srslte_rlc_config_t(): rlc_mode(LIBLTE_RRC_RLC_MODE_AM), am(), um() {}; + srslte_rlc_config_t(): rlc_mode(SRSLTE_RLC_MODE_TM), am(), um() {}; // Constructor based on liblte's RLC config - srslte_rlc_config_t(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) : rlc_mode(cnfg->rlc_mode), am(), um() + srslte_rlc_config_t(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) : rlc_mode(SRSLTE_RLC_MODE_AM), am(), um() { + // update RLC mode to internal mode struct + rlc_mode = (cnfg->rlc_mode == LIBLTE_RRC_RLC_MODE_AM) ? SRSLTE_RLC_MODE_AM : SRSLTE_RLC_MODE_UM; + switch(rlc_mode) { - case LIBLTE_RRC_RLC_MODE_AM: + case SRSLTE_RLC_MODE_AM: am.t_poll_retx = liblte_rrc_t_poll_retransmit_num[cnfg->ul_am_rlc.t_poll_retx]; am.poll_pdu = liblte_rrc_poll_pdu_num[cnfg->ul_am_rlc.poll_pdu]; am.poll_byte = liblte_rrc_poll_byte_num[cnfg->ul_am_rlc.poll_byte]*1000; // KB @@ -100,7 +111,7 @@ public: am.t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_am_rlc.t_reordering]; am.t_status_prohibit = liblte_rrc_t_status_prohibit_num[cnfg->dl_am_rlc.t_status_prohibit]; break; - case LIBLTE_RRC_RLC_MODE_UM_BI: + case SRSLTE_RLC_MODE_UM: um.t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_um_bi_rlc.t_reordering]; um.rx_sn_field_length = (rlc_umd_sn_size_t)cnfg->dl_um_bi_rlc.sn_field_len; um.rx_window_size = (RLC_UMD_SN_SIZE_5_BITS == um.rx_sn_field_length) ? 16 : 512; @@ -108,16 +119,6 @@ public: um.tx_sn_field_length = (rlc_umd_sn_size_t)cnfg->ul_um_bi_rlc.sn_field_len; um.tx_mod = (RLC_UMD_SN_SIZE_5_BITS == um.tx_sn_field_length) ? 32 : 1024; break; - case LIBLTE_RRC_RLC_MODE_UM_UNI_UL: - um.tx_sn_field_length = (rlc_umd_sn_size_t)cnfg->ul_um_uni_rlc.sn_field_len; - um.tx_mod = (RLC_UMD_SN_SIZE_5_BITS == um.tx_sn_field_length) ? 32 : 1024; - break; - case LIBLTE_RRC_RLC_MODE_UM_UNI_DL: - um.t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_um_uni_rlc.t_reordering]; - um.rx_sn_field_length = (rlc_umd_sn_size_t)cnfg->dl_um_uni_rlc.sn_field_len; - um.rx_window_size = (RLC_UMD_SN_SIZE_5_BITS == um.rx_sn_field_length) ? 16 : 512; - um.rx_mod = (RLC_UMD_SN_SIZE_5_BITS == um.rx_sn_field_length) ? 32 : 1024; - break; default: // Handle default case break; @@ -128,7 +129,7 @@ public: static srslte_rlc_config_t mch_config() { srslte_rlc_config_t cfg; - cfg.rlc_mode = LIBLTE_RRC_RLC_MODE_UM_UNI_DL; + cfg.rlc_mode = SRSLTE_RLC_MODE_UM; cfg.um.t_reordering = 0; cfg.um.rx_sn_field_length = RLC_UMD_SN_SIZE_5_BITS; cfg.um.rx_window_size = 0; diff --git a/lib/include/srslte/upper/rlc_tm.h b/lib/include/srslte/upper/rlc_tm.h index d78ab59c4..5db629231 100644 --- a/lib/include/srslte/upper/rlc_tm.h +++ b/lib/include/srslte/upper/rlc_tm.h @@ -36,8 +36,7 @@ namespace srslte { -class rlc_tm - :public rlc_common +class rlc_tm : public rlc_common { public: rlc_tm(uint32_t queue_len = 16); @@ -47,7 +46,7 @@ public: srsue::pdcp_interface_rlc *pdcp_, srsue::rrc_interface_rlc *rrc_, mac_interface_timers *mac_timers); - void configure(srslte_rlc_config_t cnfg); + bool configure(srslte_rlc_config_t cnfg); void stop(); void reestablish(); void empty_queue(); @@ -55,6 +54,10 @@ public: rlc_mode_t get_mode(); uint32_t get_bearer(); + uint32_t get_num_tx_bytes(); + uint32_t get_num_rx_bytes(); + void reset_metrics(); + // PDCP interface void write_sdu(byte_buffer_t *sdu); void write_sdu_nb(byte_buffer_t *sdu); @@ -75,6 +78,9 @@ private: bool tx_enabled; + uint32_t num_tx_bytes; + uint32_t num_rx_bytes; + // Thread-safe queues for MAC messages rlc_tx_queue ul_queue; }; diff --git a/lib/include/srslte/upper/rlc_um.h b/lib/include/srslte/upper/rlc_um.h index aae8877bb..a880b2238 100644 --- a/lib/include/srslte/upper/rlc_um.h +++ b/lib/include/srslte/upper/rlc_um.h @@ -55,7 +55,7 @@ public: srsue::pdcp_interface_rlc *pdcp_, srsue::rrc_interface_rlc *rrc_, mac_interface_timers *mac_timers_); - void configure(srslte_rlc_config_t cnfg); + bool configure(srslte_rlc_config_t cnfg); void reestablish(); void stop(); void empty_queue(); @@ -75,6 +75,10 @@ public: void write_pdu(uint8_t *payload, uint32_t nof_bytes); int get_increment_sequence_num(); + uint32_t get_num_tx_bytes(); + uint32_t get_num_rx_bytes(); + void reset_metrics(); + private: // Transmitter sub-class @@ -84,13 +88,15 @@ private: rlc_um_tx(uint32_t queue_len); ~rlc_um_tx(); void init(srslte::log *log_); - void configure(srslte_rlc_config_t cfg, std::string rb_name); + bool configure(srslte_rlc_config_t cfg, std::string rb_name); int build_data_pdu(uint8_t *payload, uint32_t nof_bytes); void stop(); void reestablish(); void empty_queue(); void write_sdu(byte_buffer_t *sdu); void try_write_sdu(byte_buffer_t *sdu); + uint32_t get_num_tx_bytes(); + void reset_metrics(); uint32_t get_buffer_size_bytes(); private: @@ -119,6 +125,8 @@ private: bool tx_enabled; + uint32_t num_tx_bytes; + // helper functions void debug_state(); const char* get_rb_name(); @@ -136,10 +144,12 @@ private: srslte::mac_interface_timers *mac_timers_); void stop(); void reestablish(); - void configure(srslte_rlc_config_t cfg, std::string rb_name); + bool configure(srslte_rlc_config_t cfg, std::string rb_name); void handle_data_pdu(uint8_t *payload, uint32_t nof_bytes); void reassemble_rx_sdus(); bool inside_reordering_window(uint16_t sn); + uint32_t get_num_rx_bytes(); + void reset_metrics(); // Timeout callback interface void timer_expired(uint32_t timeout_id); @@ -163,12 +173,14 @@ private: byte_buffer_t *rx_sdu; uint32_t vr_ur_in_rx_sdu; - // Rx state variables + // Rx state variables and counter uint32_t vr_ur; // Receive state. SN of earliest PDU still considered for reordering. uint32_t vr_ux; // t_reordering state. SN following PDU which triggered t_reordering. uint32_t vr_uh; // Highest rx state. SN following PDU with highest SN among rxed PDUs. bool pdu_lost; + uint32_t num_rx_bytes; + // Upper layer handles and variables srsue::pdcp_interface_rlc *pdcp; srsue::rrc_interface_rlc *rrc; @@ -177,6 +189,8 @@ private: // Mutexes pthread_mutex_t mutex; + bool rx_enabled; + /**************************************************************************** * Timers * Ref: 3GPP TS 36.322 v10.0.0 Section 7 @@ -196,6 +210,7 @@ private: // Common variables needed by parent class srsue::rrc_interface_rlc *rrc; + srslte::log *log; uint32_t lcid; srslte_rlc_um_config_t cfg; std::string rb_name; diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 768f50089..25fc6d770 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -61,6 +61,9 @@ rlc_am::rlc_am(uint32_t queue_len) : tx_sdu_queue(queue_len) vr_ms = 0; vr_h = 0; + num_tx_bytes = 0; + num_rx_bytes = 0; + pdu_without_poll = 0; byte_without_poll = 0; @@ -88,13 +91,15 @@ void rlc_am::init(srslte::log *log_, tx_enabled = true; } -void rlc_am::configure(srslte_rlc_config_t cfg_) +bool rlc_am::configure(srslte_rlc_config_t cfg_) { cfg = cfg_.am; log->warning("%s configured: t_poll_retx=%d, poll_pdu=%d, poll_byte=%d, max_retx_thresh=%d, " "t_reordering=%d, t_status_prohibit=%d\n", rrc->get_rb_name(lcid).c_str(), cfg.t_poll_retx, cfg.poll_pdu, cfg.poll_byte, cfg.max_retx_thresh, cfg.t_reordering, cfg.t_status_prohibit); + + return true; } @@ -363,6 +368,7 @@ unlock_and_return: int rlc_am::read_pdu(uint8_t *payload, uint32_t nof_bytes) { pthread_mutex_lock(&mutex); + int pdu_size = 0; log->debug("MAC opportunity - %d bytes\n", nof_bytes); log->debug("tx_window size - %zu PDUs\n", tx_window.size()); @@ -370,7 +376,8 @@ int rlc_am::read_pdu(uint8_t *payload, uint32_t nof_bytes) // Tx STATUS if requested if(do_status && !status_prohibited()) { pthread_mutex_unlock(&mutex); - return build_status_pdu(payload, nof_bytes); + pdu_size = build_status_pdu(payload, nof_bytes); + goto unlock_and_exit; } // if tx_window is full and retx_queue empty, retransmit next PDU to be ack'ed @@ -390,25 +397,27 @@ int rlc_am::read_pdu(uint8_t *payload, uint32_t nof_bytes) // RETX if required if(retx_queue.size() > 0) { - int ret = build_retx_pdu(payload, nof_bytes); - if (ret > 0) { - pthread_mutex_unlock(&mutex); - return ret; + pdu_size = build_retx_pdu(payload, nof_bytes); + if (pdu_size > 0) { + goto unlock_and_exit; } } // Build a PDU from SDUs - int ret = build_data_pdu(payload, nof_bytes); + pdu_size = build_data_pdu(payload, nof_bytes); +unlock_and_exit: + num_tx_bytes += pdu_size; pthread_mutex_unlock(&mutex); - return ret; + return pdu_size; } void rlc_am::write_pdu(uint8_t *payload, uint32_t nof_bytes) { - if(nof_bytes < 1) - return; + if (nof_bytes < 1) return; + pthread_mutex_lock(&mutex); + num_rx_bytes += nof_bytes; if(rlc_am_is_control_pdu(payload)) { handle_control_pdu(payload, nof_bytes); @@ -424,6 +433,25 @@ void rlc_am::write_pdu(uint8_t *payload, uint32_t nof_bytes) pthread_mutex_unlock(&mutex); } +uint32_t rlc_am::get_num_tx_bytes() +{ + return num_tx_bytes; +} + +uint32_t rlc_am::get_num_rx_bytes() +{ + return num_rx_bytes; +} + +void rlc_am::reset_metrics() +{ + pthread_mutex_lock(&mutex); + num_rx_bytes = 0; + num_tx_bytes = 0; + pthread_mutex_unlock(&mutex); +} + + /**************************************************************************** * Timer checks ***************************************************************************/ diff --git a/lib/src/upper/rlc_tm.cc b/lib/src/upper/rlc_tm.cc index 988acf2af..9b132b39b 100644 --- a/lib/src/upper/rlc_tm.cc +++ b/lib/src/upper/rlc_tm.cc @@ -35,6 +35,8 @@ rlc_tm::rlc_tm(uint32_t queue_len) : ul_queue(queue_len) pdcp = NULL; rrc = NULL; lcid = 0; + num_tx_bytes = 0; + num_rx_bytes = 0; pool = byte_buffer_pool::get_instance(); } @@ -56,16 +58,17 @@ void rlc_tm::init(srslte::log *log_, tx_enabled = true; } -void rlc_tm::configure(srslte_rlc_config_t cnfg) +bool rlc_tm::configure(srslte_rlc_config_t cnfg) { log->error("Attempted to configure TM RLC entity\n"); + return true; } void rlc_tm::empty_queue() { // Drop all messages in TX queue byte_buffer_t *buf; - while(ul_queue.try_read(&buf)) { + while (ul_queue.try_read(&buf)) { pool->deallocate(buf); } ul_queue.reset(); @@ -139,11 +142,26 @@ uint32_t rlc_tm::get_total_buffer_state() return get_buffer_state(); } +uint32_t rlc_tm::get_num_tx_bytes() +{ + return num_tx_bytes; +} + +uint32_t rlc_tm::get_num_rx_bytes() +{ + return num_rx_bytes; +} + +void rlc_tm::reset_metrics() +{ + num_tx_bytes = 0; + num_rx_bytes = 0; +} + int rlc_tm::read_pdu(uint8_t *payload, uint32_t nof_bytes) { uint32_t pdu_size = ul_queue.size_tail_bytes(); - if(pdu_size > nof_bytes) - { + if (pdu_size > nof_bytes) { log->error("TX %s PDU size larger than MAC opportunity\n", rrc->get_rb_name(lcid).c_str()); return -1; } @@ -156,6 +174,8 @@ int rlc_tm::read_pdu(uint8_t *payload, uint32_t nof_bytes) pool->deallocate(buf); log->info_hex(payload, pdu_size, "TX %s, %s PDU, queue size=%d, bytes=%d", rrc->get_rb_name(lcid).c_str(), rlc_mode_text[RLC_MODE_TM], ul_queue.size(), ul_queue.size_bytes()); + + num_tx_bytes += pdu_size; return pdu_size; } else { log->warning("Queue empty while trying to read\n"); @@ -174,6 +194,7 @@ void rlc_tm::write_pdu(uint8_t *payload, uint32_t nof_bytes) memcpy(buf->msg, payload, nof_bytes); buf->N_bytes = nof_bytes; buf->set_timestamp(); + num_rx_bytes += nof_bytes; pdcp->write_pdu(lcid, buf); } else { log->error("Fatal Error: Couldn't allocate buffer in rlc_tm::write_pdu().\n"); diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index f2f6d65ef..bf127900b 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -37,6 +37,7 @@ rlc_um::rlc_um(uint32_t queue_len) :lcid(0) ,tx(queue_len) ,rrc(NULL) + ,log(NULL) { bzero(&cfg, sizeof(srslte_rlc_um_config_t)); } @@ -57,48 +58,48 @@ void rlc_um::init(srslte::log *log_, rx.init(log_, lcid_, pdcp_, rrc_, mac_timers_); lcid = lcid_; rrc = rrc_; // needed to determine bearer name during configuration + log = log_; } -void rlc_um::configure(srslte_rlc_config_t cnfg_) +bool rlc_um::configure(srslte_rlc_config_t cnfg_) { // determine bearer name and configure Rx/Tx objects rb_name = get_rb_name(rrc, lcid, cnfg_.um.is_mrb); - rx.configure(cnfg_, rb_name); - tx.configure(cnfg_, rb_name); + if (not rx.configure(cnfg_, rb_name)) { + return false; + } + + if (not tx.configure(cnfg_, rb_name)) { + return false; + } + + log->warning("%s configured in %s mode: t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits\n", + rb_name.c_str(), srslte_rlc_mode_text[cnfg_.rlc_mode], + cfg.t_reordering, rlc_umd_sn_size_num[cfg.rx_sn_field_length], rlc_umd_sn_size_num[cfg.rx_sn_field_length]); // store config cfg = cnfg_.um; + + return true; } -void rlc_um::rlc_um_rx::configure(srslte_rlc_config_t cnfg_, std::string rb_name_) +bool rlc_um::rlc_um_rx::configure(srslte_rlc_config_t cnfg_, std::string rb_name_) { cfg = cnfg_.um; - rb_name = rb_name_; - switch(cnfg_.rlc_mode) { - case LIBLTE_RRC_RLC_MODE_UM_BI: - log->warning("%s configured in %s mode: " - "t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits\n", - get_rb_name(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode], - cfg.t_reordering, rlc_umd_sn_size_num[cfg.rx_sn_field_length], rlc_umd_sn_size_num[cfg.rx_sn_field_length]); - break; - case LIBLTE_RRC_RLC_MODE_UM_UNI_UL: - log->warning("%s configured in %s mode: tx_sn_field_length=%u bits\n", - get_rb_name(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode], - - rlc_umd_sn_size_num[cfg.rx_sn_field_length]); - break; - case LIBLTE_RRC_RLC_MODE_UM_UNI_DL: - log->warning("%s configured in %s mode: " - "t_reordering=%d ms, rx_sn_field_length=%u bits\n", - get_rb_name(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode], - cfg.t_reordering, rlc_umd_sn_size_num[cfg.rx_sn_field_length]); - break; - default: - log->error("RLC configuration mode not recognized\n"); + + if (cfg.rx_mod == 0) { + log->error("Error configuring %s RLC UM: rx_mod==0\n", get_rb_name()); + return false; } + + rb_name = rb_name_; + + rx_enabled = true; + + return true; } @@ -175,6 +176,22 @@ void rlc_um::write_pdu(uint8_t *payload, uint32_t nof_bytes) rx.handle_data_pdu(payload, nof_bytes); } +uint32_t rlc_um::get_num_tx_bytes() +{ + return tx.get_num_tx_bytes(); +} + +uint32_t rlc_um::get_num_rx_bytes() +{ + return rx.get_num_rx_bytes(); +} + +void rlc_um::reset_metrics() +{ + tx.reset_metrics(); + rx.reset_metrics(); +} + /**************************************************************************** * Helper functions @@ -203,6 +220,7 @@ rlc_um::rlc_um_tx::rlc_um_tx(uint32_t queue_len) ,tx_sdu(NULL) ,vt_us(0) ,tx_enabled(false) + ,num_tx_bytes(0) { pthread_mutex_init(&mutex, NULL); } @@ -217,17 +235,26 @@ rlc_um::rlc_um_tx::~rlc_um_tx() void rlc_um::rlc_um_tx::init(srslte::log *log_) { log = log_; - tx_enabled = true; } -void rlc_um::rlc_um_tx::configure(srslte_rlc_config_t cnfg_, std::string rb_name_) +bool rlc_um::rlc_um_tx::configure(srslte_rlc_config_t cnfg_, std::string rb_name_) { cfg = cnfg_.um; + + if (cfg.tx_mod == 0) { + log->error("Error configuring %s RLC UM: tx_mod==0\n", get_rb_name()); + return false; + } + if(cfg.is_mrb){ tx_sdu_queue.resize(512); } + rb_name = rb_name_; + tx_enabled = true; + + return true; } @@ -266,6 +293,20 @@ void rlc_um::rlc_um_tx::empty_queue() } +uint32_t rlc_um::rlc_um_tx::get_num_tx_bytes() +{ + return num_tx_bytes; +} + + +void rlc_um::rlc_um_tx::reset_metrics() +{ + pthread_mutex_lock(&mutex); + num_tx_bytes = 0; + pthread_mutex_unlock(&mutex); +} + + uint32_t rlc_um::rlc_um_tx::get_buffer_size_bytes() { // Bytes needed for tx SDUs @@ -434,6 +475,8 @@ int rlc_um::rlc_um_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) debug_state(); + num_tx_bytes += ret; + pthread_mutex_unlock(&mutex); return ret; } @@ -469,6 +512,8 @@ rlc_um::rlc_um_rx::rlc_um_rx() ,pdu_lost(false) ,mac_timers(NULL) ,lcid(0) + ,num_rx_bytes(0) + ,rx_enabled(false) { pthread_mutex_init(&mutex, NULL); } @@ -508,6 +553,8 @@ void rlc_um::rlc_um_rx::stop() vr_ux = 0; vr_uh = 0; pdu_lost = false; + rx_enabled = false; + if(rx_sdu) { pool->deallocate(rx_sdu); rx_sdu = NULL; @@ -531,10 +578,18 @@ void rlc_um::rlc_um_rx::stop() void rlc_um::rlc_um_rx::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes) { pthread_mutex_lock(&mutex); + rlc_umd_pdu_t pdu; int header_len = 0; std::map::iterator it; rlc_umd_pdu_header_t header; + + if (!rx_enabled) { + goto unlock_and_exit; + } + + num_rx_bytes += nof_bytes; + rlc_um_read_data_pdu_header(payload, nof_bytes, cfg.rx_sn_field_length, &header); log->info_hex(payload, nof_bytes, "RX %s Rx data PDU SN: %d", get_rb_name(), header.sn); @@ -596,7 +651,7 @@ void rlc_um::rlc_um_rx::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes) debug_state(); - unlock_and_exit: +unlock_and_exit: pthread_mutex_unlock(&mutex); } @@ -814,6 +869,20 @@ bool rlc_um::rlc_um_rx::inside_reordering_window(uint16_t sn) } +uint32_t rlc_um::rlc_um_rx::get_num_rx_bytes() +{ + return num_rx_bytes; +} + + +void rlc_um::rlc_um_rx::reset_metrics() +{ + pthread_mutex_lock(&mutex); + num_rx_bytes = 0; + pthread_mutex_unlock(&mutex); +} + + /**************************************************************************** * Timeout callback interface ***************************************************************************/ diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index ef04062cc..b2d68d3fa 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -169,6 +169,10 @@ void basic_test() assert(tester.sdus[i]->N_bytes == 1); assert(*(tester.sdus[i]->msg) == i); } + + // Check statistics + assert(rlc1.get_num_tx_bytes() == rlc2.get_num_rx_bytes()); + assert(rlc2.get_num_tx_bytes() == rlc1.get_num_rx_bytes()); } void concat_test() @@ -234,6 +238,10 @@ void concat_test() assert(tester.sdus[i]->N_bytes == 1); assert(*(tester.sdus[i]->msg) == i); } + + // check statistics + assert(rlc1.get_num_tx_bytes() == rlc2.get_num_rx_bytes()); + assert(rlc2.get_num_tx_bytes() == rlc1.get_num_rx_bytes()); } void segment_test() @@ -317,6 +325,9 @@ void segment_test() for(int j=0;j<10;j++) assert(tester.sdus[i]->msg[j] == j); } + + assert(rlc1.get_num_tx_bytes() == rlc2.get_num_rx_bytes()); + assert(rlc2.get_num_tx_bytes() == rlc1.get_num_rx_bytes()); } void retx_test() diff --git a/lib/test/upper/rlc_stress_test.cc b/lib/test/upper/rlc_stress_test.cc index 3a6f40a99..57624fc7c 100644 --- a/lib/test/upper/rlc_stress_test.cc +++ b/lib/test/upper/rlc_stress_test.cc @@ -325,7 +325,7 @@ void stress_test(stress_test_args_t args) srslte_rlc_config_t cnfg_; if (args.mode == "AM") { // config RLC AM bearer - cnfg_.rlc_mode = LIBLTE_RRC_RLC_MODE_AM; + cnfg_.rlc_mode = SRSLTE_RLC_MODE_AM; cnfg_.am.max_retx_thresh = 4; cnfg_.am.poll_byte = 25*1000; cnfg_.am.poll_pdu = 4; @@ -334,7 +334,7 @@ void stress_test(stress_test_args_t args) cnfg_.am.t_status_prohibit = 5; } else if (args.mode == "UM") { // config UM bearer - cnfg_.rlc_mode = LIBLTE_RRC_RLC_MODE_UM_BI; + cnfg_.rlc_mode = SRSLTE_RLC_MODE_UM; cnfg_.um.t_reordering = 5; cnfg_.um.rx_mod = 32; cnfg_.um.rx_sn_field_length = RLC_UMD_SN_SIZE_5_BITS; @@ -388,15 +388,23 @@ void stress_test(stress_test_args_t args) pcap.close(); } - printf("RLC1 received %d SDUs in %ds (%.2f PDU/s)\n", + rlc_metrics_t metrics; + rlc1.get_metrics(metrics); + + printf("RLC1 received %d SDUs in %ds (%.2f PDU/s), Throughput: DL=%4.2f Mbps, UL=%4.2f Mbps\n", tester1.get_nof_rx_pdus(), args.test_duration_sec, - (float)tester1.get_nof_rx_pdus()/args.test_duration_sec); + (float)tester1.get_nof_rx_pdus()/args.test_duration_sec, + metrics.dl_tput_mbps, + metrics.ul_tput_mbps); - printf("RLC2 received %d SDUs in %ds (%.2f PDU/s)\n", + rlc2.get_metrics(metrics); + printf("RLC2 received %d SDUs in %ds (%.2f PDU/s), Throughput: DL=%4.2f Mbps, UL=%4.2f Mbps\n", tester2.get_nof_rx_pdus(), args.test_duration_sec, - (float)tester2.get_nof_rx_pdus()/args.test_duration_sec); + (float)tester2.get_nof_rx_pdus()/args.test_duration_sec, + metrics.dl_tput_mbps, + metrics.ul_tput_mbps); } diff --git a/lib/test/upper/rlc_um_test.cc b/lib/test/upper/rlc_um_test.cc index 58cc217f1..cbeb2d3f6 100644 --- a/lib/test/upper/rlc_um_test.cc +++ b/lib/test/upper/rlc_um_test.cc @@ -130,8 +130,8 @@ void basic_test() cnfg.dl_um_bi_rlc.sn_field_len = LIBLTE_RRC_SN_FIELD_LENGTH_SIZE10; cnfg.ul_um_bi_rlc.sn_field_len = LIBLTE_RRC_SN_FIELD_LENGTH_SIZE10; - rlc1.configure(&cnfg); - rlc2.configure(&cnfg); + assert(rlc1.configure(&cnfg) == true); + assert(rlc2.configure(&cnfg) == true); tester.set_expected_sdu_len(1); diff --git a/srsenb/src/upper/rlc.cc b/srsenb/src/upper/rlc.cc index 6c97391d7..293b1c634 100644 --- a/srsenb/src/upper/rlc.cc +++ b/srsenb/src/upper/rlc.cc @@ -123,7 +123,7 @@ void rlc::add_bearer_mrb(uint16_t rnti, uint32_t lcid) { pthread_rwlock_rdlock(&rwlock); if (users.count(rnti)) { - users[rnti].rlc->add_bearer_mrb_enb(lcid); + users[rnti].rlc->add_bearer_mrb(lcid); } pthread_rwlock_unlock(&rwlock); } From eb30d86d44b157182facea6051532d009fe4c5bf Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 23 Jul 2018 17:49:26 +0200 Subject: [PATCH 50/88] process RRC PDUs in RRC thread --- srsue/hdr/upper/rrc.h | 3 +++ srsue/src/upper/rrc.cc | 19 ++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index e56db9e9e..e4d06eb1f 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -326,10 +326,12 @@ private: typedef struct { enum { + PDU, PCCH, STOP } command; byte_buffer_t *pdu; + uint16_t lcid; } cmd_msg_t; bool running; @@ -606,6 +608,7 @@ private: void send_rrc_ue_cap_info(); // Parsers + void process_pdu(uint32_t lcid, byte_buffer_t *pdu); void parse_dl_ccch(byte_buffer_t *pdu); void parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu); void parse_dl_info_transfer(uint32_t lcid, byte_buffer_t *pdu); diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 856aeedf9..1b2d2607d 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -32,7 +32,7 @@ #include #include // for printing uint64_t #include -#include "srsue/hdr/upper/rrc.h" +#include #include "srslte/asn1/liblte_rrc.h" #include "srslte/common/security.h" #include "srslte/common/bcd_helpers.h" @@ -248,11 +248,14 @@ void rrc::run_thread() { while(running) { cmd_msg_t msg = cmd_q.wait_pop(); switch(msg.command) { - case cmd_msg_t::STOP: - return; + case cmd_msg_t::PDU: + process_pdu(msg.lcid, msg.pdu); + break; case cmd_msg_t::PCCH: process_pcch(msg.pdu); break; + case cmd_msg_t::STOP: + return; } } } @@ -1939,6 +1942,16 @@ void rrc::write_sdu(uint32_t lcid, byte_buffer_t *sdu) { void rrc::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { rrc_log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU", get_rb_name(lcid).c_str()); + // add PDU to command queue + cmd_msg_t msg; + msg.pdu = pdu; + msg.command = cmd_msg_t::PDU; + msg.lcid = lcid; + cmd_q.push(msg); +} + +void rrc::process_pdu(uint32_t lcid, byte_buffer_t *pdu) +{ switch (lcid) { case RB_ID_SRB0: parse_dl_ccch(pdu); From 2b86272c5e56a8a65c4dbcddba611aa49be73324 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 24 Jul 2018 09:43:33 +0200 Subject: [PATCH 51/88] protect PCAP bearer additions with write lock --- lib/src/upper/pdcp.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index e073aeb27..e0a000c93 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -137,7 +137,7 @@ void pdcp::write_sdu_mch(uint32_t lcid, byte_buffer_t *sdu) } void pdcp::add_bearer(uint32_t lcid, srslte_pdcp_config_t cfg) { - pthread_rwlock_rdlock(&rwlock); + pthread_rwlock_wrlock(&rwlock); if (not valid_lcid(lcid)) { if (not pdcp_array.insert(pdcp_map_pair_t(lcid, new pdcp_entity())).second) { pdcp_log->error("Error inserting PDCP entity in to array\n."); @@ -154,7 +154,7 @@ void pdcp::add_bearer(uint32_t lcid, srslte_pdcp_config_t cfg) void pdcp::add_bearer_mrb(uint32_t lcid, srslte_pdcp_config_t cfg) { - pthread_rwlock_rdlock(&rwlock); + pthread_rwlock_wrlock(&rwlock); if (not valid_mch_lcid(lcid)) { if (not pdcp_array_mrb.insert(pdcp_map_pair_t(lcid, new pdcp_entity())).second) { pdcp_log->error("Error inserting PDCP entity in to array\n."); From b8438e9cc3953d8c10e2dad2c73f37269390c840 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 24 Jul 2018 15:49:09 +0200 Subject: [PATCH 52/88] extend PDCP interface to allow non-blocking write of SDUs --- lib/include/srslte/interfaces/ue_interfaces.h | 6 ++--- lib/include/srslte/upper/pdcp.h | 2 +- lib/include/srslte/upper/pdcp_entity.h | 2 +- lib/include/srslte/upper/pdcp_interface.h | 2 +- lib/include/srslte/upper/rlc.h | 3 +-- lib/src/upper/pdcp.cc | 12 +++++---- lib/src/upper/pdcp_entity.cc | 6 ++--- lib/src/upper/rlc.cc | 27 +++++++------------ lib/src/upper/rlc_am.cc | 2 ++ 9 files changed, 29 insertions(+), 33 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index a4fb2b2cb..1cfcc56e0 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -228,7 +228,7 @@ public: class pdcp_interface_gw { public: - virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; + virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu, bool blocking) = 0; virtual bool is_drb_enabled(uint32_t lcid) = 0; }; @@ -238,7 +238,7 @@ class pdcp_interface_rrc public: virtual void reestablish() = 0; virtual void reset() = 0; - virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; + virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu, bool blocking = true) = 0; virtual void add_bearer(uint32_t lcid, srslte::srslte_pdcp_config_t cnfg = srslte::srslte_pdcp_config_t()) = 0; virtual void config_security(uint32_t lcid, uint8_t *k_enc_, @@ -282,7 +282,7 @@ class rlc_interface_pdcp public: /* PDCP calls RLC to push an RLC SDU. SDU gets placed into the RLC buffer and MAC pulls * RLC PDUs according to TB size. */ - virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; + virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu, bool blocking = true) = 0; virtual bool rb_is_um(uint32_t lcid) = 0; }; diff --git a/lib/include/srslte/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index cd284619f..53149154a 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -56,7 +56,7 @@ public: // RRC interface void reestablish(); void reset(); - void write_sdu(uint32_t lcid, byte_buffer_t *sdu); + void write_sdu(uint32_t lcid, byte_buffer_t *sdu, bool blocking = true); void write_sdu_mch(uint32_t lcid, byte_buffer_t *sdu); void add_bearer(uint32_t lcid, srslte_pdcp_config_t cnfg = srslte_pdcp_config_t()); void add_bearer_mrb(uint32_t lcid, srslte_pdcp_config_t cnfg = srslte_pdcp_config_t()); diff --git a/lib/include/srslte/upper/pdcp_entity.h b/lib/include/srslte/upper/pdcp_entity.h index 6586becc0..fd69c92e9 100644 --- a/lib/include/srslte/upper/pdcp_entity.h +++ b/lib/include/srslte/upper/pdcp_entity.h @@ -76,7 +76,7 @@ public: bool is_active(); // RRC interface - void write_sdu(byte_buffer_t *sdu); + void write_sdu(byte_buffer_t *sdu, bool blocking); void config_security(uint8_t *k_enc_, uint8_t *k_int_, CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, diff --git a/lib/include/srslte/upper/pdcp_interface.h b/lib/include/srslte/upper/pdcp_interface.h index 915fbe420..0c2cb2428 100644 --- a/lib/include/srslte/upper/pdcp_interface.h +++ b/lib/include/srslte/upper/pdcp_interface.h @@ -55,7 +55,7 @@ public: virtual bool is_active() = 0; // RRC interface - virtual void write_sdu(byte_buffer_t *sdu) = 0; + virtual void write_sdu(byte_buffer_t *sdu, bool blocking) = 0; virtual void config_security(uint8_t *k_enc_, uint8_t *k_int_, CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, diff --git a/lib/include/srslte/upper/rlc.h b/lib/include/srslte/upper/rlc.h index 0d8dcad91..4a414f3fe 100644 --- a/lib/include/srslte/upper/rlc.h +++ b/lib/include/srslte/upper/rlc.h @@ -63,8 +63,7 @@ public: void get_metrics(rlc_metrics_t &m); // PDCP interface - void write_sdu(uint32_t lcid, byte_buffer_t *sdu); - void write_sdu_nb(uint32_t lcid, byte_buffer_t *sdu); + void write_sdu(uint32_t lcid, byte_buffer_t *sdu, bool blocking = true); void write_sdu_mch(uint32_t lcid, byte_buffer_t *sdu); bool rb_is_um(uint32_t lcid); diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index e0a000c93..24dbd27d3 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -115,11 +115,11 @@ bool pdcp::is_drb_enabled(uint32_t lcid) return ret; } -void pdcp::write_sdu(uint32_t lcid, byte_buffer_t *sdu) +void pdcp::write_sdu(uint32_t lcid, byte_buffer_t *sdu, bool blocking) { pthread_rwlock_rdlock(&rwlock); if (valid_lcid(lcid)) { - pdcp_array.at(lcid)->write_sdu(sdu); + pdcp_array.at(lcid)->write_sdu(sdu, blocking); } else { pdcp_log->warning("Writing sdu: lcid=%d. Deallocating sdu\n", lcid); byte_buffer_pool::get_instance()->deallocate(sdu); @@ -131,7 +131,7 @@ void pdcp::write_sdu_mch(uint32_t lcid, byte_buffer_t *sdu) { pthread_rwlock_rdlock(&rwlock); if (valid_mch_lcid(lcid)){ - pdcp_array_mrb.at(lcid)->write_sdu(sdu); + pdcp_array_mrb.at(lcid)->write_sdu(sdu, true); } pthread_rwlock_unlock(&rwlock); } @@ -141,13 +141,14 @@ void pdcp::add_bearer(uint32_t lcid, srslte_pdcp_config_t cfg) if (not valid_lcid(lcid)) { if (not pdcp_array.insert(pdcp_map_pair_t(lcid, new pdcp_entity())).second) { pdcp_log->error("Error inserting PDCP entity in to array\n."); - return; + goto unlock_and_exit; } pdcp_array.at(lcid)->init(rlc, rrc, gw, pdcp_log, lcid, cfg); pdcp_log->info("Added bearer %s\n", rrc->get_rb_name(lcid).c_str()); } else { pdcp_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rrc->get_rb_name(lcid).c_str()); } +unlock_and_exit: pthread_rwlock_unlock(&rwlock); } @@ -158,13 +159,14 @@ void pdcp::add_bearer_mrb(uint32_t lcid, srslte_pdcp_config_t cfg) if (not valid_mch_lcid(lcid)) { if (not pdcp_array_mrb.insert(pdcp_map_pair_t(lcid, new pdcp_entity())).second) { pdcp_log->error("Error inserting PDCP entity in to array\n."); - return; + goto unlock_and_exit; } pdcp_array_mrb.at(lcid)->init(rlc, rrc, gw, pdcp_log, lcid, cfg); pdcp_log->info("Added bearer %s\n", rrc->get_rb_name(lcid).c_str()); } else { pdcp_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rrc->get_rb_name(lcid).c_str()); } +unlock_and_exit: pthread_rwlock_unlock(&rwlock); } diff --git a/lib/src/upper/pdcp_entity.cc b/lib/src/upper/pdcp_entity.cc index c2c829549..b77a760b9 100644 --- a/lib/src/upper/pdcp_entity.cc +++ b/lib/src/upper/pdcp_entity.cc @@ -108,8 +108,8 @@ bool pdcp_entity::is_active() return active; } -// RRC interface -void pdcp_entity::write_sdu(byte_buffer_t *sdu) +// GW/RRC interface +void pdcp_entity::write_sdu(byte_buffer_t *sdu, bool blocking) { log->info_hex(sdu->msg, sdu->N_bytes, "TX %s SDU, SN: %d, do_integrity = %s, do_encryption = %s", @@ -141,7 +141,7 @@ void pdcp_entity::write_sdu(byte_buffer_t *sdu) } tx_count++; - rlc->write_sdu(lcid, sdu); + rlc->write_sdu(lcid, sdu, blocking); } void pdcp_entity::config_security(uint8_t *k_enc_, diff --git a/lib/src/upper/rlc.cc b/lib/src/upper/rlc.cc index 1a602d7c0..2f0e20313 100644 --- a/lib/src/upper/rlc.cc +++ b/lib/src/upper/rlc.cc @@ -165,12 +165,15 @@ void rlc::reestablish() void rlc::reset() { pthread_rwlock_wrlock(&rwlock); + for (rlc_map_t::iterator it = rlc_array.begin(); it != rlc_array.end(); ++it) { + it->second->stop(); delete(it->second); } rlc_array.clear(); for (rlc_map_t::iterator it = rlc_array_mrb.begin(); it != rlc_array_mrb.end(); ++it) { + it->second->stop(); delete(it->second); } rlc_array_mrb.clear(); @@ -195,24 +198,15 @@ void rlc::empty_queue() PDCP interface *******************************************************************************/ -void rlc::write_sdu(uint32_t lcid, byte_buffer_t *sdu) +void rlc::write_sdu(uint32_t lcid, byte_buffer_t *sdu, bool blocking) { pthread_rwlock_rdlock(&rwlock); if (valid_lcid(lcid)) { - rlc_array.at(lcid)->write_sdu(sdu); - } else { - rlc_log->warning("Writing SDU: lcid=%d. Deallocating sdu\n", lcid); - byte_buffer_pool::get_instance()->deallocate(sdu); - } - pthread_rwlock_unlock(&rwlock); -} - - -void rlc::write_sdu_nb(uint32_t lcid, byte_buffer_t *sdu) -{ - pthread_rwlock_rdlock(&rwlock); - if (valid_lcid(lcid)) { - rlc_array.at(lcid)->write_sdu_nb(sdu); + if (blocking) { + rlc_array.at(lcid)->write_sdu(sdu); + } else { + rlc_array.at(lcid)->write_sdu_nb(sdu); + } } else { rlc_log->warning("Writing SDU: lcid=%d. Deallocating sdu\n", lcid); byte_buffer_pool::get_instance()->deallocate(sdu); @@ -220,7 +214,6 @@ void rlc::write_sdu_nb(uint32_t lcid, byte_buffer_t *sdu) pthread_rwlock_unlock(&rwlock); } - void rlc::write_sdu_mch(uint32_t lcid, byte_buffer_t *sdu) { pthread_rwlock_rdlock(&rwlock); @@ -429,7 +422,7 @@ void rlc::add_bearer(uint32_t lcid, srslte_rlc_config_t cnfg) break; default: rlc_log->error("Cannot add RLC entity - invalid mode\n"); - return; + goto unlock_and_exit; } if (rlc_entity) { diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 25fc6d770..c2ce16dcc 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -105,11 +105,13 @@ bool rlc_am::configure(srslte_rlc_config_t cfg_) void rlc_am::empty_queue() { // Drop all messages in TX SDU queue + pthread_mutex_lock(&mutex); byte_buffer_t *buf; while(tx_sdu_queue.try_read(&buf)) { pool->deallocate(buf); } tx_sdu_queue.reset(); + pthread_mutex_unlock(&mutex); } void rlc_am::reestablish() { From 4da8bf26f876e32a28b8e5063366d80ffb43043f Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 24 Jul 2018 15:50:14 +0200 Subject: [PATCH 53/88] use non-blocking PDCP write in GW --- srsenb/hdr/upper/pdcp.h | 2 +- srsenb/src/upper/pdcp.cc | 3 +-- srsenb/src/upper/rlc.cc | 2 +- srsue/src/upper/gw.cc | 3 +-- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/srsenb/hdr/upper/pdcp.h b/srsenb/hdr/upper/pdcp.h index ce6b01ca6..1dc555fee 100644 --- a/srsenb/hdr/upper/pdcp.h +++ b/srsenb/hdr/upper/pdcp.h @@ -68,7 +68,7 @@ private: uint16_t rnti; srsenb::rlc_interface_pdcp *rlc; // rlc_interface_pdcp - void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu); + void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu, bool blocking); bool rb_is_um(uint32_t lcid); }; diff --git a/srsenb/src/upper/pdcp.cc b/srsenb/src/upper/pdcp.cc index 7f62477f9..4d242bdc1 100644 --- a/srsenb/src/upper/pdcp.cc +++ b/srsenb/src/upper/pdcp.cc @@ -154,9 +154,8 @@ void pdcp::user_interface_gtpu::write_pdu(uint32_t lcid, srslte::byte_buffer_t * gtpu->write_pdu(rnti, lcid, pdu); } -void pdcp::user_interface_rlc::write_sdu(uint32_t lcid, srslte::byte_buffer_t* sdu) +void pdcp::user_interface_rlc::write_sdu(uint32_t lcid, srslte::byte_buffer_t* sdu, bool blocking) { - rlc->write_sdu(rnti, lcid, sdu); } diff --git a/srsenb/src/upper/rlc.cc b/srsenb/src/upper/rlc.cc index 293b1c634..aa62ac1e1 100644 --- a/srsenb/src/upper/rlc.cc +++ b/srsenb/src/upper/rlc.cc @@ -190,7 +190,7 @@ void rlc::write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t* sdu) pthread_rwlock_rdlock(&rwlock); if (users.count(rnti)) { if(rnti != SRSLTE_MRNTI){ - users[rnti].rlc->write_sdu_nb(lcid, sdu); + users[rnti].rlc->write_sdu(lcid, sdu, false); tx_queue = users[rnti].rlc->get_total_buffer_state(lcid); }else { users[rnti].rlc->write_sdu_mch(lcid, sdu); diff --git a/srsue/src/upper/gw.cc b/srsue/src/upper/gw.cc index 3d91791b2..acf2bb07e 100644 --- a/srsue/src/upper/gw.cc +++ b/srsue/src/upper/gw.cc @@ -364,8 +364,7 @@ void gw::run_thread() if (pdcp->is_drb_enabled(cfg.lcid)) { pdu->set_timestamp(); ul_tput_bytes += pdu->N_bytes; - pdcp->write_sdu(cfg.lcid, pdu); - + pdcp->write_sdu(cfg.lcid, pdu, false); do { pdu = pool_allocate; if (!pdu) { From 6a2dc8677b8e21df3bfec795c26250b4c53e852a Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 24 Jul 2018 16:44:40 +0200 Subject: [PATCH 54/88] remove obsolete header --- lib/include/srslte/upper/rlc.h | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/include/srslte/upper/rlc.h b/lib/include/srslte/upper/rlc.h index 4a414f3fe..20123da0e 100644 --- a/lib/include/srslte/upper/rlc.h +++ b/lib/include/srslte/upper/rlc.h @@ -31,7 +31,6 @@ #include "srslte/common/log.h" #include "srslte/common/common.h" #include "srslte/interfaces/ue_interfaces.h" -#include "srslte/upper/rlc_entity.h" #include "srslte/upper/rlc_metrics.h" #include "srslte/upper/rlc_common.h" From 260fbff6ab5b9a2f13343e2adf019eaec9cdd6f2 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 25 Jul 2018 09:20:45 +0200 Subject: [PATCH 55/88] unlock before adding SRB0 again during RLC reset --- lib/src/upper/rlc.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/upper/rlc.cc b/lib/src/upper/rlc.cc index 2f0e20313..9b4323e53 100644 --- a/lib/src/upper/rlc.cc +++ b/lib/src/upper/rlc.cc @@ -178,10 +178,10 @@ void rlc::reset() } rlc_array_mrb.clear(); + pthread_rwlock_unlock(&rwlock); + // Add SRB0 again add_bearer(default_lcid, srslte_rlc_config_t()); - - pthread_rwlock_unlock(&rwlock); } void rlc::empty_queue() From 40d19e2d32df59edd6bebdc306be4e0813b88bb1 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 25 Jul 2018 15:08:35 +0200 Subject: [PATCH 56/88] fix PDCP reset --- lib/src/upper/pdcp.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index 24dbd27d3..acf0d6988 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -91,14 +91,16 @@ void pdcp::reestablish() { void pdcp::reset() { - pthread_rwlock_rdlock(&rwlock); + // destroy all bearers + pthread_rwlock_wrlock(&rwlock); for (pdcp_map_t::iterator it = pdcp_array.begin(); it != pdcp_array.end(); ++it) { - it->second->reset(); - } - if (valid_lcid(0)) { - pdcp_array.at(0)->init(rlc, rrc, gw, pdcp_log, default_lcid, default_cnfg); + delete(it->second); + pdcp_array.erase(it); } pthread_rwlock_unlock(&rwlock); + + // add default SRB0 again + add_bearer(0, default_cnfg); } /******************************************************************************* From ee5b055829e3844e63439b91fc41b574edfe3886 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 25 Jul 2018 15:09:19 +0200 Subject: [PATCH 57/88] rename pdcp function for GW to is_lcid_enabled() --- lib/include/srslte/interfaces/ue_interfaces.h | 2 +- lib/include/srslte/upper/pdcp.h | 2 +- lib/src/upper/pdcp.cc | 2 +- srsue/src/upper/gw.cc | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 1cfcc56e0..dc8128041 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -229,7 +229,7 @@ class pdcp_interface_gw { public: virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu, bool blocking) = 0; - virtual bool is_drb_enabled(uint32_t lcid) = 0; + virtual bool is_lcid_enabled(uint32_t lcid) = 0; }; // PDCP interface for RRC diff --git a/lib/include/srslte/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index 53149154a..2376bd020 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -51,7 +51,7 @@ public: void stop(); // GW interface - bool is_drb_enabled(uint32_t lcid); + bool is_lcid_enabled(uint32_t lcid); // RRC interface void reestablish(); diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index acf0d6988..c15fe6106 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -106,7 +106,7 @@ void pdcp::reset() /******************************************************************************* RRC/GW interface *******************************************************************************/ -bool pdcp::is_drb_enabled(uint32_t lcid) +bool pdcp::is_lcid_enabled(uint32_t lcid) { pthread_rwlock_rdlock(&rwlock); bool ret = false; diff --git a/srsue/src/upper/gw.cc b/srsue/src/upper/gw.cc index acf2bb07e..e78bd70bb 100644 --- a/srsue/src/upper/gw.cc +++ b/srsue/src/upper/gw.cc @@ -343,7 +343,7 @@ void gw::run_thread() { gw_log->info_hex(pdu->msg, pdu->N_bytes, "TX PDU"); - while(run_enable && !pdcp->is_drb_enabled(cfg.lcid) && attach_wait < ATTACH_WAIT_TOUT) { + while(run_enable && !pdcp->is_lcid_enabled(cfg.lcid) && attach_wait < ATTACH_WAIT_TOUT) { if (!attach_wait) { gw_log->info("LCID=%d not active, requesting NAS attach (%d/%d)\n", cfg.lcid, attach_wait, ATTACH_WAIT_TOUT); if (!nas->attach_request()) { @@ -361,7 +361,7 @@ void gw::run_thread() } // Send PDU directly to PDCP - if (pdcp->is_drb_enabled(cfg.lcid)) { + if (pdcp->is_lcid_enabled(cfg.lcid)) { pdu->set_timestamp(); ul_tput_bytes += pdu->N_bytes; pdcp->write_sdu(cfg.lcid, pdu, false); From 5444b2a0b79a8c06837a514862b87a54fc0df949 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 25 Jul 2018 15:09:54 +0200 Subject: [PATCH 58/88] tiny cosmetic changes --- lib/src/upper/pdcp_entity.cc | 11 +++++++---- lib/src/upper/rlc.cc | 4 ++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/src/upper/pdcp_entity.cc b/lib/src/upper/pdcp_entity.cc index b77a760b9..3efdf4786 100644 --- a/lib/src/upper/pdcp_entity.cc +++ b/lib/src/upper/pdcp_entity.cc @@ -70,11 +70,11 @@ void pdcp_entity::init(srsue::rlc_interface_pdcp *rlc_, cfg.sn_len = 0; sn_len_bytes = 0; - if(cfg.is_control) { + if (cfg.is_control) { cfg.sn_len = 5; sn_len_bytes = 1; } - if(cfg.is_data) { + if (cfg.is_data) { cfg.sn_len = 12; sn_len_bytes = 2; } @@ -89,6 +89,7 @@ void pdcp_entity::reestablish() { tx_count = 0; rx_count = 0; } else { + // Only reset counter in RLC-UM if (rlc->rb_is_um(lcid)) { tx_count = 0; rx_count = 0; @@ -96,11 +97,13 @@ void pdcp_entity::reestablish() { } } +// Used to stop/pause the entity (called on RRC conn release) void pdcp_entity::reset() { - active = false; - if(log) + active = false; + if (log) { log->debug("Reset %s\n", rrc->get_rb_name(lcid).c_str()); + } } bool pdcp_entity::is_active() diff --git a/lib/src/upper/rlc.cc b/lib/src/upper/rlc.cc index 9b4323e53..d256abbe3 100644 --- a/lib/src/upper/rlc.cc +++ b/lib/src/upper/rlc.cc @@ -208,7 +208,7 @@ void rlc::write_sdu(uint32_t lcid, byte_buffer_t *sdu, bool blocking) rlc_array.at(lcid)->write_sdu_nb(sdu); } } else { - rlc_log->warning("Writing SDU: lcid=%d. Deallocating sdu\n", lcid); + rlc_log->warning("RLC LCID %d doesn't exist. Deallocating SDU\n", lcid); byte_buffer_pool::get_instance()->deallocate(sdu); } pthread_rwlock_unlock(&rwlock); @@ -220,7 +220,7 @@ void rlc::write_sdu_mch(uint32_t lcid, byte_buffer_t *sdu) if (valid_lcid_mrb(lcid)) { rlc_array_mrb.at(lcid)->write_sdu_nb(sdu); } else { - rlc_log->warning("Writing SDU: lcid=%d. Deallocating sdu\n", lcid); + rlc_log->warning("RLC LCID %d doesn't exist. Deallocating SDU\n", lcid); byte_buffer_pool::get_instance()->deallocate(sdu); } pthread_rwlock_unlock(&rwlock); From 3950629a75f330e318a27dfd4be9ac0152976e5a Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 25 Jul 2018 16:06:42 +0200 Subject: [PATCH 59/88] remove obsolete RLC_MODE struct and move existing one to rlc_interface.h --- lib/include/srslte/upper/rlc_common.h | 10 +------- lib/include/srslte/upper/rlc_interface.h | 29 ++++++++++++------------ lib/src/upper/rlc.cc | 8 +++---- lib/src/upper/rlc_um.cc | 2 +- lib/test/upper/rlc_stress_test.cc | 4 ++-- 5 files changed, 23 insertions(+), 30 deletions(-) diff --git a/lib/include/srslte/upper/rlc_common.h b/lib/include/srslte/upper/rlc_common.h index f3fcec12d..540298217 100644 --- a/lib/include/srslte/upper/rlc_common.h +++ b/lib/include/srslte/upper/rlc_common.h @@ -38,15 +38,7 @@ namespace srslte { #define RLC_AM_WINDOW_SIZE 512 -typedef enum{ - RLC_MODE_TM = 0, - RLC_MODE_UM, - RLC_MODE_AM, - RLC_MODE_N_ITEMS, -}rlc_mode_t; -static const char rlc_mode_text[RLC_MODE_N_ITEMS][20] = {"Transparent Mode", - "Unacknowledged Mode", - "Acknowledged Mode"}; + typedef enum{ RLC_FI_FIELD_START_AND_END_ALIGNED = 0, diff --git a/lib/include/srslte/upper/rlc_interface.h b/lib/include/srslte/upper/rlc_interface.h index 0b2460101..4201717dd 100644 --- a/lib/include/srslte/upper/rlc_interface.h +++ b/lib/include/srslte/upper/rlc_interface.h @@ -32,14 +32,15 @@ namespace srslte { - typedef enum{ - SRSLTE_RLC_MODE_TM = 0, - SRSLTE_RLC_MODE_UM, - SRSLTE_RLC_MODE_AM, - SRSLTE_RLC_MODE_N_ITEMS -} srslte_rlc_mode_t; -static const char srslte_rlc_mode_text[SRSLTE_RLC_MODE_N_ITEMS][20] = { "TM", "UM", "AM"}; + RLC_MODE_TM = 0, + RLC_MODE_UM, + RLC_MODE_AM, + RLC_MODE_N_ITEMS, +}rlc_mode_t; +static const char rlc_mode_text[RLC_MODE_N_ITEMS][20] = {"Transparent Mode", + "Unacknowledged Mode", + "Acknowledged Mode"}; typedef enum{ RLC_UMD_SN_SIZE_5_BITS = 0, @@ -88,22 +89,22 @@ typedef struct { class srslte_rlc_config_t { public: - srslte_rlc_mode_t rlc_mode; + rlc_mode_t rlc_mode; srslte_rlc_am_config_t am; srslte_rlc_um_config_t um; // Default ctor - srslte_rlc_config_t(): rlc_mode(SRSLTE_RLC_MODE_TM), am(), um() {}; + srslte_rlc_config_t(): rlc_mode(RLC_MODE_TM), am(), um() {}; // Constructor based on liblte's RLC config - srslte_rlc_config_t(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) : rlc_mode(SRSLTE_RLC_MODE_AM), am(), um() + srslte_rlc_config_t(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) : rlc_mode(RLC_MODE_AM), am(), um() { // update RLC mode to internal mode struct - rlc_mode = (cnfg->rlc_mode == LIBLTE_RRC_RLC_MODE_AM) ? SRSLTE_RLC_MODE_AM : SRSLTE_RLC_MODE_UM; + rlc_mode = (cnfg->rlc_mode == LIBLTE_RRC_RLC_MODE_AM) ? RLC_MODE_AM : RLC_MODE_UM; switch(rlc_mode) { - case SRSLTE_RLC_MODE_AM: + case RLC_MODE_AM: am.t_poll_retx = liblte_rrc_t_poll_retransmit_num[cnfg->ul_am_rlc.t_poll_retx]; am.poll_pdu = liblte_rrc_poll_pdu_num[cnfg->ul_am_rlc.poll_pdu]; am.poll_byte = liblte_rrc_poll_byte_num[cnfg->ul_am_rlc.poll_byte]*1000; // KB @@ -111,7 +112,7 @@ public: am.t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_am_rlc.t_reordering]; am.t_status_prohibit = liblte_rrc_t_status_prohibit_num[cnfg->dl_am_rlc.t_status_prohibit]; break; - case SRSLTE_RLC_MODE_UM: + case RLC_MODE_UM: um.t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_um_bi_rlc.t_reordering]; um.rx_sn_field_length = (rlc_umd_sn_size_t)cnfg->dl_um_bi_rlc.sn_field_len; um.rx_window_size = (RLC_UMD_SN_SIZE_5_BITS == um.rx_sn_field_length) ? 16 : 512; @@ -129,7 +130,7 @@ public: static srslte_rlc_config_t mch_config() { srslte_rlc_config_t cfg; - cfg.rlc_mode = SRSLTE_RLC_MODE_UM; + cfg.rlc_mode = RLC_MODE_UM; cfg.um.t_reordering = 0; cfg.um.rx_sn_field_length = RLC_UMD_SN_SIZE_5_BITS; cfg.um.rx_window_size = 0; diff --git a/lib/src/upper/rlc.cc b/lib/src/upper/rlc.cc index d256abbe3..b461a5740 100644 --- a/lib/src/upper/rlc.cc +++ b/lib/src/upper/rlc.cc @@ -411,13 +411,13 @@ void rlc::add_bearer(uint32_t lcid, srslte_rlc_config_t cnfg) if (not valid_lcid(lcid)) { switch(cnfg.rlc_mode) { - case SRSLTE_RLC_MODE_TM: + case RLC_MODE_TM: rlc_entity = new rlc_tm(); break; - case SRSLTE_RLC_MODE_AM: + case RLC_MODE_AM: rlc_entity = new rlc_am(); break; - case SRSLTE_RLC_MODE_UM: + case RLC_MODE_UM: rlc_entity = new rlc_um(); break; default: @@ -429,7 +429,7 @@ void rlc::add_bearer(uint32_t lcid, srslte_rlc_config_t cnfg) // configure and add to array rlc_entity->init(rlc_log, lcid, pdcp, rrc, mac_timers); - if (cnfg.rlc_mode != SRSLTE_RLC_MODE_TM) { + if (cnfg.rlc_mode != RLC_MODE_TM) { if (rlc_entity->configure(cnfg) == false) { rlc_log->error("Error configuring RLC entity\n."); goto delete_and_exit; diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index bf127900b..ac80e6940 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -76,7 +76,7 @@ bool rlc_um::configure(srslte_rlc_config_t cnfg_) } log->warning("%s configured in %s mode: t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits\n", - rb_name.c_str(), srslte_rlc_mode_text[cnfg_.rlc_mode], + rb_name.c_str(), rlc_mode_text[cnfg_.rlc_mode], cfg.t_reordering, rlc_umd_sn_size_num[cfg.rx_sn_field_length], rlc_umd_sn_size_num[cfg.rx_sn_field_length]); // store config diff --git a/lib/test/upper/rlc_stress_test.cc b/lib/test/upper/rlc_stress_test.cc index 57624fc7c..d48011667 100644 --- a/lib/test/upper/rlc_stress_test.cc +++ b/lib/test/upper/rlc_stress_test.cc @@ -325,7 +325,7 @@ void stress_test(stress_test_args_t args) srslte_rlc_config_t cnfg_; if (args.mode == "AM") { // config RLC AM bearer - cnfg_.rlc_mode = SRSLTE_RLC_MODE_AM; + cnfg_.rlc_mode = RLC_MODE_AM; cnfg_.am.max_retx_thresh = 4; cnfg_.am.poll_byte = 25*1000; cnfg_.am.poll_pdu = 4; @@ -334,7 +334,7 @@ void stress_test(stress_test_args_t args) cnfg_.am.t_status_prohibit = 5; } else if (args.mode == "UM") { // config UM bearer - cnfg_.rlc_mode = SRSLTE_RLC_MODE_UM; + cnfg_.rlc_mode = RLC_MODE_UM; cnfg_.um.t_reordering = 5; cnfg_.um.rx_mod = 32; cnfg_.um.rx_sn_field_length = RLC_UMD_SN_SIZE_5_BITS; From 89df8f1582711b9805889178826e13cdb511967d Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 25 Jul 2018 16:08:07 +0200 Subject: [PATCH 60/88] unify RLC interface for writing SDUs w/ and w/o blocking --- lib/include/srslte/upper/rlc_am.h | 3 +-- lib/include/srslte/upper/rlc_common.h | 3 +-- lib/include/srslte/upper/rlc_tm.h | 3 +-- lib/include/srslte/upper/rlc_um.h | 3 +-- lib/src/upper/rlc.cc | 8 ++------ lib/src/upper/rlc_am.cc | 29 ++++++++++----------------- lib/src/upper/rlc_tm.cc | 29 +++++++++------------------ lib/src/upper/rlc_um.cc | 12 +++++------ 8 files changed, 33 insertions(+), 57 deletions(-) diff --git a/lib/include/srslte/upper/rlc_am.h b/lib/include/srslte/upper/rlc_am.h index f57a65b0b..ab2c6cd63 100644 --- a/lib/include/srslte/upper/rlc_am.h +++ b/lib/include/srslte/upper/rlc_am.h @@ -86,8 +86,7 @@ public: uint32_t get_bearer(); // PDCP interface - void write_sdu(byte_buffer_t *sdu); - void write_sdu_nb(byte_buffer_t *sdu); + void write_sdu(byte_buffer_t *sdu, bool blocking = true); // MAC interface uint32_t get_buffer_state(); diff --git a/lib/include/srslte/upper/rlc_common.h b/lib/include/srslte/upper/rlc_common.h index 540298217..71fe934df 100644 --- a/lib/include/srslte/upper/rlc_common.h +++ b/lib/include/srslte/upper/rlc_common.h @@ -166,8 +166,7 @@ public: virtual void reset_metrics() = 0; // PDCP interface - virtual void write_sdu(byte_buffer_t *sdu) = 0; - virtual void write_sdu_nb(byte_buffer_t *sdu) = 0; + virtual void write_sdu(byte_buffer_t *sdu, bool blocking) = 0; // MAC interface virtual uint32_t get_buffer_state() = 0; diff --git a/lib/include/srslte/upper/rlc_tm.h b/lib/include/srslte/upper/rlc_tm.h index 5db629231..b1fa03ac6 100644 --- a/lib/include/srslte/upper/rlc_tm.h +++ b/lib/include/srslte/upper/rlc_tm.h @@ -59,8 +59,7 @@ public: void reset_metrics(); // PDCP interface - void write_sdu(byte_buffer_t *sdu); - void write_sdu_nb(byte_buffer_t *sdu); + void write_sdu(byte_buffer_t *sdu, bool blocking); // MAC interface uint32_t get_buffer_state(); diff --git a/lib/include/srslte/upper/rlc_um.h b/lib/include/srslte/upper/rlc_um.h index a880b2238..f866417d2 100644 --- a/lib/include/srslte/upper/rlc_um.h +++ b/lib/include/srslte/upper/rlc_um.h @@ -65,8 +65,7 @@ public: uint32_t get_bearer(); // PDCP interface - void write_sdu(byte_buffer_t *sdu); - void write_sdu_nb(byte_buffer_t *sdu); + void write_sdu(byte_buffer_t *sdu, bool blocking = true); // MAC interface uint32_t get_buffer_state(); diff --git a/lib/src/upper/rlc.cc b/lib/src/upper/rlc.cc index b461a5740..31b740df4 100644 --- a/lib/src/upper/rlc.cc +++ b/lib/src/upper/rlc.cc @@ -202,11 +202,7 @@ void rlc::write_sdu(uint32_t lcid, byte_buffer_t *sdu, bool blocking) { pthread_rwlock_rdlock(&rwlock); if (valid_lcid(lcid)) { - if (blocking) { - rlc_array.at(lcid)->write_sdu(sdu); - } else { - rlc_array.at(lcid)->write_sdu_nb(sdu); - } + rlc_array.at(lcid)->write_sdu(sdu, blocking); } else { rlc_log->warning("RLC LCID %d doesn't exist. Deallocating SDU\n", lcid); byte_buffer_pool::get_instance()->deallocate(sdu); @@ -218,7 +214,7 @@ void rlc::write_sdu_mch(uint32_t lcid, byte_buffer_t *sdu) { pthread_rwlock_rdlock(&rwlock); if (valid_lcid_mrb(lcid)) { - rlc_array_mrb.at(lcid)->write_sdu_nb(sdu); + rlc_array_mrb.at(lcid)->write_sdu(sdu, false); // write in non-blocking mode by default } else { rlc_log->warning("RLC LCID %d doesn't exist. Deallocating SDU\n", lcid); byte_buffer_pool::get_instance()->deallocate(sdu); diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index c2ce16dcc..92c32410d 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -199,32 +199,25 @@ uint32_t rlc_am::get_bearer() * PDCP interface ***************************************************************************/ -void rlc_am::write_sdu(byte_buffer_t *sdu) +void rlc_am::write_sdu(byte_buffer_t *sdu, bool blocking) { if (!tx_enabled) { byte_buffer_pool::get_instance()->deallocate(sdu); return; } if (sdu) { - tx_sdu_queue.write(sdu); - log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes, tx_sdu_queue.size()); - } else { - log->warning("NULL SDU pointer in write_sdu()\n"); - } -} - -void rlc_am::write_sdu_nb(byte_buffer_t *sdu) -{ - if (!tx_enabled) { - byte_buffer_pool::get_instance()->deallocate(sdu); - return; - } - if (sdu) { - if (tx_sdu_queue.try_write(sdu)) { + if (blocking) { + // block on write to queue + tx_sdu_queue.write(sdu); log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes, tx_sdu_queue.size()); } else { - log->debug_hex(sdu->msg, sdu->N_bytes, "[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes, tx_sdu_queue.size()); - pool->deallocate(sdu); + // non-blocking write + if (tx_sdu_queue.try_write(sdu)) { + log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes, tx_sdu_queue.size()); + } else { + log->debug_hex(sdu->msg, sdu->N_bytes, "[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes, tx_sdu_queue.size()); + pool->deallocate(sdu); + } } } else { log->warning("NULL SDU pointer in write_sdu()\n"); diff --git a/lib/src/upper/rlc_tm.cc b/lib/src/upper/rlc_tm.cc index 9b132b39b..96e075cb6 100644 --- a/lib/src/upper/rlc_tm.cc +++ b/lib/src/upper/rlc_tm.cc @@ -96,35 +96,26 @@ uint32_t rlc_tm::get_bearer() } // PDCP interface -void rlc_tm::write_sdu(byte_buffer_t *sdu) +void rlc_tm::write_sdu(byte_buffer_t *sdu, bool blocking) { if (!tx_enabled) { byte_buffer_pool::get_instance()->deallocate(sdu); return; } if (sdu) { - ul_queue.write(sdu); - log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, queue size=%d, bytes=%d", - rrc->get_rb_name(lcid).c_str(), ul_queue.size(), ul_queue.size_bytes()); - } else { - log->warning("NULL SDU pointer in write_sdu()\n"); - } -} - -void rlc_tm::write_sdu_nb(byte_buffer_t *sdu) -{ - if (!tx_enabled) { - byte_buffer_pool::get_instance()->deallocate(sdu); - return; - } - if (sdu) { - if (ul_queue.try_write(sdu)) { + if (blocking) { + ul_queue.write(sdu); log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, queue size=%d, bytes=%d", rrc->get_rb_name(lcid).c_str(), ul_queue.size(), ul_queue.size_bytes()); } else { - log->debug_hex(sdu->msg, sdu->N_bytes, "[Dropped SDU] %s Tx SDU, queue size=%d, bytes=%d", + if (ul_queue.try_write(sdu)) { + log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, queue size=%d, bytes=%d", + rrc->get_rb_name(lcid).c_str(), ul_queue.size(), ul_queue.size_bytes()); + } else { + log->debug_hex(sdu->msg, sdu->N_bytes, "[Dropped SDU] %s Tx SDU, queue size=%d, bytes=%d", rrc->get_rb_name(lcid).c_str(), ul_queue.size(), ul_queue.size_bytes()); - pool->deallocate(sdu); + pool->deallocate(sdu); + } } } else { log->warning("NULL SDU pointer in write_sdu()\n"); diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index ac80e6940..9ea96f6ee 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -142,14 +142,14 @@ uint32_t rlc_um::get_bearer() /**************************************************************************** * PDCP interface ***************************************************************************/ -void rlc_um::write_sdu(byte_buffer_t *sdu) +void rlc_um::write_sdu(byte_buffer_t *sdu, bool blocking) { - tx.write_sdu(sdu); -} + if (blocking) { + tx.write_sdu(sdu); + } else { + tx.try_write_sdu(sdu); + } -void rlc_um::write_sdu_nb(byte_buffer_t *sdu) -{ - tx.try_write_sdu(sdu); } /**************************************************************************** From b0a79ac6162749741ea94c6bbca094839c1ff71a Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 26 Jul 2018 12:55:16 +0200 Subject: [PATCH 61/88] fix segfault when ASYNC thread is disabled --- lib/src/phy/rf/rf_uhd_imp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index 7fe291497..cb06af9af 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -615,8 +615,11 @@ int rf_uhd_close(void *h) uhd_tx_metadata_free(&handler->tx_md); uhd_rx_metadata_free(&handler->rx_md_first); uhd_rx_metadata_free(&handler->rx_md); + +#if HAVE_ASYNC_THREAD handler->async_thread_running = false; pthread_join(handler->async_thread, NULL); +#endif uhd_tx_streamer_free(&handler->tx_stream); uhd_rx_streamer_free(&handler->rx_stream); From 9b8d7aeddf1c7e2a1cfb98f0e38bfb852ba0dc2c Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 26 Jul 2018 13:24:12 +0200 Subject: [PATCH 62/88] fix warning --- lib/src/phy/rf/rf_uhd_imp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index cb06af9af..2f3bbd008 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -371,12 +371,13 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels) clock_src = DEFAULT; } +#if HAVE_ASYNC_THREAD bool start_async_thread = true; - if (strstr(args, "silent")) { REMOVE_SUBSTRING_WITHCOMAS(args, "silent"); start_async_thread = false; } +#endif // Set over the wire format char *otw_format = "sc16"; From e6366b45705a574f9d41be05d99a734c17edc6fb Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 26 Jul 2018 14:20:40 +0200 Subject: [PATCH 63/88] fix stopping of async thread in UHD --- lib/src/phy/rf/rf_uhd_imp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index 2f3bbd008..931de42be 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -618,8 +618,10 @@ int rf_uhd_close(void *h) uhd_rx_metadata_free(&handler->rx_md); #if HAVE_ASYNC_THREAD - handler->async_thread_running = false; - pthread_join(handler->async_thread, NULL); + if (handler->async_thread_running) { + handler->async_thread_running = false; + pthread_join(handler->async_thread, NULL); + } #endif uhd_tx_streamer_free(&handler->tx_stream); From 22f1487d64587182075703dc46215093b3a297a6 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 27 Jul 2018 11:25:13 +0200 Subject: [PATCH 64/88] log dropped SDU in RLC as info rather than warning --- lib/src/upper/rlc_am.cc | 2 +- lib/src/upper/rlc_tm.cc | 2 +- lib/src/upper/rlc_um.cc | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 92c32410d..63f1a13fd 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -215,7 +215,7 @@ void rlc_am::write_sdu(byte_buffer_t *sdu, bool blocking) if (tx_sdu_queue.try_write(sdu)) { log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes, tx_sdu_queue.size()); } else { - log->debug_hex(sdu->msg, sdu->N_bytes, "[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes, tx_sdu_queue.size()); + log->info_hex(sdu->msg, sdu->N_bytes, "[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)", rrc->get_rb_name(lcid).c_str(), sdu->N_bytes, tx_sdu_queue.size()); pool->deallocate(sdu); } } diff --git a/lib/src/upper/rlc_tm.cc b/lib/src/upper/rlc_tm.cc index 96e075cb6..14cfe37ea 100644 --- a/lib/src/upper/rlc_tm.cc +++ b/lib/src/upper/rlc_tm.cc @@ -112,7 +112,7 @@ void rlc_tm::write_sdu(byte_buffer_t *sdu, bool blocking) log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, queue size=%d, bytes=%d", rrc->get_rb_name(lcid).c_str(), ul_queue.size(), ul_queue.size_bytes()); } else { - log->debug_hex(sdu->msg, sdu->N_bytes, "[Dropped SDU] %s Tx SDU, queue size=%d, bytes=%d", + log->info_hex(sdu->msg, sdu->N_bytes, "[Dropped SDU] %s Tx SDU, queue size=%d, bytes=%d", rrc->get_rb_name(lcid).c_str(), ul_queue.size(), ul_queue.size_bytes()); pool->deallocate(sdu); } diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 9ea96f6ee..0c6c8dfec 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -339,7 +339,7 @@ void rlc_um::rlc_um_tx::write_sdu(byte_buffer_t *sdu) if (sdu) { tx_sdu_queue.write(sdu); - log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B ,tx_sdu_queue_len=%d)", get_rb_name(), sdu->N_bytes, tx_sdu_queue.size()); + log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", get_rb_name(), sdu->N_bytes, tx_sdu_queue.size()); } else { log->warning("NULL SDU pointer in write_sdu()\n"); } @@ -355,9 +355,9 @@ void rlc_um::rlc_um_tx::try_write_sdu(byte_buffer_t *sdu) if (sdu) { if (tx_sdu_queue.try_write(sdu)) { - log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B ,tx_sdu_queue_len=%d)", get_rb_name(), sdu->N_bytes, tx_sdu_queue.size()); + log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", get_rb_name(), sdu->N_bytes, tx_sdu_queue.size()); } else { - log->warning_hex(sdu->msg, sdu->N_bytes, "[Dropped SDU] %s Tx SDU (%d B ,tx_sdu_queue_len=%d)", get_rb_name(), sdu->N_bytes, tx_sdu_queue.size()); + log->info_hex(sdu->msg, sdu->N_bytes, "[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)", get_rb_name(), sdu->N_bytes, tx_sdu_queue.size()); pool->deallocate(sdu); } } else { From bfb9ba43b489aebb5e40fc87e404f42f6e3a0687 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 27 Jul 2018 12:06:39 +0200 Subject: [PATCH 65/88] increase UHD recv timeout to 1.0 --- lib/src/phy/rf/rf_uhd_imp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index 931de42be..c308a98d9 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -803,7 +803,7 @@ int rf_uhd_recv_with_time_multi(void *h, rxd_samples = 0; uhd_error error = uhd_rx_streamer_recv(handler->rx_stream, buffs_ptr, - num_rx_samples, md, 0.5, false, &rxd_samples); + num_rx_samples, md, 1.0, false, &rxd_samples); if (error) { fprintf(stderr, "Error receiving from UHD: %d\n", error); log_rx_error(handler); From dc41240106345486b5f730e7ff00f13f52cb5130 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 27 Jul 2018 14:45:17 +0200 Subject: [PATCH 66/88] increase UHD tx timeout to 1.0 --- lib/src/phy/rf/rf_uhd_imp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index c308a98d9..202b47b8d 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -913,7 +913,7 @@ int rf_uhd_send_timed_multi(void *h, buffs_ptr[i] = buff; } uhd_error error = uhd_tx_streamer_send(handler->tx_stream, buffs_ptr, - tx_samples, &handler->tx_md, 0.5, &txd_samples); + tx_samples, &handler->tx_md, 1.0, &txd_samples); if (error) { fprintf(stderr, "Error sending to UHD: %d\n", error); goto unlock; From ec9b7e921af54557beff2a8faaf94e2864f5102e Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 30 Jul 2018 11:52:39 +0200 Subject: [PATCH 67/88] fix RLC AM double unlock mutex --- lib/src/upper/rlc_am.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 63f1a13fd..71eb6fa34 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -370,7 +370,6 @@ int rlc_am::read_pdu(uint8_t *payload, uint32_t nof_bytes) // Tx STATUS if requested if(do_status && !status_prohibited()) { - pthread_mutex_unlock(&mutex); pdu_size = build_status_pdu(payload, nof_bytes); goto unlock_and_exit; } From 99964c1054661120e9c40657582c1f99dad18ffe Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 30 Jul 2018 14:54:49 +0200 Subject: [PATCH 68/88] fix RLC AM issue when building segements that require N_li in header --- lib/src/upper/rlc_am.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 71eb6fa34..92c33f652 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -663,6 +663,11 @@ int rlc_am::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_retx_t r uint32_t pdu_space = 0; head_len = rlc_am_packed_length(&new_header); + if (old_header.N_li > 0) { + // Make sure we can fit at least one N_li element if old header contained at least one + head_len += 2; + } + if(nof_bytes <= head_len) { log->warning("%s Cannot build a PDU segment - %d bytes available, %d bytes required for header\n", From 3234add1f81aff80e9ab7f0e56d2b0f381250f8a Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 30 Jul 2018 14:55:43 +0200 Subject: [PATCH 69/88] use blocking pool allocate in RLC AM --- lib/src/upper/rlc_am.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 92c33f652..416a4ad84 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -776,7 +776,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) return 0; } - byte_buffer_t *pdu = pool_allocate; + byte_buffer_t *pdu = pool_allocate_blocking; if (!pdu) { #ifdef RLC_AM_BUFFER_DEBUG log->console("Fatal Error: Could not allocate PDU in build_data_pdu()\n"); @@ -957,7 +957,7 @@ void rlc_am::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_h // Write to rx window rlc_amd_rx_pdu_t pdu; - pdu.buf = pool_allocate; + pdu.buf = pool_allocate_blocking; if (!pdu.buf) { #ifdef RLC_AM_BUFFER_DEBUG log->console("Fatal Error: Couldn't allocate PDU in handle_data_pdu().\n"); @@ -1050,7 +1050,7 @@ void rlc_am::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a } rlc_amd_rx_pdu_t segment; - segment.buf = pool_allocate; + segment.buf = pool_allocate_blocking; if (!segment.buf) { #ifdef RLC_AM_BUFFER_DEBUG log->console("Fatal Error: Couldn't allocate PDU in handle_data_pdu_segment().\n"); @@ -1217,7 +1217,7 @@ void rlc_am::reassemble_rx_sdus() { uint32_t len = 0; if(!rx_sdu) { - rx_sdu = pool_allocate; + rx_sdu = pool_allocate_blocking; if (!rx_sdu) { #ifdef RLC_AM_BUFFER_DEBUG log->console("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (1)\n"); @@ -1251,7 +1251,7 @@ void rlc_am::reassemble_rx_sdus() rx_sdu->set_timestamp(); pdcp->write_pdu(lcid, rx_sdu); - rx_sdu = pool_allocate; + rx_sdu = pool_allocate_blocking; if (!rx_sdu) { #ifdef RLC_AM_BUFFER_DEBUG log->console("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (2)\n"); @@ -1289,7 +1289,7 @@ void rlc_am::reassemble_rx_sdus() log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU (%d B)", rrc->get_rb_name(lcid).c_str(), rx_sdu->N_bytes); rx_sdu->set_timestamp(); pdcp->write_pdu(lcid, rx_sdu); - rx_sdu = pool_allocate; + rx_sdu = pool_allocate_blocking; if (!rx_sdu) { #ifdef RLC_AM_BUFFER_DEBUG log->console("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (3)\n"); @@ -1434,7 +1434,7 @@ bool rlc_am::add_segment_and_check(rlc_amd_rx_pdu_segments_t *pdu, rlc_amd_rx_pd } // Copy data - byte_buffer_t *full_pdu = pool_allocate; + byte_buffer_t *full_pdu = pool_allocate_blocking; if (!full_pdu) { #ifdef RLC_AM_BUFFER_DEBUG log->console("Fatal Error: Could not allocate PDU in add_segment_and_check()\n"); From 1160dac54f1f7b89ec95f033f2cea722ecad36ab Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 30 Jul 2018 14:56:22 +0200 Subject: [PATCH 70/88] add new RLC AM test for checking correct stopping --- lib/test/upper/rlc_am_test.cc | 83 +++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index b2d68d3fa..c80d85f9e 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -27,11 +27,13 @@ #include #include "srslte/common/log_filter.h" #include "srslte/common/logger_stdout.h" +#include "srslte/common/threads.h" #include "srslte/upper/rlc_am.h" #include "srslte/common/rlc_pcap.h" #include #define NBUFS 5 #define HAVE_PCAP 0 +#define SDU_SIZE 500 using namespace srsue; using namespace srslte; @@ -91,6 +93,48 @@ public: rlc_pcap *pcap; }; +class ul_writer : public thread +{ +public: + ul_writer(rlc_am* rlc_) : rlc(rlc_), running(false) {} + ~ul_writer() { stop(); } + void stop() + { + running = false; + int cnt=0; + while(running && cnt<100) { + usleep(10000); + cnt++; + } + wait_thread_finish(); + } + +private: + void run_thread() { + int sn = 0; + running = true; + while(running) { + byte_buffer_t *pdu = byte_buffer_pool::get_instance()->allocate("rlc_tester::run_thread", true); + if (!pdu) { + printf("Error: Could not allocate PDU in rlc_tester::run_thread\n\n\n"); + // backoff for a bit + usleep(1000); + continue; + } + for (uint32_t i = 0; i < SDU_SIZE; i++) { + pdu->msg[i] = sn; + } + sn++; + pdu->N_bytes = SDU_SIZE; + rlc->write_sdu(pdu); + } + running = false; + } + + rlc_am* rlc; + bool running; +}; + void basic_test() { srslte::log_filter log1("RLC_AM_1"); @@ -1432,6 +1476,42 @@ void reset_test() assert(0 == rlc1.get_buffer_state()); } +void stop_test() +{ + srslte::log_filter log1("RLC_AM_1"); + log1.set_level(srslte::LOG_LEVEL_DEBUG); + log1.set_hex_limit(-1); + rlc_am_tester tester; + mac_dummy_timers timers; + + rlc_am rlc1; + + log1.set_level(srslte::LOG_LEVEL_DEBUG); + + rlc1.init(&log1, 1, &tester, &tester, &timers); + + LIBLTE_RRC_RLC_CONFIG_STRUCT cnfg; + cnfg.rlc_mode = LIBLTE_RRC_RLC_MODE_AM; + cnfg.dl_am_rlc.t_reordering = LIBLTE_RRC_T_REORDERING_MS5; + cnfg.dl_am_rlc.t_status_prohibit = LIBLTE_RRC_T_STATUS_PROHIBIT_MS5; + cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4; + cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25; + cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4; + cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5; + + rlc1.configure(&cnfg); + + // start thread reading + ul_writer writer(&rlc1); + writer.start(-2); + + // let writer thread block on tx_queue + usleep(1e6); + + // stop RLC1 + rlc1.stop(); +} + int main(int argc, char **argv) { basic_test(); byte_buffer_pool::get_instance()->cleanup(); @@ -1471,4 +1551,7 @@ int main(int argc, char **argv) { reset_test(); byte_buffer_pool::get_instance()->cleanup(); + + stop_test(); + byte_buffer_pool::get_instance()->cleanup(); } From a20a8b18ad99da3e7b0a05e4c30f19c880e865d9 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 30 Jul 2018 14:57:17 +0200 Subject: [PATCH 71/88] fix rlc_stress_test, stop RLC instances and remove hard thread canceling --- lib/test/upper/rlc_stress_test.cc | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/lib/test/upper/rlc_stress_test.cc b/lib/test/upper/rlc_stress_test.cc index d48011667..ec02a699a 100644 --- a/lib/test/upper/rlc_stress_test.cc +++ b/lib/test/upper/rlc_stress_test.cc @@ -113,7 +113,6 @@ public: fail_rate = fail_rate_; opp_sdu_ratio = opp_sdu_ratio_; run_enable = true; - running = false; pdu_tx_delay_usec = pdu_tx_delay_usec_; pcap = pcap_; is_dl = is_dl_; @@ -123,21 +122,12 @@ public: void stop() { run_enable = false; - int cnt=0; - while(running && cnt<100) { - usleep(10000); - cnt++; - } - if(running) { - thread_cancel(); - } wait_thread_finish(); } private: void run_thread() { - running = true; byte_buffer_t *pdu = byte_buffer_pool::get_instance()->allocate("mac_reader::run_thread"); if (!pdu) { printf("Fatal Error: Could not allocate PDU in mac_reader::run_thread\n"); @@ -163,7 +153,6 @@ private: } } } - running = false; byte_buffer_pool::get_instance()->deallocate(pdu); } @@ -175,9 +164,7 @@ private: rlc_pcap *pcap; uint32_t lcid; bool is_dl; - bool run_enable; - bool running; }; class mac_dummy @@ -227,7 +214,6 @@ public: rlc_tester(rlc_interface_pdcp *rlc_, std::string name_, uint32_t sdu_gen_delay_usec_, uint32_t lcid_){ rlc = rlc_; run_enable = true; - running = false; rx_pdus = 0; name = name_; sdu_gen_delay_usec = sdu_gen_delay_usec_; @@ -237,14 +223,6 @@ public: void stop() { run_enable = false; - int cnt=0; - while(running && cnt<100) { - usleep(10000); - cnt++; - } - if(running) { - thread_cancel(); - } wait_thread_finish(); } @@ -275,7 +253,6 @@ private: void run_thread() { uint8_t sn = 0; - running = true; while(run_enable) { byte_buffer_t *pdu = byte_buffer_pool::get_instance()->allocate("rlc_tester::run_thread"); if (!pdu) { @@ -292,11 +269,9 @@ private: rlc->write_sdu(lcid, pdu); if (sdu_gen_delay_usec) usleep(sdu_gen_delay_usec); } - running = false; } bool run_enable; - bool running; long rx_pdus; uint32_t lcid; @@ -381,6 +356,10 @@ void stress_test(stress_test_args_t args) usleep(1e6); } + // Stop RLC instances first to release blocking writers + rlc1.stop(); + rlc2.stop(); + tester1.stop(); tester2.stop(); mac.stop(); From 2ef2baf72ac5b99651279d54ff97e8ab3aff9f3f Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 30 Jul 2018 15:11:31 +0200 Subject: [PATCH 72/88] increase size of buffer_pool - This solves an issue where in the worst-case an RLC AM instance would block because no new data nor control PDUs could be created to flush the buffers, effectivly causing a system stall. - Happens in RLC AM stress test regularly with higher drop rates. --- lib/include/srslte/common/buffer_pool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index 54708b3e1..bfd021d1b 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -169,7 +169,7 @@ public: private: - static const int POOL_SIZE = 2048; + static const int POOL_SIZE = 4096; std::stack available; std::vector used; pthread_mutex_t mutex; From 55edb92ac5f5907e9a978fbe82a0ffec0dc0396d Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 30 Jul 2018 16:35:57 +0200 Subject: [PATCH 73/88] fix RLC AM test and account for additional header room for retx segments --- lib/test/upper/rlc_am_test.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index c80d85f9e..00793e7d3 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -765,14 +765,14 @@ void resegment_test_3() // Read the retx PDU from RLC1 and force resegmentation byte_buffer_t retx1; - retx1.N_bytes = rlc1.read_pdu(retx1.msg, 14); // 4 byte header + 10 data + retx1.N_bytes = rlc1.read_pdu(retx1.msg, 16); // 6 byte header + 10 data // Write the retx PDU to RLC2 rlc2.write_pdu(retx1.msg, retx1.N_bytes); // Read the remaining segment byte_buffer_t retx2; - retx2.N_bytes = rlc1.read_pdu(retx2.msg, 14); // 4 byte header + 10 data + retx2.N_bytes = rlc1.read_pdu(retx2.msg, 16); // 6 byte header + 10 data // Write the retx PDU to RLC2 rlc2.write_pdu(retx2.msg, retx2.N_bytes); @@ -1242,7 +1242,7 @@ void resegment_test_7() byte_buffer_t retx2[4]; for (uint32_t i = 0; i < 4; i++) { assert(rlc1.get_buffer_state() != 0); - retx2[i].N_bytes = rlc1.read_pdu(retx2[i].msg, 7); + retx2[i].N_bytes = rlc1.read_pdu(retx2[i].msg, 9); assert(retx2[i].N_bytes != 0); rlc2.write_pdu(retx2[i].msg, retx2[i].N_bytes); @@ -1392,9 +1392,9 @@ void resegment_test_8() // second round of retx, reduce grant size to force different segment sizes byte_buffer_t retx2[20]; - for (uint32_t i = 0; i < 9; i++) { + for (uint32_t i = 0; i < 7; i++) { assert(rlc1.get_buffer_state() != 0); - retx2[i].N_bytes = rlc1.read_pdu(retx2[i].msg, 7); + retx2[i].N_bytes = rlc1.read_pdu(retx2[i].msg, 9); assert(retx2[i].N_bytes != 0); rlc2.write_pdu(retx2[i].msg, retx2[i].N_bytes); #if HAVE_PCAP From ca429d2be5cf7c959f6b0900297ea8f13ef8205c Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 1 Aug 2018 10:58:08 +0200 Subject: [PATCH 74/88] Fixed turbocoder free --- lib/src/phy/fec/turbocoder.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/src/phy/fec/turbocoder.c b/lib/src/phy/fec/turbocoder.c index 09d484c58..e45c9a6b2 100644 --- a/lib/src/phy/fec/turbocoder.c +++ b/lib/src/phy/fec/turbocoder.c @@ -65,11 +65,12 @@ int srslte_tcod_init(srslte_tcod_t *h, uint32_t max_long_cb) { } void srslte_tcod_free(srslte_tcod_t *h) { + h->max_long_cb = 0; + if (h->temp) { + free(h->temp); + } + if (table_initiated) { - h->max_long_cb = 0; - if (h->temp) { - free(h->temp); - } for (int i = 0; i < 188; i++) { srslte_bit_interleaver_free(&tcod_interleavers[i]); } From 3b8371d090e55377b1d13a5c81403dd21ac85568 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Sun, 5 Aug 2018 09:37:58 +0200 Subject: [PATCH 75/88] add detach support (for switch off) --- lib/include/srslte/interfaces/ue_interfaces.h | 2 +- srsue/hdr/ue.h | 4 +- srsue/hdr/ue_base.h | 4 +- srsue/hdr/upper/nas.h | 3 +- srsue/src/main.cc | 3 +- srsue/src/ue.cc | 21 ++++- srsue/src/upper/nas.cc | 79 ++++++++++++++++++- 7 files changed, 103 insertions(+), 13 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index dc8128041..a21448305 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -146,7 +146,7 @@ class nas_interface_ue { public: virtual bool attach_request() = 0; - virtual bool deattach_request() = 0; + virtual bool detach_request() = 0; }; // NAS interface for UE diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index b45c079c5..12072f6f3 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -69,8 +69,8 @@ public: bool init(all_args_t *args_); void stop(); - bool attach(); - bool deattach(); + bool switch_on(); + bool switch_off(); bool is_attached(); void start_plot(); void print_mbms(); diff --git a/srsue/hdr/ue_base.h b/srsue/hdr/ue_base.h index c41a951bb..6e4853dfd 100644 --- a/srsue/hdr/ue_base.h +++ b/srsue/hdr/ue_base.h @@ -159,8 +159,8 @@ public: virtual bool init(all_args_t *args_) = 0; virtual void stop() = 0; - virtual bool attach() = 0; - virtual bool deattach() = 0; + virtual bool switch_on() = 0; + virtual bool switch_off() = 0; virtual bool is_attached() = 0; virtual void start_plot() = 0; diff --git a/srsue/hdr/upper/nas.h b/srsue/hdr/upper/nas.h index 32f6898f9..150f97b0a 100644 --- a/srsue/hdr/upper/nas.h +++ b/srsue/hdr/upper/nas.h @@ -90,7 +90,7 @@ public: // UE interface bool attach_request(); - bool deattach_request(); + bool detach_request(); // PCAP void start_pcap(srslte::nas_pcap *pcap_); @@ -186,6 +186,7 @@ private: void send_authentication_failure(const uint8_t cause, const uint8_t* auth_fail_param); void gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg); void send_security_mode_reject(uint8_t cause); + void send_detach_request(bool switch_off); // security context persistence file bool read_ctxt_file(nas_sec_ctxt *ctxt); diff --git a/srsue/src/main.cc b/srsue/src/main.cc index d0dd59f3e..cc1638169 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -545,7 +545,7 @@ int main(int argc, char *argv[]) pthread_create(&input, NULL, &input_loop, &args); printf("Attaching UE...\n"); - while (!ue->attach() && running) { + while (!ue->switch_on() && running) { sleep(1); } if (running) { @@ -585,6 +585,7 @@ int main(int argc, char *argv[]) } sleep(1); } + ue->switch_off(); pthread_cancel(input); metricshub.stop(); ue->stop(); diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index a12a66d65..56e8b6c44 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -301,12 +301,27 @@ void ue::stop() } } -bool ue::attach() { +bool ue::switch_on() { return nas.attach_request(); } -bool ue::deattach() { - return nas.deattach_request(); +bool ue::switch_off() { + // generate detach request + nas.detach_request(); + + // wait for max. 5s for it to be sent (according to TS 24.301 Sec 25.5.2.2) + const uint32_t RB_ID_SRB1 = 1; + int cnt = 0, timeout = 5; + while (rlc.get_buffer_state(RB_ID_SRB1) && ++cnt <= timeout) { + sleep(1); + } + bool detach_sent = true; + if (rlc.get_buffer_state(RB_ID_SRB1)) { + nas_log.warning("Detach couldn't be sent after %ds.\n", timeout); + detach_sent = false; + } + + return detach_sent; } bool ue::is_attached() diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index df581e21a..30bd50f50 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -172,9 +172,25 @@ bool nas::attach_request() { return false; } -bool nas::deattach_request() { - state = EMM_STATE_DEREGISTERED_INITIATED; - nas_log->info("Dettach request not supported\n"); +bool nas::detach_request() { + // attempt detach for 5s + nas_log->info("Detach Request\n"); + + switch (state) { + case EMM_STATE_DEREGISTERED: + // do nothing .. + break; + case EMM_STATE_REGISTERED: + // send detach request + send_detach_request(true); + state = EMM_STATE_DEREGISTERED_INITIATED; + break; + case EMM_STATE_DEREGISTERED_INITIATED: + // do nothing .. + break; + default: + break; + } return false; } @@ -1132,6 +1148,63 @@ void nas::send_security_mode_reject(uint8_t cause) { rrc->write_sdu(cfg.lcid, msg); } +void nas::send_detach_request(bool switch_off) +{ + byte_buffer_t *pdu = pool_allocate_blocking; + if (!pdu) { + nas_log->error("Fatal Error: Couldn't allocate PDU in %s().\n", __FUNCTION__); + return; + } + + LIBLTE_MME_DETACH_REQUEST_MSG_STRUCT detach_request = {}; + if (switch_off) { + detach_request.detach_type.switch_off = 1; + detach_request.detach_type.type_of_detach = LIBLTE_MME_SO_FLAG_SWITCH_OFF; + } else { + detach_request.detach_type.switch_off = 0; + detach_request.detach_type.type_of_detach = LIBLTE_MME_SO_FLAG_NORMAL_DETACH; + } + + // GUTI or IMSI detach + if (have_guti && have_ctxt) { + detach_request.eps_mobile_id.type_of_id = LIBLTE_MME_EPS_MOBILE_ID_TYPE_GUTI; + memcpy(&detach_request.eps_mobile_id.guti, &ctxt.guti, sizeof(LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT)); + detach_request.nas_ksi.tsc_flag = LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE; + detach_request.nas_ksi.nas_ksi = ctxt.ksi; + nas_log->info("Requesting Detach with GUTI\n"); + liblte_mme_pack_detach_request_msg(&detach_request, + LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY, + ctxt.tx_count, + (LIBLTE_BYTE_MSG_STRUCT *) pdu); + + // Add MAC + if (pdu->N_bytes > 5) { + integrity_generate(&k_nas_int[16], + ctxt.tx_count, + SECURITY_DIRECTION_UPLINK, + &pdu->msg[5], + pdu->N_bytes - 5, + &pdu->msg[1]); + } else { + nas_log->error("Invalid PDU size %d\n", pdu->N_bytes); + } + } else { + detach_request.eps_mobile_id.type_of_id = LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI; + detach_request.nas_ksi.tsc_flag = LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE; + detach_request.nas_ksi.nas_ksi = 0; + usim->get_imsi_vec(detach_request.eps_mobile_id.imsi, 15); + nas_log->info("Requesting IMSI detach (IMSI=%s)\n", usim->get_imsi_str().c_str()); + liblte_mme_pack_detach_request_msg(&detach_request, LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT *) pdu); + } + + if(pcap != NULL) { + pcap->write_nas(pdu->msg, pdu->N_bytes); + } + + nas_log->info("Sending detach request\n"); + rrc->write_sdu(cfg.lcid, pdu); +} + void nas::send_authentication_response(const uint8_t* res, const size_t res_len, const uint8_t sec_hdr_type) { byte_buffer_t *pdu = pool_allocate_blocking; From 91492b87ef72106c45daf9f424f6ae48911ed698 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 3 Aug 2018 16:28:06 +0200 Subject: [PATCH 76/88] add del_bearer for RLC/PDCP --- lib/include/srslte/interfaces/ue_interfaces.h | 1 + lib/include/srslte/upper/pdcp.h | 1 + lib/include/srslte/upper/rlc.h | 1 + lib/src/upper/pdcp.cc | 17 ++++++++++++++++- lib/src/upper/rlc.cc | 18 ++++++++++++++++++ 5 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index a21448305..0caa68d94 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -274,6 +274,7 @@ public: virtual void add_bearer(uint32_t lcid) = 0; virtual void add_bearer(uint32_t lcid, srslte::srslte_rlc_config_t cnfg) = 0; virtual void add_bearer_mrb(uint32_t lcid) = 0; + virtual void del_bearer(uint32_t lcid) = 0; }; // RLC interface for PDCP diff --git a/lib/include/srslte/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index 2376bd020..f1e02400a 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -60,6 +60,7 @@ public: void write_sdu_mch(uint32_t lcid, byte_buffer_t *sdu); void add_bearer(uint32_t lcid, srslte_pdcp_config_t cnfg = srslte_pdcp_config_t()); void add_bearer_mrb(uint32_t lcid, srslte_pdcp_config_t cnfg = srslte_pdcp_config_t()); + void del_bearer(uint32_t lcid); void config_security(uint32_t lcid, uint8_t *k_enc, uint8_t *k_int, diff --git a/lib/include/srslte/upper/rlc.h b/lib/include/srslte/upper/rlc.h index 20123da0e..a56f48eff 100644 --- a/lib/include/srslte/upper/rlc.h +++ b/lib/include/srslte/upper/rlc.h @@ -86,6 +86,7 @@ public: void add_bearer(uint32_t lcid); void add_bearer(uint32_t lcid, srslte_rlc_config_t cnfg); void add_bearer_mrb(uint32_t lcid); + void del_bearer(uint32_t lcid); private: void reset_metrics(); diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index c15fe6106..4ad9b2b16 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -137,6 +137,7 @@ void pdcp::write_sdu_mch(uint32_t lcid, byte_buffer_t *sdu) } pthread_rwlock_unlock(&rwlock); } + void pdcp::add_bearer(uint32_t lcid, srslte_pdcp_config_t cfg) { pthread_rwlock_wrlock(&rwlock); @@ -154,7 +155,6 @@ unlock_and_exit: pthread_rwlock_unlock(&rwlock); } - void pdcp::add_bearer_mrb(uint32_t lcid, srslte_pdcp_config_t cfg) { pthread_rwlock_wrlock(&rwlock); @@ -172,6 +172,21 @@ unlock_and_exit: pthread_rwlock_unlock(&rwlock); } +void pdcp::del_bearer(uint32_t lcid) +{ + pthread_rwlock_wrlock(&rwlock); + if (valid_lcid(lcid)) { + pdcp_map_t::iterator it = pdcp_array.find(lcid); + delete(it->second); + pdcp_array.erase(it); + pdcp_log->warning("Deleted PDCP bearer %s\n", rrc->get_rb_name(lcid).c_str()); + } else { + pdcp_log->warning("Can't delete bearer %s. Bearer doesn't exist.\n", rrc->get_rb_name(lcid).c_str()); + } + pthread_rwlock_unlock(&rwlock); +} + + void pdcp::config_security(uint32_t lcid, uint8_t *k_enc, uint8_t *k_int, diff --git a/lib/src/upper/rlc.cc b/lib/src/upper/rlc.cc index 31b740df4..237891430 100644 --- a/lib/src/upper/rlc.cc +++ b/lib/src/upper/rlc.cc @@ -494,6 +494,24 @@ unlock_and_exit: } +void rlc::del_bearer(uint32_t lcid) +{ + pthread_rwlock_wrlock(&rwlock); + + if (valid_lcid_mrb(lcid)) { + rlc_map_t::iterator it = rlc_array.find(lcid); + it->second->stop(); + delete(it->second); + rlc_array.erase(it); + rlc_log->warning("Deleted RLC bearer %s\n", rrc->get_rb_name(lcid).c_str()); + } else { + rlc_log->warning("Can't delete bearer %s. Bearer doesn't exist.\n", rrc->get_rb_name(lcid).c_str()); + } + + pthread_rwlock_unlock(&rwlock); +} + + /******************************************************************************* Helpers (Lock must be hold when calling those) *******************************************************************************/ From 716b0280237987299c5418f4a9cac03689426196 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 6 Aug 2018 15:48:52 +0200 Subject: [PATCH 77/88] reset PDCP entities --- lib/src/upper/pdcp.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index 4ad9b2b16..a73b44283 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -94,6 +94,7 @@ void pdcp::reset() // destroy all bearers pthread_rwlock_wrlock(&rwlock); for (pdcp_map_t::iterator it = pdcp_array.begin(); it != pdcp_array.end(); ++it) { + it->second->reset(); delete(it->second); pdcp_array.erase(it); } From 8a869d83f23cb5a25c1f1799170a58ff9d882038 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 6 Aug 2018 15:58:51 +0200 Subject: [PATCH 78/88] drop PDCP SDU that do not pass integrity check --- lib/src/upper/pdcp_entity.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/src/upper/pdcp_entity.cc b/lib/src/upper/pdcp_entity.cc index 3efdf4786..412937069 100644 --- a/lib/src/upper/pdcp_entity.cc +++ b/lib/src/upper/pdcp_entity.cc @@ -214,10 +214,13 @@ void pdcp_entity::write_pdu(byte_buffer_t *pdu) } if (do_integrity) { - integrity_verify(pdu->msg, + if (not integrity_verify(pdu->msg, rx_count, pdu->N_bytes - 4, - &(pdu->msg[pdu->N_bytes - 4])); + &(pdu->msg[pdu->N_bytes - 4]))) { + log->error_hex(pdu->msg, pdu->N_bytes, "RX %s PDU SN: %d", rrc->get_rb_name(lcid).c_str(), sn); + goto exit; + } } pdcp_unpack_control_pdu(pdu, &sn); @@ -226,6 +229,7 @@ void pdcp_entity::write_pdu(byte_buffer_t *pdu) // pass to RRC rrc->write_pdu(lcid, pdu); } +exit: rx_count++; } From 40aef7674573094c51c6a9b21098ee517d7afe21 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 6 Aug 2018 18:29:14 +0200 Subject: [PATCH 79/88] fix logging when removing DRB --- srsue/hdr/upper/rrc.h | 4 ++-- srsue/src/upper/rrc.cc | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index e4d06eb1f..72a5ff678 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -637,8 +637,8 @@ private: void handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT *reconfig); void add_srb(LIBLTE_RRC_SRB_TO_ADD_MOD_STRUCT *srb_cnfg); void add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg); - void release_drb(uint8_t lcid); - void add_mrb(uint32_t lcid, uint32_t port); + void release_drb(uint32_t drb_id); + void add_mrb(uint32_t lcid, uint32_t port); bool apply_rr_config_dedicated(LIBLTE_RRC_RR_CONFIG_DEDICATED_STRUCT *cnfg); void apply_phy_config_dedicated(LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT *phy_cnfg, bool apply_defaults); void apply_mac_config_dedicated(LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT *mac_cfg, bool apply_defaults); diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 1b2d2607d..f09442cbb 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -2699,8 +2699,13 @@ void rrc::add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg) { rrc_log->info("Added radio bearer %s\n", get_rb_name(lcid).c_str()); } -void rrc::release_drb(uint8_t lcid) { - // TODO +void rrc::release_drb(uint32_t drb_id) +{ + uint32_t lcid = RB_ID_SRB2 + drb_id; + rrc_log->info("Releasing radio bearer %s\n", get_rb_name(lcid).c_str()); + drbs.erase(lcid); + + // FIXME: add body } void rrc::add_mrb(uint32_t lcid, uint32_t port) From 32ed7d9f3abd1ef3cac727085ac8425b8417cbc6 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 7 Aug 2018 09:40:52 +0200 Subject: [PATCH 80/88] print error when DRB couldn't be released --- srsue/src/upper/rrc.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index f09442cbb..ecbfa0b04 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -2702,10 +2702,13 @@ void rrc::add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg) { void rrc::release_drb(uint32_t drb_id) { uint32_t lcid = RB_ID_SRB2 + drb_id; - rrc_log->info("Releasing radio bearer %s\n", get_rb_name(lcid).c_str()); - drbs.erase(lcid); - // FIXME: add body + if (drbs.find(lcid) != drbs.end()) { + rrc_log->info("Releasing radio bearer %s\n", get_rb_name(lcid).c_str()); + drbs.erase(lcid); + } else { + rrc_log->error("Couldn't release radio bearer %s. Doesn't exist.\n", get_rb_name(lcid).c_str()); + } } void rrc::add_mrb(uint32_t lcid, uint32_t port) From 527261e35b2ccc0f8197cf6aa9fab97364b720e8 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 7 Aug 2018 10:20:52 +0200 Subject: [PATCH 81/88] fix drb release --- srsue/src/upper/rrc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index ecbfa0b04..09267908c 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -2703,7 +2703,7 @@ void rrc::release_drb(uint32_t drb_id) { uint32_t lcid = RB_ID_SRB2 + drb_id; - if (drbs.find(lcid) != drbs.end()) { + if (drbs.find(drb_id) != drbs.end()) { rrc_log->info("Releasing radio bearer %s\n", get_rb_name(lcid).c_str()); drbs.erase(lcid); } else { From 9f838dc65c6d201aba902d731238af7025bdf26f Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 7 Aug 2018 10:50:07 +0200 Subject: [PATCH 82/88] bzero DL-DCCH object before unpacking --- srsue/src/upper/rrc.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 09267908c..ec2281dce 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -2021,6 +2021,7 @@ void rrc::parse_dl_ccch(byte_buffer_t *pdu) { void rrc::parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu) { srslte_bit_unpack_vector(pdu->msg, bit_buf.msg, pdu->N_bytes * 8); bit_buf.N_bits = pdu->N_bytes * 8; + bzero(&dl_dcch_msg, sizeof(dl_dcch_msg)); liblte_rrc_unpack_dl_dcch_msg((LIBLTE_BIT_MSG_STRUCT *) &bit_buf, &dl_dcch_msg); rrc_log->info("%s - Received %s\n", From 86f70011d69b05c5a887efc0e8bf39f8b7a4083f Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 7 Aug 2018 14:40:33 +0200 Subject: [PATCH 83/88] print LCID in RLC AM when providing buffer report --- lib/src/upper/rlc_am.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 416a4ad84..4b15e9bc5 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -238,7 +238,7 @@ uint32_t rlc_am::get_total_buffer_state() check_reordering_timeout(); if(do_status && !status_prohibited()) { n_bytes += prepare_status(); - log->debug("Buffer state - status report: %d bytes\n", n_bytes); + log->debug("%s Buffer state - total status report: %d bytes\n", rrc->get_rb_name(lcid).c_str(), n_bytes); } // Bytes needed for retx @@ -292,7 +292,7 @@ uint32_t rlc_am::get_buffer_state() check_reordering_timeout(); if(do_status && !status_prohibited()) { n_bytes = prepare_status(); - log->debug("Buffer state - status report: %d bytes\n", n_bytes); + log->debug("%s Buffer state - status report: %d bytes\n", rrc->get_rb_name(lcid).c_str(), n_bytes); goto unlock_and_return; } From 06c9a3f07fa9814999c55db563cf1de670a8a9bf Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 7 Aug 2018 15:18:07 +0200 Subject: [PATCH 84/88] add network initiated detach --- srsue/hdr/upper/nas.h | 2 ++ srsue/src/upper/nas.cc | 55 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/srsue/hdr/upper/nas.h b/srsue/hdr/upper/nas.h index 150f97b0a..70ccbea35 100644 --- a/srsue/hdr/upper/nas.h +++ b/srsue/hdr/upper/nas.h @@ -173,6 +173,7 @@ private: void parse_service_reject(uint32_t lcid, byte_buffer_t *pdu); void parse_esm_information_request(uint32_t lcid, byte_buffer_t *pdu); void parse_emm_information(uint32_t lcid, byte_buffer_t *pdu); + void parse_detach_request(uint32_t lcid, byte_buffer_t *pdu); // Packet generators void gen_attach_request(byte_buffer_t *msg); @@ -187,6 +188,7 @@ private: void gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg); void send_security_mode_reject(uint8_t cause); void send_detach_request(bool switch_off); + void send_detach_accept(); // security context persistence file bool read_ctxt_file(nas_sec_ctxt *ctxt); diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 30bd50f50..1438f005a 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -371,6 +371,9 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { case LIBLTE_MME_MSG_TYPE_EMM_INFORMATION: parse_emm_information(lcid, pdu); break; + case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST: + parse_detach_request(lcid, pdu); + break; default: nas_log->error("Not handling NAS message with MSG_TYPE=%02X\n", msg_type); pool->deallocate(pdu); @@ -975,6 +978,23 @@ void nas::parse_emm_information(uint32_t lcid, byte_buffer_t *pdu) { pool->deallocate(pdu); } +void nas::parse_detach_request(uint32_t lcid, byte_buffer_t *pdu) +{ + LIBLTE_MME_DETACH_REQUEST_MSG_STRUCT detach_request; + liblte_mme_unpack_detach_request_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &detach_request); + ctxt.rx_count++; + pool->deallocate(pdu); + + if (state == EMM_STATE_REGISTERED) { + nas_log->info("Received Detach request (type=%d)\n", detach_request.detach_type.type_of_detach); + state = EMM_STATE_DEREGISTERED; + // send accept + send_detach_accept(); + } else { + nas_log->warning("Received detach request in invalid state (state=%d)\n", state); + } +} + /******************************************************************************* * Senders ******************************************************************************/ @@ -1205,6 +1225,41 @@ void nas::send_detach_request(bool switch_off) rrc->write_sdu(cfg.lcid, pdu); } +void nas::send_detach_accept() +{ + byte_buffer_t *pdu = pool_allocate_blocking; + if (!pdu) { + nas_log->error("Fatal Error: Couldn't allocate PDU in %s().\n", __FUNCTION__); + return; + } + + LIBLTE_MME_DETACH_ACCEPT_MSG_STRUCT detach_accept; + bzero(&detach_accept, sizeof(detach_accept)); + liblte_mme_pack_detach_accept_msg(&detach_accept, + LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY, + ctxt.tx_count, + (LIBLTE_BYTE_MSG_STRUCT *) pdu); + + // Add MAC + if (pdu->N_bytes > 5) { + integrity_generate(&k_nas_int[16], + ctxt.tx_count, + SECURITY_DIRECTION_UPLINK, + &pdu->msg[5], + pdu->N_bytes - 5, + &pdu->msg[1]); + } else { + nas_log->error("Invalid PDU size %d\n", pdu->N_bytes); + } + + if(pcap != NULL) { + pcap->write_nas(pdu->msg, pdu->N_bytes); + } + + nas_log->info("Sending detach accept\n"); + rrc->write_sdu(cfg.lcid, pdu); +} + void nas::send_authentication_response(const uint8_t* res, const size_t res_len, const uint8_t sec_hdr_type) { byte_buffer_t *pdu = pool_allocate_blocking; From e2470685a535eddb1fa53b85dac527c4ba5afac8 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 8 Aug 2018 13:03:15 +0200 Subject: [PATCH 85/88] send attach_request and detach_accept ciphered --- srsue/src/upper/nas.cc | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 1438f005a..0109be17f 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -1193,12 +1193,17 @@ void nas::send_detach_request(bool switch_off) detach_request.nas_ksi.nas_ksi = ctxt.ksi; nas_log->info("Requesting Detach with GUTI\n"); liblte_mme_pack_detach_request_msg(&detach_request, - LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY, + LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT *) pdu); + if(pcap != NULL) { + pcap->write_nas(pdu->msg, pdu->N_bytes); + } + // Add MAC if (pdu->N_bytes > 5) { + cipher_encrypt(pdu); integrity_generate(&k_nas_int[16], ctxt.tx_count, SECURITY_DIRECTION_UPLINK, @@ -1215,10 +1220,10 @@ void nas::send_detach_request(bool switch_off) usim->get_imsi_vec(detach_request.eps_mobile_id.imsi, 15); nas_log->info("Requesting IMSI detach (IMSI=%s)\n", usim->get_imsi_str().c_str()); liblte_mme_pack_detach_request_msg(&detach_request, LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT *) pdu); - } - if(pcap != NULL) { - pcap->write_nas(pdu->msg, pdu->N_bytes); + if(pcap != NULL) { + pcap->write_nas(pdu->msg, pdu->N_bytes); + } } nas_log->info("Sending detach request\n"); @@ -1236,12 +1241,17 @@ void nas::send_detach_accept() LIBLTE_MME_DETACH_ACCEPT_MSG_STRUCT detach_accept; bzero(&detach_accept, sizeof(detach_accept)); liblte_mme_pack_detach_accept_msg(&detach_accept, - LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY, + LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT *) pdu); - // Add MAC + if(pcap != NULL) { + pcap->write_nas(pdu->msg, pdu->N_bytes); + } + + // Encrypt and add MAC if (pdu->N_bytes > 5) { + cipher_encrypt(pdu); integrity_generate(&k_nas_int[16], ctxt.tx_count, SECURITY_DIRECTION_UPLINK, @@ -1252,10 +1262,6 @@ void nas::send_detach_accept() nas_log->error("Invalid PDU size %d\n", pdu->N_bytes); } - if(pcap != NULL) { - pcap->write_nas(pdu->msg, pdu->N_bytes); - } - nas_log->info("Sending detach accept\n"); rrc->write_sdu(cfg.lcid, pdu); } From f56592b0fe5f50b7b42fa9b874f236bad35186fe Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 8 Aug 2018 16:03:17 +0200 Subject: [PATCH 86/88] add getter for PDCP ul/dl counter --- lib/include/srslte/interfaces/ue_interfaces.h | 2 ++ lib/include/srslte/upper/pdcp.h | 2 ++ lib/include/srslte/upper/pdcp_entity.h | 2 ++ lib/include/srslte/upper/pdcp_interface.h | 2 ++ lib/src/upper/pdcp.cc | 23 +++++++++++++++++++ lib/src/upper/pdcp_entity.cc | 11 +++++++++ 6 files changed, 42 insertions(+) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 0caa68d94..959635afc 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -251,6 +251,8 @@ public: srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) = 0; virtual void enable_integrity(uint32_t lcid) = 0; virtual void enable_encryption(uint32_t lcid) = 0; + virtual uint32_t get_dl_count(uint32_t lcid) = 0; + virtual uint32_t get_ul_count(uint32_t lcid) = 0; }; // PDCP interface for RLC diff --git a/lib/include/srslte/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index f1e02400a..e4be9d548 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -72,6 +72,8 @@ public: INTEGRITY_ALGORITHM_ID_ENUM integ_algo); void enable_integrity(uint32_t lcid); void enable_encryption(uint32_t lcid); + uint32_t get_dl_count(uint32_t lcid); + uint32_t get_ul_count(uint32_t lcid); // RLC interface void write_pdu(uint32_t lcid, byte_buffer_t *sdu); diff --git a/lib/include/srslte/upper/pdcp_entity.h b/lib/include/srslte/upper/pdcp_entity.h index fd69c92e9..aea49462c 100644 --- a/lib/include/srslte/upper/pdcp_entity.h +++ b/lib/include/srslte/upper/pdcp_entity.h @@ -83,6 +83,8 @@ public: INTEGRITY_ALGORITHM_ID_ENUM integ_algo_); void enable_integrity(); void enable_encryption(); + uint32_t get_dl_count(); + uint32_t get_ul_count(); // RLC interface void write_pdu(byte_buffer_t *pdu); diff --git a/lib/include/srslte/upper/pdcp_interface.h b/lib/include/srslte/upper/pdcp_interface.h index 0c2cb2428..9c4df085e 100644 --- a/lib/include/srslte/upper/pdcp_interface.h +++ b/lib/include/srslte/upper/pdcp_interface.h @@ -62,6 +62,8 @@ public: INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) = 0; virtual void enable_integrity() = 0; virtual void enable_encryption() = 0; + virtual uint32_t get_dl_count() = 0; + virtual uint32_t get_ul_count() = 0; // RLC interface virtual void write_pdu(byte_buffer_t *pdu) = 0; diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index a73b44283..c8391518b 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -231,6 +231,29 @@ void pdcp::enable_encryption(uint32_t lcid) pthread_rwlock_unlock(&rwlock); } +uint32_t pdcp::get_dl_count(uint32_t lcid) +{ + int ret = 0; + pthread_rwlock_rdlock(&rwlock); + if (valid_lcid(lcid)) { + ret = pdcp_array.at(lcid)->get_dl_count(); + } + pthread_rwlock_unlock(&rwlock); + return ret; +} + +uint32_t pdcp::get_ul_count(uint32_t lcid) +{ + int ret = 0; + pthread_rwlock_rdlock(&rwlock); + if (valid_lcid(lcid)) { + ret = pdcp_array.at(lcid)->get_ul_count(); + } + pthread_rwlock_unlock(&rwlock); + return ret; +} + + /******************************************************************************* RLC interface *******************************************************************************/ diff --git a/lib/src/upper/pdcp_entity.cc b/lib/src/upper/pdcp_entity.cc index 412937069..65bb07fae 100644 --- a/lib/src/upper/pdcp_entity.cc +++ b/lib/src/upper/pdcp_entity.cc @@ -408,6 +408,17 @@ uint8_t pdcp_entity::get_bearer_id(uint8_t lcid) } +uint32_t pdcp_entity::get_dl_count() +{ + return rx_count; +} + + +uint32_t pdcp_entity::get_ul_count() +{ + return tx_count; +} + /**************************************************************************** * Pack/Unpack helper functions * Ref: 3GPP TS 36.323 v10.1.0 From 9cd725de211bb3da5d93a1a6ac7065e5971fc615 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 9 Aug 2018 12:18:03 +0200 Subject: [PATCH 87/88] Trigger measurement only for cells in MeasObj not the discovered ones --- srsue/hdr/upper/rrc.h | 3 ++- srsue/src/upper/rrc.cc | 26 +++++++++++++------------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index e4d06eb1f..93f162755 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -479,7 +479,8 @@ private: typedef struct { uint32_t earfcn; float q_offset; - std::map cells; + std::map meas_cells; + std::map found_cells; } meas_obj_t; typedef struct { diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 1b2d2607d..65d492fda 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -32,7 +32,7 @@ #include #include // for printing uint64_t #include -#include +#include "srsue/hdr/upper/rrc.h" #include "srslte/asn1/liblte_rrc.h" #include "srslte/common/security.h" #include "srslte/common/bcd_helpers.h" @@ -2846,9 +2846,9 @@ void rrc::rrc_meas::new_phy_meas(uint32_t earfcn, uint32_t pci, float rsrp, floa if (objects[m->object_id].earfcn == earfcn) { // If it's a newly discovered cell, add it to objects if (!m->cell_values.count(pci)) { - uint32_t cell_idx = objects[m->object_id].cells.size(); - objects[m->object_id].cells[cell_idx].pci = pci; - objects[m->object_id].cells[cell_idx].q_offset = 0; + uint32_t cell_idx = objects[m->object_id].found_cells.size(); + objects[m->object_id].found_cells[cell_idx].pci = pci; + objects[m->object_id].found_cells[cell_idx].q_offset = 0; } // Update or add cell L3_filter(&m->cell_values[pci], values); @@ -2886,7 +2886,7 @@ bool rrc::rrc_meas::find_earfcn_cell(uint32_t earfcn, uint32_t pci, meas_obj_t * if (object) { *object = &obj->second; } - for (std::map::iterator c = obj->second.cells.begin(); c != obj->second.cells.end(); ++c) { + for (std::map::iterator c = obj->second.found_cells.begin(); c != obj->second.found_cells.end(); ++c) { if (c->second.pci == pci) { if (cell_idx) { *cell_idx = c->first; @@ -3012,7 +3012,7 @@ void rrc::rrc_meas::calculate_triggers(uint32_t tti) if (find_earfcn_cell(phy->get_current_earfcn(), phy->get_current_pci(), &serving_object, &serving_cell_idx)) { Ofp = serving_object->q_offset; if (serving_cell_idx >= 0) { - Ocp = serving_object->cells[serving_cell_idx].q_offset; + Ocp = serving_object->found_cells[serving_cell_idx].q_offset; } } else { log_h->warning("Can't find current eafcn=%d, pci=%d in objects list. Using Ofp=0, Ocp=0\n", @@ -3057,7 +3057,7 @@ void rrc::rrc_meas::calculate_triggers(uint32_t tti) // Rest are evaluated for every cell in frequency } else { meas_obj_t *obj = &objects[m->second.object_id]; - for (std::map::iterator cell = obj->cells.begin(); cell != obj->cells.end(); ++cell) { + for (std::map::iterator cell = obj->found_cells.begin(); cell != obj->found_cells.end(); ++cell) { if (m->second.cell_values.count(cell->second.pci)) { float Ofn = obj->q_offset; float Ocn = cell->second.q_offset; @@ -3214,18 +3214,18 @@ bool rrc::rrc_meas::parse_meas_config(LIBLTE_RRC_MEAS_CONFIG_STRUCT *cfg) if (src_obj->black_cells_to_remove_list_present) { for (uint32_t j=0;jblack_cells_to_remove_list.N_cell_idx;j++) { - dst_obj->cells.erase(src_obj->black_cells_to_remove_list.cell_idx[j]); + dst_obj->meas_cells.erase(src_obj->black_cells_to_remove_list.cell_idx[j]); } } for (uint32_t j=0;jN_cells_to_add_mod;j++) { - dst_obj->cells[src_obj->cells_to_add_mod_list[j].cell_idx].q_offset = liblte_rrc_q_offset_range_num[src_obj->cells_to_add_mod_list[j].cell_offset]; - dst_obj->cells[src_obj->cells_to_add_mod_list[j].cell_idx].pci = src_obj->cells_to_add_mod_list[j].pci; + dst_obj->meas_cells[src_obj->cells_to_add_mod_list[j].cell_idx].q_offset = liblte_rrc_q_offset_range_num[src_obj->cells_to_add_mod_list[j].cell_offset]; + dst_obj->meas_cells[src_obj->cells_to_add_mod_list[j].cell_idx].pci = src_obj->cells_to_add_mod_list[j].pci; log_h->info("MEAS: Added measObjectId=%d, earfcn=%d, q_offset=%f, pci=%d, offset_cell=%f\n", cfg->meas_obj_to_add_mod_list.meas_obj_list[i].meas_obj_id, dst_obj->earfcn, dst_obj->q_offset, - dst_obj->cells[src_obj->cells_to_add_mod_list[j].cell_idx].pci, - dst_obj->cells[src_obj->cells_to_add_mod_list[j].cell_idx].q_offset); + dst_obj->meas_cells[src_obj->cells_to_add_mod_list[j].cell_idx].pci, + dst_obj->meas_cells[src_obj->cells_to_add_mod_list[j].cell_idx].q_offset); } @@ -3353,7 +3353,7 @@ void rrc::rrc_meas::update_phy() meas_obj_t o = objects[m.object_id]; // Instruct PHY to look for neighbour cells on this frequency phy->meas_start(o.earfcn); - for(std::map::iterator iter=o.cells.begin(); iter!=o.cells.end(); ++iter) { + for(std::map::iterator iter=o.meas_cells.begin(); iter!=o.meas_cells.end(); ++iter) { // Instruct PHY to look for cells IDs on this frequency phy->meas_start(o.earfcn, iter->second.pci); } From 44dcbfc8da8779e9e393b249375c66889c3a2806 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 10 Aug 2018 20:05:59 +0200 Subject: [PATCH 88/88] Instruct PHY to measure objects instead of measId (duplicate objects) --- srsue/src/upper/rrc.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 65d492fda..968aac735 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -3348,9 +3348,8 @@ bool rrc::rrc_meas::parse_meas_config(LIBLTE_RRC_MEAS_CONFIG_STRUCT *cfg) void rrc::rrc_meas::update_phy() { phy->meas_reset(); - for(std::map::iterator iter=active.begin(); iter!=active.end(); ++iter) { - meas_t m = iter->second; - meas_obj_t o = objects[m.object_id]; + for(std::map::iterator iter=objects.begin(); iter!=objects.end(); ++iter) { + meas_obj_t o = iter->second; // Instruct PHY to look for neighbour cells on this frequency phy->meas_start(o.earfcn); for(std::map::iterator iter=o.meas_cells.begin(); iter!=o.meas_cells.end(); ++iter) {