From 6745eced497befc766c9421551c21e0e447439d3 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 6 Sep 2021 21:30:40 +0200 Subject: [PATCH 01/47] ssb: avoid NaN when SSB can't be detected when PSS+SSS can't be detected the RSRP was 0 and the resulting conversion to dB resulted in NaN. --- lib/src/phy/sync/ssb.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/src/phy/sync/ssb.c b/lib/src/phy/sync/ssb.c index e79826d13..357ab7710 100644 --- a/lib/src/phy/sync/ssb.c +++ b/lib/src/phy/sync/ssb.c @@ -704,6 +704,11 @@ ssb_measure(srsran_ssb_t* q, const cf_t ssb_grid[SRSRAN_SSB_NOF_RE], uint32_t N_ float rsrp_sss = SRSRAN_CSQABS(corr_sss); float rsrp = (rsrp_pss + rsrp_sss) / 2.0f; + // avoid taking log of 0 (NaN) + if (rsrp == 0.0) { + rsrp = 1.0; + } + // Compute Noise float n0_pss = 1e-9; // Almost 0 float n0_sss = 1e-9; // Almost 0 From ba17b64c70d6a760cf1f8fc9a82a0bfbbd00b10e Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 6 Sep 2021 21:32:04 +0200 Subject: [PATCH 02/47] worker_pool: fix newline --- srsue/src/phy/nr/worker_pool.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsue/src/phy/nr/worker_pool.cc b/srsue/src/phy/nr/worker_pool.cc index d50bba912..1e6543636 100644 --- a/srsue/src/phy/nr/worker_pool.cc +++ b/srsue/src/phy/nr/worker_pool.cc @@ -191,6 +191,7 @@ void worker_pool::get_metrics(phy_metrics_t& m) { phy_state.get_metrics(m); } + int worker_pool::tx_request(const phy_interface_mac_nr::tx_request_t& request) { return 0; From 54ab64327a7e55b0689e61207a7a28a67680b8a5 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 6 Sep 2021 11:49:29 +0200 Subject: [PATCH 03/47] ue,mac_nr: move BSR levels lookup table into lib header prepare for shared use with gNB --- lib/include/srsran/mac/bsr_nr.h | 93 +++++++++++++++++++++++++++ srsue/hdr/stack/mac_nr/mux_nr.h | 2 +- srsue/hdr/stack/mac_nr/proc_bsr_nr.h | 8 +-- srsue/src/stack/mac_nr/mux_nr.cc | 6 +- srsue/src/stack/mac_nr/proc_bsr_nr.cc | 62 +----------------- 5 files changed, 101 insertions(+), 70 deletions(-) create mode 100644 lib/include/srsran/mac/bsr_nr.h diff --git a/lib/include/srsran/mac/bsr_nr.h b/lib/include/srsran/mac/bsr_nr.h new file mode 100644 index 000000000..a9922c442 --- /dev/null +++ b/lib/include/srsran/mac/bsr_nr.h @@ -0,0 +1,93 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#ifndef SRSRAN_BSR_NR_H +#define SRSRAN_BSR_NR_H + +#include + +/** + * @brief Buffer size format definition and levels according to 3GPP TS 38.321 version 15.3.0 + * + * Shared between UE and gNB MAC layers + */ + +namespace srsran { + +// TS 38.321 Sec 6.1.3.1 +typedef enum { SHORT_BSR, LONG_BSR, SHORT_TRUNC_BSR, LONG_TRUNC_BSR } bsr_format_nr_t; + +// TS 38.321, Table 6.1.3.1-1 Buffer size levels (in bytes) for 5-bit Buffer Size field, all values <= except marked +static const uint32_t buffer_size_levels_5bit_max_idx = 31; +static uint32_t buffer_size_levels_5bit[buffer_size_levels_5bit_max_idx + 1] = { + /* == */ 0, 10, 14, 20, 28, 38, 53, 74, 102, 142, 198, + 276, 384, 535, 745, 1038, 1446, 2014, 2806, 3909, 5446, 7587, + 10570, 14726, 20516, 28581, 39818, 55474, 77284, 107669, 150000, /* > */ 150000}; + +// TS 38.321, Table 6.1.3.1-2: Buffer size levels (in bytes) for 8-bit Buffer Size field, all values <= except marked +static const uint32_t buffer_size_levels_8bit_max_idx = 254; +static uint32_t buffer_size_levels_8bit[buffer_size_levels_8bit_max_idx + 1] = { + /* == */ 0, 10, 11, 12, 13, + 14, 15, 16, 17, 18, + 19, 20, 22, 23, 25, + 26, 28, 30, 32, 34, + 36, 38, 40, 43, 46, + 49, 52, 55, 59, 62, + 66, 71, 75, 80, 85, + 91, 97, 103, 110, 117, + 124, 132, 141, 150, 160, + 170, 181, 193, 205, 218, + 233, 248, 264, 281, 299, + 318, 339, 361, 384, 409, + 436, 464, 494, 526, 560, + 597, 635, 677, 720, 767, + 817, 870, 926, 987, 1051, + 1119, 1191, 1269, 1351, 1439, + 1532, 1631, 1737, 1850, 1970, + 2098, 2234, 2379, 2533, 2698, + 2873, 3059, 3258, 3469, 3694, + 3934, 4189, 4461, 4751, 5059, + 5387, 5737, 6109, 6506, 6928, + 7378, 7857, 8367, 8910, 9488, + 10104, 10760, 11458, 12202, 12994, + 13838, 14736, 15692, 16711, 17795, + 18951, 20181, 21491, 22885, 24371, + 25953, 27638, 29431, 31342, 33376, + 35543, 37850, 40307, 42923, 45709, + 48676, 51836, 55200, 58784, 62599, + 66663, 70990, 75598, 80505, 85730, + 91295, 97221, 103532, 110252, 117409, + 125030, 133146, 141789, 150992, 160793, + 171231, 182345, 194182, 206786, 220209, + 234503, 249725, 265935, 283197, 301579, + 321155, 342002, 364202, 387842, 413018, + 439827, 468377, 498780, 531156, 565634, + 602350, 641449, 683087, 727427, 774645, + 824928, 878475, 935498, 996222, 1060888, + 1129752, 1203085, 1281179, 1364342, 1452903, + 1547213, 1647644, 1754595, 1868488, 1989774, + 2118933, 2256475, 2402946, 2558924, 2725027, + 2901912, 3090279, 3290873, 3504487, 3731968, + 3974215, 4232186, 4506902, 4799451, 5110989, + 5442750, 5796046, 6172275, 6572925, 6999582, + 7453933, 7937777, 8453028, 9001725, 9586039, + 10208280, 10870913, 11576557, 12328006, 13128233, + 13980403, 14887889, 15854280, 16883401, 17979324, + 19146385, 20389201, 21712690, 23122088, 24622972, + 26221280, 27923336, 29735875, 31666069, 33721553, + 35910462, 38241455, 40723756, 43367187, 46182206, + 49179951, 52372284, 55771835, 59392055, 63247269, + 67352729, 71724679, 76380419, 81338368, /* > */ 81338368}; + +} // namespace srsran + +#endif // SRSRAN_BSR_NR_H diff --git a/srsue/hdr/stack/mac_nr/mux_nr.h b/srsue/hdr/stack/mac_nr/mux_nr.h index 18e5b3a6c..c4bf9e4d4 100644 --- a/srsue/hdr/stack/mac_nr/mux_nr.h +++ b/srsue/hdr/stack/mac_nr/mux_nr.h @@ -47,7 +47,7 @@ public: srsran::unique_byte_buffer_t get_pdu(uint32_t max_pdu_len); // Interface for BSR procedure - void generate_bsr_mac_ce(const bsr_interface_mux_nr::bsr_format_nr_t& format); + void generate_bsr_mac_ce(const srsran::bsr_format_nr_t& format); private: // internal helper methods diff --git a/srsue/hdr/stack/mac_nr/proc_bsr_nr.h b/srsue/hdr/stack/mac_nr/proc_bsr_nr.h index 162a661f6..da2e88c6f 100644 --- a/srsue/hdr/stack/mac_nr/proc_bsr_nr.h +++ b/srsue/hdr/stack/mac_nr/proc_bsr_nr.h @@ -18,6 +18,7 @@ #include "proc_sr_nr.h" #include "srsran/common/task_scheduler.h" +#include "srsran/mac/bsr_nr.h" #include "srsran/mac/mac_sch_pdu_nr.h" #include "srsran/srslog/srslog.h" #include "srsue/hdr/stack/mac_common/mac_common.h" @@ -32,9 +33,6 @@ class rlc_interface_mac; class bsr_interface_mux_nr { public: - // TS 38.321 Sec 6.1.3.1 - typedef enum { SHORT_BSR, LONG_BSR, SHORT_TRUNC_BSR, LONG_TRUNC_BSR } bsr_format_nr_t; - /// MUX calls BSR to receive the buffer state of a single LCG. virtual srsran::mac_sch_subpdu_nr::lcg_bsr_t generate_sbsr() = 0; }; @@ -43,7 +41,7 @@ class mux_interface_bsr_nr { public: /// Inform MUX unit to that a BSR needs to be generated in the next UL transmission. - virtual void generate_bsr_mac_ce(const bsr_interface_mux_nr::bsr_format_nr_t& format) = 0; + virtual void generate_bsr_mac_ce(const srsran::bsr_format_nr_t& format) = 0; }; /** @@ -101,7 +99,7 @@ private: bool check_new_data(const mac_buffer_states_t& new_buffer_state); bool check_any_channel(); - uint8_t buff_size_bytes_to_field(uint32_t buffer_size, bsr_format_nr_t format); + uint8_t buff_size_bytes_to_field(uint32_t buffer_size, srsran::bsr_format_nr_t format); uint32_t find_max_priority_lcg_with_data(); diff --git a/srsue/src/stack/mac_nr/mux_nr.cc b/srsue/src/stack/mac_nr/mux_nr.cc index dfe3ca7d8..6aab037e5 100644 --- a/srsue/src/stack/mac_nr/mux_nr.cc +++ b/srsue/src/stack/mac_nr/mux_nr.cc @@ -170,13 +170,13 @@ bool mux_nr::msg3_is_empty() return msg3_buff->N_bytes == 0; } -void mux_nr::generate_bsr_mac_ce(const bsr_interface_mux_nr::bsr_format_nr_t& format) +void mux_nr::generate_bsr_mac_ce(const srsran::bsr_format_nr_t& format) { switch (format) { - case bsr_interface_mux_nr::SHORT_BSR: + case srsran::SHORT_BSR: add_bsr_ce = sbsr_ce; break; - case bsr_interface_mux_nr::LONG_BSR: + case srsran::LONG_BSR: add_bsr_ce = lbsr_ce; default: logger.error("MUX can only be instructred to generate short or long BSRs."); diff --git a/srsue/src/stack/mac_nr/proc_bsr_nr.cc b/srsue/src/stack/mac_nr/proc_bsr_nr.cc index e0bbf6ce7..7cca98ede 100644 --- a/srsue/src/stack/mac_nr/proc_bsr_nr.cc +++ b/srsue/src/stack/mac_nr/proc_bsr_nr.cc @@ -16,67 +16,7 @@ namespace srsue { -// TS 38.321, Table 6.1.3.1-1 Buffer size levels (in bytes) for 5-bit Buffer Size field, all values <= except marked -static const uint32_t buffer_size_levels_5bit_max_idx = 31; -static uint32_t buffer_size_levels_5bit[buffer_size_levels_5bit_max_idx + 1] = { - /* == */ 0, 10, 14, 20, 28, 38, 53, 74, 102, 142, 198, - 276, 384, 535, 745, 1038, 1446, 2014, 2806, 3909, 5446, 7587, - 10570, 14726, 20516, 28581, 39818, 55474, 77284, 107669, 150000, /* > */ 150000}; - -// TS 38.321, Table 6.1.3.1-2: Buffer size levels (in bytes) for 8-bit Buffer Size field, all values <= except marked -static const uint32_t buffer_size_levels_8bit_max_idx = 254; -static uint32_t buffer_size_levels_8bit[buffer_size_levels_8bit_max_idx + 1] = { - /* == */ 0, 10, 11, 12, 13, - 14, 15, 16, 17, 18, - 19, 20, 22, 23, 25, - 26, 28, 30, 32, 34, - 36, 38, 40, 43, 46, - 49, 52, 55, 59, 62, - 66, 71, 75, 80, 85, - 91, 97, 103, 110, 117, - 124, 132, 141, 150, 160, - 170, 181, 193, 205, 218, - 233, 248, 264, 281, 299, - 318, 339, 361, 384, 409, - 436, 464, 494, 526, 560, - 597, 635, 677, 720, 767, - 817, 870, 926, 987, 1051, - 1119, 1191, 1269, 1351, 1439, - 1532, 1631, 1737, 1850, 1970, - 2098, 2234, 2379, 2533, 2698, - 2873, 3059, 3258, 3469, 3694, - 3934, 4189, 4461, 4751, 5059, - 5387, 5737, 6109, 6506, 6928, - 7378, 7857, 8367, 8910, 9488, - 10104, 10760, 11458, 12202, 12994, - 13838, 14736, 15692, 16711, 17795, - 18951, 20181, 21491, 22885, 24371, - 25953, 27638, 29431, 31342, 33376, - 35543, 37850, 40307, 42923, 45709, - 48676, 51836, 55200, 58784, 62599, - 66663, 70990, 75598, 80505, 85730, - 91295, 97221, 103532, 110252, 117409, - 125030, 133146, 141789, 150992, 160793, - 171231, 182345, 194182, 206786, 220209, - 234503, 249725, 265935, 283197, 301579, - 321155, 342002, 364202, 387842, 413018, - 439827, 468377, 498780, 531156, 565634, - 602350, 641449, 683087, 727427, 774645, - 824928, 878475, 935498, 996222, 1060888, - 1129752, 1203085, 1281179, 1364342, 1452903, - 1547213, 1647644, 1754595, 1868488, 1989774, - 2118933, 2256475, 2402946, 2558924, 2725027, - 2901912, 3090279, 3290873, 3504487, 3731968, - 3974215, 4232186, 4506902, 4799451, 5110989, - 5442750, 5796046, 6172275, 6572925, 6999582, - 7453933, 7937777, 8453028, 9001725, 9586039, - 10208280, 10870913, 11576557, 12328006, 13128233, - 13980403, 14887889, 15854280, 16883401, 17979324, - 19146385, 20389201, 21712690, 23122088, 24622972, - 26221280, 27923336, 29735875, 31666069, 33721553, - 35910462, 38241455, 40723756, 43367187, 46182206, - 49179951, 52372284, 55771835, 59392055, 63247269, - 67352729, 71724679, 76380419, 81338368, /* > */ 81338368}; +using namespace srsran; int32_t proc_bsr_nr::init(proc_sr_nr* sr_, mux_interface_bsr_nr* mux_, From aba0ba9ad8b7df054a882ab87471b6014b7ae89f Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 6 Sep 2021 12:22:18 +0200 Subject: [PATCH 04/47] mac_sch_pdu_nr: fix newline in logs --- lib/src/mac/mac_sch_pdu_nr.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/mac/mac_sch_pdu_nr.cc b/lib/src/mac/mac_sch_pdu_nr.cc index 432f9e1ea..268e8ebd8 100644 --- a/lib/src/mac/mac_sch_pdu_nr.cc +++ b/lib/src/mac/mac_sch_pdu_nr.cc @@ -359,7 +359,7 @@ int mac_sch_pdu_nr::unpack(const uint8_t* payload, const uint32_t& len) while (offset < len) { mac_sch_subpdu_nr sch_pdu(this); if (sch_pdu.read_subheader(payload + offset) == SRSRAN_ERROR) { - logger.error("Malformed MAC PDU (len=%d, offset=%d)\n", len, offset); + logger.error("Malformed MAC PDU (len=%d, offset=%d)", len, offset); return SRSRAN_ERROR; } offset += sch_pdu.get_total_length(); @@ -372,7 +372,7 @@ int mac_sch_pdu_nr::unpack(const uint8_t* payload, const uint32_t& len) subpdus.push_back(sch_pdu); } if (offset != len) { - logger.error("Malformed MAC PDU (len=%d, offset=%d)\n", len, offset); + logger.error("Malformed MAC PDU (len=%d, offset=%d)", len, offset); return SRSRAN_ERROR; } From f7e943b6b61aeec84d1d5c52ab1920e83f9f2a6b Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 6 Sep 2021 12:22:45 +0200 Subject: [PATCH 05/47] enb,mac_nr: add handling of SBSR MAC CE --- srsenb/hdr/stack/mac/nr/ue_nr.h | 4 +++ srsenb/src/stack/mac/nr/ue_nr.cc | 52 +++++++++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/ue_nr.h b/srsenb/hdr/stack/mac/nr/ue_nr.h index 7a4b0e254..b6923a434 100644 --- a/srsenb/hdr/stack/mac/nr/ue_nr.h +++ b/srsenb/hdr/stack/mac/nr/ue_nr.h @@ -18,6 +18,7 @@ #include "srsran/common/block_queue.h" #include "srsran/common/interfaces_common.h" #include "srsran/interfaces/enb_rlc_interfaces.h" +#include "srsran/mac/bsr_nr.h" #include "srsran/mac/mac_sch_pdu_nr.h" #include #include @@ -64,6 +65,9 @@ public: uint32_t read_pdu(uint32_t lcid, uint8_t* payload, uint32_t requested_bytes) final; private: + // helper methods + uint32_t buff_size_field_to_bytes(uint32_t buff_size_index, const srsran::bsr_format_nr_t& format); + rlc_interface_mac* rlc = nullptr; rrc_interface_mac_nr* rrc = nullptr; phy_interface_stack_nr* phy = nullptr; diff --git a/srsenb/src/stack/mac/nr/ue_nr.cc b/srsenb/src/stack/mac/nr/ue_nr.cc index f6a534598..5342c27c7 100644 --- a/srsenb/src/stack/mac/nr/ue_nr.cc +++ b/srsenb/src/stack/mac/nr/ue_nr.cc @@ -96,13 +96,20 @@ int ue_nr::process_pdu(srsran::unique_byte_buffer_t pdu) } } break; case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::SHORT_BSR: - logger.info("SHORT_BSR CE not implemented."); - break; + case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::SHORT_TRUNC_BSR: { + srsran::mac_sch_subpdu_nr::lcg_bsr_t sbsr = subpdu.get_sbsr(); + uint32_t buffer_size_bytes = buff_size_field_to_bytes(sbsr.buffer_size, srsran::SHORT_BSR); + // FIXME: a UE might send a zero BSR but still needs an UL grant to finish RA procedure + if (buffer_size_bytes == 0) { + buffer_size_bytes++; + } + sched->ul_bsr(rnti, sbsr.lcg_id, buffer_size_bytes); + } break; case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::LONG_BSR: logger.info("LONG_BSR CE not implemented."); break; - case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::SHORT_TRUNC_BSR: - logger.info("SHORT_TRUNC_BSR CE not implemented."); + case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::LONG_TRUNC_BSR: + logger.info("LONG_TRUNC_BSR CE not implemented."); break; default: if (subpdu.is_sdu()) { @@ -210,4 +217,41 @@ void ue_nr::metrics_cnt() ue_metrics.nof_tti++; } +/** Converts the buffer size field of a BSR (5 or 8-bit Buffer Size field) into Bytes + * @param buff_size_field The buffer size field contained in the MAC PDU + * @param format The BSR format that determines the buffer size field length + * @return uint32_t The actual buffer size level in Bytes + */ +uint32_t ue_nr::buff_size_field_to_bytes(uint32_t buff_size_index, const srsran::bsr_format_nr_t& format) +{ + using namespace srsran; + + // early exit + if (buff_size_index == 0) { + return 0; + } + + const uint32_t max_offset = 1; // make the reported value bigger than the 2nd biggest + + switch (format) { + case SHORT_BSR: + case SHORT_TRUNC_BSR: + if (buff_size_index >= buffer_size_levels_5bit_max_idx) { + return buffer_size_levels_5bit[buffer_size_levels_5bit_max_idx] + max_offset; + } else { + return buffer_size_levels_5bit[buff_size_index]; + } + break; + case LONG_BSR: + case LONG_TRUNC_BSR: + if (buff_size_index > buffer_size_levels_8bit_max_idx) { + return buffer_size_levels_8bit[buffer_size_levels_8bit_max_idx] + max_offset; + } else { + return buffer_size_levels_8bit[buff_size_index]; + } + break; + } + return 0; +} + } // namespace srsenb From 5a936d9940fda0d60641b4cfc3d2d9b93b2709f2 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 6 Sep 2021 12:48:37 +0200 Subject: [PATCH 06/47] ue,rrc: handle DRB removal correctly when RRC receives a command to remove a DRB, it also needs to delete the bearer at RLC and PDCP --- srsue/hdr/stack/rrc/rrc.h | 1 + srsue/src/stack/rrc/rrc.cc | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/srsue/hdr/stack/rrc/rrc.h b/srsue/hdr/stack/rrc/rrc.h index c33c837cf..b7ebe69e4 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -383,6 +383,7 @@ private: void add_srb(const asn1::rrc::srb_to_add_mod_s& srb_cnfg); void add_drb(const asn1::rrc::drb_to_add_mod_s& drb_cnfg); void release_drb(uint32_t drb_id); + uint32_t get_lcid_for_drb_id(const uint32_t& drb_id); uint32_t get_lcid_for_eps_bearer(const uint32_t& eps_bearer_id); uint32_t get_drb_id_for_eps_bearer(const uint32_t& eps_bearer_id); uint32_t get_eps_bearer_id_for_drb_id(const uint32_t& drb_id); diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index 6ddf107eb..03d1d6843 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -2756,6 +2756,13 @@ void rrc::release_drb(uint32_t drb_id) { if (drbs.find(drb_id) != drbs.end()) { logger.info("Releasing DRB Id %d", drb_id); + + // remvove RLC and PDCP for this LCID + uint32_t lcid = get_lcid_for_drb_id(drb_id); + rlc->del_bearer(lcid); + pdcp->del_bearer(lcid); + // TODO: implement bearer removal at MAC + // remove EPS bearer associated with this DRB from Stack (GW will trigger service request if needed) stack->remove_eps_bearer(get_eps_bearer_id_for_drb_id(drb_id)); drbs.erase(drb_id); @@ -2764,6 +2771,26 @@ void rrc::release_drb(uint32_t drb_id) } } +/** + * @brief check if this DRB id exists and return it's LCID + * + * if the DRB couldn't be found, 0 is returned. This is an invalid + * LCID for DRB and the caller should handle it. + */ +uint32_t rrc::get_lcid_for_drb_id(const uint32_t& drb_id) +{ + uint32_t lcid = 0; + if (drbs.find(drb_id) != drbs.end()) { + asn1::rrc::drb_to_add_mod_s drb_cnfg = drbs[drb_id]; + if (drb_cnfg.lc_ch_id_present) { + lcid = drb_cnfg.lc_ch_id; + } else { + lcid = srsran::MAX_LTE_SRB_ID + drb_cnfg.drb_id; + } + } + return lcid; +} + uint32_t rrc::get_lcid_for_eps_bearer(const uint32_t& eps_bearer_id) { // check if this bearer id exists and return it's LCID From c1892eb2ec03f0b602233c738cc6117eecaff4ce Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 6 Sep 2021 17:05:01 +0200 Subject: [PATCH 07/47] enb,nsa: refactor of SgNB addition interface * update of FSM * better integration of parameter for X2 calls --- .../srsran/interfaces/enb_rrc_interfaces.h | 36 +++++-- srsenb/hdr/stack/rrc/rrc.h | 6 +- srsenb/hdr/stack/rrc/rrc_endc.h | 95 +++++++++++-------- srsenb/hdr/stack/rrc/rrc_nr.h | 10 +- srsenb/src/stack/rrc/rrc.cc | 16 ++-- srsenb/src/stack/rrc/rrc_endc.cc | 62 ++++++------ srsenb/src/stack/rrc/rrc_nr.cc | 46 +++++---- srsenb/src/stack/rrc/rrc_ue.cc | 4 +- 8 files changed, 163 insertions(+), 112 deletions(-) diff --git a/lib/include/srsran/interfaces/enb_rrc_interfaces.h b/lib/include/srsran/interfaces/enb_rrc_interfaces.h index 85f961080..e1ac72d33 100644 --- a/lib/include/srsran/interfaces/enb_rrc_interfaces.h +++ b/lib/include/srsran/interfaces/enb_rrc_interfaces.h @@ -126,8 +126,15 @@ public: class rrc_nr_interface_rrc { public: - /// Request addition of NR carrier for UE (TODO: add configuration check, QCI, security, etc.) - virtual int sgnb_addition_request(uint16_t eutra_rnti) = 0; + struct sgnb_addition_req_params_t { + uint32_t eps_bearer_id; + // add configuration check + // E-RAB Parameters, Tunnel address (IP address, TEID) + // QCI, security, etc + }; + + /// Request addition of NR carrier for UE + virtual int sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params) = 0; /// Provide information whether the requested configuration was applied successfully by the UE virtual int sgnb_reconfiguration_complete(uint16_t eutra_rnti, asn1::dyn_octstring reconfig_response) = 0; @@ -137,16 +144,26 @@ public: class rrc_eutra_interface_rrc_nr { public: + /** + * @brief List of parameters included in the SgNB addition Ack message + * @param nr_secondary_cell_group_cfg_r15 Encoded part of the RRC Reconfiguration + * @param nr_radio_bearer_cfg1_r15 Encoded part of the RRC Reconfiguration + * @param eps_bearer_id ID of the transfered bearer + */ + struct sgnb_addition_ack_params_t { + uint16_t nr_rnti = SRSRAN_INVALID_RNTI; // RNTI that was assigned to the UE + asn1::dyn_octstring nr_secondary_cell_group_cfg_r15; + asn1::dyn_octstring nr_radio_bearer_cfg1_r15; + uint32_t eps_bearer_id = 0; // (list of) successfully transfered EPS bearers + }; + /** * @brief Signal successful addition of UE * * @param eutra_rnti The RNTI that the EUTRA RRC used to request the SgNB addition - * @param nr_secondary_cell_group_cfg_r15 Encoded part of the RRC Reconfiguration - * @param nr_radio_bearer_cfg1_r15 Encoded part of the RRC Reconfiguration + * @param params Parameter list */ - virtual void sgnb_addition_ack(uint16_t eutra_rnti, - const asn1::dyn_octstring& nr_secondary_cell_group_cfg_r15, - const asn1::dyn_octstring& nr_radio_bearer_cfg1_r15) = 0; + virtual void sgnb_addition_ack(uint16_t eutra_rnti, sgnb_addition_ack_params_t params) = 0; /** * @brief Signal unsuccessful SgNB addition @@ -158,9 +175,10 @@ public: /** * @brief Signal completion of SgNB addition after UE (with new NR identity) has attached * - * @param nr_rnti The RNTI that the EUTRA RRC used to request the SgNB addition + * @param eutra_rnti The RNTI that the EUTRA RRC used to request the SgNB addition + * @param nr_rnti The RNTI that has been assigned to the UE on the SgNB */ - virtual void sgnb_addition_complete(uint16_t eutra_rnti) = 0; + virtual void sgnb_addition_complete(uint16_t eutra_rnti, uint16_t nr_rnti) = 0; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/rrc/rrc.h b/srsenb/hdr/stack/rrc/rrc.h index a9f038c12..332ef793e 100644 --- a/srsenb/hdr/stack/rrc/rrc.h +++ b/srsenb/hdr/stack/rrc/rrc.h @@ -127,11 +127,9 @@ public: int notify_ue_erab_updates(uint16_t rnti, srsran::const_byte_span nas_pdu) override; // rrc_eutra_interface_rrc_nr - void sgnb_addition_ack(uint16_t eutra_rnti, - const asn1::dyn_octstring& nr_secondary_cell_group_cfg_r15, - const asn1::dyn_octstring& nr_radio_bearer_cfg1_r15) override; + void sgnb_addition_ack(uint16_t eutra_rnti, const sgnb_addition_ack_params_t params) override; void sgnb_addition_reject(uint16_t eutra_rnti) override; - void sgnb_addition_complete(uint16_t eutra_rnti) override; + void sgnb_addition_complete(uint16_t eutra_rnti, uint16_t nr_rnti) override; // rrc_interface_pdcp void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) override; diff --git a/srsenb/hdr/stack/rrc/rrc_endc.h b/srsenb/hdr/stack/rrc/rrc_endc.h index c33c9752c..842367d88 100644 --- a/srsenb/hdr/stack/rrc/rrc_endc.h +++ b/srsenb/hdr/stack/rrc/rrc_endc.h @@ -29,15 +29,23 @@ namespace srsenb { class rrc::ue::rrc_endc : public srsran::fsm_t { public: - // public events - struct user_crnti_upd_ev { - uint16_t crnti; - uint16_t temp_crnti; + // public events called from EUTRA-RRC + struct sgnb_add_req_sent_ev {}; + + /// called when 5G RRC accepted new user + struct sgnb_add_req_ack_ev { + sgnb_addition_ack_params_t params; }; - struct ho_cancel_ev { - asn1::s1ap::cause_c cause; - ho_cancel_ev(const asn1::s1ap::cause_c& cause_) : cause(cause_) {} + struct sgnb_add_req_reject_ev {}; + + /** + * @brief Non-standard event sent from NR-RRC to EUTRA when UE has attached to NR cell + * + * sent after Reconfig complete and contention resolution on NR side + */ + struct sgnb_add_complete_ev { + uint16_t nr_rnti; /// RNTI assigned to UE on NR carrier }; rrc_endc(srsenb::rrc::ue* outer_ue); @@ -45,17 +53,14 @@ public: bool fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn_recfg); void handle_eutra_capabilities(const asn1::rrc::ue_eutra_cap_s& eutra_caps); void handle_ue_meas_report(const asn1::rrc::meas_report_s& msg); - void handle_sgnb_addition_ack(const asn1::dyn_octstring& nr_secondary_cell_group_cfg_r15, - const asn1::dyn_octstring& nr_radio_bearer_cfg1_r15); - void handle_sgnb_addition_reject(); - void handle_sgnb_addition_complete(); + bool is_endc_supported(); private: // Send SgNB addition request to gNB bool start_sgnb_addition(); - bool is_endc_activation_running() const { return not is_in_state(); } + bool is_endc_activation_running() const { return not is_in_state(); } rrc::ue* rrc_ue = nullptr; rrc* rrc_enb = nullptr; @@ -65,51 +70,57 @@ private: bool endc_supported = false; asn1::rrc::rrc_conn_recfg_complete_s pending_recfg_complete; - // temporary storage for NR reconfiguration - asn1::dyn_octstring nr_secondary_cell_group_cfg_r15; - asn1::dyn_octstring nr_radio_bearer_cfg1_r15; + // fixed ENDC variables + const uint32_t eutra_drb_id = 1; // The DRB ID that converted to NR + const uint32_t lcid_drb_nr = 4; - // events - struct sgnb_add_req_sent_ev {}; - struct sgnb_add_req_ack_ev {}; - struct sgnb_add_req_reject_ev {}; + // internal events struct rrc_recfg_sent_ev {}; - struct prach_nr_received_ev {}; - - using recfg_complete_ev = asn1::rrc::rrc_conn_recfg_complete_s; - using status_transfer_ev = asn1::s1ap::bearers_subject_to_status_transfer_list_l; // states - struct idle_st {}; - struct wait_sgnb_add_req_resp {}; - struct prepare_recfg {}; - struct wait_recfg_comp {}; - struct wait_prach_nr {}; + struct endc_deactivated_st {}; // initial state where user is served over EUTRA only + struct wait_sgnb_add_req_resp_st {}; + struct prepare_recfg_st { + sgnb_addition_ack_params_t sgnb_config; // Store NR cell group config, etc. + + void enter(rrc_endc* f, const sgnb_add_req_ack_ev& ev); + + explicit prepare_recfg_st(rrc_endc* parent_); + + private: + srslog::basic_logger& logger; + }; + struct wait_add_complete_st {}; // user needs to complete RA procedure and send C-RNTI CE + struct endc_activated_st {}; // user has enabled EN-DC successfully and is currently served // FSM guards // FSM transition handlers - void handle_recfg_complete(wait_recfg_comp& s, const recfg_complete_ev& ev); - void handle_sgnb_addition_request_sent(const sgnb_add_req_sent_ev& ev); + void handle_sgnb_add_req_ack(wait_sgnb_add_req_resp_st& s, const sgnb_add_req_ack_ev& ev); protected: // states - state_list - states{this, idle_st{}, wait_sgnb_add_req_resp{}, prepare_recfg{}, wait_recfg_comp{}, wait_prach_nr{}}; + state_list + states{this, + endc_deactivated_st{}, + wait_sgnb_add_req_resp_st{}, + prepare_recfg_st{this}, + wait_add_complete_st{}, + endc_activated_st{}}; // transitions using fsm = rrc_endc; // clang-format off - using transitions = transition_table< - // Start Target Event Action Guard - // +-----------------------+-----------------------+------------------------+----------------------------+-------------------------+ - row< idle_st, wait_sgnb_add_req_resp, sgnb_add_req_sent_ev, nullptr >, - // +-----------------------+-----------------------+------------------------+----------------------------+-------------------------+ - row< wait_sgnb_add_req_resp, prepare_recfg, sgnb_add_req_ack_ev >, - row< wait_sgnb_add_req_resp, idle_st, sgnb_add_req_reject_ev >, - row< prepare_recfg, wait_recfg_comp, rrc_recfg_sent_ev >, - row< wait_recfg_comp, idle_st, recfg_complete_ev, &fsm::handle_recfg_complete > - // +-----------------------+-----------------------+------------------------+----------------------------+-------------------------+ + using transitions = transition_table< + // Start Target Event Action Guard + // +---------------------------+--------------------------+------------------------+------------------------------+-------------------------+ + row< endc_deactivated_st, wait_sgnb_add_req_resp_st, sgnb_add_req_sent_ev, nullptr >, + // +---------------------------+--------------------------+------------------------+------------------------------+-------------------------+ + row< wait_sgnb_add_req_resp_st, prepare_recfg_st, sgnb_add_req_ack_ev, &fsm::handle_sgnb_add_req_ack >, + row< wait_sgnb_add_req_resp_st, endc_deactivated_st, sgnb_add_req_reject_ev >, + row< prepare_recfg_st, wait_add_complete_st, rrc_recfg_sent_ev >, + row< wait_add_complete_st, endc_activated_st, sgnb_add_complete_ev > + // +---------------------------+--------------------------+------------------------+------------------------------+-------------------------+ >; // clang-format on }; diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index e1b73269b..5b3200edc 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -81,7 +81,7 @@ public: void notify_pdcp_integrity_error(uint16_t rnti, uint32_t lcid) final; // Interface for EUTRA RRC - int sgnb_addition_request(uint16_t rnti); + int sgnb_addition_request(uint16_t rnti, const sgnb_addition_req_params_t& params); int sgnb_reconfiguration_complete(uint16_t rnti, asn1::dyn_octstring reconfig_response); // Interfaces for NGAP @@ -99,12 +99,14 @@ public: void send_connection_setup(); void send_dl_ccch(asn1::rrc_nr::dl_ccch_msg_s* dl_dcch_msg); - int handle_sgnb_addition_request(uint16_t eutra_rnti); + int handle_sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params); + void crnti_ce_received(); // getters bool is_connected() { return state == rrc_nr_state_t::RRC_CONNECTED; } bool is_idle() { return state == rrc_nr_state_t::RRC_IDLE; } bool is_inactive() { return state == rrc_nr_state_t::RRC_INACTIVE; } + bool is_endc() { return endc; } // setters @@ -129,6 +131,10 @@ public: asn1::rrc_nr::radio_bearer_cfg_s radio_bearer_cfg; const uint32_t drb1_lcid = 4; + + // NSA specific variables + bool endc = false; + uint16_t eutra_rnti = SRSRAN_INVALID_RNTI; }; private: diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index bc61d1bd5..0097f8aca 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -559,12 +559,10 @@ void rrc::set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_st EN-DC/NSA helper functions *******************************************************************************/ -void rrc::sgnb_addition_ack(uint16_t eutra_rnti, - const asn1::dyn_octstring& nr_secondary_cell_group_cfg_r15, - const asn1::dyn_octstring& nr_radio_bearer_cfg1_r15) +void rrc::sgnb_addition_ack(uint16_t eutra_rnti, sgnb_addition_ack_params_t params) { - users.at(eutra_rnti) - ->endc_handler->handle_sgnb_addition_ack(nr_secondary_cell_group_cfg_r15, nr_radio_bearer_cfg1_r15); + logger.info("Received SgNB addition acknowledgement for rnti=%d", eutra_rnti); + users.at(eutra_rnti)->endc_handler->trigger(ue::rrc_endc::sgnb_add_req_ack_ev{params}); // trigger RRC Reconfiguration to send NR config to UE users.at(eutra_rnti)->send_connection_reconf(); @@ -572,12 +570,14 @@ void rrc::sgnb_addition_ack(uint16_t eutra_rnti, void rrc::sgnb_addition_reject(uint16_t eutra_rnti) { - users.at(eutra_rnti)->endc_handler->handle_sgnb_addition_reject(); + logger.error("Received SgNB addition reject for rnti=%d", eutra_rnti); + users.at(eutra_rnti)->endc_handler->trigger(ue::rrc_endc::sgnb_add_req_reject_ev{}); } -void rrc::sgnb_addition_complete(uint16_t eutra_rnti) +void rrc::sgnb_addition_complete(uint16_t eutra_rnti, uint16_t nr_rnti) { - users.at(eutra_rnti)->endc_handler->handle_sgnb_addition_complete(); + logger.info("User rnti=0x%x successfully enabled EN-DC", eutra_rnti); + users.at(eutra_rnti)->endc_handler->trigger(ue::rrc_endc::sgnb_add_complete_ev{nr_rnti}); } /******************************************************************************* diff --git a/srsenb/src/stack/rrc/rrc_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index da4f2d883..4b16ca61b 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -124,7 +124,7 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn meas_cfg.meas_gap_cfg_present = true; meas_cfg.meas_gap_cfg.set_setup(); meas_cfg.meas_gap_cfg.setup().gap_offset.set_gp0() = 16; - } else if (is_in_state()) { + } else if (is_in_state()) { // FIXME: use bearer manager to remove EUTRA DRB conn_recfg->rr_cfg_ded.drb_to_release_list_present = true; conn_recfg->rr_cfg_ded.drb_to_release_list.resize(1); @@ -148,13 +148,14 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn reconf_v1510.nr_cfg_r15.setup().endc_release_and_add_r15 = false; reconf_v1510.nr_cfg_r15.setup().nr_secondary_cell_group_cfg_r15_present = true; - reconf_v1510.nr_cfg_r15.setup().nr_secondary_cell_group_cfg_r15 = nr_secondary_cell_group_cfg_r15; + reconf_v1510.nr_cfg_r15.setup().nr_secondary_cell_group_cfg_r15 = + get_state()->sgnb_config.nr_secondary_cell_group_cfg_r15; reconf_v1510.sk_counter_r15_present = true; reconf_v1510.sk_counter_r15 = 0; reconf_v1510.nr_radio_bearer_cfg1_r15_present = true; - reconf_v1510.nr_radio_bearer_cfg1_r15 = nr_radio_bearer_cfg1_r15; + reconf_v1510.nr_radio_bearer_cfg1_r15 = get_state()->sgnb_config.nr_radio_bearer_cfg1_r15; // inform FSM rrc_recfg_sent_ev recfg_sent{}; @@ -225,7 +226,7 @@ void rrc::ue::rrc_endc::handle_ue_meas_report(const meas_report_s& msg) return; } - if (not is_in_state()) { + if (not is_in_state()) { Info("Received a MeasReport while already enabling ENDC support. Ignoring..."); return; } @@ -242,45 +243,48 @@ void rrc::ue::rrc_endc::handle_ue_meas_report(const meas_report_s& msg) return; } - // Start EN-DC activation + // Start EN-DC activation using EPS bearer of EUTRA DRB1 + rrc_nr_interface_rrc::sgnb_addition_req_params_t params = {}; + params.eps_bearer_id = + rrc_enb->bearer_manager.get_lcid_bearer(rrc_ue->rnti, drb_to_lcid((lte_drb)eutra_drb_id)).eps_bearer_id; logger.info("Triggering SgNB addition"); - rrc_enb->rrc_nr->sgnb_addition_request(rrc_ue->rnti); + rrc_enb->rrc_nr->sgnb_addition_request(rrc_ue->rnti, params); sgnb_add_req_sent_ev sgnb_add_req{}; trigger(sgnb_add_req); } -void rrc::ue::rrc_endc::handle_sgnb_addition_ack(const asn1::dyn_octstring& nr_secondary_cell_group_cfg_r15_, - const asn1::dyn_octstring& nr_radio_bearer_cfg1_r15_) -{ - logger.info("Received SgNB addition acknowledgement for rnti=%d", rrc_ue->rnti); +rrc::ue::rrc_endc::prepare_recfg_st::prepare_recfg_st(rrc_endc* parent_) : logger(parent_->logger) {} - // store received configurations - nr_secondary_cell_group_cfg_r15 = nr_secondary_cell_group_cfg_r15_; - nr_radio_bearer_cfg1_r15 = nr_radio_bearer_cfg1_r15_; +void rrc::ue::rrc_endc::prepare_recfg_st::enter(rrc_endc* f, const sgnb_add_req_ack_ev& ev) +{ + // store SgNB provided config + sgnb_config = ev.params; - logger.debug(nr_secondary_cell_group_cfg_r15.data(), - nr_secondary_cell_group_cfg_r15.size(), + logger.debug(sgnb_config.nr_secondary_cell_group_cfg_r15.data(), + sgnb_config.nr_secondary_cell_group_cfg_r15.size(), "nr-SecondaryCellGroupConfig-r15:"); - logger.debug(nr_radio_bearer_cfg1_r15.data(), nr_radio_bearer_cfg1_r15.size(), "nr-RadioBearerConfig1-r15:"); - - sgnb_add_req_ack_ev sgnb_add_ack{}; - trigger(sgnb_add_ack); + logger.debug(sgnb_config.nr_radio_bearer_cfg1_r15.data(), + sgnb_config.nr_radio_bearer_cfg1_r15.size(), + "nr-RadioBearerConfig1-r15:"); } -void rrc::ue::rrc_endc::handle_sgnb_addition_reject() +// The gNB has accepted the SgNB addition and has already allocated the user and established all bearers +void rrc::ue::rrc_endc::handle_sgnb_add_req_ack(wait_sgnb_add_req_resp_st& s, const sgnb_add_req_ack_ev& ev) { - logger.error("Received SgNB addition reject for rnti=%d", rrc_ue->rnti); -} + // TODO: copy buffered PDCP data to SeNB -void rrc::ue::rrc_endc::handle_recfg_complete(wait_recfg_comp& s, const recfg_complete_ev& ev) -{ - logger.info("User rnti=0x%x successfully enabled EN-DC", rrc_ue->rnti); -} + // TODO: path update procedure with GTPU modify bearer request (for mode 3A and 3X) -void rrc::ue::rrc_endc::handle_sgnb_addition_complete() -{ - logger.info("Received SgNB addition complete for rnti=%d", rrc_ue->rnti); + // delete EPS bearer mapping over EUTRA PDCP + rrc_enb->bearer_manager.remove_eps_bearer(rrc_ue->rnti, ev.params.eps_bearer_id); + + // re-register EPS bearer over NR PDCP + rrc_enb->bearer_manager.add_eps_bearer( + ev.params.nr_rnti, ev.params.eps_bearer_id, srsran::srsran_rat_t::nr, lcid_drb_nr); + + // change GTPU tunnel RNTI to match NR RNTI + rrc_enb->gtpu->mod_bearer_rnti(rrc_ue->rnti, ev.params.nr_rnti); } bool rrc::ue::rrc_endc::is_endc_supported() diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 8a6623d13..1e8180951 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -186,11 +186,9 @@ int rrc_nr::update_user(uint16_t new_rnti, uint16_t old_rnti) } ue* ue_ptr = old_it->second.get(); - // Assume that SgNB addition is running logger.info("Resuming rnti=0x%x RRC connection due to received C-RNTI CE from rnti=0x%x.", old_rnti, new_rnti); - if (ue_ptr->is_connected()) { - rrc_eutra->sgnb_addition_complete(new_rnti); - } + ue_ptr->crnti_ce_received(); + return SRSRAN_SUCCESS; } @@ -404,9 +402,9 @@ void rrc_nr::write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) {} Interface for EUTRA RRC *******************************************************************************/ -int rrc_nr::sgnb_addition_request(uint16_t eutra_rnti) +int rrc_nr::sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params) { - task_sched.defer_task([this, eutra_rnti]() { + task_sched.defer_task([this, eutra_rnti, params]() { // try to allocate new user uint16_t nr_rnti = mac->reserve_rnti(0); if (nr_rnti == SRSRAN_INVALID_RNTI) { @@ -427,7 +425,7 @@ int rrc_nr::sgnb_addition_request(uint16_t eutra_rnti) logger.warning("Unrecognised rnti: 0x%x", nr_rnti); return; } - user_it->second->handle_sgnb_addition_request(eutra_rnti); + user_it->second->handle_sgnb_addition_request(eutra_rnti, params); }); // return straight away @@ -436,6 +434,8 @@ int rrc_nr::sgnb_addition_request(uint16_t eutra_rnti) int rrc_nr::sgnb_reconfiguration_complete(uint16_t eutra_rnti, asn1::dyn_octstring reconfig_response) { + // user has completeted the reconfiguration and has acked on 4G side, wait until RA on NR + logger.info("Received Reconfiguration complete for RNTI=0x%x", eutra_rnti); return SRSRAN_SUCCESS; } @@ -1101,36 +1101,50 @@ int rrc_nr::ue::pack_nr_radio_bearer_config(asn1::dyn_octstring& packed_nr_beare return SRSRAN_SUCCESS; } -int rrc_nr::ue::handle_sgnb_addition_request(uint16_t eutra_rnti) +int rrc_nr::ue::handle_sgnb_addition_request(uint16_t eutra_rnti_, const sgnb_addition_req_params_t& req_params) { // Add DRB1 to RLC and PDCP if (add_drb() != SRSRAN_SUCCESS) { parent->logger.error("Failed to configure DRB"); - parent->rrc_eutra->sgnb_addition_reject(eutra_rnti); + parent->rrc_eutra->sgnb_addition_reject(eutra_rnti_); return SRSRAN_ERROR; } // provide hard-coded NR configs - asn1::dyn_octstring nr_secondary_cell_group_cfg; - if (pack_rrc_reconfiguraiton(nr_secondary_cell_group_cfg) == SRSRAN_ERROR) { + rrc_eutra_interface_rrc_nr::sgnb_addition_ack_params_t ack_params = {}; + if (pack_rrc_reconfiguraiton(ack_params.nr_secondary_cell_group_cfg_r15) == SRSRAN_ERROR) { parent->logger.error("Failed to pack RRC Reconfiguration. Sending SgNB addition reject."); - parent->rrc_eutra->sgnb_addition_reject(eutra_rnti); + parent->rrc_eutra->sgnb_addition_reject(eutra_rnti_); return SRSRAN_ERROR; } - asn1::dyn_octstring radio_bearer_config_buffer; - if (pack_nr_radio_bearer_config(radio_bearer_config_buffer) == SRSRAN_ERROR) { + if (pack_nr_radio_bearer_config(ack_params.nr_radio_bearer_cfg1_r15) == SRSRAN_ERROR) { parent->logger.error("Failed to pack NR radio bearer config. Sending SgNB addition reject."); - parent->rrc_eutra->sgnb_addition_reject(eutra_rnti); + parent->rrc_eutra->sgnb_addition_reject(eutra_rnti_); return SRSRAN_ERROR; } // send response to EUTRA - parent->rrc_eutra->sgnb_addition_ack(eutra_rnti, nr_secondary_cell_group_cfg, radio_bearer_config_buffer); + ack_params.nr_rnti = rnti; + ack_params.eps_bearer_id = req_params.eps_bearer_id; + parent->rrc_eutra->sgnb_addition_ack(eutra_rnti_, ack_params); + + // recognize RNTI as ENDC user + endc = true; + eutra_rnti = eutra_rnti_; return SRSRAN_SUCCESS; } +void rrc_nr::ue::crnti_ce_received() +{ + // Assume NSA mode active + if (endc) { + // send SgNB addition complete for ENDC users + parent->rrc_eutra->sgnb_addition_complete(eutra_rnti, rnti); + } +} + /** * @brief Set DRB configuration * diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 70dbb4d4f..b6510c7e7 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -396,7 +396,7 @@ void rrc::ue::parse_ul_dcch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) } else { parent->logger.warning("Received MeasReport but no mobility configuration is available"); } - if (endc_handler) { + if (endc_handler != nullptr) { endc_handler->handle_ue_meas_report(ul_dcch_msg.msg.c1().meas_report()); } break; @@ -1009,7 +1009,7 @@ int rrc::ue::handle_ue_cap_info(ue_cap_info_s* msg) parent->logger.info("UE rnti: 0x%x category: %d", rnti, eutra_capabilities.ue_category); - if (endc_handler) { + if (endc_handler != nullptr) { endc_handler->handle_eutra_capabilities(eutra_capabilities); } } From f814a0ed090b49c73fbf075722adfb54991b1e00 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 6 Sep 2021 17:06:12 +0200 Subject: [PATCH 08/47] ue_nr: reduction of log level when packing MAC PDU --- srsenb/src/stack/mac/nr/ue_nr.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsenb/src/stack/mac/nr/ue_nr.cc b/srsenb/src/stack/mac/nr/ue_nr.cc index 5342c27c7..ae45ba81d 100644 --- a/srsenb/src/stack/mac/nr/ue_nr.cc +++ b/srsenb/src/stack/mac/nr/ue_nr.cc @@ -141,9 +141,9 @@ int ue_nr::generate_pdu(srsran::byte_buffer_t* pdu, uint32_t grant_size) // Only create PDU if RLC has something to tx if (pdu_len > 0) { - logger.info("Adding MAC PDU for RNTI=%d", rnti); + logger.debug("Adding MAC PDU for RNTI=%d", rnti); ue_rlc_buffer->N_bytes = pdu_len; - logger.info(ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes, "Read %d B from RLC", ue_rlc_buffer->N_bytes); + logger.debug(ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes, "Read %d B from RLC", ue_rlc_buffer->N_bytes); // add to MAC PDU and pack mac_pdu_dl.add_sdu(lcid, ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes); From 312a91a460cd22c43af836b3c65d684b9ec270c9 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 6 Sep 2021 19:02:17 +0200 Subject: [PATCH 09/47] enb,rrc_nr: disable encryption for DRB --- srsenb/src/stack/rrc/rrc_nr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 1e8180951..82f480d29 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -1085,7 +1085,7 @@ int rrc_nr::ue::pack_nr_radio_bearer_config(asn1::dyn_octstring& packed_nr_beare sec_cfg.key_to_use_present = true; sec_cfg.key_to_use = asn1::rrc_nr::security_cfg_s::key_to_use_opts::secondary; sec_cfg.security_algorithm_cfg_present = true; - sec_cfg.security_algorithm_cfg.ciphering_algorithm = ciphering_algorithm_opts::nea2; + sec_cfg.security_algorithm_cfg.ciphering_algorithm = ciphering_algorithm_opts::nea0; // pack it packed_nr_bearer_config.resize(128); From a518b81a109b31f6ce3461ae7c059b8b9eb513b3 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 7 Sep 2021 15:03:22 +0200 Subject: [PATCH 10/47] phy,nr: don't print hex content of failed PDSCH --- srsue/src/phy/nr/cc_worker.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index 11478547f..5718639ab 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -294,7 +294,7 @@ bool cc_worker::decode_pdsch_dl() str_extra.data()); } else { logger.info(pdsch_res.tb[0].payload, - pdsch_cfg.grant.tb[0].tbs / 8, + pdsch_res.tb[0].crc ? pdsch_cfg.grant.tb[0].tbs / 8 : 0, "PDSCH: cc=%d pid=%d %s ack_tti_tx=%d", cc_idx, pid, From f382a7c7dbde92be8489c35c4aba35bd90fba8af Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 8 Sep 2021 10:33:52 +0200 Subject: [PATCH 11/47] Revert "ue,proc_ra_nr: add temporary flag to skip RAR reception" This reverts commit 28668aac343232d6121efa405ca6ef66f6685569. --- lib/include/srsran/interfaces/mac_interface_types.h | 2 -- srsue/hdr/stack/rrc/rrc_nr.h | 1 - srsue/src/main.cc | 1 - srsue/src/stack/mac_nr/proc_ra_nr.cc | 6 ------ srsue/src/stack/rrc/rrc_nr.cc | 1 - 5 files changed, 11 deletions(-) diff --git a/lib/include/srsran/interfaces/mac_interface_types.h b/lib/include/srsran/interfaces/mac_interface_types.h index 9aa6eee32..e5ec84609 100644 --- a/lib/include/srsran/interfaces/mac_interface_types.h +++ b/lib/include/srsran/interfaces/mac_interface_types.h @@ -131,7 +131,6 @@ struct rach_nr_cfg_t { uint32_t powerRampingStep; uint32_t ra_responseWindow; uint32_t ra_ContentionResolutionTimer; - bool skip_rar; rach_nr_cfg_t() { reset(); } void reset() @@ -141,7 +140,6 @@ struct rach_nr_cfg_t { powerRampingStep = 0; preambleTransMax = 0; ra_responseWindow = 0; - skip_rar = false; } }; diff --git a/srsue/hdr/stack/rrc/rrc_nr.h b/srsue/hdr/stack/rrc/rrc_nr.h index 6deec7583..642bdbf4f 100644 --- a/srsue/hdr/stack/rrc/rrc_nr.h +++ b/srsue/hdr/stack/rrc/rrc_nr.h @@ -42,7 +42,6 @@ struct rrc_nr_args_t { core_less_args_t coreless; uint32_t sim_nr_meas_pci; bool pdcp_short_sn_support; - bool skip_rar; std::string supported_bands_nr_str; std::vector supported_bands_nr; std::vector supported_bands_eutra; diff --git a/srsue/src/main.cc b/srsue/src/main.cc index e14ea853f..666ba2c6c 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -132,7 +132,6 @@ static int parse_args(all_args_t* args, int argc, char* argv[]) ("rrc.mbms_service_port", bpo::value(&args->stack.rrc.mbms_service_port)->default_value(4321), "Port of the MBMS service") ("rrc.nr_measurement_pci", bpo::value(&args->stack.rrc_nr.sim_nr_meas_pci)->default_value(500), "NR PCI for the simulated NR measurement") ("rrc.nr_short_sn_support", bpo::value(&args->stack.rrc_nr.pdcp_short_sn_support)->default_value(true), "Announce PDCP short SN support") - ("rrc.skip_nr_rar", bpo::value(&args->stack.rrc_nr.skip_rar)->default_value(false), "Whether to skip RAR reception (temporary feature)") ("nas.apn", bpo::value(&args->stack.nas.apn_name)->default_value(""), "Set Access Point Name (APN) for data services") ("nas.apn_protocol", bpo::value(&args->stack.nas.apn_protocol)->default_value(""), "Set Access Point Name (APN) protocol for data services") diff --git a/srsue/src/stack/mac_nr/proc_ra_nr.cc b/srsue/src/stack/mac_nr/proc_ra_nr.cc index abdb1eb60..4177df8b0 100644 --- a/srsue/src/stack/mac_nr/proc_ra_nr.cc +++ b/srsue/src/stack/mac_nr/proc_ra_nr.cc @@ -347,12 +347,6 @@ void proc_ra_nr::prach_sent(uint32_t tti, uint32_t s_id, uint32_t t_id, uint32_t ra_window_start = TTI_ADD(tti, 3); logger.debug("Calculated ra_window_start=%d, ra_window_length=%d", ra_window_start, ra_window_length); state = WAITING_FOR_RESPONSE_RECEPTION; - - if (rach_cfg.skip_rar) { - // temp hack for NSA eNB development - state = WAITING_FOR_COMPLETION; - ra_completion(); - } }); } diff --git a/srsue/src/stack/rrc/rrc_nr.cc b/srsue/src/stack/rrc/rrc_nr.cc index ab2f95577..d2e5ac402 100644 --- a/srsue/src/stack/rrc/rrc_nr.cc +++ b/srsue/src/stack/rrc/rrc_nr.cc @@ -918,7 +918,6 @@ bool rrc_nr::apply_ul_common_cfg(const asn1::rrc_nr::ul_cfg_common_s& ul_cfg_com if (ul_cfg_common.init_ul_bwp.rach_cfg_common_present) { if (ul_cfg_common.init_ul_bwp.rach_cfg_common.type() == setup_release_c::types_opts::setup) { rach_nr_cfg_t rach_nr_cfg = make_mac_rach_cfg(ul_cfg_common.init_ul_bwp.rach_cfg_common.setup()); - rach_nr_cfg.skip_rar = args.skip_rar; mac->set_config(rach_nr_cfg); // Make the RACH configuration for PHY From 5703752faa7798f6cf86dc7fa8642528744b46ec Mon Sep 17 00:00:00 2001 From: faluco Date: Fri, 10 Sep 2021 14:12:50 +0200 Subject: [PATCH 12/47] Fix a enb crash when no more users could be added into the bearer manager map. This was caused by not removing old user from the map, so add the code to cleanup the map on user removal. --- lib/src/common/bearer_manager.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/src/common/bearer_manager.cc b/lib/src/common/bearer_manager.cc index dbdd36f43..63cbbc92e 100644 --- a/lib/src/common/bearer_manager.cc +++ b/lib/src/common/bearer_manager.cc @@ -117,7 +117,11 @@ void enb_bearer_manager::add_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id, sr auto user_it = users_map.find(rnti); if (user_it == users_map.end()) { // add empty bearer map - auto p = users_map.insert(rnti, srsran::detail::ue_bearer_manager_impl{}); + auto p = users_map.insert(rnti, srsran::detail::ue_bearer_manager_impl{}); + if (!p) { + logger.error("Bearers: Unable to add a new bearer map for rnti=0x%x", rnti); + return; + } user_it = p.value(); } @@ -149,7 +153,14 @@ void enb_bearer_manager::remove_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id) void enb_bearer_manager::rem_user(uint16_t rnti) { + auto user_it = users_map.find(rnti); + if (user_it == users_map.end()) { + logger.error("Bearers: No EPS bearer registered for rnti=0x%x", rnti); + return; + } + logger.info("Bearers: Removed rnti=0x%x from EPS bearer manager", rnti); + users_map.erase(user_it); } bool enb_bearer_manager::has_active_radio_bearer(uint16_t rnti, uint32_t eps_bearer_id) From b5dcf7804c15c727c81f7725f8808211e3ba6e00 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 8 Sep 2021 12:40:08 +0200 Subject: [PATCH 13/47] enb,cfg: add new NR cell list to RR configuration parser --- srsenb/src/enb_cfg_parser.cc | 80 +++++++++++++++++++++++++++++------- srsenb/src/enb_cfg_parser.h | 16 +++++++- 2 files changed, 81 insertions(+), 15 deletions(-) diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 3c9436b47..8c379e5ed 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -741,16 +741,21 @@ int parse_rr(all_args_t* args_, rrc_cfg_t* rrc_cfg_) cqi_report_cnfg.add_field(new parser::field("simultaneousAckCQI", &rrc_cfg_->cqi_cfg.simultaneousAckCQI)); cqi_report_cnfg.add_field(new field_sf_mapping(rrc_cfg_->cqi_cfg.sf_mapping, &rrc_cfg_->cqi_cfg.nof_subframes, 1)); - /* RRC config section */ - parser::section rrc_cnfg("cell_list"); - rrc_cnfg.set_optional(&rrc_cfg_->meas_cfg_present); - rrc_cnfg.add_field(new rr_sections::cell_list_section(args_, rrc_cfg_)); + // EUTRA RRC and cell config section + parser::section cell_cnfg("cell_list"); + cell_cnfg.set_optional(&rrc_cfg_->meas_cfg_present); + cell_cnfg.add_field(new rr_sections::cell_list_section(args_, rrc_cfg_)); + + // NR RRC and cell config section + parser::section nr_cell_cnfg("nr_cell_list"); + nr_cell_cnfg.add_field(new rr_sections::nr_cell_list_section(args_, rrc_cfg_)); // Run parser with two sections parser p(args_->enb_files.rr_config); p.add_section(&mac_cnfg); p.add_section(&phy_cfg_); - p.add_section(&rrc_cnfg); + p.add_section(&cell_cnfg); + p.add_section(&nr_cell_cnfg); return p.parse(); } @@ -864,15 +869,7 @@ static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root) HANDLEPARSERCODE(parse_scell_list(cell_cfg, cellroot)); } - std::string type = "lte"; - if (cellroot.exists("type")) { - cellroot.lookupValue("type", type); - } - if (type == "lte") { - rrc_cfg->cell_list.push_back(cell_cfg); - } else if (type == "nr") { - rrc_cfg->cell_list_nr.push_back(cell_cfg); - } + rrc_cfg->cell_list.push_back(cell_cfg); } // Configuration check @@ -895,12 +892,67 @@ static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root) return SRSRAN_SUCCESS; } +static int parse_nr_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root) +{ + for (uint32_t n = 0; n < (uint32_t)root.getLength(); ++n) { + cell_cfg_t cell_cfg = {}; + auto& cellroot = root[n]; + + parse_opt_field(cell_cfg.rf_port, cellroot, "rf_port"); + HANDLEPARSERCODE(parse_required_field(cell_cfg.cell_id, cellroot, "cell_id")); + HANDLEPARSERCODE(parse_required_field(cell_cfg.tac, cellroot, "tac")); + HANDLEPARSERCODE(parse_required_field(cell_cfg.pci, cellroot, "pci")); + cell_cfg.pci = cell_cfg.pci % SRSRAN_NOF_NID_NR; + HANDLEPARSERCODE(parse_required_field(cell_cfg.dl_earfcn, cellroot, "dl_arfcn")); + // frequencies get derived from ARFCN + + // Add further cell-specific parameters + + rrc_cfg->cell_list_nr.push_back(cell_cfg); + } + + // Configuration check + for (auto it = rrc_cfg->cell_list_nr.begin(); it != rrc_cfg->cell_list_nr.end(); ++it) { + // check against NR cells + for (auto it2 = it + 1; it2 != rrc_cfg->cell_list_nr.end(); it2++) { + // Check RF port is not repeated + if (it->rf_port == it2->rf_port) { + ERROR("Repeated RF port for multiple cells"); + return SRSRAN_ERROR; + } + + // Check cell ID is not repeated + if (it->cell_id == it2->cell_id) { + ERROR("Repeated Cell identifier"); + return SRSRAN_ERROR; + } + } + + // also check RF port against EUTRA cells + for (auto it_eutra = rrc_cfg->cell_list.begin(); it_eutra != rrc_cfg->cell_list.end(); ++it_eutra) { + // Check RF port is not repeated + if (it->rf_port == it_eutra->rf_port) { + ERROR("Repeated RF port for multiple cells"); + return SRSRAN_ERROR; + } + } + } + + return SRSRAN_SUCCESS; +} + int cell_list_section::parse(libconfig::Setting& root) { HANDLEPARSERCODE(parse_cell_list(args, rrc_cfg, root)); return 0; } +int nr_cell_list_section::parse(libconfig::Setting& root) +{ + HANDLEPARSERCODE(parse_nr_cell_list(args, rrc_cfg, root)); + return 0; +} + } // namespace rr_sections namespace enb_conf_sections { diff --git a/srsenb/src/enb_cfg_parser.h b/srsenb/src/enb_cfg_parser.h index 6ea75ffa2..f8a9d9241 100644 --- a/srsenb/src/enb_cfg_parser.h +++ b/srsenb/src/enb_cfg_parser.h @@ -75,7 +75,21 @@ public: int parse(Setting& root) override; - const char* get_name() override { return "meas_cell_list"; } + const char* get_name() override { return "cell_list"; } + +private: + rrc_cfg_t* rrc_cfg; + all_args_t* args; +}; + +class nr_cell_list_section final : public parser::field_itf +{ +public: + explicit nr_cell_list_section(all_args_t* all_args_, rrc_cfg_t* rrc_cfg_) : args(all_args_), rrc_cfg(rrc_cfg_) {} + + int parse(Setting& root) override; + + const char* get_name() override { return "nr_cell_list"; } private: rrc_cfg_t* rrc_cfg; From 1f01e4be514a58143ce0ab22f547ba1d20c7925c Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 8 Sep 2021 12:40:41 +0200 Subject: [PATCH 14/47] rr.conf.example: add empty NR cell list to example --- srsenb/rr.conf.example | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/srsenb/rr.conf.example b/srsenb/rr.conf.example index 68b371d81..cfb984a7f 100644 --- a/srsenb/rr.conf.example +++ b/srsenb/rr.conf.example @@ -98,3 +98,8 @@ cell_list = } // Add here more cells ); + +nr_cell_list = +( + // no NR cells +); \ No newline at end of file From 93e1d7712d1071a5e0e964311276dfda611377a6 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 10 Sep 2021 13:52:22 +0200 Subject: [PATCH 15/47] enb,phy: add checks for invalid EARFCN and exit eNB if config is wrong --- lib/src/phy/common/phy_common.c | 4 ++++ srsenb/src/enb_cfg_parser.cc | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/lib/src/phy/common/phy_common.c b/lib/src/phy/common/phy_common.c index d96a49310..f5b5a8f05 100644 --- a/lib/src/phy/common/phy_common.c +++ b/lib/src/phy/common/phy_common.c @@ -653,6 +653,7 @@ uint8_t srsran_band_get_band(uint32_t dl_earfcn) uint32_t i = SRSRAN_NOF_LTE_BANDS - 1; if (dl_earfcn > lte_bands[i].dl_earfcn_offset) { ERROR("Invalid DL_EARFCN=%d", dl_earfcn); + return 0; } i--; while (i > 0 && lte_bands[i].dl_earfcn_offset > dl_earfcn) { @@ -666,6 +667,7 @@ double srsran_band_fd(uint32_t dl_earfcn) uint32_t i = SRSRAN_NOF_LTE_BANDS - 1; if (dl_earfcn > lte_bands[i].dl_earfcn_offset) { ERROR("Invalid DL_EARFCN=%d", dl_earfcn); + return 0; } i--; while (i > 0 && lte_bands[i].dl_earfcn_offset > dl_earfcn) { @@ -679,6 +681,7 @@ double srsran_band_fu(uint32_t ul_earfcn) uint32_t i = SRSRAN_NOF_LTE_BANDS - 1; if (ul_earfcn > lte_bands[i].ul_earfcn_offset) { ERROR("Invalid UL_EARFCN=%d", ul_earfcn); + return 0; } i--; while (i > 0 && (lte_bands[i].ul_earfcn_offset > ul_earfcn || lte_bands[i].ul_earfcn_offset == 0)) { @@ -692,6 +695,7 @@ uint32_t srsran_band_ul_earfcn(uint32_t dl_earfcn) uint32_t i = SRSRAN_NOF_LTE_BANDS - 1; if (dl_earfcn > lte_bands[i].dl_earfcn_offset) { ERROR("Invalid DL_EARFCN=%d", dl_earfcn); + return 0; } i--; while (i > 0 && lte_bands[i].dl_earfcn_offset > dl_earfcn) { diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 8c379e5ed..d7666ef84 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -1104,6 +1104,10 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_ phy_cell_cfg.dl_freq_hz = cfg.dl_freq_hz; } else { phy_cell_cfg.dl_freq_hz = 1e6 * srsran_band_fd(cfg.dl_earfcn); + if (phy_cell_cfg.dl_freq_hz == 0.0) { + ERROR("Couldn't derive DL frequency for EARFCN=%d", cfg.dl_earfcn); + return SRSRAN_ERROR; + } } if (cfg.ul_freq_hz > 0) { @@ -1113,6 +1117,10 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_ cfg.ul_earfcn = srsran_band_ul_earfcn(cfg.dl_earfcn); } phy_cell_cfg.ul_freq_hz = 1e6 * srsran_band_fu(cfg.ul_earfcn); + if (phy_cell_cfg.ul_freq_hz == 0.0) { + ERROR("Couldn't derive UL frequency for EARFCN=%d", cfg.ul_earfcn); + return SRSRAN_ERROR; + } } for (auto scell_it = cfg.scell_list.begin(); scell_it != cfg.scell_list.end();) { From dbbc621905e40c6b8e8024e1e1e537e2708c2860 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 10 Sep 2021 13:53:26 +0200 Subject: [PATCH 16/47] phy_common: fix PRB lookup for NR cells --- srsenb/hdr/phy/phy_common.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/srsenb/hdr/phy/phy_common.h b/srsenb/hdr/phy/phy_common.h index f5fe18c3a..1bc0b7a66 100644 --- a/srsenb/hdr/phy/phy_common.h +++ b/srsenb/hdr/phy/phy_common.h @@ -69,13 +69,20 @@ public: { uint32_t ret = 0; + if (cc_idx >= get_nof_carriers()) { + // invalid CC index + return ret; + } + if (cc_idx < cell_list_lte.size()) { ret = cell_list_lte[cc_idx].cell.nof_prb; - } else if (cc_idx == 1 && !cell_list_nr.empty()) { - // for basic NSA config return width of first NR carrier - ret = cell_list_nr[0].carrier.nof_prb; + } else if (cc_idx >= cell_list_lte.size()) { + // offset CC index by all LTE carriers + cc_idx -= cell_list_lte.size(); + if (cc_idx < cell_list_nr.size()) { + ret = cell_list_nr[cc_idx].carrier.nof_prb; + } } - return ret; }; uint32_t get_nof_ports(uint32_t cc_idx) From 69619d725a9d87a1b780f8754c1ba73379d960be Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 8 Sep 2021 23:13:27 +0200 Subject: [PATCH 17/47] band_helper: add helper to derive UL ARFCN from DL ARFCN --- lib/include/srsran/common/band_helper.h | 11 +++++++++++ lib/src/common/band_helper.cc | 20 +++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/include/srsran/common/band_helper.h b/lib/include/srsran/common/band_helper.h index 0ffde42c9..2779cf9c8 100644 --- a/lib/include/srsran/common/band_helper.h +++ b/lib/include/srsran/common/band_helper.h @@ -59,6 +59,17 @@ public: */ uint16_t get_band_from_dl_arfcn(uint32_t arfcn) const; + /** + * @brief Get the respective UL ARFCN of a DL ARFCN + * + * For paired spectrum (FDD) the function returns the respective ARFCN in the same band. + * For unparied spectrum (TDD) the function returns the same ARFCN. + * + * @param dl_arfcn The DL ARFCN + * @return uint32_t + */ + uint32_t get_ul_arfcn_from_dl_arfcn(uint32_t dl_arfcn) const; + /** * @brief Selects the SSB pattern case according to the band number and subcarrier spacing * @remark Described by TS 38.101-1 Table 5.4.3.3-1: Applicable SS raster entries per operating band diff --git a/lib/src/common/band_helper.cc b/lib/src/common/band_helper.cc index 5b760a480..b2ea0f925 100644 --- a/lib/src/common/band_helper.cc +++ b/lib/src/common/band_helper.cc @@ -32,7 +32,7 @@ double srsran_band_helper::nr_arfcn_to_freq(uint32_t nr_arfcn) return (params.F_REF_Offs_MHz * 1e6 + params.delta_F_global_kHz * (nr_arfcn - params.N_REF_Offs) * 1e3); } -// Implements 5.4.2.1 in TS 38.401 +// Implements 5.4.2.1 in TS 38.104 std::vector srsran_band_helper::get_bands_nr(uint32_t nr_arfcn, srsran_band_helper::delta_f_raster_t delta_f_raster) { @@ -79,6 +79,24 @@ uint16_t srsran_band_helper::get_band_from_dl_arfcn(uint32_t arfcn) const return UINT16_MAX; } +uint32_t srsran_band_helper::get_ul_arfcn_from_dl_arfcn(uint32_t dl_arfcn) const +{ + // return same ARFCN for TDD bands + if (get_duplex_mode(get_band_from_dl_arfcn(dl_arfcn)) == SRSRAN_DUPLEX_MODE_TDD) { + return dl_arfcn; + } + + // derive UL ARFCN for FDD bands + for (const auto& band : nr_band_table_fr1) { + if (band.band == get_band_from_dl_arfcn(dl_arfcn)) { + uint32_t offset = (dl_arfcn - band.dl_nref_first) / band.dl_nref_step; + return (band.ul_nref_first + offset * band.ul_nref_step); + } + } + + return UINT16_MAX; +} + srsran_ssb_patern_t srsran_band_helper::get_ssb_pattern(uint16_t band, srsran_subcarrier_spacing_t scs) const { // Look for the given band and SCS From 377eb52b86e9821298d4cdd659d4ce22a00abd61 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 8 Sep 2021 23:14:19 +0200 Subject: [PATCH 18/47] band_helper_test: add TC for band n5 --- lib/src/common/test/band_helper_test.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/src/common/test/band_helper_test.cc b/lib/src/common/test/band_helper_test.cc index 290129c17..bde96fd2b 100644 --- a/lib/src/common/test/band_helper_test.cc +++ b/lib/src/common/test/band_helper_test.cc @@ -33,6 +33,11 @@ int bands_test_nr() // b32 b75 TESTASSERT(bands.nr_arfcn_to_freq(290400) == 1452.0e6); TESTASSERT(bands.nr_arfcn_to_freq(294400) == 1472.0e6); + // b5 + TESTASSERT(bands.get_duplex_mode(5) == SRSRAN_DUPLEX_MODE_FDD); + TESTASSERT(bands.nr_arfcn_to_freq(176300) == 881.5e6); + TESTASSERT(bands.get_ul_arfcn_from_dl_arfcn(176300) == 167300); + TESTASSERT(bands.nr_arfcn_to_freq(167300) == 836.5e6); // b3 TESTASSERT(bands.nr_arfcn_to_freq(342000) == 1710.0e6); TESTASSERT(bands.nr_arfcn_to_freq(348000) == 1740.0e6); From d26a7e035081c786add3b3f9a64de4cccec60629 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 9 Sep 2021 18:17:29 +0200 Subject: [PATCH 19/47] band_helper: add helper to derive DL/UL freq from abs_freq_point calculate DL and UL freq in carrier struct based on given values --- lib/include/srsran/common/band_helper.h | 30 +++++++++++-- lib/src/common/band_helper.cc | 58 ++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/lib/include/srsran/common/band_helper.h b/lib/include/srsran/common/band_helper.h index 2779cf9c8..3053ed9bc 100644 --- a/lib/include/srsran/common/band_helper.h +++ b/lib/include/srsran/common/band_helper.h @@ -31,6 +31,9 @@ public: // Return frequency of given NR-ARFCN in Hz double nr_arfcn_to_freq(uint32_t nr_arfcn); + // Frequency in Hz to NR-ARFCN + uint32_t freq_to_nr_arfcn(double freq); + // Possible values of delta f_raster in Table 5.4.2.3-1 and Table 5.4.2.3-2 enum delta_f_raster_t { DEFAULT = 0, // for bands with 2 possible values for delta_f_raster (e.g. 15 and 30 kHz), the lower is chosen @@ -70,6 +73,16 @@ public: */ uint32_t get_ul_arfcn_from_dl_arfcn(uint32_t dl_arfcn) const; + /** + * @brief Compute the DL and UL center frequency for a NR carrier + * + * Results are stored inside the carrier struct. + * + * @param carrier Reference to a carrier struct including PRB, abs. frequency point A and carrier offset. + * @return int SRSRAN_SUCESS The center frequency + */ + int get_center_freq_from_abs_freq_point_a(srsran_carrier_nr_t& carrier); + /** * @brief Selects the SSB pattern case according to the band number and subcarrier spacing * @remark Described by TS 38.101-1 Table 5.4.3.3-1: Applicable SS raster entries per operating band @@ -165,25 +178,36 @@ private: }}; struct nr_raster_params { + double freq_range_start; + double freq_range_end; double delta_F_global_kHz; double F_REF_Offs_MHz; uint32_t N_REF_Offs; uint32_t N_REF_min; uint32_t N_REF_max; + + bool operator==(const nr_raster_params& rhs) const + { + return freq_range_start == rhs.freq_range_start && freq_range_end == rhs.freq_range_end && + delta_F_global_kHz == rhs.delta_F_global_kHz && F_REF_Offs_MHz == rhs.F_REF_Offs_MHz && + N_REF_Offs == rhs.N_REF_Offs && N_REF_min == rhs.N_REF_min && N_REF_max == rhs.N_REF_max; + } }; // Helper to calculate F_REF according to Table 5.4.2.1-1 nr_raster_params get_raster_params(uint32_t nr_arfcn); + nr_raster_params get_raster_params(double freq); + bool is_valid_raster_param(const nr_raster_params& raster); static const uint32_t max_nr_arfcn = 3279165; static constexpr std::array nr_fr_params = {{ // clang-format off // Frequency range 0 - 3000 MHz - {5, 0.0, 0, 0, 599999}, + {0, 3000, 5, 0.0, 0, 0, 599999}, // Frequency range 3000 - 24250 MHz - {15, 3000.0, 600000, 600000, 2016666}, + {3000, 24250, 15, 3000.0, 600000, 600000, 2016666}, // Frequency range 24250 - 100000 MHz - {60, 24250.08, 2016667, 2016667, max_nr_arfcn} + {24250, 100000, 60, 24250.08, 2016667, 2016667, max_nr_arfcn} // clang-format on }}; diff --git a/lib/src/common/band_helper.cc b/lib/src/common/band_helper.cc index b2ea0f925..8bfe06c0e 100644 --- a/lib/src/common/band_helper.cc +++ b/lib/src/common/band_helper.cc @@ -29,9 +29,21 @@ constexpr std::array srsran_band_helper::get_bands_nr(uint32_t nr_arfcn, srsran_band_helper::delta_f_raster_t delta_f_raster) @@ -94,7 +106,31 @@ uint32_t srsran_band_helper::get_ul_arfcn_from_dl_arfcn(uint32_t dl_arfcn) const } } - return UINT16_MAX; + return 0; +} + +int srsran_band_helper::get_center_freq_from_abs_freq_point_a(srsran_carrier_nr_t& carrier) +{ + // for FR1 unit of resources blocks for freq calc is always 180kHz regardless for actual SCS of carrier + // TODO: add offset_to_carrier + double abs_freq_point_a_freq = nr_arfcn_to_freq(carrier.absolute_frequency_point_a); + carrier.dl_center_freq = + abs_freq_point_a_freq + + (carrier.nof_prb / 2 * SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_t::srsran_subcarrier_spacing_15kHz) * + SRSRAN_NRE); + + // UL depends on duplex + if (get_duplex_mode(get_band_from_dl_arfcn(carrier.absolute_frequency_point_a)) == SRSRAN_DUPLEX_MODE_TDD) { + // TDD case + carrier.ul_center_freq = carrier.dl_center_freq; + } else { + // FDD case + uint32_t dl_arfcn = freq_to_nr_arfcn(carrier.dl_center_freq); + uint32_t ul_arfcn = get_ul_arfcn_from_dl_arfcn(dl_arfcn); + carrier.ul_center_freq = nr_arfcn_to_freq(ul_arfcn); + } + + return SRSRAN_SUCCESS; } srsran_ssb_patern_t srsran_band_helper::get_ssb_pattern(uint16_t band, srsran_subcarrier_spacing_t scs) const @@ -198,4 +234,24 @@ srsran_band_helper::nr_raster_params srsran_band_helper::get_raster_params(uint3 return {}; // return empty params } +srsran_band_helper::nr_raster_params srsran_band_helper::get_raster_params(double freq) +{ + for (auto& fr : nr_fr_params) { + if (freq >= fr.freq_range_start * 1e6 && freq <= fr.freq_range_end * 1e6) { + return fr; + } + } + return {}; // return empty params +} + +bool srsran_band_helper::is_valid_raster_param(const srsran_band_helper::nr_raster_params& raster) +{ + for (auto& fr : nr_fr_params) { + if (fr == raster) { + return true; + } + } + return false; +} + } // namespace srsran From 11af5662a7574bf832a08849d7e8fe2943093276 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 9 Sep 2021 18:18:52 +0200 Subject: [PATCH 20/47] band_helper_test: extend TC for band 5 FDD freq calcs --- lib/src/common/test/band_helper_test.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/src/common/test/band_helper_test.cc b/lib/src/common/test/band_helper_test.cc index bde96fd2b..a5c8165cd 100644 --- a/lib/src/common/test/band_helper_test.cc +++ b/lib/src/common/test/band_helper_test.cc @@ -36,8 +36,18 @@ int bands_test_nr() // b5 TESTASSERT(bands.get_duplex_mode(5) == SRSRAN_DUPLEX_MODE_FDD); TESTASSERT(bands.nr_arfcn_to_freq(176300) == 881.5e6); + TESTASSERT(bands.freq_to_nr_arfcn(881.5e6) == 176300); TESTASSERT(bands.get_ul_arfcn_from_dl_arfcn(176300) == 167300); TESTASSERT(bands.nr_arfcn_to_freq(167300) == 836.5e6); + + // check actual freqs for FDD carrier (example values are for 52 PRB) + srsran_carrier_nr_t carrier = {}; + carrier.absolute_frequency_point_a = 175364; + carrier.nof_prb = 52; + TESTASSERT(bands.get_center_freq_from_abs_freq_point_a(carrier) == SRSRAN_SUCCESS); + TESTASSERT(carrier.dl_center_freq == 881.5e6); + TESTASSERT(carrier.ul_center_freq == 836.5e6); + // b3 TESTASSERT(bands.nr_arfcn_to_freq(342000) == 1710.0e6); TESTASSERT(bands.nr_arfcn_to_freq(348000) == 1740.0e6); From 07019a5bd6318ac7b6f271ea2f852b42b3618624 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 10 Sep 2021 16:00:39 +0200 Subject: [PATCH 21/47] nr: refactor DL/UL frequency deriviation * add separate DL/UL freq point a in NR carrier struct * use freqInfoDL/freqInfoUL to get freq point a * simplify carrier tuning logic --- lib/include/srsran/common/band_helper.h | 31 +++++++++++------ lib/include/srsran/phy/common/phy_common_nr.h | 3 +- lib/src/asn1/rrc_nr_utils.cc | 12 ++++--- lib/src/common/band_helper.cc | 34 ++++++++----------- lib/src/common/phy_cfg_nr_default.cc | 28 +++++++-------- lib/src/common/test/band_helper_test.cc | 8 ++--- lib/src/phy/ch_estimation/test/csi_rs_test.c | 3 +- .../phy/ch_estimation/test/dmrs_pdsch_test.c | 3 +- lib/src/phy/phch/test/pdcch_nr_test.c | 3 +- lib/src/phy/phch/test/pdsch_nr_test.c | 3 +- lib/src/phy/phch/test/pucch_nr_test.c | 3 +- lib/src/phy/phch/test/pusch_nr_test.c | 3 +- lib/src/phy/phch/test/sch_nr_test.c | 3 +- lib/src/phy/ue/test/ue_dl_nr_file_test.c | 3 +- lib/test/phy/phy_dl_nr_test.c | 3 +- srsue/src/phy/nr/cc_worker.cc | 2 +- srsue/src/phy/nr/worker_pool.cc | 2 +- srsue/src/phy/phy.cc | 20 +++++------ srsue/src/stack/rrc/rrc_nr.cc | 27 ++++++++------- 19 files changed, 105 insertions(+), 89 deletions(-) diff --git a/lib/include/srsran/common/band_helper.h b/lib/include/srsran/common/band_helper.h index 3053ed9bc..7729dc34d 100644 --- a/lib/include/srsran/common/band_helper.h +++ b/lib/include/srsran/common/band_helper.h @@ -69,20 +69,10 @@ public: * For unparied spectrum (TDD) the function returns the same ARFCN. * * @param dl_arfcn The DL ARFCN - * @return uint32_t + * @return uint32_t the UL ARFCN */ uint32_t get_ul_arfcn_from_dl_arfcn(uint32_t dl_arfcn) const; - /** - * @brief Compute the DL and UL center frequency for a NR carrier - * - * Results are stored inside the carrier struct. - * - * @param carrier Reference to a carrier struct including PRB, abs. frequency point A and carrier offset. - * @return int SRSRAN_SUCESS The center frequency - */ - int get_center_freq_from_abs_freq_point_a(srsran_carrier_nr_t& carrier); - /** * @brief Selects the SSB pattern case according to the band number and subcarrier spacing * @remark Described by TS 38.101-1 Table 5.4.3.3-1: Applicable SS raster entries per operating band @@ -99,6 +89,22 @@ public: */ srsran_duplex_mode_t get_duplex_mode(uint16_t band) const; + /** + * @brief Compute the DL center frequency for a NR carrier + * + * @param carrier Const Reference to a carrier struct including PRB, abs. frequency point A and carrier offset. + * @return double Frequency in Hz + */ + double get_dl_center_freq(const srsran_carrier_nr_t& carrier); + + /** + * @brief Compute the UL center frequency for a NR carrier + * + * @param carrier Const Reference to a carrier struct including PRB, abs. frequency point A and carrier offset. + * @return double Frequency in Hz + */ + double get_ul_center_freq(const srsran_carrier_nr_t& carrier); + class sync_raster_t { protected: @@ -130,6 +136,9 @@ public: sync_raster_t get_sync_raster(uint16_t band, srsran_subcarrier_spacing_t scs) const; private: + // internal helper + double get_center_freq_from_abs_freq_point_a(uint32_t nof_prb, uint32_t freq_point_a_arfcn); + // Elements of TS 38.101-1 Table 5.2-1: NR operating bands in FR1 struct nr_operating_band { uint16_t band; diff --git a/lib/include/srsran/phy/common/phy_common_nr.h b/lib/include/srsran/phy/common/phy_common_nr.h index 7cd174c82..5f50e650f 100644 --- a/lib/include/srsran/phy/common/phy_common_nr.h +++ b/lib/include/srsran/phy/common/phy_common_nr.h @@ -363,7 +363,8 @@ typedef enum SRSRAN_API { typedef struct SRSRAN_API { uint32_t pci; uint32_t absolute_frequency_ssb; - uint32_t absolute_frequency_point_a; + uint32_t dl_absolute_frequency_point_a; + uint32_t ul_absolute_frequency_point_a; uint32_t offset_to_carrier; ///< Offset between point A and the lowest subcarrier of the lowest RB srsran_subcarrier_spacing_t scs; uint32_t nof_prb; ///< @brief See TS 38.101-1 Table 5.3.2-1 for more details diff --git a/lib/src/asn1/rrc_nr_utils.cc b/lib/src/asn1/rrc_nr_utils.cc index 7b44e9fba..32c386a74 100644 --- a/lib/src/asn1/rrc_nr_utils.cc +++ b/lib/src/asn1/rrc_nr_utils.cc @@ -1349,11 +1349,13 @@ bool make_phy_carrier_cfg(const freq_info_dl_s& asn1_freq_info_dl, srsran_carrie } // As the carrier structure requires parameters from different objects, set fields separately - out_carrier_nr->absolute_frequency_ssb = absolute_frequency_ssb; - out_carrier_nr->absolute_frequency_point_a = asn1_freq_info_dl.absolute_freq_point_a; - out_carrier_nr->offset_to_carrier = asn1_freq_info_dl.scs_specific_carrier_list[0].offset_to_carrier; - out_carrier_nr->nof_prb = asn1_freq_info_dl.scs_specific_carrier_list[0].carrier_bw; - out_carrier_nr->scs = scs; + out_carrier_nr->absolute_frequency_ssb = absolute_frequency_ssb; + out_carrier_nr->dl_absolute_frequency_point_a = asn1_freq_info_dl.absolute_freq_point_a; + out_carrier_nr->ul_absolute_frequency_point_a = + out_carrier_nr->dl_absolute_frequency_point_a; // needs to be updated for FDD + out_carrier_nr->offset_to_carrier = asn1_freq_info_dl.scs_specific_carrier_list[0].offset_to_carrier; + out_carrier_nr->nof_prb = asn1_freq_info_dl.scs_specific_carrier_list[0].carrier_bw; + out_carrier_nr->scs = scs; return true; } diff --git a/lib/src/common/band_helper.cc b/lib/src/common/band_helper.cc index 8bfe06c0e..ec31770a1 100644 --- a/lib/src/common/band_helper.cc +++ b/lib/src/common/band_helper.cc @@ -109,28 +109,24 @@ uint32_t srsran_band_helper::get_ul_arfcn_from_dl_arfcn(uint32_t dl_arfcn) const return 0; } -int srsran_band_helper::get_center_freq_from_abs_freq_point_a(srsran_carrier_nr_t& carrier) +double srsran_band_helper::get_dl_center_freq(const srsran_carrier_nr_t& carrier) +{ + return get_center_freq_from_abs_freq_point_a(carrier.nof_prb, carrier.dl_absolute_frequency_point_a); +} + +double srsran_band_helper::get_ul_center_freq(const srsran_carrier_nr_t& carrier) +{ + return get_center_freq_from_abs_freq_point_a(carrier.nof_prb, carrier.ul_absolute_frequency_point_a); +} + +double srsran_band_helper::get_center_freq_from_abs_freq_point_a(uint32_t nof_prb, uint32_t freq_point_a_arfcn) { // for FR1 unit of resources blocks for freq calc is always 180kHz regardless for actual SCS of carrier // TODO: add offset_to_carrier - double abs_freq_point_a_freq = nr_arfcn_to_freq(carrier.absolute_frequency_point_a); - carrier.dl_center_freq = - abs_freq_point_a_freq + - (carrier.nof_prb / 2 * SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_t::srsran_subcarrier_spacing_15kHz) * - SRSRAN_NRE); - - // UL depends on duplex - if (get_duplex_mode(get_band_from_dl_arfcn(carrier.absolute_frequency_point_a)) == SRSRAN_DUPLEX_MODE_TDD) { - // TDD case - carrier.ul_center_freq = carrier.dl_center_freq; - } else { - // FDD case - uint32_t dl_arfcn = freq_to_nr_arfcn(carrier.dl_center_freq); - uint32_t ul_arfcn = get_ul_arfcn_from_dl_arfcn(dl_arfcn); - carrier.ul_center_freq = nr_arfcn_to_freq(ul_arfcn); - } - - return SRSRAN_SUCCESS; + double abs_freq_point_a_freq = nr_arfcn_to_freq(freq_point_a_arfcn); + return abs_freq_point_a_freq + + (nof_prb / 2 * SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_t::srsran_subcarrier_spacing_15kHz) * + SRSRAN_NRE); } srsran_ssb_patern_t srsran_band_helper::get_ssb_pattern(uint16_t band, srsran_subcarrier_spacing_t scs) const diff --git a/lib/src/common/phy_cfg_nr_default.cc b/lib/src/common/phy_cfg_nr_default.cc index 034c0c5d1..370e5ca57 100644 --- a/lib/src/common/phy_cfg_nr_default.cc +++ b/lib/src/common/phy_cfg_nr_default.cc @@ -66,24 +66,24 @@ phy_cfg_nr_default_t::reference_cfg_t::reference_cfg_t(const std::string& args) void phy_cfg_nr_default_t::make_carrier_custom_10MHz(srsran_carrier_nr_t& carrier) { - carrier.nof_prb = 52; - carrier.max_mimo_layers = 1; - carrier.pci = 500; - carrier.absolute_frequency_point_a = 633928; - carrier.absolute_frequency_ssb = 634176; - carrier.offset_to_carrier = 0; - carrier.scs = srsran_subcarrier_spacing_15kHz; + carrier.nof_prb = 52; + carrier.max_mimo_layers = 1; + carrier.pci = 500; + carrier.dl_absolute_frequency_point_a = 633928; + carrier.absolute_frequency_ssb = 634176; + carrier.offset_to_carrier = 0; + carrier.scs = srsran_subcarrier_spacing_15kHz; } void phy_cfg_nr_default_t::make_carrier_custom_20MHz(srsran_carrier_nr_t& carrier) { - carrier.nof_prb = 106; - carrier.max_mimo_layers = 1; - carrier.pci = 500; - carrier.absolute_frequency_point_a = 633928; - carrier.absolute_frequency_ssb = 634176; - carrier.offset_to_carrier = 0; - carrier.scs = srsran_subcarrier_spacing_15kHz; + carrier.nof_prb = 106; + carrier.max_mimo_layers = 1; + carrier.pci = 500; + carrier.dl_absolute_frequency_point_a = 633928; + carrier.absolute_frequency_ssb = 634176; + carrier.offset_to_carrier = 0; + carrier.scs = srsran_subcarrier_spacing_15kHz; } void phy_cfg_nr_default_t::make_tdd_custom_6_4(srsran_tdd_config_nr_t& tdd) diff --git a/lib/src/common/test/band_helper_test.cc b/lib/src/common/test/band_helper_test.cc index a5c8165cd..d8ef68335 100644 --- a/lib/src/common/test/band_helper_test.cc +++ b/lib/src/common/test/band_helper_test.cc @@ -42,11 +42,11 @@ int bands_test_nr() // check actual freqs for FDD carrier (example values are for 52 PRB) srsran_carrier_nr_t carrier = {}; - carrier.absolute_frequency_point_a = 175364; + carrier.dl_absolute_frequency_point_a = 175364; + carrier.ul_absolute_frequency_point_a = 166364; carrier.nof_prb = 52; - TESTASSERT(bands.get_center_freq_from_abs_freq_point_a(carrier) == SRSRAN_SUCCESS); - TESTASSERT(carrier.dl_center_freq == 881.5e6); - TESTASSERT(carrier.ul_center_freq == 836.5e6); + TESTASSERT(bands.get_dl_center_freq(carrier) == 881.5e6); + TESTASSERT(bands.get_ul_center_freq(carrier) == 836.5e6); // b3 TESTASSERT(bands.nr_arfcn_to_freq(342000) == 1710.0e6); diff --git a/lib/src/phy/ch_estimation/test/csi_rs_test.c b/lib/src/phy/ch_estimation/test/csi_rs_test.c index cdd89f66c..e47514412 100644 --- a/lib/src/phy/ch_estimation/test/csi_rs_test.c +++ b/lib/src/phy/ch_estimation/test/csi_rs_test.c @@ -20,7 +20,8 @@ static srsran_carrier_nr_t carrier = { 1, // pci 0, // absolute_frequency_ssb - 0, // absolute_frequency_point_a + 0, // dl_absolute_frequency_point_a + 0, // ul_absolute_frequency_point_a 0, // offset_to_carrier srsran_subcarrier_spacing_15kHz, // scs 50, // nof_prb diff --git a/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c b/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c index 4a8b55b83..bc46780d3 100644 --- a/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c +++ b/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c @@ -23,7 +23,8 @@ static srsran_carrier_nr_t carrier = { 1, // pci 0, // absolute_frequency_ssb - 0, // absolute_frequency_point_a + 0, // dl_absolute_frequency_point_a + 0, // ul_absolute_frequency_point_a 0, // offset_to_carrier srsran_subcarrier_spacing_15kHz, // scs 50, // nof_prb diff --git a/lib/src/phy/phch/test/pdcch_nr_test.c b/lib/src/phy/phch/test/pdcch_nr_test.c index 52a799d2f..c5c212fad 100644 --- a/lib/src/phy/phch/test/pdcch_nr_test.c +++ b/lib/src/phy/phch/test/pdcch_nr_test.c @@ -18,7 +18,8 @@ static srsran_carrier_nr_t carrier = { 1, // pci 0, // absolute_frequency_ssb - 0, // absolute_frequency_point_a + 0, // dl_absolute_frequency_point_a + 0, // ul_absolute_frequency_point_a 0, // offset_to_carrier srsran_subcarrier_spacing_15kHz, // scs 50, // nof_prb diff --git a/lib/src/phy/phch/test/pdsch_nr_test.c b/lib/src/phy/phch/test/pdsch_nr_test.c index f353cf3f8..0ca921d49 100644 --- a/lib/src/phy/phch/test/pdsch_nr_test.c +++ b/lib/src/phy/phch/test/pdsch_nr_test.c @@ -23,7 +23,8 @@ static srsran_carrier_nr_t carrier = { 1, // pci 0, // absolute_frequency_ssb - 0, // absolute_frequency_point_a + 0, // dl_absolute_frequency_point_a + 0, // ul_absolute_frequency_point_a 0, // offset_to_carrier srsran_subcarrier_spacing_15kHz, // scs SRSRAN_MAX_PRB_NR, // nof_prb diff --git a/lib/src/phy/phch/test/pucch_nr_test.c b/lib/src/phy/phch/test/pucch_nr_test.c index 067c3b8ad..8a660d830 100644 --- a/lib/src/phy/phch/test/pucch_nr_test.c +++ b/lib/src/phy/phch/test/pucch_nr_test.c @@ -25,7 +25,8 @@ static srsran_carrier_nr_t carrier = { 1, // pci 0, // absolute_frequency_ssb - 0, // absolute_frequency_point_a + 0, // dl_absolute_frequency_point_a + 0, // ul_absolute_frequency_point_a 0, // offset_to_carrier srsran_subcarrier_spacing_15kHz, // scs 6, // nof_prb diff --git a/lib/src/phy/phch/test/pusch_nr_test.c b/lib/src/phy/phch/test/pusch_nr_test.c index fbffeefaa..b4f363269 100644 --- a/lib/src/phy/phch/test/pusch_nr_test.c +++ b/lib/src/phy/phch/test/pusch_nr_test.c @@ -22,7 +22,8 @@ static srsran_carrier_nr_t carrier = { 1, // pci 0, // absolute_frequency_ssb - 0, // absolute_frequency_point_a + 0, // dl_absolute_frequency_point_a + 0, // ul_absolute_frequency_point_a 0, // offset_to_carrier srsran_subcarrier_spacing_15kHz, // scs SRSRAN_MAX_PRB_NR, // nof_prb diff --git a/lib/src/phy/phch/test/sch_nr_test.c b/lib/src/phy/phch/test/sch_nr_test.c index 2e633febd..b2c1cc865 100644 --- a/lib/src/phy/phch/test/sch_nr_test.c +++ b/lib/src/phy/phch/test/sch_nr_test.c @@ -21,7 +21,8 @@ static srsran_carrier_nr_t carrier = { 1, // pci 0, // absolute_frequency_ssb - 0, // absolute_frequency_point_a + 0, // dl_absolute_frequency_point_a + 0, // ul_absolute_frequency_point_a 0, // offset_to_carrier srsran_subcarrier_spacing_15kHz, // scs SRSRAN_MAX_PRB_NR, // nof_prb diff --git a/lib/src/phy/ue/test/ue_dl_nr_file_test.c b/lib/src/phy/ue/test/ue_dl_nr_file_test.c index a3a58a2e2..45ca71d7a 100644 --- a/lib/src/phy/ue/test/ue_dl_nr_file_test.c +++ b/lib/src/phy/ue/test/ue_dl_nr_file_test.c @@ -19,7 +19,8 @@ static srsran_carrier_nr_t carrier = { 501, // pci 0, // absolute_frequency_ssb - 0, // absolute_frequency_point_a + 0, // dl_absolute_frequency_point_a + 0, // ul_absolute_frequency_point_a 0, // offset_to_carrier srsran_subcarrier_spacing_15kHz, // scs 52, // nof_prb diff --git a/lib/test/phy/phy_dl_nr_test.c b/lib/test/phy/phy_dl_nr_test.c index 528721d95..6855fcb15 100644 --- a/lib/test/phy/phy_dl_nr_test.c +++ b/lib/test/phy/phy_dl_nr_test.c @@ -22,7 +22,8 @@ static srsran_carrier_nr_t carrier = { 501, // pci 0, // absolute_frequency_ssb - 0, // absolute_frequency_point_a + 0, // dl_absolute_frequency_point_a + 0, // ul_absolute_frequency_point_a 0, // offset_to_carrier srsran_subcarrier_spacing_15kHz, // scs 52, // nof_prb diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index 5718639ab..74210d093 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -85,7 +85,7 @@ bool cc_worker::update_cfg() } double abs_freq_point_a_freq = - srsran::srsran_band_helper().nr_arfcn_to_freq(phy.cfg.carrier.absolute_frequency_point_a); + srsran::srsran_band_helper().nr_arfcn_to_freq(phy.cfg.carrier.dl_absolute_frequency_point_a); double abs_freq_ssb_freq = srsran::srsran_band_helper().nr_arfcn_to_freq(phy.cfg.carrier.absolute_frequency_ssb); double carrier_center_freq = diff --git a/srsue/src/phy/nr/worker_pool.cc b/srsue/src/phy/nr/worker_pool.cc index 1e6543636..00a2fb446 100644 --- a/srsue/src/phy/nr/worker_pool.cc +++ b/srsue/src/phy/nr/worker_pool.cc @@ -136,7 +136,7 @@ bool worker_pool::set_config(const srsran::phy_cfg_nr_t& cfg) phy_state.cfg = cfg; logger.info( - "Setting new PHY configuration ARFCN=%d, PCI=%d", cfg.carrier.absolute_frequency_point_a, cfg.carrier.pci); + "Setting new PHY configuration ARFCN=%d, PCI=%d", cfg.carrier.dl_absolute_frequency_point_a, cfg.carrier.pci); // Set carrier information info_metrics_t info = {}; diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index 288df38f2..ede466fd1 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -649,20 +649,16 @@ void phy::set_earfcn(std::vector earfcns) bool phy::set_config(const srsran::phy_cfg_nr_t& cfg) { - // Derive actual RF frequencies for NR carrier - double abs_freq_point_a_freq = srsran::srsran_band_helper().nr_arfcn_to_freq(cfg.carrier.absolute_frequency_point_a); - - // for FR1 unit of resources blocks for freq calc is always 180kHz regardless for actual SCS of carrier - // TODO: add offset_to_carrier - double carrier_center_freq = - abs_freq_point_a_freq + - (cfg.carrier.nof_prb / 2 * SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_t::srsran_subcarrier_spacing_15kHz) * - SRSRAN_NRE); + srsran::srsran_band_helper band_helper; + double dl_freq_hz = band_helper.get_dl_center_freq(cfg.carrier); + double ul_freq_hz = band_helper.get_ul_center_freq(cfg.carrier); + // tune radio for (uint32_t i = 0; i < common.args->nof_nr_carriers; i++) { - logger_phy.info("Tuning channel %d to %.2f GHz", i + common.args->nof_lte_carriers, carrier_center_freq / 1e6); - radio->set_rx_freq(i + common.args->nof_lte_carriers, carrier_center_freq); - radio->set_tx_freq(i + common.args->nof_lte_carriers, carrier_center_freq); + logger_phy.info("Tuning Rx channel %d to %.2f GHz", i + common.args->nof_lte_carriers, dl_freq_hz / 1e6); + radio->set_rx_freq(i + common.args->nof_lte_carriers, dl_freq_hz); + logger_phy.info("Tuning Tx channel %d to %.2f GHz", i + common.args->nof_lte_carriers, ul_freq_hz / 1e6); + radio->set_tx_freq(i + common.args->nof_lte_carriers, ul_freq_hz); } return nr_workers.set_config(cfg); diff --git a/srsue/src/stack/rrc/rrc_nr.cc b/srsue/src/stack/rrc/rrc_nr.cc index d2e5ac402..636534793 100644 --- a/srsue/src/stack/rrc/rrc_nr.cc +++ b/srsue/src/stack/rrc/rrc_nr.cc @@ -773,16 +773,16 @@ bool rrc_nr::apply_csi_meas_cfg(const asn1::rrc_nr::csi_meas_cfg_s& csi_meas_cfg bool rrc_nr::apply_dl_common_cfg(const asn1::rrc_nr::dl_cfg_common_s& dl_cfg_common) { - if (dl_cfg_common.init_dl_bwp_present) { - if (dl_cfg_common.freq_info_dl_present) { - if (make_phy_carrier_cfg(dl_cfg_common.freq_info_dl, &phy_cfg.carrier) == false) { - logger.warning("Warning while making carrier phy config"); - return false; - } - } else { - logger.warning("Option freq_info_dl not present"); + if (dl_cfg_common.freq_info_dl_present) { + if (make_phy_carrier_cfg(dl_cfg_common.freq_info_dl, &phy_cfg.carrier) == false) { + logger.warning("Warning while making carrier phy config"); return false; } + } else { + logger.warning("Option freq_info_dl not present, S-UL not supported."); + return false; + } + if (dl_cfg_common.init_dl_bwp_present) { if (dl_cfg_common.init_dl_bwp.pdsch_cfg_common_present) { if (dl_cfg_common.init_dl_bwp.pdsch_cfg_common.type() == asn1::rrc_nr::setup_release_c::types_opts::setup) { @@ -790,13 +790,12 @@ bool rrc_nr::apply_dl_common_cfg(const asn1::rrc_nr::dl_cfg_common_s& dl_cfg_com // Load CORESET Zero if (pdcch_cfg_common.ctrl_res_set_zero_present) { - srsran::srsran_band_helper band_helper; - // Get band number - uint16_t band = band_helper.get_band_from_dl_arfcn(phy_cfg.carrier.absolute_frequency_point_a); + srsran::srsran_band_helper band_helper; + uint16_t band = band_helper.get_band_from_dl_arfcn(phy_cfg.carrier.dl_absolute_frequency_point_a); // Get pointA and SSB absolute frequencies - double pointA_abs_freq_Hz = band_helper.nr_arfcn_to_freq(phy_cfg.carrier.absolute_frequency_point_a); + double pointA_abs_freq_Hz = band_helper.nr_arfcn_to_freq(phy_cfg.carrier.dl_absolute_frequency_point_a); double ssb_abs_freq_Hz = band_helper.nr_arfcn_to_freq(phy_cfg.carrier.absolute_frequency_ssb); // Calculate integer SSB to pointA frequency offset in Hz @@ -914,6 +913,10 @@ bool rrc_nr::apply_dl_common_cfg(const asn1::rrc_nr::dl_cfg_common_s& dl_cfg_com bool rrc_nr::apply_ul_common_cfg(const asn1::rrc_nr::ul_cfg_common_s& ul_cfg_common) { + if (ul_cfg_common.freq_info_ul_present && ul_cfg_common.freq_info_ul.absolute_freq_point_a_present) { + // Update UL frequency point if provided + phy_cfg.carrier.ul_absolute_frequency_point_a = ul_cfg_common.freq_info_ul.absolute_freq_point_a; + } if (ul_cfg_common.init_ul_bwp_present) { if (ul_cfg_common.init_ul_bwp.rach_cfg_common_present) { if (ul_cfg_common.init_ul_bwp.rach_cfg_common.type() == setup_release_c::types_opts::setup) { From 8cde3f20e72c7c3c4f60e63e08e6994db2b3adf4 Mon Sep 17 00:00:00 2001 From: faluco Date: Thu, 9 Sep 2021 17:35:06 +0200 Subject: [PATCH 22/47] Catch exceptions thrown on invalid format strings in the log backend and print an error message to signal the issue. --- lib/src/srslog/formatters/json_formatter.cpp | 12 ++++++++++-- lib/src/srslog/formatters/text_formatter.cpp | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/src/srslog/formatters/json_formatter.cpp b/lib/src/srslog/formatters/json_formatter.cpp index c7953501e..d3805aaf3 100644 --- a/lib/src/srslog/formatters/json_formatter.cpp +++ b/lib/src/srslog/formatters/json_formatter.cpp @@ -28,7 +28,11 @@ void json_formatter::format(detail::log_entry_metadata&& metadata, fmt::memory_b if (metadata.fmtstring) { if (metadata.store) { fmt::basic_format_args > args(*metadata.store); - fmt::vprintf(buffer, fmt::to_string_view(metadata.fmtstring), args); + try { + fmt::vprintf(buffer, fmt::to_string_view(metadata.fmtstring), args); + } catch (...) { + fmt::print(stderr, "srsLog error - Invalid format string: \"{}\"\n", metadata.fmtstring); + } fmt::format_to(buffer, fmt::to_string_view("\"")); } else { fmt::format_to(buffer, "{}\"", metadata.fmtstring); @@ -58,7 +62,11 @@ void json_formatter::format_context_begin(const detail::log_entry_metadata& md, if (md.store) { fmt::format_to(buffer, " \"log_entry\": \""); fmt::basic_format_args > args(*md.store); - fmt::vprintf(buffer, fmt::to_string_view(md.fmtstring), args); + try { + fmt::vprintf(buffer, fmt::to_string_view(md.fmtstring), args); + } catch (...) { + fmt::print(stderr, "srsLog error - Invalid format string: \"{}\"\n", md.fmtstring); + } fmt::format_to(buffer, "\",\n"); } else { fmt::format_to(buffer, " \"log_entry\": \"{}\",\n", md.fmtstring); diff --git a/lib/src/srslog/formatters/text_formatter.cpp b/lib/src/srslog/formatters/text_formatter.cpp index ba6fb8185..0bd4e9460 100644 --- a/lib/src/srslog/formatters/text_formatter.cpp +++ b/lib/src/srslog/formatters/text_formatter.cpp @@ -66,7 +66,11 @@ void text_formatter::format(detail::log_entry_metadata&& metadata, fmt::memory_b if (metadata.fmtstring) { if (metadata.store) { fmt::basic_format_args > args(*metadata.store); - fmt::vprintf(buffer, fmt::to_string_view(metadata.fmtstring), args); + try { + fmt::vprintf(buffer, fmt::to_string_view(metadata.fmtstring), args); + } catch (...) { + fmt::print(stderr, "srsLog error - Invalid format string: \"{}\"\n", metadata.fmtstring); + } fmt::format_to(buffer, "\n"); } else { fmt::format_to(buffer, "{}\n", metadata.fmtstring); @@ -106,7 +110,11 @@ void text_formatter::format_context_end(const detail::log_entry_metadata& md, if (md.store) { fmt::format_to(buffer, "]: "); fmt::basic_format_args > args(*md.store); - fmt::vprintf(buffer, fmt::to_string_view(md.fmtstring), args); + try { + fmt::vprintf(buffer, fmt::to_string_view(md.fmtstring), args); + } catch (...) { + fmt::print(stderr, "srsLog error - Invalid format string: \"{}\"\n", md.fmtstring); + } fmt::format_to(buffer, "\n"); } else { fmt::format_to(buffer, "]: {}\n", md.fmtstring); From 9571109a69de3f687619b1a223187762f10279ef Mon Sep 17 00:00:00 2001 From: faluco Date: Fri, 10 Sep 2021 13:22:25 +0200 Subject: [PATCH 23/47] Abort program execution if STOP_ON_WARNING is defined when formatting an invalid log entry. --- lib/src/srslog/formatters/json_formatter.cpp | 6 ++++++ lib/src/srslog/formatters/text_formatter.cpp | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/lib/src/srslog/formatters/json_formatter.cpp b/lib/src/srslog/formatters/json_formatter.cpp index d3805aaf3..41387646e 100644 --- a/lib/src/srslog/formatters/json_formatter.cpp +++ b/lib/src/srslog/formatters/json_formatter.cpp @@ -32,6 +32,9 @@ void json_formatter::format(detail::log_entry_metadata&& metadata, fmt::memory_b fmt::vprintf(buffer, fmt::to_string_view(metadata.fmtstring), args); } catch (...) { fmt::print(stderr, "srsLog error - Invalid format string: \"{}\"\n", metadata.fmtstring); +#ifdef STOP_ON_WARNING + std::abort(); +#endif } fmt::format_to(buffer, fmt::to_string_view("\"")); } else { @@ -66,6 +69,9 @@ void json_formatter::format_context_begin(const detail::log_entry_metadata& md, fmt::vprintf(buffer, fmt::to_string_view(md.fmtstring), args); } catch (...) { fmt::print(stderr, "srsLog error - Invalid format string: \"{}\"\n", md.fmtstring); +#ifdef STOP_ON_WARNING + std::abort(); +#endif } fmt::format_to(buffer, "\",\n"); } else { diff --git a/lib/src/srslog/formatters/text_formatter.cpp b/lib/src/srslog/formatters/text_formatter.cpp index 0bd4e9460..216cf0718 100644 --- a/lib/src/srslog/formatters/text_formatter.cpp +++ b/lib/src/srslog/formatters/text_formatter.cpp @@ -70,6 +70,9 @@ void text_formatter::format(detail::log_entry_metadata&& metadata, fmt::memory_b fmt::vprintf(buffer, fmt::to_string_view(metadata.fmtstring), args); } catch (...) { fmt::print(stderr, "srsLog error - Invalid format string: \"{}\"\n", metadata.fmtstring); +#ifdef STOP_ON_WARNING + std::abort(); +#endif } fmt::format_to(buffer, "\n"); } else { @@ -114,6 +117,9 @@ void text_formatter::format_context_end(const detail::log_entry_metadata& md, fmt::vprintf(buffer, fmt::to_string_view(md.fmtstring), args); } catch (...) { fmt::print(stderr, "srsLog error - Invalid format string: \"{}\"\n", md.fmtstring); +#ifdef STOP_ON_WARNING + std::abort(); +#endif } fmt::format_to(buffer, "\n"); } else { From c7ddedcf72d59a8081be8446730ce21e59f917f7 Mon Sep 17 00:00:00 2001 From: faluco Date: Fri, 10 Sep 2021 15:02:36 +0200 Subject: [PATCH 24/47] Log the invalid format string to help grepping it in the logs. --- lib/src/srslog/formatters/json_formatter.cpp | 2 ++ lib/src/srslog/formatters/text_formatter.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/lib/src/srslog/formatters/json_formatter.cpp b/lib/src/srslog/formatters/json_formatter.cpp index 41387646e..02c8f12b9 100644 --- a/lib/src/srslog/formatters/json_formatter.cpp +++ b/lib/src/srslog/formatters/json_formatter.cpp @@ -32,6 +32,7 @@ void json_formatter::format(detail::log_entry_metadata&& metadata, fmt::memory_b fmt::vprintf(buffer, fmt::to_string_view(metadata.fmtstring), args); } catch (...) { fmt::print(stderr, "srsLog error - Invalid format string: \"{}\"\n", metadata.fmtstring); + fmt::format_to(buffer, " -> srsLog error - Invalid format string: \"{}\"", metadata.fmtstring); #ifdef STOP_ON_WARNING std::abort(); #endif @@ -69,6 +70,7 @@ void json_formatter::format_context_begin(const detail::log_entry_metadata& md, fmt::vprintf(buffer, fmt::to_string_view(md.fmtstring), args); } catch (...) { fmt::print(stderr, "srsLog error - Invalid format string: \"{}\"\n", md.fmtstring); + fmt::format_to(buffer, " -> srsLog error - Invalid format string: \"{}\"", md.fmtstring); #ifdef STOP_ON_WARNING std::abort(); #endif diff --git a/lib/src/srslog/formatters/text_formatter.cpp b/lib/src/srslog/formatters/text_formatter.cpp index 216cf0718..0020bd7c1 100644 --- a/lib/src/srslog/formatters/text_formatter.cpp +++ b/lib/src/srslog/formatters/text_formatter.cpp @@ -70,6 +70,7 @@ void text_formatter::format(detail::log_entry_metadata&& metadata, fmt::memory_b fmt::vprintf(buffer, fmt::to_string_view(metadata.fmtstring), args); } catch (...) { fmt::print(stderr, "srsLog error - Invalid format string: \"{}\"\n", metadata.fmtstring); + fmt::format_to(buffer, " -> srsLog error - Invalid format string: \"{}\"", metadata.fmtstring); #ifdef STOP_ON_WARNING std::abort(); #endif @@ -117,6 +118,7 @@ void text_formatter::format_context_end(const detail::log_entry_metadata& md, fmt::vprintf(buffer, fmt::to_string_view(md.fmtstring), args); } catch (...) { fmt::print(stderr, "srsLog error - Invalid format string: \"{}\"\n", md.fmtstring); + fmt::format_to(buffer, " -> srsLog error - Invalid format string: \"{}\"", md.fmtstring); #ifdef STOP_ON_WARNING std::abort(); #endif From 06f000c2c475980fa498bb23079b3bf76ff779c4 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 13 Sep 2021 12:34:45 +0200 Subject: [PATCH 25/47] band_helper: fix format --- lib/src/common/test/band_helper_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/common/test/band_helper_test.cc b/lib/src/common/test/band_helper_test.cc index d8ef68335..3dfc8d4cc 100644 --- a/lib/src/common/test/band_helper_test.cc +++ b/lib/src/common/test/band_helper_test.cc @@ -41,10 +41,10 @@ int bands_test_nr() TESTASSERT(bands.nr_arfcn_to_freq(167300) == 836.5e6); // check actual freqs for FDD carrier (example values are for 52 PRB) - srsran_carrier_nr_t carrier = {}; + srsran_carrier_nr_t carrier = {}; carrier.dl_absolute_frequency_point_a = 175364; carrier.ul_absolute_frequency_point_a = 166364; - carrier.nof_prb = 52; + carrier.nof_prb = 52; TESTASSERT(bands.get_dl_center_freq(carrier) == 881.5e6); TESTASSERT(bands.get_ul_center_freq(carrier) == 836.5e6); From 9a49d4796899bebfecaef5d0df5af783e04590bc Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 13 Sep 2021 13:01:34 +0200 Subject: [PATCH 26/47] sched_nr_interface: disable auto-refill of NR scheduler --- srsenb/hdr/stack/mac/nr/sched_nr_interface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h index e9acc51b9..8d89e0804 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h @@ -68,7 +68,7 @@ public: struct sched_cfg_t { bool pdsch_enabled = true; bool pusch_enabled = true; - bool auto_refill_buffer = true; + bool auto_refill_buffer = false; std::string logger_name = "MAC"; }; From 88878e07c61a54258466b6bd2ce9bc400d0fb065 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 13 Sep 2021 13:01:52 +0200 Subject: [PATCH 27/47] sched_nr_test: enable auto-refill for failing NR sched tests --- srsenb/test/mac/nr/sched_nr_test.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/srsenb/test/mac/nr/sched_nr_test.cc b/srsenb/test/mac/nr/sched_nr_test.cc index 7ee6cdbf1..fccf4ee9e 100644 --- a/srsenb/test/mac/nr/sched_nr_test.cc +++ b/srsenb/test/mac/nr/sched_nr_test.cc @@ -83,6 +83,8 @@ void sched_nr_cfg_serialized_test() task_job_manager tasks; sched_nr_interface::sched_cfg_t cfg; + cfg.auto_refill_buffer = true; + std::vector cells_cfg = get_default_cells_cfg(nof_sectors); sched_nr_sim_base sched_tester(cfg, cells_cfg, "Serialized Test"); @@ -131,7 +133,9 @@ void sched_nr_cfg_parallel_cc_test() uint32_t max_nof_ttis = 1000; task_job_manager tasks; - sched_nr_interface::sched_cfg_t cfg; + sched_nr_interface::sched_cfg_t cfg; + cfg.auto_refill_buffer = true; + std::vector cells_cfg = get_default_cells_cfg(nof_sectors); sched_nr_sim_base sched_tester(cfg, cells_cfg, "Parallel CC Test"); From 13d4fd174b734c87fdf0c4fdfe92dfe940403966 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20F=C3=BCrste?= Date: Mon, 13 Sep 2021 12:36:48 +0200 Subject: [PATCH 28/47] cmake: Export non-default SoapySDR driver path --- cmake/modules/FindSoapySDR.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/modules/FindSoapySDR.cmake b/cmake/modules/FindSoapySDR.cmake index bdd410fb4..b691b5af0 100644 --- a/cmake/modules/FindSoapySDR.cmake +++ b/cmake/modules/FindSoapySDR.cmake @@ -12,6 +12,8 @@ if(NOT SOAPYSDR_FOUND) find_path(SOAPYSDR_INCLUDE_DIRS NAMES Device.h + HINTS $ENV{SOAPY_DIR}/include + $ENV{SOAPY_DIR}/include/SoapySDR PATHS ${SOAPYSDR_PKG_INCLUDE_DIRS} /usr/include/SoapySDR /usr/local/include/SoapySDR @@ -19,6 +21,7 @@ if(NOT SOAPYSDR_FOUND) find_library(SOAPYSDR_LIBRARIES NAMES SoapySDR + HINTS $ENV{SOAPY_DIR}/lib PATHS ${SOAPYSDR_PKG_LIBRARY_DIRS} /usr/lib /usr/local/lib From c177ed3331d1cf5850cd426fd6c23f9bede022c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20F=C3=BCrste?= Date: Mon, 13 Sep 2021 15:21:24 +0200 Subject: [PATCH 29/47] cmake: Export non-default libbladerf driver path --- cmake/modules/FindbladeRF.cmake | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/cmake/modules/FindbladeRF.cmake b/cmake/modules/FindbladeRF.cmake index 265015fbe..0e97fa395 100644 --- a/cmake/modules/FindbladeRF.cmake +++ b/cmake/modules/FindbladeRF.cmake @@ -8,18 +8,21 @@ if(NOT BLADERF_FOUND) pkg_check_modules (BLADERF_PKG libbladeRF) - find_path(BLADERF_INCLUDE_DIRS NAMES libbladeRF.h - PATHS - ${BLADERF_PKG_INCLUDE_DIRS} - /usr/include - /usr/local/include + + find_path(BLADERF_INCLUDE_DIRS + NAMES libbladeRF.h + HINTS $ENV{BLADERF_DIR}/include + PATHS ${BLADERF_PKG_INCLUDE_DIRS} + /usr/include + /usr/local/include ) - find_library(BLADERF_LIBRARIES NAMES bladeRF - PATHS - ${BLADERF_PKG_LIBRARY_DIRS} - /usr/lib - /usr/local/lib + find_library(BLADERF_LIBRARIES + NAMES bladeRF + HINTS $ENV{BLADERF_DIR}/lib + PATHS ${BLADERF_PKG_LIBRARY_DIRS} + /usr/lib + /usr/local/lib ) if(BLADERF_INCLUDE_DIRS AND BLADERF_LIBRARIES) From 690bccccc6ad90e77832b0295a448e32bd9c0784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20F=C3=BCrste?= Date: Mon, 13 Sep 2021 15:48:05 +0200 Subject: [PATCH 30/47] cmake: Export non-default Limesuite driver path --- cmake/modules/FindLimeSDR.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/modules/FindLimeSDR.cmake b/cmake/modules/FindLimeSDR.cmake index 6186350e4..cf31cfaa4 100644 --- a/cmake/modules/FindLimeSDR.cmake +++ b/cmake/modules/FindLimeSDR.cmake @@ -11,13 +11,16 @@ if(NOT LIMESDR_FOUND) find_path(LIMESDR_INCLUDE_DIRS NAMES LimeSuite.h + HINTS $ENV{LIMESUITE_DIR}/include PATHS ${LIMESDR_PKG_INCLUDE_DIRS} /usr/include/lime /usr/local/include/lime + $ENV{LIMESUITE_DIR}/include/lime ) find_library(LIMESDR_LIBRARIES NAMES LimeSuite + HINTS $ENV{LIMESUITE_DIR}/lib PATHS ${LIMESDR_PKG_LIBRARY_DIRS} /usr/lib /usr/local/lib From d75fe22a0a0f42fc5e52b051aef94f27fc18dd57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20F=C3=BCrste?= Date: Mon, 13 Sep 2021 20:46:52 +0200 Subject: [PATCH 31/47] Soapy: Fix include path of Types.h --- lib/src/phy/rf/rf_soapy_imp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/phy/rf/rf_soapy_imp.c b/lib/src/phy/rf/rf_soapy_imp.c index adbc9f559..8110126d3 100644 --- a/lib/src/phy/rf/rf_soapy_imp.c +++ b/lib/src/phy/rf/rf_soapy_imp.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #define HAVE_ASYNC_THREAD 0 From 485ec2edab3ff4e00071eae83b8c5cc7190b4ff1 Mon Sep 17 00:00:00 2001 From: faluco Date: Mon, 13 Sep 2021 11:08:56 +0200 Subject: [PATCH 32/47] Implement a new option to flush the file sink contents on every write. --- lib/include/srsran/srslog/srslog.h | 6 ++++-- lib/include/srsran/srslog/srslog_c.h | 3 ++- lib/src/srslog/sinks/file_sink.h | 8 +++++++- lib/src/srslog/srslog.cpp | 10 +++++++--- lib/src/srslog/srslog_c.cpp | 4 ++-- lib/test/srslog/file_sink_test.cpp | 4 ++-- srsenb/src/main.cc | 4 ++-- srsue/src/main.cc | 2 +- 8 files changed, 27 insertions(+), 14 deletions(-) diff --git a/lib/include/srsran/srslog/srslog.h b/lib/include/srsran/srslog/srslog.h index b9af1f5bc..cab1ca125 100644 --- a/lib/include/srsran/srslog/srslog.h +++ b/lib/include/srsran/srslog/srslog.h @@ -179,10 +179,12 @@ sink& fetch_stderr_sink(const std::string& id = "stderr", /// Specifying a max_size value different to zero will make the sink create a /// new file each time the current file exceeds this value. The units of /// max_size are bytes. +/// Setting force_flush to true will flush the sink after every write. /// NOTE: Any '#' characters in the path will get removed. sink& fetch_file_sink(const std::string& path, - size_t max_size = 0, - std::unique_ptr f = get_default_log_formatter()); + size_t max_size = 0, + bool force_flush = false, + std::unique_ptr f = get_default_log_formatter()); /// Returns an instance of a sink that writes into syslog /// preamble: The string prepended to every message, If ident is "", the program name is used. diff --git a/lib/include/srsran/srslog/srslog_c.h b/lib/include/srsran/srslog/srslog_c.h index 4b55a5767..041615830 100644 --- a/lib/include/srsran/srslog/srslog_c.h +++ b/lib/include/srsran/srslog/srslog_c.h @@ -148,9 +148,10 @@ srslog_sink* srslog_fetch_stderr_sink(void); * Specifying a max_size value different to zero will make the sink create a * new file each time the current file exceeds this value. The units of * max_size are bytes. + * Setting force_flush to true will flush the sink after every write. * NOTE: Any '#' characters in the id will get removed. */ -srslog_sink* srslog_fetch_file_sink(const char* path, size_t max_size); +srslog_sink* srslog_fetch_file_sink(const char* path, size_t max_size, srslog_bool force_flush); #ifdef __cplusplus } diff --git a/lib/src/srslog/sinks/file_sink.h b/lib/src/srslog/sinks/file_sink.h index 5a15d9318..32a98926a 100644 --- a/lib/src/srslog/sinks/file_sink.h +++ b/lib/src/srslog/sinks/file_sink.h @@ -24,9 +24,10 @@ namespace srslog { class file_sink : public sink { public: - file_sink(std::string name, size_t max_size, std::unique_ptr f) : + file_sink(std::string name, size_t max_size, bool force_flush, std::unique_ptr f) : sink(std::move(f)), max_size((max_size == 0) ? 0 : std::max(max_size, 4 * 1024)), + force_flush(force_flush), base_filename(std::move(name)) {} @@ -53,6 +54,10 @@ public: return err_str; } + if (force_flush) { + flush(); + } + return handler.write(buffer); } @@ -88,6 +93,7 @@ private: private: const size_t max_size; + const bool force_flush; const std::string base_filename; file_utils::file handler; size_t current_size = 0; diff --git a/lib/src/srslog/srslog.cpp b/lib/src/srslog/srslog.cpp index 947cea375..f54979460 100644 --- a/lib/src/srslog/srslog.cpp +++ b/lib/src/srslog/srslog.cpp @@ -148,7 +148,10 @@ sink& srslog::fetch_stderr_sink(const std::string& id, std::unique_ptr f) +sink& srslog::fetch_file_sink(const std::string& path, + size_t max_size, + bool force_flush, + std::unique_ptr f) { assert(!path.empty() && "Empty path string"); @@ -161,7 +164,7 @@ sink& srslog::fetch_file_sink(const std::string& path, size_t max_size, std::uni auto& s = srslog_instance::get().get_sink_repo().emplace( std::piecewise_construct, std::forward_as_tuple(path), - std::forward_as_tuple(new file_sink(path, max_size, std::move(f)))); + std::forward_as_tuple(new file_sink(path, max_size, force_flush, std::move(f)))); return *s; } @@ -388,7 +391,8 @@ sink* srslog::create_file_sink(const std::string& path, size_t max_size) .get_sink_repo() .emplace(std::piecewise_construct, std::forward_as_tuple(path), - std::forward_as_tuple(new file_sink(path, max_size, std::unique_ptr(new text_formatter)))) + std::forward_as_tuple( + new file_sink(path, max_size, false, std::unique_ptr(new text_formatter)))) .get(); } diff --git a/lib/src/srslog/srslog_c.cpp b/lib/src/srslog/srslog_c.cpp index 3b6edbf0c..87554d6d1 100644 --- a/lib/src/srslog/srslog_c.cpp +++ b/lib/src/srslog/srslog_c.cpp @@ -181,7 +181,7 @@ srslog_sink* srslog_fetch_stderr_sink(void) return c_cast(&fetch_stderr_sink()); } -srslog_sink* srslog_fetch_file_sink(const char* path, size_t max_size) +srslog_sink* srslog_fetch_file_sink(const char* path, size_t max_size, srslog_bool force_flush) { - return c_cast(&fetch_file_sink(path, max_size)); + return c_cast(&fetch_file_sink(path, max_size, force_flush)); } diff --git a/lib/test/srslog/file_sink_test.cpp b/lib/test/srslog/file_sink_test.cpp index 39689e0af..822be9aa0 100644 --- a/lib/test/srslog/file_sink_test.cpp +++ b/lib/test/srslog/file_sink_test.cpp @@ -22,7 +22,7 @@ static constexpr char log_filename[] = "file_sink_test.log"; static bool when_data_is_written_to_file_then_contents_are_valid() { file_test_utils::scoped_file_deleter deleter(log_filename); - file_sink file(log_filename, 0, std::unique_ptr(new test_dummies::log_formatter_dummy)); + file_sink file(log_filename, 0, false, std::unique_ptr(new test_dummies::log_formatter_dummy)); std::vector entries; for (unsigned i = 0; i != 10; ++i) { @@ -45,7 +45,7 @@ class file_sink_subclass : public file_sink { public: file_sink_subclass(std::string name, size_t max_size) : - file_sink(std::move(name), max_size, std::unique_ptr(new test_dummies::log_formatter_dummy)) + file_sink(std::move(name), max_size, false, std::unique_ptr(new test_dummies::log_formatter_dummy)) {} uint32_t get_num_of_files() const { return get_file_index(); } diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 79f036a3c..bdc743716 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -550,7 +550,7 @@ int main(int argc, char* argv[]) : srslog::fetch_file_sink(args.log.filename, fixup_log_file_maxsize(args.log.file_max_size))); // Alarms log channel creation. - srslog::sink& alarm_sink = srslog::fetch_file_sink(args.general.alarms_filename); + srslog::sink& alarm_sink = srslog::fetch_file_sink(args.general.alarms_filename, 0, true); srslog::log_channel& alarms_channel = srslog::fetch_log_channel("alarms", alarm_sink, {"ALRM", '\0', false}); alarms_channel.set_enabled(args.general.alarms_log_enable); @@ -573,7 +573,7 @@ int main(int argc, char* argv[]) // Set up the JSON log channel used by metrics and events. srslog::sink& json_sink = - srslog::fetch_file_sink(args.general.report_json_filename, 0, srslog::create_json_formatter()); + srslog::fetch_file_sink(args.general.report_json_filename, 0, false, srslog::create_json_formatter()); srslog::log_channel& json_channel = srslog::fetch_log_channel("JSON_channel", json_sink, {}); json_channel.set_enabled(args.general.report_json_enable); diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 666ba2c6c..15a5a0c12 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -725,7 +725,7 @@ int main(int argc, char* argv[]) // Set up the JSON log channel used by metrics. srslog::sink& json_sink = - srslog::fetch_file_sink(args.general.metrics_json_filename, 0, srslog::create_json_formatter()); + srslog::fetch_file_sink(args.general.metrics_json_filename, 0, false, srslog::create_json_formatter()); srslog::log_channel& json_channel = srslog::fetch_log_channel("JSON_channel", json_sink, {}); json_channel.set_enabled(args.general.metrics_json_enable); From cf20b143c06263a30de76e3385e253bfd9cde020 Mon Sep 17 00:00:00 2001 From: faluco Date: Mon, 13 Sep 2021 15:06:57 +0200 Subject: [PATCH 33/47] Fix the default constructor of the optional class to avoid a spurious uninitialized value warning in older GCC versions (seen for ARM32 and GCC 8.3). Use a union of a byte and the real storage, and init the char by default. --- lib/include/srsran/adt/optional.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/include/srsran/adt/optional.h b/lib/include/srsran/adt/optional.h index 8a08df6f2..939665248 100644 --- a/lib/include/srsran/adt/optional.h +++ b/lib/include/srsran/adt/optional.h @@ -24,7 +24,7 @@ class optional public: using value_type = T; - optional() : has_val_(false) {} + optional() : has_val_(false), empty() {} optional(const T& t) : has_val_(true) { storage.emplace(t); } optional(T&& t) : has_val_(true) { storage.emplace(std::move(t)); } optional(const optional& other) : has_val_(other.has_value()) @@ -98,8 +98,11 @@ public: } private: - bool has_val_; - detail::type_storage storage; + bool has_val_; + union { + char empty; + detail::type_storage storage; + }; }; template From dbcf5c95034474efb2a000d73724717b80b669ea Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 13 Sep 2021 15:11:17 +0200 Subject: [PATCH 34/47] sched_nr: add ue_exists() helper --- srsenb/hdr/stack/mac/nr/sched_nr.h | 1 + srsenb/hdr/stack/mac/nr/sched_nr_interface.h | 1 + srsenb/src/stack/mac/nr/sched_nr.cc | 5 +++++ 3 files changed, 7 insertions(+) diff --git a/srsenb/hdr/stack/mac/nr/sched_nr.h b/srsenb/hdr/stack/mac/nr/sched_nr.h index 75094bb60..9ed0debd5 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr.h @@ -41,6 +41,7 @@ public: int cell_cfg(srsran::const_span cell_list) override; void ue_cfg(uint16_t rnti, const ue_cfg_t& cfg) override; void ue_rem(uint16_t rnti) override; + bool ue_exists(uint16_t rnti) override; int dl_rach_info(uint32_t cc, const dl_sched_rar_info_t& rar_info); diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h index 8d89e0804..48ea5c197 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h @@ -119,6 +119,7 @@ public: virtual int cell_cfg(srsran::const_span ue_cfg) = 0; virtual void ue_cfg(uint16_t rnti, const ue_cfg_t& ue_cfg) = 0; virtual void ue_rem(uint16_t rnti) = 0; + virtual bool ue_exists(uint16_t rnti) = 0; virtual int get_dl_sched(slot_point slot_rx, uint32_t cc, dl_sched_res_t& result) = 0; virtual int get_ul_sched(slot_point slot_rx, uint32_t cc, ul_sched_t& result) = 0; diff --git a/srsenb/src/stack/mac/nr/sched_nr.cc b/srsenb/src/stack/mac/nr/sched_nr.cc index 477cc8724..53d541aee 100644 --- a/srsenb/src/stack/mac/nr/sched_nr.cc +++ b/srsenb/src/stack/mac/nr/sched_nr.cc @@ -100,6 +100,11 @@ void sched_nr::ue_rem(uint16_t rnti) sched_workers->enqueue_event(rnti, [this, rnti]() { ue_db.erase(rnti); }); } +bool sched_nr::ue_exists(uint16_t rnti) +{ + return ue_db.contains(rnti); +} + void sched_nr::ue_cfg_impl(uint16_t rnti, const ue_cfg_t& uecfg) { if (not ue_db.contains(rnti)) { From 4a5d2a8659f5419013a0f9f08b5b596f2aaabf5d Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 13 Sep 2021 15:13:27 +0200 Subject: [PATCH 35/47] mac_nr: add basic get_metrics() implementation --- srsenb/hdr/stack/mac/mac_nr.h | 2 +- srsenb/src/stack/mac/nr/mac_nr.cc | 27 ++++++++++++++++++++++----- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/srsenb/hdr/stack/mac/mac_nr.h b/srsenb/hdr/stack/mac/mac_nr.h index 6b3814ec5..cc6b423fb 100644 --- a/srsenb/hdr/stack/mac/mac_nr.h +++ b/srsenb/hdr/stack/mac/mac_nr.h @@ -107,7 +107,7 @@ private: const static uint32_t NUMEROLOGY_IDX = 0; /// only 15kHz supported at this stage srsran::slot_point pdsch_slot, pusch_slot; srsenb::sched_nr sched; - srsenb::sched_interface::cell_cfg_t cfg = {}; + srsran::const_span cell_config; // Map of active UEs pthread_rwlock_t rwlock = {}; diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 4c57490f0..64b38c298 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -77,21 +77,38 @@ void mac_nr::stop() } } -void mac_nr::get_metrics(srsenb::mac_metrics_t& metrics) {} +void mac_nr::get_metrics(srsenb::mac_metrics_t& metrics) +{ + srsran::rwlock_read_guard lock(rwlock); + metrics.ues.reserve(ue_db.size()); + for (auto& u : ue_db) { + if (not sched.ue_exists(u.first)) { + continue; + } + metrics.ues.emplace_back(); + u.second->metrics_read(&metrics.ues.back()); + } + metrics.cc_info.resize(detected_rachs.size()); + for (unsigned cc = 0, e = detected_rachs.size(); cc != e; ++cc) { + metrics.cc_info[cc].cc_rach_counter = detected_rachs[cc]; + metrics.cc_info[cc].pci = (cc < cell_config.size()) ? cell_config[cc].carrier.pci : 0; + } +} -int mac_nr::cell_cfg(const sched_interface::cell_cfg_t& cell, +int mac_nr::cell_cfg(const sched_interface::cell_cfg_t& eutra_cell_config, srsran::const_span nr_cells) { - cfg = cell; + cell_config = nr_cells; sched.cell_cfg(nr_cells); detected_rachs.resize(nr_cells.size()); // read SIBs from RRC (SIB1 for now only) for (int i = 0; i < 1 /* srsenb::sched_interface::MAX_SIBS */; i++) { - if (cell.sibs->len > 0) { + // TODO: add flag for SIBs into cell config + if (true) { sib_info_t sib = {}; sib.index = i; - sib.periodicity = cell.sibs->period_rf; + sib.periodicity = 4; // TODO: read period_rf from config sib.payload = srsran::make_byte_buffer(); if (sib.payload == nullptr) { logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); From 6a46931144009b626fa775d9cbbdff28a21eecb4 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 13 Sep 2021 15:16:43 +0200 Subject: [PATCH 36/47] mac_nr,enb: move header into nr subfolder --- srsenb/hdr/stack/enb_stack_lte.h | 2 +- srsenb/hdr/stack/gnb_stack_nr.h | 2 +- srsenb/hdr/stack/mac/{ => nr}/mac_nr.h | 0 srsenb/src/stack/mac/nr/mac_nr.cc | 2 +- test/phy/dummy_gnb_stack.h | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename srsenb/hdr/stack/mac/{ => nr}/mac_nr.h (100%) diff --git a/srsenb/hdr/stack/enb_stack_lte.h b/srsenb/hdr/stack/enb_stack_lte.h index bb5eff576..b01ea3a20 100644 --- a/srsenb/hdr/stack/enb_stack_lte.h +++ b/srsenb/hdr/stack/enb_stack_lte.h @@ -19,7 +19,7 @@ #define SRSRAN_ENB_STACK_LTE_H #include "mac/mac.h" -#include "mac/mac_nr.h" +#include "mac/nr/mac_nr.h" #include "rrc/rrc.h" #include "rrc/rrc_nr.h" #include "s1ap/s1ap.h" diff --git a/srsenb/hdr/stack/gnb_stack_nr.h b/srsenb/hdr/stack/gnb_stack_nr.h index 0fcdc8534..48102f5d9 100644 --- a/srsenb/hdr/stack/gnb_stack_nr.h +++ b/srsenb/hdr/stack/gnb_stack_nr.h @@ -19,7 +19,7 @@ #define SRSRAN_GNB_STACK_NR_H #include "s1ap/s1ap.h" -#include "srsenb/hdr/stack/mac/mac_nr.h" +#include "srsenb/hdr/stack/mac/nr/mac_nr.h" #include "srsenb/hdr/stack/rrc/rrc_nr.h" #include "srsenb/hdr/stack/upper/pdcp_nr.h" #include "srsenb/hdr/stack/upper/rlc_nr.h" diff --git a/srsenb/hdr/stack/mac/mac_nr.h b/srsenb/hdr/stack/mac/nr/mac_nr.h similarity index 100% rename from srsenb/hdr/stack/mac/mac_nr.h rename to srsenb/hdr/stack/mac/nr/mac_nr.h diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 64b38c298..9cb333465 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -10,7 +10,7 @@ * */ -#include "srsenb/hdr/stack/mac/mac_nr.h" +#include "srsenb/hdr/stack/mac/nr/mac_nr.h" #include "srsenb/test/mac/nr/sched_nr_cfg_generators.h" #include "srsran/common/buffer_pool.h" #include "srsran/common/log_helper.h" diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index e1e943f76..00cba3989 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -15,7 +15,7 @@ #include "dummy_rx_harq_proc.h" #include "dummy_tx_harq_proc.h" -#include "srsenb/hdr/stack/mac/mac_nr.h" +#include "srsenb/hdr/stack/mac/nr/mac_nr.h" #include "srsenb/hdr/stack/mac/nr/sched_nr.h" #include "srsenb/test/common/dummy_classes_nr.h" #include "srsenb/test/common/rlc_test_dummy.h" From e2b1bbe2dce782300f81afc09493ba114fbe1a36 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 13 Sep 2021 15:17:19 +0200 Subject: [PATCH 37/47] enb,metrics: add helper method to print MAC metrics preparation to be used to print MAC metrics for EUTRA and NR cells --- srsenb/hdr/metrics_stdout.h | 1 + srsenb/src/metrics_stdout.cc | 115 ++++++++++++++++++----------------- 2 files changed, 60 insertions(+), 56 deletions(-) diff --git a/srsenb/hdr/metrics_stdout.h b/srsenb/hdr/metrics_stdout.h index 9e6cf4341..2c8e0f328 100644 --- a/srsenb/hdr/metrics_stdout.h +++ b/srsenb/hdr/metrics_stdout.h @@ -37,6 +37,7 @@ public: void stop(){}; private: + void set_metrics_helper(uint32_t num_ue, const mac_metrics_t& mac, const std::vector& phy); std::string float_to_string(float f, int digits, int field_width = 6); std::string float_to_eng_string(float f, int digits); diff --git a/srsenb/src/metrics_stdout.cc b/srsenb/src/metrics_stdout.cc index db6ad1981..f6b141472 100644 --- a/srsenb/src/metrics_stdout.cc +++ b/srsenb/src/metrics_stdout.cc @@ -71,62 +71,43 @@ static bool iszero(float x) return fabsf(x) < 2 * DBL_EPSILON; } -void metrics_stdout::set_metrics(const enb_metrics_t& metrics, const uint32_t period_usec) +void metrics_stdout::set_metrics_helper(uint32_t num_ue, + const mac_metrics_t& mac, + const std::vector& phy) { - if (!do_print || enb == nullptr) { - return; - } - - if (metrics.rf.rf_error) { - fmt::print("RF status: O={}, U={}, L={}\n", metrics.rf.rf_o, metrics.rf.rf_u, metrics.rf.rf_l); - } - - if (metrics.stack.rrc.ues.size() == 0) { - return; - } - - if (++n_reports > 10) { - n_reports = 0; - fmt::print("\n"); - fmt::print("-------------------DL--------------------|-------------------------UL-------------------------\n"); - fmt::print("rnti cqi ri mcs brate ok nok (%) | pusch pucch phr mcs brate ok nok (%) bsr\n"); - } - - for (size_t i = 0; i < metrics.stack.rrc.ues.size(); i++) { + for (size_t i = 0; i < num_ue; i++) { // make sure we have stats for MAC and PHY layer too - if (i >= metrics.stack.mac.ues.size() || i >= metrics.phy.size()) { + if (i >= mac.ues.size() || i >= phy.size()) { break; } - if (metrics.stack.mac.ues[i].tx_errors > metrics.stack.mac.ues[i].tx_pkts) { - fmt::print("tx caution errors {} > {}\n", metrics.stack.mac.ues[i].tx_errors, metrics.stack.mac.ues[i].tx_pkts); + if (mac.ues[i].tx_errors > mac.ues[i].tx_pkts) { + fmt::print("tx caution errors {} > {}\n", mac.ues[i].tx_errors, mac.ues[i].tx_pkts); } - if (metrics.stack.mac.ues[i].rx_errors > metrics.stack.mac.ues[i].rx_pkts) { - fmt::print("rx caution errors {} > {}\n", metrics.stack.mac.ues[i].rx_errors, metrics.stack.mac.ues[i].rx_pkts); + if (mac.ues[i].rx_errors > mac.ues[i].rx_pkts) { + fmt::print("rx caution errors {} > {}\n", mac.ues[i].rx_errors, mac.ues[i].rx_pkts); } - fmt::print("{:>4x}", metrics.stack.mac.ues[i].rnti); - if (not iszero(metrics.stack.mac.ues[i].dl_cqi)) { - fmt::print(" {:>3}", int(metrics.stack.mac.ues[i].dl_cqi)); + fmt::print("{:>4x}", mac.ues[i].rnti); + if (not iszero(mac.ues[i].dl_cqi)) { + fmt::print(" {:>3}", int(mac.ues[i].dl_cqi)); } else { fmt::print(" {:>3.3}", "n/a"); } - fmt::print(" {:>1}", int(metrics.stack.mac.ues[i].dl_ri)); - if (not isnan(metrics.phy[i].dl.mcs)) { - fmt::print(" {:>2}", int(metrics.phy[i].dl.mcs)); + fmt::print(" {:>1}", int(mac.ues[i].dl_ri)); + if (not isnan(phy[i].dl.mcs)) { + fmt::print(" {:>2}", int(phy[i].dl.mcs)); } else { fmt::print(" {:>2}", 0); } - if (metrics.stack.mac.ues[i].tx_brate > 0) { - fmt::print( - " {:>6.6}", - float_to_eng_string((float)metrics.stack.mac.ues[i].tx_brate / (metrics.stack.mac.ues[i].nof_tti * 1e-3), 1)); + if (mac.ues[i].tx_brate > 0) { + fmt::print(" {:>6.6}", float_to_eng_string((float)mac.ues[i].tx_brate / (mac.ues[i].nof_tti * 1e-3), 1)); } else { fmt::print(" {:>6}", 0); } - fmt::print(" {:>4}", metrics.stack.mac.ues[i].tx_pkts - metrics.stack.mac.ues[i].tx_errors); - fmt::print(" {:>4}", metrics.stack.mac.ues[i].tx_errors); - if (metrics.stack.mac.ues[i].tx_pkts > 0 && metrics.stack.mac.ues[i].tx_errors) { - fmt::print(" {:>3}%", int((float)100 * metrics.stack.mac.ues[i].tx_errors / metrics.stack.mac.ues[i].tx_pkts)); + fmt::print(" {:>4}", mac.ues[i].tx_pkts - mac.ues[i].tx_errors); + fmt::print(" {:>4}", mac.ues[i].tx_errors); + if (mac.ues[i].tx_pkts > 0 && mac.ues[i].tx_errors) { + fmt::print(" {:>3}%", int((float)100 * mac.ues[i].tx_errors / mac.ues[i].tx_pkts)); } else { fmt::print(" {:>3}%", 0); } @@ -143,44 +124,66 @@ void metrics_stdout::set_metrics(const enb_metrics_t& metrics, const uint32_t pe return sinr; }; - if (not isnan(metrics.phy[i].ul.pusch_sinr) and not iszero(metrics.phy[i].ul.pusch_sinr)) { - fmt::print(" {:>5.1f}", clamp_sinr(metrics.phy[i].ul.pusch_sinr)); + if (not isnan(phy[i].ul.pusch_sinr) and not iszero(phy[i].ul.pusch_sinr)) { + fmt::print(" {:>5.1f}", clamp_sinr(phy[i].ul.pusch_sinr)); } else { fmt::print(" {:>5.5}", "n/a"); } - if (not isnan(metrics.phy[i].ul.pucch_sinr) and not iszero(metrics.phy[i].ul.pucch_sinr)) { - fmt::print(" {:>5.1f}", clamp_sinr(metrics.phy[i].ul.pucch_sinr)); + if (not isnan(phy[i].ul.pucch_sinr) and not iszero(phy[i].ul.pucch_sinr)) { + fmt::print(" {:>5.1f}", clamp_sinr(phy[i].ul.pucch_sinr)); } else { fmt::print(" {:>5.5}", "n/a"); } - fmt::print(" {:>3}", int(metrics.stack.mac.ues[i].phr)); - if (not isnan(metrics.phy[i].ul.mcs)) { - fmt::print(" {:>2}", int(metrics.phy[i].ul.mcs)); + fmt::print(" {:>3}", int(mac.ues[i].phr)); + if (not isnan(phy[i].ul.mcs)) { + fmt::print(" {:>2}", int(phy[i].ul.mcs)); } else { fmt::print(" {:>2}", 0); } - if (metrics.stack.mac.ues[i].rx_brate > 0) { - fmt::print( - " {:>6.6}", - float_to_eng_string((float)metrics.stack.mac.ues[i].rx_brate / (metrics.stack.mac.ues[i].nof_tti * 1e-3), 1)); + if (mac.ues[i].rx_brate > 0) { + fmt::print(" {:>6.6}", float_to_eng_string((float)mac.ues[i].rx_brate / (mac.ues[i].nof_tti * 1e-3), 1)); } else { fmt::print(" {:>6}", 0); } - fmt::print(" {:>4}", metrics.stack.mac.ues[i].rx_pkts - metrics.stack.mac.ues[i].rx_errors); - fmt::print(" {:>4}", metrics.stack.mac.ues[i].rx_errors); + fmt::print(" {:>4}", mac.ues[i].rx_pkts - mac.ues[i].rx_errors); + fmt::print(" {:>4}", mac.ues[i].rx_errors); - if (metrics.stack.mac.ues[i].rx_pkts > 0 && metrics.stack.mac.ues[i].rx_errors > 0) { - fmt::print(" {:>3}%", int((float)100 * metrics.stack.mac.ues[i].rx_errors / metrics.stack.mac.ues[i].rx_pkts)); + if (mac.ues[i].rx_pkts > 0 && mac.ues[i].rx_errors > 0) { + fmt::print(" {:>3}%", int((float)100 * mac.ues[i].rx_errors / mac.ues[i].rx_pkts)); } else { fmt::print(" {:>3}%", 0); } - fmt::print(" {:>6.6}", float_to_eng_string(metrics.stack.mac.ues[i].ul_buffer, 2)); + fmt::print(" {:>6.6}", float_to_eng_string(mac.ues[i].ul_buffer, 2)); fmt::print("\n"); } } +void metrics_stdout::set_metrics(const enb_metrics_t& metrics, const uint32_t period_usec) +{ + if (!do_print || enb == nullptr) { + return; + } + + if (metrics.rf.rf_error) { + fmt::print("RF status: O={}, U={}, L={}\n", metrics.rf.rf_o, metrics.rf.rf_u, metrics.rf.rf_l); + } + + if (metrics.stack.rrc.ues.size() == 0) { + return; + } + + if (++n_reports > 10) { + n_reports = 0; + fmt::print("\n"); + fmt::print(" -----------------DL----------------|-------------------------UL-------------------------\n"); + fmt::print("rnti cqi ri mcs brate ok nok (%) | pusch pucch phr mcs brate ok nok (%) bsr\n"); + } + + set_metrics_helper(metrics.stack.rrc.ues.size(), metrics.stack.mac, metrics.phy); +} + std::string metrics_stdout::float_to_string(float f, int digits, int field_width) { std::ostringstream os; From ed92f2bd3480fafab10a4a9bd58dc85a6cf77e2a Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 15 Sep 2021 10:53:54 +0200 Subject: [PATCH 38/47] enb,mac_nr: remove EUTRA cell param for MAC-NR cell config calls * the old srsran_cell_cfg_t is only carried for SIB params * the SIB scheduling, etc needs to be ported and integrated into NR data structures * disbable SIB test for the moment --- lib/include/srsran/interfaces/gnb_mac_interfaces.h | 3 +-- srsenb/hdr/stack/mac/nr/mac_nr.h | 11 +++++------ srsenb/src/stack/mac/nr/mac_nr.cc | 3 +-- srsenb/src/stack/rrc/rrc_nr.cc | 6 ++++-- srsenb/test/common/dummy_classes_nr.h | 7 +------ srsenb/test/rrc/rrc_nr_test.cc | 3 ++- test/phy/dummy_gnb_stack.h | 2 +- 7 files changed, 15 insertions(+), 20 deletions(-) diff --git a/lib/include/srsran/interfaces/gnb_mac_interfaces.h b/lib/include/srsran/interfaces/gnb_mac_interfaces.h index c0f633fb6..0d233824e 100644 --- a/lib/include/srsran/interfaces/gnb_mac_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_mac_interfaces.h @@ -21,8 +21,7 @@ class mac_interface_rrc_nr { public: // Provides cell configuration including SIB periodicity, etc. - virtual int cell_cfg(const sched_interface::cell_cfg_t& cell, - srsran::const_span nr_cells) = 0; + virtual int cell_cfg(const std::vector& nr_cells) = 0; /// Allocates a new user/RNTI at MAC. Returns RNTI on success or SRSRAN_INVALID_RNTI otherwise. virtual uint16_t reserve_rnti(uint32_t enb_cc_idx) = 0; diff --git a/srsenb/hdr/stack/mac/nr/mac_nr.h b/srsenb/hdr/stack/mac/nr/mac_nr.h index cc6b423fb..e59d6ff97 100644 --- a/srsenb/hdr/stack/mac/nr/mac_nr.h +++ b/srsenb/hdr/stack/mac/nr/mac_nr.h @@ -50,8 +50,7 @@ public: void get_metrics(srsenb::mac_metrics_t& metrics); // MAC interface for RRC - int cell_cfg(const sched_interface::cell_cfg_t& cell, - srsran::const_span nr_cells) override; + int cell_cfg(const std::vector& nr_cells) override; uint16_t reserve_rnti(uint32_t enb_cc_idx) override; int read_pdu_bcch_bch(uint8_t* payload); int ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) override; @@ -104,10 +103,10 @@ private: std::atomic started = {false}; - const static uint32_t NUMEROLOGY_IDX = 0; /// only 15kHz supported at this stage - srsran::slot_point pdsch_slot, pusch_slot; - srsenb::sched_nr sched; - srsran::const_span cell_config; + const static uint32_t NUMEROLOGY_IDX = 0; /// only 15kHz supported at this stage + srsran::slot_point pdsch_slot, pusch_slot; + srsenb::sched_nr sched; + std::vector cell_config; // Map of active UEs pthread_rwlock_t rwlock = {}; diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 9cb333465..21620d240 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -95,8 +95,7 @@ void mac_nr::get_metrics(srsenb::mac_metrics_t& metrics) } } -int mac_nr::cell_cfg(const sched_interface::cell_cfg_t& eutra_cell_config, - srsran::const_span nr_cells) +int mac_nr::cell_cfg(const std::vector& nr_cells) { cell_config = nr_cells; sched.cell_cfg(nr_cells); diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 82f480d29..cb7213307 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -211,6 +211,8 @@ void rrc_nr::config_mac() // Fill MAC scheduler configuration for SIBs // TODO: use parsed cell NR cfg configuration std::vector sched_cells_cfg = {srsenb::get_default_cells_cfg(1)}; + + // FIXME: entire SI configuration, etc needs to be ported to NR sched_interface::cell_cfg_t cell_cfg; set_sched_cell_cfg_sib1(&cell_cfg, cfg.sib1); @@ -226,8 +228,8 @@ void rrc_nr::config_mac() // Copy Cell configuration cell_cfg.cell = cfg.cell; - // Configure MAC scheduler - mac->cell_cfg(cell_cfg, sched_cells_cfg); + // Configure MAC/scheduler + mac->cell_cfg(sched_cells_cfg); } int32_t rrc_nr::generate_sibs() diff --git a/srsenb/test/common/dummy_classes_nr.h b/srsenb/test/common/dummy_classes_nr.h index f33300ded..501f7a327 100644 --- a/srsenb/test/common/dummy_classes_nr.h +++ b/srsenb/test/common/dummy_classes_nr.h @@ -38,12 +38,7 @@ public: class mac_nr_dummy : public mac_interface_rrc_nr { public: - int cell_cfg(const sched_interface::cell_cfg_t& cell, - srsran::const_span nr_cells) override - { - cellcfgobj = cell; - return SRSRAN_SUCCESS; - } + int cell_cfg(const std::vector& nr_cells) override { return SRSRAN_SUCCESS; } uint16_t reserve_rnti(uint32_t enb_cc_idx) override { return 0x4601; } int ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) override { return SRSRAN_SUCCESS; } diff --git a/srsenb/test/rrc/rrc_nr_test.cc b/srsenb/test/rrc/rrc_nr_test.cc index 5803cf84a..7df9b3a72 100644 --- a/srsenb/test/rrc/rrc_nr_test.cc +++ b/srsenb/test/rrc/rrc_nr_test.cc @@ -93,7 +93,8 @@ int test_rrc_setup() int main() { - TESTASSERT(srsenb::test_sib_generation() == SRSRAN_SUCCESS); + // FIXME: disabled temporarily until SIB generation is fixed + // TESTASSERT(srsenb::test_sib_generation() == SRSRAN_SUCCESS); TESTASSERT(srsenb::test_rrc_setup() == SRSRAN_SUCCESS); return SRSRAN_SUCCESS; diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index 00cba3989..66ac4636b 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -344,7 +344,7 @@ public: mac.reset(new srsenb::mac_nr{&task_sched, sched_cfg}); mac->init(srsenb::mac_nr_args_t{}, nullptr, nullptr, &rlc_obj, &rrc_obj); std::vector cells_cfg = srsenb::get_default_cells_cfg(1, phy_cfg); - mac->cell_cfg(srsenb::sched_interface::cell_cfg_t{}, cells_cfg); + mac->cell_cfg(cells_cfg); // add UE to scheduler if (not use_dummy_sched and not args.wait_preamble) { From cc2d71183e100abef2625411f87c404ea84070cf Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 14 Sep 2021 21:10:40 +0200 Subject: [PATCH 39/47] ue,phy,nr: fix race condition when setting UL grant for Msg3 the Msg3 UL grant requires the TTI in which the RAR has been received to calcualte the correct timing. There was a race between PHY and Stack thread. This patch circumvents the issue by removing a PHY state member that only holds the RAR Rx timing. In the new interface the RA proc passes the Rx TTI to the PHY again when setting the UL grant so the PHY can calculate the correct timing without any state. --- lib/include/srsran/interfaces/ue_nr_interfaces.h | 8 +++++--- srsue/hdr/phy/nr/state.h | 2 -- srsue/hdr/phy/nr/worker_pool.h | 3 ++- srsue/hdr/phy/phy.h | 3 ++- srsue/src/phy/nr/cc_worker.cc | 9 +++------ srsue/src/phy/nr/worker_pool.cc | 13 +++++++++---- srsue/src/phy/phy.cc | 5 +++-- srsue/src/stack/mac_nr/proc_ra_nr.cc | 2 +- srsue/src/stack/mac_nr/test/mac_nr_test.cc | 5 ++++- srsue/src/stack/mac_nr/test/proc_ra_nr_test.cc | 5 ++++- srsue/src/stack/mac_nr/test/proc_sr_nr_test.cc | 5 ++++- 11 files changed, 37 insertions(+), 23 deletions(-) diff --git a/lib/include/srsran/interfaces/ue_nr_interfaces.h b/lib/include/srsran/interfaces/ue_nr_interfaces.h index 04fc73ee5..030082010 100644 --- a/lib/include/srsran/interfaces/ue_nr_interfaces.h +++ b/lib/include/srsran/interfaces/ue_nr_interfaces.h @@ -54,8 +54,9 @@ public: } mac_nr_grant_dl_t; typedef struct { - srsran::unique_byte_buffer_t payload; // TB when decoded successfully, nullptr otherwise - bool ack; // HARQ information + uint32_t rx_slot_idx; // Slot when DL TB has been decoded + srsran::unique_byte_buffer_t payload; // TB when decoded successfully, nullptr otherwise + bool ack; // HARQ information } tb_action_dl_result_t; // UL grant as conveyed between PHY and MAC @@ -212,7 +213,8 @@ public: } tx_request_t; // MAC informs PHY about UL grant included in RAR PDU - virtual int set_ul_grant(std::array packed_ul_grant, + virtual int set_ul_grant(uint32_t rar_slot_idx, + std::array packed_ul_grant, uint16_t rnti, srsran_rnti_type_t rnti_type) = 0; diff --git a/srsue/hdr/phy/nr/state.h b/srsue/hdr/phy/nr/state.h index f804b8a6a..c6f8c3186 100644 --- a/srsue/hdr/phy/nr/state.h +++ b/srsue/hdr/phy/nr/state.h @@ -90,8 +90,6 @@ public: /// Semaphore for aligning UL work srsran::tti_semaphore dl_ul_semaphore; - srsran_slot_cfg_t rar_grant_slot = {}; - state() { // Hard-coded values, this should be set when the measurements take place diff --git a/srsue/hdr/phy/nr/worker_pool.h b/srsue/hdr/phy/nr/worker_pool.h index c0d96232e..b49b90dfe 100644 --- a/srsue/hdr/phy/nr/worker_pool.h +++ b/srsue/hdr/phy/nr/worker_pool.h @@ -41,7 +41,8 @@ public: const int preamble_index, const float preamble_received_target_power, const float ta_base_sec = 0.0f) override; - int set_ul_grant(std::array array, + int set_ul_grant(uint32_t rx_tti, + std::array array, uint16_t rnti, srsran_rnti_type_t rnti_type) override; bool set_config(const srsran::phy_cfg_nr_t& cfg) override; diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index 96a98611d..2a4ec37c6 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -165,7 +165,8 @@ public: int init(const phy_args_nr_t& args_, stack_interface_phy_nr* stack_, srsran::radio_interface_phy* radio_) final; bool set_config(const srsran::phy_cfg_nr_t& cfg) final; - int set_ul_grant(std::array packed_ul_grant, + int set_ul_grant(uint32_t rx_tti, + std::array packed_ul_grant, uint16_t rnti, srsran_rnti_type_t rnti_type) final; void send_prach(const uint32_t prach_occasion, diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index 74210d093..337baa17e 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -336,14 +336,11 @@ bool cc_worker::decode_pdsch_dl() // Notify MAC about PDSCH decoding result mac_interface_phy_nr::tb_action_dl_result_t mac_dl_result = {}; - mac_dl_result.ack = pdsch_res.tb[0].crc; - mac_dl_result.payload = mac_dl_result.ack ? std::move(data) : nullptr; // only pass data when successful + mac_dl_result.rx_slot_idx = dl_slot_cfg.idx; // Rx TTI for this TB (required for correct Msg3 timing) + mac_dl_result.ack = pdsch_res.tb[0].crc; + mac_dl_result.payload = mac_dl_result.ack ? std::move(data) : nullptr; // only pass data when successful phy.stack->tb_decoded(cc_idx, mac_dl_grant, std::move(mac_dl_result)); - if (pdsch_cfg.grant.rnti_type == srsran_rnti_type_ra) { - phy.rar_grant_slot = dl_slot_cfg; - } - if (pdsch_res.tb[0].crc) { // Generate DL metrics dl_metrics_t dl_m = {}; diff --git a/srsue/src/phy/nr/worker_pool.cc b/srsue/src/phy/nr/worker_pool.cc index 00a2fb446..d41183d4b 100644 --- a/srsue/src/phy/nr/worker_pool.cc +++ b/srsue/src/phy/nr/worker_pool.cc @@ -99,7 +99,9 @@ void worker_pool::send_prach(const uint32_t prach_occasion, prach_buffer->prepare_to_send(preamble_index); } -int worker_pool::set_ul_grant(std::array packed_ul_grant, +// called from Stack thread when processing RAR PDU +int worker_pool::set_ul_grant(uint32_t rar_slot_idx, + std::array packed_ul_grant, uint16_t rnti, srsran_rnti_type_t rnti_type) { @@ -113,21 +115,24 @@ int worker_pool::set_ul_grant(std::array pac srsran_vec_u8_copy(dci_msg.payload, packed_ul_grant.data(), SRSRAN_RAR_UL_GRANT_NBITS); srsran_dci_ul_nr_t dci_ul = {}; - if (srsran_dci_nr_ul_unpack(NULL, &dci_msg, &dci_ul) < SRSRAN_SUCCESS) { logger.error("Couldn't unpack UL grant"); return SRSRAN_ERROR; } + // initialize with Rx TTI of RAR + srsran_slot_cfg_t msg3_slot_cfg = {}; + msg3_slot_cfg.idx = rar_slot_idx; + if (logger.info.enabled()) { std::array str; srsran_dci_nr_t dci = {}; srsran_dci_ul_nr_to_str(&dci, &dci_ul, str.data(), str.size()); - logger.set_context(phy_state.rar_grant_slot.idx); + logger.set_context(msg3_slot_cfg.idx); logger.info("Setting RAR Grant: %s", str.data()); } - phy_state.set_ul_pending_grant(phy_state.rar_grant_slot, dci_ul); + phy_state.set_ul_pending_grant(msg3_slot_cfg, dci_ul); return SRSRAN_SUCCESS; } diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index ede466fd1..c6fb51f3a 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -622,11 +622,12 @@ int phy::init(const phy_args_nr_t& args_, stack_interface_phy_nr* stack_, srsran return SRSRAN_SUCCESS; } -int phy::set_ul_grant(std::array packed_ul_grant, +int phy::set_ul_grant(uint32_t rar_slot_idx, + std::array packed_ul_grant, uint16_t rnti, srsran_rnti_type_t rnti_type) { - return nr_workers.set_ul_grant(packed_ul_grant, rnti, rnti_type); + return nr_workers.set_ul_grant(rar_slot_idx, packed_ul_grant, rnti, rnti_type); } void phy::send_prach(const uint32_t prach_occasion, diff --git a/srsue/src/stack/mac_nr/proc_ra_nr.cc b/srsue/src/stack/mac_nr/proc_ra_nr.cc index 4177df8b0..402bec56b 100644 --- a/srsue/src/stack/mac_nr/proc_ra_nr.cc +++ b/srsue/src/stack/mac_nr/proc_ra_nr.cc @@ -207,7 +207,7 @@ void proc_ra_nr::ra_response_reception(const mac_interface_phy_nr::tb_action_dl_ temp_crnti = subpdu.get_temp_crnti(); // Set Temporary-C-RNTI if provided, otherwise C-RNTI is ok - phy->set_ul_grant(subpdu.get_ul_grant(), temp_crnti, srsran_rnti_type_ra); + phy->set_ul_grant(tb.rx_slot_idx, subpdu.get_ul_grant(), temp_crnti, srsran_rnti_type_ra); // reset all parameters that are used before rar rar_rnti = SRSRAN_INVALID_RNTI; diff --git a/srsue/src/stack/mac_nr/test/mac_nr_test.cc b/srsue/src/stack/mac_nr/test/mac_nr_test.cc index 17de4be67..b7899bb10 100644 --- a/srsue/src/stack/mac_nr/test/mac_nr_test.cc +++ b/srsue/src/stack/mac_nr/test/mac_nr_test.cc @@ -36,7 +36,10 @@ public: preamble_received_target_power = preamble_received_target_power_; } int tx_request(const tx_request_t& request) override { return 0; } - int set_ul_grant(std::array, uint16_t rnti, srsran_rnti_type_t rnti_type) override + int set_ul_grant(uint32_t rar_slot_idx, + std::array, + uint16_t rnti, + srsran_rnti_type_t rnti_type) override { return 0; } diff --git a/srsue/src/stack/mac_nr/test/proc_ra_nr_test.cc b/srsue/src/stack/mac_nr/test/proc_ra_nr_test.cc index 4867c6edb..fabf2632e 100644 --- a/srsue/src/stack/mac_nr/test/proc_ra_nr_test.cc +++ b/srsue/src/stack/mac_nr/test/proc_ra_nr_test.cc @@ -30,7 +30,10 @@ public: preamble_received_target_power = preamble_received_target_power_; } int tx_request(const tx_request_t& request) override { return 0; } - int set_ul_grant(std::array, uint16_t rnti, srsran_rnti_type_t rnti_type) override + int set_ul_grant(uint32_t rar_slot_idx, + std::array, + uint16_t rnti, + srsran_rnti_type_t rnti_type) override { return 0; } diff --git a/srsue/src/stack/mac_nr/test/proc_sr_nr_test.cc b/srsue/src/stack/mac_nr/test/proc_sr_nr_test.cc index 666bce515..83ecb1fad 100644 --- a/srsue/src/stack/mac_nr/test/proc_sr_nr_test.cc +++ b/srsue/src/stack/mac_nr/test/proc_sr_nr_test.cc @@ -31,7 +31,10 @@ public: preamble_received_target_power = preamble_received_target_power_; } int tx_request(const tx_request_t& request) override { return 0; } - int set_ul_grant(std::array, uint16_t rnti, srsran_rnti_type_t rnti_type) override + int set_ul_grant(uint32_t rar_slot_idx, + std::array, + uint16_t rnti, + srsran_rnti_type_t rnti_type) override { return 0; } From 2248e63219ff065e487b73b8fdff036f90d31576 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 15 Sep 2021 10:04:03 +0200 Subject: [PATCH 40/47] ue,proc_ra_nr: add mutex to protect access from PHY and Stack detected with TSAN --- srsue/hdr/stack/mac_nr/proc_ra_nr.h | 1 + srsue/src/stack/mac_nr/proc_ra_nr.cc | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/srsue/hdr/stack/mac_nr/proc_ra_nr.h b/srsue/hdr/stack/mac_nr/proc_ra_nr.h index d3e2a02b0..3658c0c59 100644 --- a/srsue/hdr/stack/mac_nr/proc_ra_nr.h +++ b/srsue/hdr/stack/mac_nr/proc_ra_nr.h @@ -64,6 +64,7 @@ private: int ra_window_length = -1, ra_window_start = -1; uint16_t rar_rnti = SRSRAN_INVALID_RNTI; uint16_t temp_crnti = SRSRAN_INVALID_RNTI; + std::mutex mutex; srsran::rach_nr_cfg_t rach_cfg = {}; bool configured = false; diff --git a/srsue/src/stack/mac_nr/proc_ra_nr.cc b/srsue/src/stack/mac_nr/proc_ra_nr.cc index 402bec56b..745216473 100644 --- a/srsue/src/stack/mac_nr/proc_ra_nr.cc +++ b/srsue/src/stack/mac_nr/proc_ra_nr.cc @@ -114,11 +114,13 @@ bool proc_ra_nr::has_rar_rnti() bool proc_ra_nr::has_temp_crnti() { + std::lock_guard lock(mutex); return temp_crnti != SRSRAN_INVALID_RNTI; } uint16_t proc_ra_nr::get_temp_crnti() { + std::lock_guard lock(mutex); return temp_crnti; } @@ -180,6 +182,7 @@ void proc_ra_nr::ra_preamble_transmission() // 5.1.4 Random Access Preamble transmission void proc_ra_nr::ra_response_reception(const mac_interface_phy_nr::tb_action_dl_result_t& tb) { + std::lock_guard lock(mutex); if (state != WAITING_FOR_RESPONSE_RECEPTION) { logger.warning( "Wrong state for ra reponse reception %s (expected state %s)", @@ -265,6 +268,7 @@ void proc_ra_nr::ra_contention_resolution(uint64_t rx_contention_id) void proc_ra_nr::ra_completion() { + std::lock_guard lock(mutex); if (state != WAITING_FOR_COMPLETION) { logger.warning("Wrong state for ra completion by phy %s (expected state %s)", srsran::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, state), @@ -279,6 +283,7 @@ void proc_ra_nr::ra_completion() void proc_ra_nr::ra_error() { + std::lock_guard lock(mutex); temp_crnti = SRSRAN_INVALID_RNTI; preamble_transmission_counter++; contention_resolution_timer.stop(); From ab6210b1fcdcc3c9f47e70f254b3ae361ed0e5a2 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 15 Sep 2021 10:05:44 +0200 Subject: [PATCH 41/47] ue,proc_sr_nr: add mutex to protect access from PHY and Stack also detected by TSAN --- srsue/hdr/stack/mac_nr/proc_sr_nr.h | 7 +++++-- srsue/src/stack/mac_nr/proc_sr_nr.cc | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/srsue/hdr/stack/mac_nr/proc_sr_nr.h b/srsue/hdr/stack/mac_nr/proc_sr_nr.h index 1d0224350..ab57b0a5e 100644 --- a/srsue/hdr/stack/mac_nr/proc_sr_nr.h +++ b/srsue/hdr/stack/mac_nr/proc_sr_nr.h @@ -13,10 +13,11 @@ #ifndef SRSUE_PROC_SR_NR_H #define SRSUE_PROC_SR_NR_H -#include "srsue/hdr/stack/mac_nr/mac_nr_interfaces.h" #include "srsran/interfaces/ue_mac_interfaces.h" #include "srsran/interfaces/ue_nr_interfaces.h" #include "srsran/srslog/srslog.h" +#include "srsue/hdr/stack/mac_nr/mac_nr_interfaces.h" +#include #include /// Scheduling Request procedure as defined in 5.4.4 of 38.321 @@ -39,6 +40,7 @@ public: bool sr_opportunity(uint32_t tti, uint32_t sr_id, bool meas_gap, bool ul_sch_tx); private: + void reset_unsafe(); int sr_counter = 0; bool is_pending_sr = false; @@ -49,7 +51,8 @@ private: phy_interface_mac_nr* phy = nullptr; srslog::basic_logger& logger; - bool initiated = false; + bool initiated = false; + std::mutex mutex; }; } // namespace srsue diff --git a/srsue/src/stack/mac_nr/proc_sr_nr.cc b/srsue/src/stack/mac_nr/proc_sr_nr.cc index a35db5c69..e68b0483b 100644 --- a/srsue/src/stack/mac_nr/proc_sr_nr.cc +++ b/srsue/src/stack/mac_nr/proc_sr_nr.cc @@ -21,6 +21,7 @@ proc_sr_nr::proc_sr_nr(srslog::basic_logger& logger) : logger(logger) {} int32_t proc_sr_nr::init(mac_interface_sr_nr* mac_, phy_interface_mac_nr* phy_, rrc_interface_mac* rrc_) { + std::lock_guard lock(mutex); rrc = rrc_; mac = mac_; phy = phy_; @@ -32,6 +33,12 @@ int32_t proc_sr_nr::init(mac_interface_sr_nr* mac_, phy_interface_mac_nr* phy_, } void proc_sr_nr::reset() +{ + std::lock_guard lock(mutex); + reset_unsafe(); +} + +void proc_sr_nr::reset_unsafe() { is_pending_sr = false; } @@ -70,6 +77,7 @@ int32_t proc_sr_nr::set_config(const srsran::sr_cfg_nr_t& cfg_) void proc_sr_nr::step(uint32_t tti) { + std::lock_guard lock(mutex); if (!initiated) { return; } @@ -84,7 +92,7 @@ void proc_sr_nr::step(uint32_t tti) // 2> initiate a Random Access procedure (see clause 5.1) on the SpCell and cancel the pending SR. logger.info("SR: PUCCH not configured. Starting RA procedure"); mac->start_ra(); - reset(); + reset_unsafe(); return; } @@ -102,12 +110,13 @@ void proc_sr_nr::step(uint32_t tti) // ... TODO mac->start_ra(); - reset(); + reset_unsafe(); } } bool proc_sr_nr::sr_opportunity(uint32_t tti, uint32_t sr_id, bool meas_gap, bool ul_sch_tx) { + std::lock_guard lock(mutex); // 2> when the MAC entity has an SR transmission occasion on the valid PUCCH resource for SR configured; and if (!initiated || !cfg.enabled || !is_pending_sr) { return false; @@ -147,6 +156,7 @@ bool proc_sr_nr::sr_opportunity(uint32_t tti, uint32_t sr_id, bool meas_gap, boo void proc_sr_nr::start() { + std::lock_guard lock(mutex); if (initiated) { if (not is_pending_sr) { logger.info("SR: Starting procedure"); From 36af79b9d5005aa78ae8566839053be7dfc811a9 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 15 Sep 2021 10:06:43 +0200 Subject: [PATCH 42/47] ue,proc_bsr_nr: add missing mutex when redeading SBSR detected with TSAN --- srsue/src/stack/mac_nr/proc_bsr_nr.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/srsue/src/stack/mac_nr/proc_bsr_nr.cc b/srsue/src/stack/mac_nr/proc_bsr_nr.cc index 7cca98ede..1fd3387ab 100644 --- a/srsue/src/stack/mac_nr/proc_bsr_nr.cc +++ b/srsue/src/stack/mac_nr/proc_bsr_nr.cc @@ -136,8 +136,15 @@ bool proc_bsr_nr::check_new_data(const mac_buffer_states_t& new_buffer_state) return false; } +/** + * @brief Called by Mux through PHY worker whenever a new SBSR CE + * needs to be included in a MAC PDU. + * + * @return SBSR CE for subPDU containing the buffer state of the highest priority LCG + */ srsran::mac_sch_subpdu_nr::lcg_bsr_t proc_bsr_nr::generate_sbsr() { + std::lock_guard lock(mutex); srsran::mac_sch_subpdu_nr::lcg_bsr_t sbsr = {}; if (buffer_state.nof_lcgs_with_data > 0) { sbsr.lcg_id = buffer_state.last_non_zero_lcg; From e8a464228d34bba1cbd1047c2d0de0ff82ea6bed Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Thu, 16 Sep 2021 11:53:12 +0200 Subject: [PATCH 43/47] Cleaned string helpers --- lib/include/srsran/common/string_helpers.h | 45 +++++++++++++++++ srsepc/hdr/hss/hss.h | 3 +- srsepc/src/hss/hss.cc | 58 +++++----------------- srsue/hdr/stack/upper/nas.h | 14 ------ 4 files changed, 58 insertions(+), 62 deletions(-) diff --git a/lib/include/srsran/common/string_helpers.h b/lib/include/srsran/common/string_helpers.h index d20692568..a55ed0254 100644 --- a/lib/include/srsran/common/string_helpers.h +++ b/lib/include/srsran/common/string_helpers.h @@ -15,6 +15,8 @@ #include "srsran/srslog/bundled/fmt/format.h" #include +#include +#include #include #include #include @@ -119,6 +121,49 @@ const char* to_c_str(fmt::basic_memory_buffer& mem_buffer) return mem_buffer.data(); } +static inline bool replace(std::string& str, const std::string& from, const std::string& to) +{ + size_t start_pos = str.find(from); + if (start_pos == std::string::npos) + return false; + str.replace(start_pos, from.length(), to); + return true; +} + +static inline std::vector split_string(const std::string& str, char delimiter) +{ + std::vector tokens; + std::string token; + std::istringstream tokenStream(str); + + while (std::getline(tokenStream, token, delimiter)) { + tokens.push_back(token); + } + return tokens; +} + +static inline void get_uint_vec_from_hex_str(const std::string& key_str, uint8_t* key, uint len) +{ + const char* pos = key_str.c_str(); + + for (uint count = 0; count < len; count++) { + sscanf(pos, "%2hhx", &key[count]); + pos += 2; + } + return; +} + +static inline std::string hex_string(uint8_t* hex, int size) +{ + std::stringstream ss; + + ss << std::hex << std::setfill('0'); + for (int i = 0; i < size; i++) { + ss << std::setw(2) << static_cast(hex[i]); + } + return ss.str(); +} + } // namespace srsran #endif // SRSRAN_STRING_HELPERS_H diff --git a/srsepc/hdr/hss/hss.h b/srsepc/hdr/hss/hss.h index 953eb2941..43e12d28e 100644 --- a/srsepc/hdr/hss/hss.h +++ b/srsepc/hdr/hss/hss.h @@ -24,7 +24,7 @@ #include "srsran/interfaces/epc_interfaces.h" #include "srsran/srslog/srslog.h" #include -#include + #include #define LTE_FDD_ENB_IND_HE_N_BITS 5 @@ -94,7 +94,6 @@ private: void resync_sqn_milenage(hss_ue_ctx_t* ue_ctx, uint8_t* auts); void resync_sqn_xor(hss_ue_ctx_t* ue_ctx, uint8_t* auts); - std::vector split_string(const std::string& str, char delimiter); void get_uint_vec_from_hex_str(const std::string& key_str, uint8_t* key, uint len); void increment_ue_sqn(hss_ue_ctx_t* ue_ctx); diff --git a/srsepc/src/hss/hss.cc b/srsepc/src/hss/hss.cc index 114d28d30..2c6e5468d 100644 --- a/srsepc/src/hss/hss.cc +++ b/srsepc/src/hss/hss.cc @@ -11,6 +11,7 @@ */ #include "srsepc/hdr/hss/hss.h" #include "srsran/common/security.h" +#include "srsran/common/string_helpers.h" #include #include // for printing uint64_t #include @@ -94,7 +95,7 @@ bool hss::read_db_file(std::string db_filename) while (std::getline(m_db_file, line)) { if (line[0] != '#' && line.length() > 0) { uint column_size = 10; - std::vector split = split_string(line, ','); + std::vector split = srsran::split_string(line, ','); if (split.size() != column_size) { m_logger.error("Error parsing UE database. Wrong number of columns in .csv"); m_logger.error("Columns: %zd, Expected %d.", split.size(), column_size); @@ -115,20 +116,20 @@ bool hss::read_db_file(std::string db_filename) return false; } ue_ctx->imsi = strtoull(split[2].c_str(), nullptr, 10); - get_uint_vec_from_hex_str(split[3], ue_ctx->key, 16); + srsran::get_uint_vec_from_hex_str(split[3], ue_ctx->key, 16); if (split[4] == std::string("op")) { ue_ctx->op_configured = true; - get_uint_vec_from_hex_str(split[5], ue_ctx->op, 16); + srsran::get_uint_vec_from_hex_str(split[5], ue_ctx->op, 16); srsran::compute_opc(ue_ctx->key, ue_ctx->op, ue_ctx->opc); } else if (split[4] == std::string("opc")) { ue_ctx->op_configured = false; - get_uint_vec_from_hex_str(split[5], ue_ctx->opc, 16); + srsran::get_uint_vec_from_hex_str(split[5], ue_ctx->opc, 16); } else { m_logger.error("Neither OP nor OPc configured."); return false; } - get_uint_vec_from_hex_str(split[6], ue_ctx->amf, 2); - get_uint_vec_from_hex_str(split[7], ue_ctx->sqn, 6); + srsran::get_uint_vec_from_hex_str(split[6], ue_ctx->amf, 2); + srsran::get_uint_vec_from_hex_str(split[7], ue_ctx->sqn, 6); m_logger.debug("Added user from DB, IMSI: %015" PRIu64 "", ue_ctx->imsi); m_logger.debug(ue_ctx->key, 16, "User Key : "); @@ -214,19 +215,19 @@ bool hss::write_db_file(std::string db_filename) m_db_file << ","; m_db_file << std::setfill('0') << std::setw(15) << it->second->imsi; m_db_file << ","; - m_db_file << hex_string(it->second->key, 16); + m_db_file << srsran::hex_string(it->second->key, 16); m_db_file << ","; if (it->second->op_configured) { m_db_file << "op,"; - m_db_file << hex_string(it->second->op, 16); + m_db_file << srsran::hex_string(it->second->op, 16); } else { m_db_file << "opc,"; - m_db_file << hex_string(it->second->opc, 16); + m_db_file << srsran::hex_string(it->second->opc, 16); } m_db_file << ","; - m_db_file << hex_string(it->second->amf, 2); + m_db_file << srsran::hex_string(it->second->amf, 2); m_db_file << ","; - m_db_file << hex_string(it->second->sqn, 6); + m_db_file << srsran::hex_string(it->second->sqn, 6); m_db_file << ","; m_db_file << it->second->qci; if (it->second->static_ip_addr != "0.0.0.0") { @@ -611,41 +612,6 @@ hss_ue_ctx_t* hss::get_ue_ctx(uint64_t imsi) return ue_ctx_it->second.get(); } -/* Helper functions*/ -std::vector hss::split_string(const std::string& str, char delimiter) -{ - std::vector tokens; - std::string token; - std::istringstream tokenStream(str); - - while (std::getline(tokenStream, token, delimiter)) { - tokens.push_back(token); - } - return tokens; -} - -void hss::get_uint_vec_from_hex_str(const std::string& key_str, uint8_t* key, uint len) -{ - const char* pos = key_str.c_str(); - - for (uint count = 0; count < len; count++) { - sscanf(pos, "%2hhx", &key[count]); - pos += 2; - } - return; -} - -std::string hss::hex_string(uint8_t* hex, int size) -{ - std::stringstream ss; - - ss << std::hex << std::setfill('0'); - for (int i = 0; i < size; i++) { - ss << std::setw(2) << static_cast(hex[i]); - } - return ss.str(); -} - std::map hss::get_ip_to_imsi(void) const { return m_ip_to_imsi; diff --git a/srsue/hdr/stack/upper/nas.h b/srsue/hdr/stack/upper/nas.h index d919a6050..42d643b63 100644 --- a/srsue/hdr/stack/upper/nas.h +++ b/srsue/hdr/stack/upper/nas.h @@ -258,20 +258,6 @@ private: return true; } - std::vector split_string(const std::string input) - { - std::vector list; - std::stringstream ss(input); - while (ss.good()) { - std::string substr; - getline(ss, substr, ','); - if (not substr.empty()) { - list.push_back(strtol(substr.c_str(), nullptr, 10)); - } - } - return list; - } - // NAS Idle procedures class plmn_search_proc; // PLMN selection proc (fwd declared) From b127327684f96e84a64cf9969d1e2b28d4ed7d60 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 16 Sep 2021 11:53:47 +0200 Subject: [PATCH 44/47] enb,s1ap: print filename when writing S1AP PCAP --- lib/include/srsran/common/s1ap_pcap.h | 14 ++++++-------- lib/src/common/s1ap_pcap.cc | 7 ++++--- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/include/srsran/common/s1ap_pcap.h b/lib/include/srsran/common/s1ap_pcap.h index 819e4845e..f2a0b1164 100644 --- a/lib/include/srsran/common/s1ap_pcap.h +++ b/lib/include/srsran/common/s1ap_pcap.h @@ -14,25 +14,23 @@ #define SRSRAN_S1AP_PCAP_H #include "srsran/common/pcap.h" +#include namespace srsran { class s1ap_pcap { public: - s1ap_pcap() - { - enable_write = false; - pcap_file = NULL; - } + s1ap_pcap() = default; void enable(); - void open(const char* filename); + void open(const char* filename_); void close(); void write_s1ap(uint8_t* pdu, uint32_t pdu_len_bytes); private: - bool enable_write; - FILE* pcap_file; + bool enable_write = false; + std::string filename; + FILE* pcap_file = nullptr; }; } // namespace srsran diff --git a/lib/src/common/s1ap_pcap.cc b/lib/src/common/s1ap_pcap.cc index b6a91c1e3..ce06c5a6e 100644 --- a/lib/src/common/s1ap_pcap.cc +++ b/lib/src/common/s1ap_pcap.cc @@ -21,14 +21,15 @@ void s1ap_pcap::enable() { enable_write = true; } -void s1ap_pcap::open(const char* filename) +void s1ap_pcap::open(const char* filename_) { - pcap_file = DLT_PCAP_Open(S1AP_LTE_DLT, filename); + filename = filename_; + pcap_file = DLT_PCAP_Open(S1AP_LTE_DLT, filename.c_str()); enable_write = true; } void s1ap_pcap::close() { - fprintf(stdout, "Saving S1AP PCAP file\n"); + fprintf(stdout, "Saving S1AP PCAP file (DLT=%d) to %s\n", S1AP_LTE_DLT, filename.c_str()); DLT_PCAP_Close(pcap_file); } From c9478a43064cf45015a172a82b53bf45fc4fcda2 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 16 Sep 2021 11:54:25 +0200 Subject: [PATCH 45/47] enb,erab: fix error handling when setting up ERABs when handling ERAB setup requests from MME, don't add the ERAB before all checks have been performed, otherwise the ERAB needs to be removed again. Since this was not the case, invalid NAS PDUs have been transmitted. Also raise error level for some events to error since the eNB misses a config or is mal-configured and cant recover from that. --- srsenb/src/stack/rrc/rrc_bearer_cfg.cc | 26 ++++++++++++++------------ srsenb/src/stack/rrc/rrc_ue.cc | 2 ++ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc index c300ba9ac..88807add3 100644 --- a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc +++ b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc @@ -258,19 +258,14 @@ int bearer_cfg_handler::add_erab(uint8_t } const rrc_cfg_qci_t& qci_cfg = qci_it->second; - erabs[erab_id].id = erab_id; - erabs[erab_id].lcid = lcid; - erabs[erab_id].qos_params = qos; - erabs[erab_id].address = addr; - erabs[erab_id].teid_out = teid_out; - + // perform checks on QCI config if (addr.length() > 32) { logger->error("Only addresses with length <= 32 are supported"); cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::invalid_qos_combination; return SRSRAN_ERROR; } if (qos.gbr_qos_info_present and not qci_cfg.configured) { - logger->warning("Provided E-RAB id=%d QoS not supported", erab_id); + logger->error("Provided E-RAB id=%d QoS not supported", erab_id); cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::invalid_qos_combination; return SRSRAN_ERROR; } @@ -280,21 +275,28 @@ int bearer_cfg_handler::add_erab(uint8_t int16_t pbr_kbps = qci_cfg.lc_cfg.prioritised_bit_rate.to_number(); uint64_t pbr = pbr_kbps < 0 ? std::numeric_limits::max() : pbr_kbps * 1000u; if (req_bitrate > pbr) { - logger->warning("Provided E-RAB id=%d QoS not supported (guaranteed bitrates)", erab_id); + logger->error("Provided E-RAB id=%d QoS not supported (guaranteed bitrates)", erab_id); cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::invalid_qos_combination; return SRSRAN_ERROR; } } if (qos.alloc_retention_prio.pre_emption_cap.value == asn1::s1ap::pre_emption_cap_opts::may_trigger_pre_emption and qos.alloc_retention_prio.prio_level < qci_cfg.lc_cfg.prio) { - logger->warning("Provided E-RAB id=%d QoS not supported (priority %d < %d)", - erab_id, - qos.alloc_retention_prio.prio_level, - qci_cfg.lc_cfg.prio); + logger->error("Provided E-RAB id=%d QoS not supported (priority %d < %d)", + erab_id, + qos.alloc_retention_prio.prio_level, + qci_cfg.lc_cfg.prio); cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::invalid_qos_combination; return SRSRAN_ERROR; } + // Consider ERAB as accepted + erabs[erab_id].id = erab_id; + erabs[erab_id].lcid = lcid; + erabs[erab_id].qos_params = qos; + erabs[erab_id].address = addr; + erabs[erab_id].teid_out = teid_out; + if (not nas_pdu.empty()) { erab_info_list[erab_id].assign(nas_pdu.begin(), nas_pdu.end()); logger->info( diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index b6510c7e7..059d0f288 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -1163,11 +1163,13 @@ int rrc::ue::setup_erab(uint16_t erab_ return SRSRAN_ERROR; } if (bearer_list.add_erab(erab_id, qos_params, addr, gtpu_teid_out, nas_pdu, cause) != SRSRAN_SUCCESS) { + parent->logger.error("Couldn't add E-RAB id=%d for rnti=0x%x", erab_id, rnti); return SRSRAN_ERROR; } if (bearer_list.add_gtpu_bearer(erab_id) != SRSRAN_SUCCESS) { cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::radio_res_not_available; bearer_list.release_erab(erab_id); + parent->logger.error("Couldn't add E-RAB id=%d for rnti=0x%x", erab_id, rnti); return SRSRAN_ERROR; } return SRSRAN_SUCCESS; From e563e5918e69fda143272dec14f0f872e4cf3d63 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 14 Sep 2021 15:30:08 +0200 Subject: [PATCH 46/47] rf_imp: fail opening RF altogether if specified device fails to open we've had a few runs in the CI where opening the specified RF device failed but the eNB/UE still continued to run, just picking the next available run. This led to false-positive tests. The policy should be that whenever the user specified a RF device to be openend, and this device fails, the whole process should fail and the application should exit. The auto-detection mode is still available but only if no device name is specified at all. --- lib/src/phy/rf/rf_imp.c | 43 +++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/lib/src/phy/rf/rf_imp.c b/lib/src/phy/rf/rf_imp.c index 9a6d25966..bccfe5758 100644 --- a/lib/src/phy/rf/rf_imp.c +++ b/lib/src/phy/rf/rf_imp.c @@ -93,32 +93,33 @@ const char* srsran_rf_get_devname(srsran_rf_t* rf) int srsran_rf_open_devname(srsran_rf_t* rf, const char* devname, char* args, uint32_t nof_channels) { rf->thread_gain_run = false; - /* Try to open the device if name is provided */ - if (devname) { - if (devname[0] != '\0') { - int i = 0; - while (available_devices[i] != NULL) { - if (!strcasecmp(available_devices[i]->name, devname)) { - rf->dev = available_devices[i]; - return available_devices[i]->srsran_rf_open_multi(args, &rf->handler, nof_channels); - } - i++; + + // Try to open the device if name is provided + if (devname && devname[0] != '\0') { + int i = 0; + while (available_devices[i] != NULL) { + if (!strcasecmp(available_devices[i]->name, devname)) { + rf->dev = available_devices[i]; + return available_devices[i]->srsran_rf_open_multi(args, &rf->handler, nof_channels); } - printf("Device %s not found. Switching to auto mode\n", devname); + i++; } - } - - /* If in auto mode or provided device not found, try to open in order of apperance in available_devices[] array */ - int i = 0; - while (available_devices[i] != NULL) { - if (!available_devices[i]->srsran_rf_open_multi(args, &rf->handler, nof_channels)) { - rf->dev = available_devices[i]; - return 0; + // provided device not found, abort + return SRSRAN_ERROR; + } else { + // auto-mode, try to open in order of apperance in available_devices[] array + int i = 0; + while (available_devices[i] != NULL) { + if (!available_devices[i]->srsran_rf_open_multi(args, &rf->handler, nof_channels)) { + rf->dev = available_devices[i]; + return SRSRAN_SUCCESS; + } + i++; } - i++; } + ERROR("No compatible RF frontend found"); - return -1; + return SRSRAN_ERROR; } const char* srsran_rf_name(srsran_rf_t* rf) From c988fc49b4aab21cc137dc0c7589fb84785d053d Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 16 Sep 2021 11:44:59 +0100 Subject: [PATCH 47/47] Remove comparison between LGC priority and allocation retantion priority, as these do not seem related. --- srsenb/src/stack/rrc/rrc_bearer_cfg.cc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc index 88807add3..6870d22f0 100644 --- a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc +++ b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc @@ -280,15 +280,6 @@ int bearer_cfg_handler::add_erab(uint8_t return SRSRAN_ERROR; } } - if (qos.alloc_retention_prio.pre_emption_cap.value == asn1::s1ap::pre_emption_cap_opts::may_trigger_pre_emption and - qos.alloc_retention_prio.prio_level < qci_cfg.lc_cfg.prio) { - logger->error("Provided E-RAB id=%d QoS not supported (priority %d < %d)", - erab_id, - qos.alloc_retention_prio.prio_level, - qci_cfg.lc_cfg.prio); - cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::invalid_qos_combination; - return SRSRAN_ERROR; - } // Consider ERAB as accepted erabs[erab_id].id = erab_id;