diff --git a/.clang-tidy b/.clang-tidy index 99d622a7b..c5a75d316 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -20,6 +20,8 @@ Checks: '*,-fuchsia-*, -google-runtime-references,-google-readability-casting,-google-build-using-namespace, google-default-arguments,-cppcoreguidelines-pro-bounds-pointer-arithmetic, -cert-err58-cpp, + -misc-non-private-member-variables-in-classes,-altera-struct-pack-align,-readability-uppercase-literal-suffix, + -cppcoreguidelines-non-private-member-variables-in-classes, readability-identifier-naming' HeaderFilterRegex: '' AnalyzeTemporaryDtors: false diff --git a/CMakeLists.txt b/CMakeLists.txt index f03cc15c5..82bc168d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,6 +92,8 @@ option(ENABLE_TIMEPROF "Enable time profiling" ON) option(FORCE_32BIT "Add flags to force 32 bit compilation" OFF) +option(ENABLE_SRSLOG_TRACING "Enable event tracing using srslog" OFF) + # Users that want to try this feature need to make sure the lto plugin is # loaded by bintools (ar, nm, ...). Older versions of bintools will not do # it automatically so it is necessary to use the gcc wrappers of the compiler @@ -105,6 +107,17 @@ else(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") set(GCC_ARCH native CACHE STRING "GCC compile for specific architecture.") endif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") +# On RAM constrained (embedded) systems it may be useful to limit parallel compilation with, e.g. -DPARALLEL_COMPILE_JOBS=1 +if (PARALLEL_COMPILE_JOBS) + set(CMAKE_JOB_POOL_COMPILE compile_job_pool${CMAKE_CURRENT_SOURCE_DIR}) + string (REGEX REPLACE "[^a-zA-Z0-9]+" "_" CMAKE_JOB_POOL_COMPILE ${CMAKE_JOB_POOL_COMPILE}) + set_property(GLOBAL APPEND PROPERTY JOB_POOLS ${CMAKE_JOB_POOL_COMPILE}=${PARALLEL_COMPILE_JOBS}) + message(STATUS "${CMAKE_CURRENT_SOURCE_DIR}: Limiting compiler jobs to ${PARALLEL_COMPILE_JOBS}") +endif () + +if (ENABLE_SRSLOG_TRACING) + add_definitions(-DENABLE_SRSLOG_EVENT_TRACE) +endif (ENABLE_SRSLOG_TRACING) ######################################################################## # Find dependencies diff --git a/lib/include/srslte/adt/bounded_bitset.h b/lib/include/srslte/adt/bounded_bitset.h index 99c760484..a96b2b4de 100644 --- a/lib/include/srslte/adt/bounded_bitset.h +++ b/lib/include/srslte/adt/bounded_bitset.h @@ -23,6 +23,7 @@ #define SRSLTE_DYN_BITSET_H #include "adt_utils.h" +#include "srslte/srslog/bundled/fmt/format.h" #include #include #include @@ -41,9 +42,9 @@ class bounded_bitset static const size_t bits_per_word = 8 * sizeof(word_t); public: - constexpr bounded_bitset() : buffer(), cur_size(0) {} + constexpr bounded_bitset() = default; - constexpr explicit bounded_bitset(size_t cur_size_) : buffer(), cur_size(cur_size_) {} + constexpr explicit bounded_bitset(size_t cur_size_) : cur_size(cur_size_) {} constexpr size_t max_size() const noexcept { return N; } @@ -62,7 +63,7 @@ public: cur_size = new_size; sanitize_(); for (size_t i = nof_words_(); i < max_nof_words_(); ++i) { - get_word_(i) = static_cast(0); + buffer[i] = static_cast(0); } } @@ -172,10 +173,12 @@ public: size_t result = 0; for (size_t i = 0; i < nof_words_(); i++) { // result += __builtin_popcountl(buffer[i]); - word_t w = buffer[i]; - for (; w; w >>= 1u) { - result += (w & 1u); + // Note: use an "int" for count triggers popcount optimization if SSE instructions are enabled. + int c = 0; + for (word_t w = buffer[i]; w > 0; c++) { + w &= w - 1; } + result += c; } return result; } @@ -228,24 +231,25 @@ public: return ret; } - std::string to_string() const + template + OutputIt to_string(OutputIt&& mem_buffer) const { + if (size() == 0) { + return mem_buffer; + } + std::string s; s.assign(size(), '0'); if (not reversed) { for (size_t i = size(); i > 0; --i) { - if (test(i - 1)) { - s[size() - i] = '1'; - } + fmt::format_to(mem_buffer, "{}", test(i - 1) ? '1' : '0'); } } else { for (size_t i = 0; i < size(); ++i) { - if (test(i)) { - s[i] = '1'; - } + fmt::format_to(mem_buffer, "{}", test(i) ? '1' : '0'); } } - return s; + return mem_buffer; } uint64_t to_uint64() const @@ -257,24 +261,26 @@ public: return get_word_(0); } - std::string to_hex() const noexcept + template + OutputIt to_hex(OutputIt&& mem_buffer) const noexcept { - size_t nof_digits = (size() - 1) / 4 + 1; - char cstr[ceil_div(ceil_div(N, bits_per_word) * bits_per_word, 4) + 1]; - size_t count = 0; - - for (int i = nof_words_() - 1; i >= 0; --i) { - count += sprintf(&cstr[count], "%016" PRIx64, buffer[i]); + if (size() == 0) { + return mem_buffer; } - - size_t skip = nof_words_() * bits_per_word / 4 - nof_digits; - // printf("bitstring: %s\n", to_string().c_str()); - return std::string(&cstr[skip], &cstr[nof_digits + skip + 1]); + // first word may not print 16 hex digits + int i = nof_words_() - 1; + size_t rem_symbols = ceil_div((size() - (size() / bits_per_word) * bits_per_word), 4U); + fmt::format_to(mem_buffer, "{:0>{}x}", buffer[i], rem_symbols); + // remaining words will occupy 16 hex digits + for (--i; i >= 0; --i) { + fmt::format_to(mem_buffer, "{:0>16x}", buffer[i]); + } + return mem_buffer; } private: - word_t buffer[(N - 1) / bits_per_word + 1]; - size_t cur_size; + word_t buffer[(N - 1) / bits_per_word + 1] = {0}; + size_t cur_size = 0; void sanitize_() { @@ -327,7 +333,7 @@ private: template inline bounded_bitset operator&(const bounded_bitset& lhs, - const bounded_bitset& rhs)noexcept + const bounded_bitset& rhs) noexcept { bounded_bitset res(lhs); res &= rhs; @@ -357,4 +363,36 @@ inline bounded_bitset fliplr(const bounded_bitset& oth } // namespace srslte +namespace fmt { +/// Custom formatter for bounded_bitset +template +struct formatter > { + enum { hexadecimal, binary } mode = binary; + + template + auto parse(ParseContext& ctx) -> decltype(ctx.begin()) + { + auto it = ctx.begin(); + while (it != ctx.end() and *it != '}') { + if (*it == 'x') { + mode = hexadecimal; + } + ++it; + } + + return it; + } + + template + auto format(const srslte::bounded_bitset& s, FormatContext& ctx) + -> decltype(std::declval().out()) + { + if (mode == hexadecimal) { + return s.template to_hex(ctx.out()); + } + return s.template to_string(ctx.out()); + } +}; +} // namespace fmt + #endif // SRSLTE_DYN_BITSET_H diff --git a/lib/include/srslte/adt/bounded_vector.h b/lib/include/srslte/adt/bounded_vector.h index 5dc97cb97..b0bfb9479 100644 --- a/lib/include/srslte/adt/bounded_vector.h +++ b/lib/include/srslte/adt/bounded_vector.h @@ -36,21 +36,15 @@ public: using iterator = T*; using const_iterator = const T*; using size_type = std::size_t; + using value_type = T; bounded_vector() = default; - template ::value, int>::type = 0> - bounded_vector(size_type N) - { - append(N); - } - template ::value, int>::type = 0> - bounded_vector(size_type N, const U& init_val) - { - append(N, T(init_val)); - } + explicit bounded_vector(size_type N) { append(N); } + bounded_vector(size_type N, const T& val) { append(N, val); } bounded_vector(const bounded_vector& other) { append(other.begin(), other.end()); } bounded_vector(bounded_vector&& other) noexcept { + static_assert(std::is_move_constructible::value, "T must be move-constructible"); std::uninitialized_copy(std::make_move_iterator(other.begin()), std::make_move_iterator(other.end()), end()); size_ = other.size(); other.clear(); @@ -122,19 +116,20 @@ public: } T& front() { return (*this)[0]; } const T& front() const { return (*this)[0]; } - T* data() { return reinterpret_cast(&buffer[0]); } - const T* data() const { return reinterpret_cast(&buffer[0]); } + T* data() { return &front(); } + const T* data() const { return &front(); } // Iterators - iterator begin() { return reinterpret_cast(&buffer[0]); } + iterator begin() { return data(); } iterator end() { return begin() + size_; } - const_iterator begin() const { return reinterpret_cast(&buffer[0]); } + const_iterator begin() const { return data(); } const_iterator end() const { return begin() + size_; } // Capacity bool empty() const { return size_ == 0; } std::size_t size() const { return size_; } std::size_t capacity() const { return MAX_N; } + bool full() const { return size_ == MAX_N; } // modifiers void clear() @@ -166,19 +161,22 @@ public: } void push_back(const T& value) { + static_assert(std::is_copy_constructible::value, "T must be copy-constructible"); size_++; assert(size_ <= MAX_N); new (&back()) T(value); } void push_back(T&& value) { + static_assert(std::is_move_constructible::value, "T must be move-constructible"); size_++; assert(size_ <= MAX_N); new (&back()) T(std::move(value)); } template - typename std::enable_if::value>::type emplace_back(Args&&... args) + void emplace_back(Args&&... args) { + static_assert(std::is_constructible::value, "Passed arguments to emplace_back are invalid"); size_++; assert(size_ <= MAX_N); new (&back()) T(std::forward(args)...); @@ -189,9 +187,14 @@ public: back().~T(); size_--; } - typename std::enable_if::value>::type resize(size_type count) { resize(count, T()); } - void resize(size_type count, const T& value) + void resize(size_type count) + { + static_assert(std::is_default_constructible::value, "T must be default constructible"); + resize(count, T()); + } + void resize(size_type count, const T& value) { + static_assert(std::is_copy_constructible::value, "T must be copy constructible"); if (size_ > count) { destroy(begin() + count, end()); size_ = count; @@ -222,12 +225,14 @@ private: } void append(size_type N, const T& element) { + static_assert(std::is_copy_constructible::value, "T must be copy-constructible"); assert(N + size_ <= MAX_N); std::uninitialized_fill_n(end(), N, element); size_ += N; } void append(size_type N) { + static_assert(std::is_default_constructible::value, "T must be default-constructible"); assert(N + size_ <= MAX_N); for (size_type i = size_; i < size_ + N; ++i) { new (&buffer[i]) T(); diff --git a/lib/include/srslte/adt/circular_buffer.h b/lib/include/srslte/adt/circular_buffer.h new file mode 100644 index 000000000..84c3f40d5 --- /dev/null +++ b/lib/include/srslte/adt/circular_buffer.h @@ -0,0 +1,450 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 SRSLTE_CIRCULAR_BUFFER_H +#define SRSLTE_CIRCULAR_BUFFER_H + +#include "srslte/adt/expected.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace srslte { + +namespace detail { + +template +size_t get_max_size(const std::array& a) +{ + return a.max_size(); +} + +template +size_t get_max_size(const std::vector& a) +{ + return a.capacity(); +} + +/** + * Base common class for definition of circular buffer data structures with the following features: + * - no allocations while pushing/popping new elements. Just an internal index update + * - it provides helper methods to add/remove objects + * - it provides an iterator interface to iterate over added elements in the buffer + * - not thread-safe + * @tparam Container underlying container type used as buffer (e.g. std::array or std::vector) + */ +template +class base_circular_buffer +{ + using T = typename Container::value_type; + +public: + using value_type = T; + using difference_type = typename Container::difference_type; + + struct iterator { + iterator(base_circular_buffer& parent_, size_t i) : parent(&parent_), idx(i) {} + iterator& operator++() + { + idx = (idx + 1) % parent->max_size(); + return *this; + } + iterator operator++(int) + { + iterator tmp(*this); + ++(*this); + return tmp; + } + iterator operator+(difference_type n) + { + iterator tmp(*this); + tmp += n; + return tmp; + } + iterator& operator+=(difference_type n) + { + idx = (idx + n) % parent->max_size(); + return *this; + } + value_type* operator->() { return &parent->buffer[idx]; } + const value_type* operator->() const { return &parent->buffer[idx]; } + value_type& operator*() { return parent->buffer[idx]; } + const value_type& operator*() const { return parent->buffer[idx]; } + bool operator==(const iterator& it) const { return it.parent == parent and it.idx == idx; } + bool operator!=(const iterator& it) const { return not(*this == it); } + + private: + base_circular_buffer* parent; + size_t idx; + }; + + template + explicit base_circular_buffer(Args&&... args) : buffer(std::forward(args)...) + {} + + bool try_push(T&& t) + { + if (full()) { + return false; + } + push(std::move(t)); + } + void push(T&& t) + { + assert(not full()); + size_t wpos = (rpos + count) % max_size(); + buffer[wpos] = std::move(t); + count++; + } + bool try_push(const T& t) + { + if (full()) { + return false; + } + push(t); + } + void push(const T& t) + { + assert(not full()); + size_t wpos = (rpos + count) % max_size(); + buffer[wpos] = t; + count++; + } + void pop() + { + assert(not empty()); + rpos = (rpos + 1) % max_size(); + count--; + } + T& top() + { + assert(not empty()); + return buffer[rpos]; + } + const T& top() const + { + assert(not empty()); + return buffer[rpos]; + } + void clear() { count = 0; } + + bool full() const { return count == max_size(); } + bool empty() const { return count == 0; } + size_t size() const { return count; } + size_t max_size() const { return detail::get_max_size(buffer); } + + iterator begin() { return iterator(*this, rpos); } + iterator end() { return iterator(*this, (rpos + count) % max_size()); } + + template >::value> > + void set_size(size_t size) + { + buffer.resize(size); + } + +private: + Container buffer; + size_t rpos = 0; + size_t count = 0; +}; + +struct noop_operator { + template + void operator()(const T&) + { + // noop + } +}; + +/** + * Base common class for definition of blocking queue data structures with the following features: + * - it stores pushed/popped samples in an internal circular buffer + * - provides blocking and non-blocking push/pop APIs + * - thread-safe + * @tparam CircBuffer underlying circular buffer data type (e.g. static_circular_buffer or dyn_circular_buffer) + * @tparam PushingFunc function void(const T&) called while pushing an element to the queue + * @tparam PoppingFunc function void(const T&) called while popping an element from the queue + */ +template +class base_blocking_queue +{ + using T = typename CircBuffer::value_type; + +public: + template + base_blocking_queue(PushingFunc push_func_, PoppingFunc pop_func_, Args&&... args) : + circ_buffer(std::forward(args)...), push_func(push_func_), pop_func(pop_func_) + {} + + void stop() + { + std::unique_lock lock(mutex); + if (active) { + active = false; + if (nof_waiting == 0) { + return; + } + do { + lock.unlock(); + cvar_empty.notify_all(); + cvar_full.notify_all(); + std::this_thread::yield(); + lock.lock(); + } while (nof_waiting > 0); + } + } + + bool try_push(const T& t) { return push_(t, false); } + srslte::error_type try_push(T&& t) { return push_(std::move(t), false); } + bool push_blocking(const T& t) { return push_(t, true); } + srslte::error_type push_blocking(T&& t) { return push_(std::move(t), true); } + bool try_pop(T& obj) { return pop_(obj, false); } + T pop_blocking() + { + T obj{}; + pop_(obj, true); + return obj; + } + bool pop_wait_until(T& obj, const std::chrono::system_clock::time_point& until) { return pop_(obj, true, &until); } + void clear() + { + std::lock_guard lock(mutex); + T obj; + while (pop_(obj, false)) { + } + } + + size_t size() const + { + std::lock_guard lock(mutex); + return circ_buffer.size(); + } + bool empty() const + { + std::lock_guard lock(mutex); + return circ_buffer.empty(); + } + bool full() const + { + std::lock_guard lock(mutex); + return circ_buffer.full(); + } + size_t max_size() const + { + std::lock_guard lock(mutex); + return circ_buffer.max_size(); + } + bool is_stopped() const + { + std::lock_guard lock(mutex); + return not active; + } + template + bool try_call_on_front(F&& f) + { + std::lock_guard lock(mutex); + if (not circ_buffer.empty()) { + f(circ_buffer.top()); + return true; + } + return false; + } + +protected: + bool active = true; + uint8_t nof_waiting = 0; + mutable std::mutex mutex; + std::condition_variable cvar_empty, cvar_full; + PushingFunc push_func; + PoppingFunc pop_func; + CircBuffer circ_buffer; + + ~base_blocking_queue() { stop(); } + + bool push_(const T& t, bool block_mode) + { + std::unique_lock lock(mutex); + if (not active) { + return false; + } + if (circ_buffer.full()) { + if (not block_mode) { + return false; + } + nof_waiting++; + while (circ_buffer.full() and active) { + cvar_full.wait(lock); + } + nof_waiting--; + if (not active) { + return false; + } + } + push_func(t); + circ_buffer.push(t); + lock.unlock(); + cvar_empty.notify_one(); + return true; + } + srslte::error_type push_(T&& t, bool block_mode) + { + std::unique_lock lock(mutex); + if (not active) { + return std::move(t); + } + if (circ_buffer.full()) { + if (not block_mode) { + return std::move(t); + } + nof_waiting++; + while (circ_buffer.full() and active) { + cvar_full.wait(lock); + } + nof_waiting--; + if (not active) { + return std::move(t); + } + } + push_func(t); + circ_buffer.push(std::move(t)); + lock.unlock(); + cvar_empty.notify_one(); + return {}; + } + + bool pop_(T& obj, bool block, const std::chrono::system_clock::time_point* until = nullptr) + { + std::unique_lock lock(mutex); + if (not active) { + return false; + } + if (circ_buffer.empty()) { + if (not block) { + return false; + } + nof_waiting++; + if (until == nullptr) { + cvar_empty.wait(lock, [this]() { return not circ_buffer.empty() or not active; }); + } else { + cvar_empty.wait_until(lock, *until, [this]() { return not circ_buffer.empty() or not active; }); + } + nof_waiting--; + if (circ_buffer.empty()) { + // either queue got deactivated or there was a timeout + return false; + } + } + obj = std::move(circ_buffer.top()); + pop_func(obj); + circ_buffer.pop(); + lock.unlock(); + cvar_full.notify_one(); + return true; + } +}; + +} // namespace detail + +/** + * Circular buffer with fixed, embedded buffer storage via a std::array. + * - Single allocation at object creation for std::array. Given that the buffer size is known at compile-time, the + * circular iteration over the buffer may be more optimized (e.g. when N is a power of 2, % operator can be avoided) + * - not thread-safe + * @tparam T value type stored by buffer + * @tparam N size of the queue + */ +template +class static_circular_buffer : public detail::base_circular_buffer > +{}; + +/** + * Circular buffer with buffer storage via a std::vector. + * - size can be defined at run-time. + * - not thread-safe + * @tparam T value type stored by buffer + */ +template +class dyn_circular_buffer : public detail::base_circular_buffer > +{ + using base_t = detail::base_circular_buffer >; + +public: + dyn_circular_buffer() = default; + explicit dyn_circular_buffer(size_t size) : base_t(size) {} + + void set_size(size_t size) + { + // Note: dynamic resizes not supported. + assert(base_t::empty()); + base_t::set_size(size); + } +}; + +/** + * Blocking queue with fixed, embedded buffer storage via a std::array. + * - Blocking push/pop API via push_blocking(...) and pop_blocking(...) methods + * - Non-blocking push/pop API via try_push(...) and try_pop(...) methods + * - Only one initial allocation for the std::array + * - thread-safe + * @tparam T value type stored by buffer + * @tparam N size of queue + * @tparam PushingCallback function void(const T&) called while pushing an element to the queue + * @tparam PoppingCallback function void(const T&) called while popping an element from the queue + */ +template +class static_blocking_queue + : public detail::base_blocking_queue, PushingCallback, PoppingCallback> +{ + using base_t = detail::base_blocking_queue, PushingCallback, PoppingCallback>; + +public: + explicit static_blocking_queue(PushingCallback push_callback = {}, PoppingCallback pop_callback = {}) : + base_t(push_callback, pop_callback) + {} +}; + +/** + * Blocking queue with buffer storage represented via a std::vector. Features: + * - Blocking push/pop API via push_blocking(...) and pop_blocking(...) methods + * - Non-blocking push/pop API via try_push(...) and try_pop(...) methods + * - Size can be defined at runtime. + * - thread-safe + * @tparam T value type stored by buffer + * @tparam PushingCallback function void(const T&) called while pushing an element to the queue + * @tparam PoppingCallback function void(const T&) called while popping an element from the queue + */ +template +class dyn_blocking_queue : public detail::base_blocking_queue, PushingCallback, PoppingCallback> +{ + using base_t = detail::base_blocking_queue, PushingCallback, PoppingCallback>; + +public: + dyn_blocking_queue() = default; + explicit dyn_blocking_queue(size_t size, PushingCallback push_callback = {}, PoppingCallback pop_callback = {}) : + base_t(push_callback, pop_callback, size) + {} + void set_size(size_t size) { base_t::circ_buffer.set_size(size); } +}; + +} // namespace srslte + +#endif // SRSLTE_CIRCULAR_BUFFER_H diff --git a/lib/include/srslte/adt/interval.h b/lib/include/srslte/adt/interval.h index 5efa504e5..490eaba21 100644 --- a/lib/include/srslte/adt/interval.h +++ b/lib/include/srslte/adt/interval.h @@ -86,8 +86,6 @@ public: bool contains(T point) const { return start_ <= point and point < stop_; } - std::string to_string() const { return fmt::format("[{},{})", start_, stop_); } - private: T start_; T stop_; @@ -143,13 +141,19 @@ interval make_intersection(const interval& lhs, const interval& rhs) return lhs & rhs; } +} // namespace srslte + +namespace fmt { + template -std::ostream& operator<<(std::ostream& out, const interval& interv) -{ - out << interv.to_string(); - return out; -} +struct formatter > : public formatter { + template + auto format(const srslte::interval& interv, FormatContext& ctx) -> decltype(std::declval().out()) + { + return format_to(ctx.out(), "[{}, {})", interv.start(), interv.stop()); + } +}; -} // namespace srslte +} // namespace fmt #endif // SRSLTE_INTERVAL_H diff --git a/lib/include/srslte/adt/mem_pool.h b/lib/include/srslte/adt/mem_pool.h index bee58ed96..4412534c7 100644 --- a/lib/include/srslte/adt/mem_pool.h +++ b/lib/include/srslte/adt/mem_pool.h @@ -22,6 +22,7 @@ #ifndef SRSLTE_MEM_POOL_H #define SRSLTE_MEM_POOL_H +#include "srslte/common/thread_pool.h" #include #include #include @@ -205,6 +206,97 @@ public: } }; +/** + * Pool specialized for in allocating batches of objects in a preemptive way in a background thread to minimize latency. + * Note: Current implementation assumes that the pool object will outlive the background callbacks to allocate new + * batches + * @tparam T individual object type that is being allocated + * @tparam BatchSize number of T objects in a batch + * @tparam ThresholdSize number of T objects below which a new batch needs to be allocated + */ +template +class background_allocator_obj_pool +{ + static_assert(ThresholdSize > 0, "ThresholdSize needs to be positive"); + static_assert(BatchSize > 1, "BatchSize needs to be higher than 1"); + +public: + background_allocator_obj_pool(bool lazy_start = false) + { + if (not lazy_start) { + allocate_batch_in_background(); + } + } + background_allocator_obj_pool(background_allocator_obj_pool&&) = delete; + background_allocator_obj_pool(const background_allocator_obj_pool&) = delete; + background_allocator_obj_pool& operator=(background_allocator_obj_pool&&) = delete; + background_allocator_obj_pool& operator=(const background_allocator_obj_pool&) = delete; + ~background_allocator_obj_pool() + { + std::lock_guard lock(mutex); + batches.clear(); + } + + /// alloc new object space. If no memory is pre-reserved in the pool, malloc is called to allocate new batch. + void* allocate_node(size_t sz) + { + assert(sz == sizeof(T)); + std::lock_guard lock(mutex); + uint8_t* block = obj_cache.try_pop(); + + if (block != nullptr) { + // allocation successful + if (obj_cache.size() < ThresholdSize) { + get_background_workers().push_task([this]() { + std::lock_guard lock(mutex); + allocate_batch_(); + }); + } + return block; + } + + // try allocation of new batch in same thread as caller. + allocate_batch_(); + return obj_cache.try_pop(); + } + + void deallocate_node(void* p) + { + std::lock_guard lock(mutex); + assert(p != nullptr); + if (p != nullptr) { + obj_cache.push(static_cast(p)); + } + } + + void allocate_batch_in_background() + { + get_background_workers().push_task([this]() { + std::lock_guard lock(mutex); + allocate_batch_(); + }); + } + +private: + using obj_storage_t = typename std::aligned_storage::type; + using batch_obj_t = std::array; + + /// Unprotected allocation of new Batch of Objects + void allocate_batch_() + { + batches.emplace_back(new batch_obj_t()); + batch_obj_t& batch = *batches.back(); + for (obj_storage_t& obj_store : batch) { + obj_cache.push(reinterpret_cast(&obj_store)); + } + } + + // memory stack to cache allocate memory chunks + std::mutex mutex; + memblock_stack obj_cache; + std::vector > batches; +}; + } // namespace srslte #endif // SRSLTE_MEM_POOL_H diff --git a/lib/include/srslte/adt/move_callback.h b/lib/include/srslte/adt/move_callback.h index 790a8a049..e9b494a4b 100644 --- a/lib/include/srslte/adt/move_callback.h +++ b/lib/include/srslte/adt/move_callback.h @@ -181,7 +181,7 @@ public: R operator()(Args&&... args) const noexcept { return oper_ptr->call(&buffer, std::forward(args)...); } - bool is_empty() const { return oper_ptr == empty_table; } + bool is_empty() const { return oper_ptr == &empty_table; } bool is_in_small_buffer() const { return oper_ptr->is_in_small_buffer(); } private: diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index a65bd861b..0469861af 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -35,7 +35,6 @@ *******************************************************************************/ #include "srslte/common/common.h" -#include "srslte/common/log.h" #include "srslte/srslog/srslog.h" namespace srslte { @@ -60,6 +59,7 @@ public: if (capacity_ > 0) { nof_buffers = (uint32_t)capacity_; } + used.reserve(nof_buffers); pthread_mutex_init(&mutex, nullptr); pthread_cond_init(&cv_not_empty, nullptr); for (uint32_t i = 0; i < nof_buffers; i++) { diff --git a/lib/include/srslte/common/log.h b/lib/include/srslte/common/log.h deleted file mode 100644 index 1e9957553..000000000 --- a/lib/include/srslte/common/log.h +++ /dev/null @@ -1,159 +0,0 @@ -/** - * Copyright 2013-2021 Software Radio Systems Limited - * - * This file is part of srsLTE. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -/****************************************************************************** - * File: log.h - * - * Description: Abstract logging service - * - * Reference: - *****************************************************************************/ - -#ifndef SRSLTE_LOG_H -#define SRSLTE_LOG_H - -#include "srslte/common/standard_streams.h" -#include -#include -#include - -namespace srslte { - -typedef enum { - LOG_LEVEL_NONE = 0, - LOG_LEVEL_ERROR, - LOG_LEVEL_WARNING, - LOG_LEVEL_INFO, - LOG_LEVEL_DEBUG, - LOG_LEVEL_N_ITEMS -} LOG_LEVEL_ENUM; -static const char log_level_text[LOG_LEVEL_N_ITEMS][16] = {"None ", "Error ", "Warning", "Info ", "Debug "}; - -static const char log_level_text_short[LOG_LEVEL_N_ITEMS][16] = {"[-]", "[E]", "[W]", "[I]", "[D]"}; - -class log -{ -public: - log() - { - service_name = ""; - tti = 0; - level = LOG_LEVEL_NONE; - hex_limit = 0; - add_string_en = false; - } - - explicit log(std::string service_name_) - { - service_name = std::move(service_name_); - tti = 0; - level = LOG_LEVEL_NONE; - hex_limit = 0; - add_string_en = false; - } - - log(const log&) = delete; - log& operator=(const log&) = delete; - - virtual ~log() = default; - - // This function shall be called at the start of every tti for printing tti - void step(uint32_t tti_) - { - tti = tti_; - add_string_en = false; - } - - void prepend_string(std::string s) - { - add_string_en = true; - add_string_val = std::move(s); - } - - uint32_t get_tti() { return tti; } - - void set_level(LOG_LEVEL_ENUM l) { level = l; } - - void set_level(std::string l) { set_level(get_level_from_string(std::move(l))); } - - static srslte::LOG_LEVEL_ENUM get_level_from_string(std::string l) - { - std::transform(l.begin(), l.end(), l.begin(), ::toupper); - if ("NONE" == l) { - return srslte::LOG_LEVEL_NONE; - } else if ("ERROR" == l) { - return srslte::LOG_LEVEL_ERROR; - } else if ("WARNING" == l) { - return srslte::LOG_LEVEL_WARNING; - } else if ("INFO" == l) { - return srslte::LOG_LEVEL_INFO; - } else if ("DEBUG" == l) { - return srslte::LOG_LEVEL_DEBUG; - } else { - return srslte::LOG_LEVEL_NONE; - } - } - - LOG_LEVEL_ENUM get_level() { return level; } - const std::string& get_service_name() const { return service_name; } - - void set_hex_limit(int limit) { hex_limit = limit; } - int get_hex_limit() { return hex_limit; } - - // Pure virtual methods for logging - virtual void error(const char* message, ...) __attribute__((format(printf, 2, 3))) = 0; - virtual void warning(const char* message, ...) __attribute__((format(printf, 2, 3))) = 0; - virtual void info(const char* message, ...) __attribute__((format(printf, 2, 3))) = 0; - virtual void info_long(const char* message, ...) __attribute__((format(printf, 2, 3))) = 0; - virtual void debug(const char* message, ...) __attribute__((format(printf, 2, 3))) = 0; - virtual void debug_long(const char* message, ...) __attribute__((format(printf, 2, 3))) = 0; - - // Same with hex dump - virtual void error_hex(const uint8_t*, int, const char*, ...) __attribute__((format(printf, 4, 5))) - { - error("error_hex not implemented.\n"); - } - virtual void warning_hex(const uint8_t*, int, const char*, ...) __attribute__((format(printf, 4, 5))) - { - error("warning_hex not implemented.\n"); - } - virtual void info_hex(const uint8_t*, int, const char*, ...) __attribute__((format(printf, 4, 5))) - { - error("info_hex not implemented.\n"); - } - virtual void debug_hex(const uint8_t*, int, const char*, ...) __attribute__((format(printf, 4, 5))) - { - error("debug_hex not implemented.\n"); - } - -protected: - uint32_t tti; - LOG_LEVEL_ENUM level; - int hex_limit; - - bool add_string_en; - std::string add_string_val; - std::string service_name; -}; - -} // namespace srslte - -#endif // SRSLTE_LOG_H diff --git a/lib/include/srslte/common/log_filter.h b/lib/include/srslte/common/log_filter.h deleted file mode 100644 index b6b9e6100..000000000 --- a/lib/include/srslte/common/log_filter.h +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Copyright 2013-2021 Software Radio Systems Limited - * - * This file is part of srsLTE. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -/****************************************************************************** - * File: log_filter.h - * Description: Log filter for a specific layer or element. - * Performs filtering based on log level, generates - * timestamped log strings and passes them to the - * common logger object. - *****************************************************************************/ - -#ifndef SRSLTE_LOG_FILTER_H -#define SRSLTE_LOG_FILTER_H - -#include -#include - -#include "srslte/common/log.h" -#include "srslte/common/logger.h" -#include "srslte/common/logger_srslog_wrapper.h" -#include "srslte/phy/common/timestamp.h" - -namespace srslte { - -typedef std::string* str_ptr; - -class log_filter : public srslte::log -{ -public: - log_filter(); - log_filter(std::string layer); - log_filter(std::string layer, logger* logger_, bool tti = false); - - void init(std::string layer, logger* logger_, bool tti = false); - - void error(const char* message, ...) __attribute__((format(printf, 2, 3))); - void warning(const char* message, ...) __attribute__((format(printf, 2, 3))); - void info(const char* message, ...) __attribute__((format(printf, 2, 3))); - void info_long(const char* message, ...) __attribute__((format(printf, 2, 3))); - void debug(const char* message, ...) __attribute__((format(printf, 2, 3))); - void debug_long(const char* message, ...) __attribute__((format(printf, 2, 3))); - - void error_hex(const uint8_t* hex, int size, const char* message, ...) __attribute__((format(printf, 4, 5))); - void warning_hex(const uint8_t* hex, int size, const char* message, ...) __attribute__((format(printf, 4, 5))); - void info_hex(const uint8_t* hex, int size, const char* message, ...) __attribute__((format(printf, 4, 5))); - void debug_hex(const uint8_t* hex, int size, const char* message, ...) __attribute__((format(printf, 4, 5))); - - class time_itf - { - public: - virtual srslte_timestamp_t get_time() = 0; - }; - - typedef enum { TIME, EPOCH } time_format_t; - - void set_time_src(time_itf* source, time_format_t format); - -protected: - std::unique_ptr default_logger; - logger* logger_h; - bool do_tti; - - static const int char_buff_size = logger::preallocated_log_str_size - 64 * 3; - - time_itf* time_src; - time_format_t time_format; - - void all_log(srslte::LOG_LEVEL_ENUM level, - uint32_t tti, - char* msg, - const uint8_t* hex = nullptr, - int size = 0, - bool long_msg = false); - void now_time(char* buffer, const uint32_t buffer_len); - void get_tti_str(const uint32_t tti_, char* buffer, const uint32_t buffer_len); - std::string hex_string(const uint8_t* hex, int size); -}; - -} // namespace srslte - -#endif // SRSLTE_LOG_FILTER_H diff --git a/lib/include/srslte/common/log_helper.h b/lib/include/srslte/common/log_helper.h index 4576ef9a7..d13bb450c 100644 --- a/lib/include/srslte/common/log_helper.h +++ b/lib/include/srslte/common/log_helper.h @@ -30,37 +30,11 @@ namespace srslte { -#define Error(fmt, ...) \ - do { \ - if (log_h.get() != nullptr) { \ - log_h->error(fmt, ##__VA_ARGS__); \ - } \ - } while (0) -#define Warning(fmt, ...) \ - do { \ - if (log_h.get() != nullptr) { \ - log_h->warning(fmt, ##__VA_ARGS__); \ - } \ - } while (0) -#define Info(fmt, ...) \ - do { \ - if (log_h.get() != nullptr) { \ - log_h->info(fmt, ##__VA_ARGS__); \ - } \ - } while (0) -#define Debug(fmt, ...) \ - do { \ - if (log_h.get() != nullptr) { \ - log_h->debug(fmt, ##__VA_ARGS__); \ - } \ - } while (0) - -#define Console(fmt, ...) \ - do { \ - if (log_h.get() != nullptr) { \ - srslte::console(fmt, ##__VA_ARGS__); \ - } \ - } while (0) +#define Error(fmt, ...) logger.error(fmt, ##__VA_ARGS__) +#define Warning(fmt, ...) logger.warning(fmt, ##__VA_ARGS__) +#define Info(fmt, ...) logger.info(fmt, ##__VA_ARGS__) +#define Debug(fmt, ...) logger.debug(fmt, ##__VA_ARGS__) +#define Console(fmt, ...) srslte::console(fmt, ##__VA_ARGS__) } // namespace srslte diff --git a/lib/include/srslte/common/logger.h b/lib/include/srslte/common/logger.h deleted file mode 100644 index 31fb8dc5f..000000000 --- a/lib/include/srslte/common/logger.h +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Copyright 2013-2021 Software Radio Systems Limited - * - * This file is part of srsLTE. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -/****************************************************************************** - * File: logger.h - * Description: Interface for logging output - *****************************************************************************/ - -#ifndef SRSLTE_LOGGER_H -#define SRSLTE_LOGGER_H - -#include "buffer_pool.h" -#include -#include -#include - -namespace srslte { - -class logger -{ -public: - const static uint32_t preallocated_log_str_size = 1024; - - logger() : pool(16 * 1024) {} - virtual ~logger() = default; - - class log_str - { - public: - log_str(const char* msg_ = nullptr, uint32_t size_ = 0) - { - size = size_ ? size_ : preallocated_log_str_size; - msg = new char[size]; - if (msg_) { - strncpy(msg, msg_, size); - } else { - msg[0] = '\0'; - } - } - log_str(const log_str&) = delete; - log_str& operator=(const log_str&) = delete; - ~log_str() { delete[] msg; } - void reset() { msg[0] = '\0'; } - char* str() { return msg; } - uint32_t get_buffer_size() { return size; } -#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED - char debug_name[SRSLTE_BUFFER_POOL_LOG_NAME_LEN] = {}; -#endif - - private: - uint32_t size; - char* msg; - }; - - typedef buffer_pool log_str_pool_t; - - class log_str_deleter - { - public: - explicit log_str_deleter(log_str_pool_t* pool_ = nullptr) : pool(pool_) {} - void operator()(log_str* buf) - { - if (buf) { - if (pool) { - buf->reset(); - pool->deallocate(buf); - } else { - delete buf; - } - } - } - - private: - log_str_pool_t* pool; - }; - typedef std::unique_ptr unique_log_str_t; - - void log_char(const char* msg) { log(unique_log_str_t(new log_str(msg), log_str_deleter())); } - - virtual void log(unique_log_str_t msg) = 0; - - log_str_pool_t& get_pool() { return pool; } - unique_log_str_t allocate_unique_log_str() - { - return unique_log_str_t(pool.allocate(), logger::log_str_deleter(&pool)); - } - -private: - log_str_pool_t pool; -}; - -} // namespace srslte - -#endif // SRSLTE_LOGGER_H diff --git a/lib/include/srslte/common/logger_srslog_wrapper.h b/lib/include/srslte/common/logger_srslog_wrapper.h deleted file mode 100644 index 5140678db..000000000 --- a/lib/include/srslte/common/logger_srslog_wrapper.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright 2013-2021 Software Radio Systems Limited - * - * This file is part of srsLTE. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#ifndef SRSLTE_LOGGER_SRSLOG_WRAPPER_H -#define SRSLTE_LOGGER_SRSLOG_WRAPPER_H - -#include "srslte/common/logger.h" - -namespace srslog { - -class log_channel; - -} // namespace srslog - -namespace srslte { - -/// This logger implementation uses the srsLog framework to write log entries. -class srslog_wrapper : public logger -{ -public: - explicit srslog_wrapper(srslog::log_channel& chan) : chan(chan) {} - - void log(unique_log_str_t msg) override; - -private: - srslog::log_channel& chan; -}; - -} // namespace srslte - -#endif // SRSLTE_LOGGER_SRSLOG_WRAPPER_H diff --git a/lib/include/srslte/common/logmap.h b/lib/include/srslte/common/logmap.h deleted file mode 100644 index 0ed59f1e4..000000000 --- a/lib/include/srslte/common/logmap.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Copyright 2013-2021 Software Radio Systems Limited - * - * This file is part of srsLTE. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#ifndef SRSLTE_LOGMAP_H -#define SRSLTE_LOGMAP_H - -#include "srslte/common/log.h" -#include "srslte/common/logger.h" -#include "srslte/common/logger_srslog_wrapper.h" -#include "srslte/common/singleton.h" - -#include -#include -#include - -namespace srslte { - -class log_ref -{ - using ptr_type = std::unique_ptr*; - -public: - log_ref() = default; - explicit log_ref(ptr_type p) : ptr_(p) {} - explicit log_ref(const char* name); - - // works like a log* - log* operator->() { return ptr_->get(); } - log* operator->() const { return ptr_->get(); } - - // in case we want to obtain log* - log* operator*() { return ptr_->get(); } - log* get() { return ptr_->get(); } - - // identity defined by ref address - bool operator==(const log_ref& l) { return ptr_ == l.ptr_; } - - // to do checks like if(log_ref) - operator bool() { return ptr_ != nullptr; } - -private: - ptr_type ptr_ = nullptr; -}; - -class logmap : public singleton_t -{ -public: - // Access to log map by servicename. If servicename does not exist, create a new log_filter with default cfg - // Access to the map is protected by a mutex - static log_ref get(std::string servicename); - - // register manually created log - static void register_log(std::unique_ptr log_ptr); - - static std::unique_ptr deregister_log(const std::string& servicename); - - // set default logger - static void set_default_logger(logger* logger_); - - // set default log level - static void set_default_log_level(LOG_LEVEL_ENUM l); - - // set default hex limit - static void set_default_hex_limit(int hex_limit); - -protected: - logmap(); - -private: - log_ref get_impl(std::string servicename); - - // default cfg - std::unique_ptr stdout_channel; - logger* default_logger = nullptr; - srslte::LOG_LEVEL_ENUM default_log_level = LOG_LEVEL_WARNING; - int default_hex_limit = 1024; - - // state - std::mutex mutex; - std::unordered_map > log_map; -}; - -} // namespace srslte - -#endif // SRSLTE_LOGMAP_H diff --git a/lib/include/srslte/common/mac_pcap_base.h b/lib/include/srslte/common/mac_pcap_base.h index da10c8abd..dedf07691 100644 --- a/lib/include/srslte/common/mac_pcap_base.h +++ b/lib/include/srslte/common/mac_pcap_base.h @@ -22,7 +22,7 @@ #ifndef SRSLTE_MAC_PCAP_BASE_H #define SRSLTE_MAC_PCAP_BASE_H -#include "srslte/common/block_queue.h" +#include "srslte/adt/circular_buffer.h" #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" #include "srslte/common/pcap.h" @@ -102,11 +102,11 @@ protected: virtual void write_pdu(pcap_pdu_t& pdu) = 0; void run_thread() final; - std::mutex mutex; - srslog::basic_logger& logger; - bool running = false; - block_queue queue; - uint16_t ue_id = 0; + std::mutex mutex; + srslog::basic_logger& logger; + bool running = false; + static_blocking_queue queue; + uint16_t ue_id = 0; private: void pack_and_queue(uint8_t* payload, diff --git a/lib/include/srslte/common/netsource_handler.h b/lib/include/srslte/common/netsource_handler.h index 5d44eeec1..0e2d17406 100644 --- a/lib/include/srslte/common/netsource_handler.h +++ b/lib/include/srslte/common/netsource_handler.h @@ -27,7 +27,6 @@ #ifndef SRSLTE_NETSOURE_HANDLER_H #define SRSLTE_NETSOURE_HANDLER_H -#include "srslte/common/log.h" #include "srslte/common/threads.h" #include "srslte/phy/io/netsource.h" #include @@ -70,8 +69,6 @@ public: unique_byte_array_t rx_buf; srslte_netsource_t net_source; - - srslte::log* log = nullptr; }; #endif // SRSLTE_NETSOURE_HANDLER_H diff --git a/lib/include/srslte/common/string_helpers.h b/lib/include/srslte/common/string_helpers.h index 5510d95d6..68800d662 100644 --- a/lib/include/srslte/common/string_helpers.h +++ b/lib/include/srslte/common/string_helpers.h @@ -22,6 +22,7 @@ #ifndef SRSLTE_STRING_HELPERS_H #define SRSLTE_STRING_HELPERS_H +#include "srslte/srslog/bundled/fmt/format.h" #include #include #include @@ -120,6 +121,13 @@ static inline void string_parse_list(const std::string& input, char delimiter, I } } +template +const char* to_c_str(fmt::basic_memory_buffer& mem_buffer) +{ + mem_buffer.push_back('\0'); + return mem_buffer.data(); +} + } // namespace srslte #endif // SRSLTE_STRING_HELPERS_H diff --git a/lib/include/srslte/common/test_common.h b/lib/include/srslte/common/test_common.h index ce4013e91..39d125fad 100644 --- a/lib/include/srslte/common/test_common.h +++ b/lib/include/srslte/common/test_common.h @@ -26,73 +26,13 @@ #ifdef __cplusplus -#include "srslte/common/log.h" -#include "srslte/common/log_filter.h" -#include "srslte/common/logmap.h" +#include "srslte/common/standard_streams.h" #include "srslte/srslog/srslog.h" #include #include namespace srslte { -// Description: log filter that we can instantiate in a specific test scope, and cleans itself on scope exit -// useful if we want to define specific logging policies within a scope (e.g. null logger, count number of errors, -// exit on error, log special diagnostics on destruction). It restores the previous logger after exiting the scope -class test_log_filter : public srslte::log_filter -{ -public: - explicit test_log_filter(std::string layer) : srslte::log_filter(std::move(layer)) - { - set_level(srslte::LOG_LEVEL_DEBUG); - } - test_log_filter(const test_log_filter&) = delete; - test_log_filter(test_log_filter&&) = delete; - test_log_filter& operator=(const test_log_filter&) = delete; - test_log_filter& operator=(test_log_filter&&) = delete; - ~test_log_filter() override = default; - - void error(const char* message, ...) override __attribute__((format(printf, 2, 3))) - { - error_counter++; - if (level >= srslte::LOG_LEVEL_ERROR) { - char args_msg[char_buff_size]; - va_list args; - va_start(args, message); - if (vsnprintf(args_msg, char_buff_size, message, args) > 0) { - all_log(srslte::LOG_LEVEL_ERROR, tti, args_msg); - } - va_end(args); - } - if (exit_on_error) { - exit(-1); - } - } - - void warning(const char* message, ...) override __attribute__((format(printf, 2, 3))) - { - warn_counter++; - if (level >= srslte::LOG_LEVEL_WARNING) { - char args_msg[char_buff_size]; - va_list args; - va_start(args, message); - if (vsnprintf(args_msg, char_buff_size, message, args) > 0) { - all_log(srslte::LOG_LEVEL_WARNING, tti, args_msg); - } - va_end(args); - } - } - - virtual void log_diagnostics() - { - if (error_counter > 0 or warn_counter > 0) { - info("STATUS: counted %d errors and %d warnings.\n", error_counter, warn_counter); - } - } - - bool exit_on_error = false; - uint32_t error_counter = 0, warn_counter = 0; -}; - /// This custom sink intercepts log messages to count error and warning log entries. class log_sink_spy : public srslog::sink { @@ -197,106 +137,17 @@ private: std::vector entries; }; -// specialization of test_log_filter to store last logged message -class nullsink_log : public test_log_filter -{ -public: - explicit nullsink_log(std::string layer) : test_log_filter(std::move(layer)) {} - - void debug(const char* message, ...) override __attribute__((format(printf, 2, 3))) - { - va_list args; - va_start(args, message); - log_va_list(LOG_LEVEL_DEBUG, message, args); - va_end(args); - } - - void info(const char* message, ...) override __attribute__((format(printf, 2, 3))) - { - va_list args; - va_start(args, message); - log_va_list(LOG_LEVEL_INFO, message, args); - va_end(args); - } - - void warning(const char* message, ...) override __attribute__((format(printf, 2, 3))) - { - warn_counter++; - va_list args; - va_start(args, message); - log_va_list(LOG_LEVEL_WARNING, message, args); - va_end(args); - } - - void error(const char* message, ...) override __attribute__((format(printf, 2, 3))) - { - error_counter++; - va_list args; - va_start(args, message); - log_va_list(LOG_LEVEL_ERROR, message, args); - va_end(args); - if (exit_on_error) { - exit(-1); - } - } - - srslte::LOG_LEVEL_ENUM last_log_level = LOG_LEVEL_NONE; - std::string last_log_msg; - -private: - void log_va_list(srslte::LOG_LEVEL_ENUM loglevel, const char* message, va_list argp) - { - last_log_level = loglevel; - if (level >= loglevel) { - char args_msg[char_buff_size]; - if (vsnprintf(args_msg, char_buff_size, message, argp) > 0) { - last_log_msg = args_msg; - } - } - } -}; - -template -class scoped_log -{ -public: - template - explicit scoped_log(Args&&... args) - { - std::unique_ptr l{new Log{std::forward(args)...}}; - // store previous log, and register the newly created one - prev_log = srslte::logmap::deregister_log(l->get_service_name()); - current_log = l.get(); - srslte::logmap::register_log(std::move(l)); - } - scoped_log(scoped_log&&) noexcept = default; - ~scoped_log() - { - srslte::logmap::deregister_log(current_log->get_service_name()); - if (prev_log != nullptr) { - srslte::logmap::register_log(std::move(prev_log)); - } - } - - Log* operator->() { return current_log; } - Log* get() { return current_log; } - -private: - Log* current_log = nullptr; - std::unique_ptr prev_log; -}; - } // namespace srslte #define TESTERROR(fmt, ...) \ do { \ - srslte::logmap::get("TEST")->error(fmt, ##__VA_ARGS__); \ + srslog::fetch_basic_logger("TEST").error(fmt, ##__VA_ARGS__); \ return SRSLTE_ERROR; \ } while (0) #define TESTWARN(fmt, ...) \ do { \ - srslte::logmap::get("TEST")->warning(fmt, ##__VA_ARGS__); \ + srslog::fetch_basic_logger("TEST").warning(fmt, ##__VA_ARGS__); \ } while (0) #define CONDERROR(cond, fmt, ...) \ diff --git a/lib/include/srslte/common/timers.h b/lib/include/srslte/common/timers.h index e453c75fa..fb506ee82 100644 --- a/lib/include/srslte/common/timers.h +++ b/lib/include/srslte/common/timers.h @@ -29,6 +29,7 @@ #ifndef SRSLTE_TIMERS_H #define SRSLTE_TIMERS_H +#include "srslte/adt/move_callback.h" #include "srslte/phy/utils/debug.h" #include #include @@ -54,11 +55,11 @@ class timer_handler constexpr static uint32_t MAX_TIMER_VALUE = std::numeric_limits::max() / 2; struct timer_impl { - timer_handler* parent; - uint32_t duration = 0, timeout = 0; - bool running = false; - bool active = false; - std::function callback; + timer_handler* parent; + uint32_t duration = 0, timeout = 0; + bool running = false; + bool active = false; + srslte::move_callback callback; explicit timer_impl(timer_handler* parent_) : parent(parent_) {} @@ -88,7 +89,7 @@ class timer_handler return true; } - bool set(uint32_t duration_, std::function callback_) + bool set(uint32_t duration_, srslte::move_callback callback_) { if (set(duration_)) { callback = std::move(callback_); @@ -122,7 +123,7 @@ class timer_handler stop(); duration = 0; active = false; - callback = std::function(); + callback = srslte::move_callback(); // leave run_id unchanged. Since the timeout was changed, we shall not get spurious triggering } @@ -130,7 +131,7 @@ class timer_handler { if (is_running()) { running = false; - if (callback) { + if (not callback.is_empty()) { callback(id()); } } @@ -173,7 +174,10 @@ public: bool is_valid() const { return parent != nullptr; } - void set(uint32_t duration_, const std::function& callback_) { impl()->set(duration_, callback_); } + void set(uint32_t duration_, move_callback callback_) + { + impl()->set(duration_, std::move(callback_)); + } void set(uint32_t duration_) { impl()->set(duration_); } @@ -279,8 +283,8 @@ public: template void defer_callback(uint32_t duration, const F& func) { - uint32_t id = alloc_timer(); - std::function c = [func, this, id](uint32_t tid) { + uint32_t id = alloc_timer(); + srslte::move_callback c = [func, this, id](uint32_t tid) { func(); // auto-deletes timer timer_list[id].clear(); diff --git a/lib/include/srslte/interfaces/enb_gtpu_interfaces.h b/lib/include/srslte/interfaces/enb_gtpu_interfaces.h index 92449130b..4821e20f6 100644 --- a/lib/include/srslte/interfaces/enb_gtpu_interfaces.h +++ b/lib/include/srslte/interfaces/enb_gtpu_interfaces.h @@ -22,6 +22,8 @@ #ifndef SRSLTE_ENB_GTPU_INTERFACES_H #define SRSLTE_ENB_GTPU_INTERFACES_H +#include "srslte/common/byte_buffer.h" + namespace srsenb { // GTPU interface for PDCP diff --git a/lib/include/srslte/interfaces/enb_pdcp_interfaces.h b/lib/include/srslte/interfaces/enb_pdcp_interfaces.h index 1dbac3ec9..a3b50f43a 100644 --- a/lib/include/srslte/interfaces/enb_pdcp_interfaces.h +++ b/lib/include/srslte/interfaces/enb_pdcp_interfaces.h @@ -62,8 +62,8 @@ class pdcp_interface_rlc public: /* RLC calls PDCP to push a PDCP PDU. */ virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t pdu) = 0; - virtual void notify_delivery(uint16_t rnti, uint32_t lcid, const std::vector& pdcp_sns) = 0; - virtual void notify_failure(uint16_t rnti, uint32_t lcid, const std::vector& pdcp_sns) = 0; + virtual void notify_delivery(uint16_t rnti, uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sns) = 0; + virtual void notify_failure(uint16_t rnti, uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sns) = 0; }; } // namespace srsenb diff --git a/lib/include/srslte/interfaces/gnb_interfaces.h b/lib/include/srslte/interfaces/gnb_interfaces.h index f682ccc09..ba45548e6 100644 --- a/lib/include/srslte/interfaces/gnb_interfaces.h +++ b/lib/include/srslte/interfaces/gnb_interfaces.h @@ -92,8 +92,8 @@ class pdcp_interface_rlc_nr public: /* RLC calls PDCP to push a PDCP PDU. */ virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; - virtual void notify_delivery(uint16_t rnti, uint32_t lcid, const std::vector& tx_count) = 0; - virtual void notify_failure(uint16_t rnti, uint32_t lcid, const std::vector& tx_count) = 0; + virtual void notify_delivery(uint16_t rnti, uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sns) = 0; + virtual void notify_failure(uint16_t rnti, uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sns) = 0; }; class pdcp_interface_rrc_nr diff --git a/lib/include/srslte/interfaces/pdcp_interface_types.h b/lib/include/srslte/interfaces/pdcp_interface_types.h index 31e034f11..8ab60516e 100644 --- a/lib/include/srslte/interfaces/pdcp_interface_types.h +++ b/lib/include/srslte/interfaces/pdcp_interface_types.h @@ -27,6 +27,7 @@ #ifndef SRSLTE_PDCP_INTERFACE_TYPES_H #define SRSLTE_PDCP_INTERFACE_TYPES_H +#include "srslte/adt/bounded_vector.h" #include "srslte/common/security.h" #include #include @@ -177,6 +178,11 @@ struct pdcp_lte_state_t { uint32_t reordering_pdcp_rx_count; }; +// Custom type for interface between PDCP and RLC to convey SDU delivery status +#define MAX_SDUS_PER_RLC_PDU (256) // default to RLC SDU queue length +#define MAX_SDUS_TO_NOTIFY (MAX_SDUS_PER_RLC_PDU) // Arbitrarily chosen limit +typedef srslte::bounded_vector pdcp_sn_vector_t; + } // namespace srslte #endif // SRSLTE_PDCP_INTERFACE_TYPES_H diff --git a/lib/include/srslte/interfaces/ue_gw_interfaces.h b/lib/include/srslte/interfaces/ue_gw_interfaces.h index 64883c013..4157f3c4d 100644 --- a/lib/include/srslte/interfaces/ue_gw_interfaces.h +++ b/lib/include/srslte/interfaces/ue_gw_interfaces.h @@ -23,6 +23,7 @@ #define SRSLTE_UE_GW_INTERFACES_H #include "srslte/asn1/liblte_mme.h" +#include "srslte/common/byte_buffer.h" namespace srsue { diff --git a/lib/include/srslte/interfaces/ue_pdcp_interfaces.h b/lib/include/srslte/interfaces/ue_pdcp_interfaces.h index 6f7c0f4fd..1ff57145f 100644 --- a/lib/include/srslte/interfaces/ue_pdcp_interfaces.h +++ b/lib/include/srslte/interfaces/ue_pdcp_interfaces.h @@ -23,6 +23,7 @@ #define SRSLTE_UE_PDCP_INTERFACES_H #include "pdcp_interface_types.h" +#include "srslte/common/byte_buffer.h" namespace srsue { @@ -48,13 +49,13 @@ class pdcp_interface_rlc { public: /* RLC calls PDCP to push a PDCP PDU. */ - virtual void write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; - virtual void write_pdu_bcch_bch(srslte::unique_byte_buffer_t sdu) = 0; - virtual void write_pdu_bcch_dlsch(srslte::unique_byte_buffer_t sdu) = 0; - virtual void write_pdu_pcch(srslte::unique_byte_buffer_t sdu) = 0; - virtual void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; - virtual void notify_delivery(uint32_t lcid, const std::vector& pdcp_sn) = 0; - virtual void notify_failure(uint32_t lcid, const std::vector& pdcp_sn) = 0; + virtual void write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; + virtual void write_pdu_bcch_bch(srslte::unique_byte_buffer_t sdu) = 0; + virtual void write_pdu_bcch_dlsch(srslte::unique_byte_buffer_t sdu) = 0; + virtual void write_pdu_pcch(srslte::unique_byte_buffer_t sdu) = 0; + virtual void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; + virtual void notify_delivery(uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sn) = 0; + virtual void notify_failure(uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sn) = 0; }; class pdcp_interface_gw diff --git a/lib/include/srslte/mac/mac_sch_pdu_nr.h b/lib/include/srslte/mac/mac_sch_pdu_nr.h index bddaf9102..1c31a3616 100644 --- a/lib/include/srslte/mac/mac_sch_pdu_nr.h +++ b/lib/include/srslte/mac/mac_sch_pdu_nr.h @@ -22,8 +22,8 @@ #ifndef SRSLTE_MAC_SCH_PDU_NR_H #define SRSLTE_MAC_SCH_PDU_NR_H +#include "srslte/common/byte_buffer.h" #include "srslte/common/common.h" -#include "srslte/common/logmap.h" #include "srslte/config.h" #include "srslte/srslog/srslog.h" #include @@ -110,7 +110,7 @@ private: static const uint8_t mac_ce_payload_len = 8 + 1; // Long BSR has max. 9 octets (see sizeof_ce() too) std::array ce_write_buffer; // Buffer for CE payload - mac_sch_pdu_nr* parent = nullptr; + mac_sch_pdu_nr* parent = nullptr; }; class mac_sch_pdu_nr @@ -144,9 +144,9 @@ private: bool ulsch = false; std::vector subpdus; - byte_buffer_t* buffer = nullptr; - uint32_t pdu_len = 0; - uint32_t remaining_len = 0; + byte_buffer_t* buffer = nullptr; + uint32_t pdu_len = 0; + uint32_t remaining_len = 0; srslog::basic_logger& logger; }; diff --git a/lib/include/srslte/mac/pdu.h b/lib/include/srslte/mac/pdu.h index dd6700db6..7016e8c19 100644 --- a/lib/include/srslte/mac/pdu.h +++ b/lib/include/srslte/mac/pdu.h @@ -23,7 +23,6 @@ #define SRSLTE_PDU_H #include "srslte/common/interfaces_common.h" -#include "srslte/common/logmap.h" #include "srslte/srslog/srslog.h" #include #include @@ -142,13 +141,12 @@ public: {} virtual ~pdu() = default; - std::string to_string() + void to_string(fmt::memory_buffer& buffer) { - std::stringstream ss; for (int i = 0; i < nof_subheaders; i++) { - ss << subheaders[i].to_string() << " "; + fmt::format_to(buffer, " "); + subheaders[i].to_string(buffer); } - return ss.str(); } /* Resets the Read/Write position and remaining PDU length */ @@ -298,11 +296,11 @@ class subh public: virtual ~subh() {} - virtual bool read_subheader(uint8_t** ptr) = 0; - virtual void read_payload(uint8_t** ptr) = 0; - virtual void write_subheader(uint8_t** ptr, bool is_last) = 0; - virtual void write_payload(uint8_t** ptr) = 0; - virtual std::string to_string() = 0; + virtual bool read_subheader(uint8_t** ptr) = 0; + virtual void read_payload(uint8_t** ptr) = 0; + virtual void write_subheader(uint8_t** ptr, bool is_last) = 0; + virtual void write_payload(uint8_t** ptr) = 0; + virtual void to_string(fmt::memory_buffer& buffer) = 0; pdu* parent = nullptr; @@ -366,8 +364,8 @@ public: void set_padding(uint32_t padding_len); void set_type(subh_type type_); - void init(); - std::string to_string(); + void init(); + void to_string(fmt::memory_buffer& buffer); bool set_next_mch_sched_info(uint8_t lcid, uint16_t mtch_stop); @@ -405,7 +403,7 @@ public: static uint32_t size_header_sdu(uint32_t nbytes); bool update_space_ce(uint32_t nbytes, bool var_len = false); bool update_space_sdu(uint32_t nbytes); - std::string to_string(); + void to_string(fmt::memory_buffer& buffer); }; class rar_subh : public subh @@ -442,8 +440,8 @@ public: void set_temp_crnti(uint16_t temp_rnti); void set_sched_grant(uint8_t grant[RAR_GRANT_LEN]); - void init(); - std::string to_string(); + void init(); + void to_string(fmt::memory_buffer& buffer); private: uint8_t grant[RAR_GRANT_LEN]; @@ -462,8 +460,8 @@ public: bool has_backoff(); uint8_t get_backoff(); - bool write_packet(uint8_t* ptr); - std::string to_string(); + bool write_packet(uint8_t* ptr); + void to_string(fmt::memory_buffer& buffer); private: bool has_backoff_indicator; diff --git a/lib/include/srslte/mac/pdu_queue.h b/lib/include/srslte/mac/pdu_queue.h index e290138db..bdb107d73 100644 --- a/lib/include/srslte/mac/pdu_queue.h +++ b/lib/include/srslte/mac/pdu_queue.h @@ -22,9 +22,9 @@ #ifndef SRSLTE_PDU_QUEUE_H #define SRSLTE_PDU_QUEUE_H +#include "srslte/adt/circular_buffer.h" #include "srslte/common/block_queue.h" #include "srslte/common/buffer_pool.h" -#include "srslte/common/log.h" #include "srslte/common/timers.h" #include "srslte/mac/pdu.h" @@ -42,9 +42,7 @@ public: virtual void process_pdu(uint8_t* buff, uint32_t len, channel_t channel) = 0; }; - pdu_queue(srslog::basic_logger& logger, uint32_t pool_size = DEFAULT_POOL_SIZE) : - pool(pool_size), callback(NULL), logger(logger) - {} + pdu_queue(srslog::basic_logger& logger) : pool(DEFAULT_POOL_SIZE), callback(NULL), logger(logger) {} void init(process_callback* callback); uint8_t* request(uint32_t len); @@ -56,7 +54,7 @@ public: void reset(); private: - const static int DEFAULT_POOL_SIZE = 64; // Number of PDU buffers in total + const static int DEFAULT_POOL_SIZE = 128; // Number of PDU buffers in total const static int MAX_PDU_LEN = 150 * 1024 / 8; // ~ 150 Mbps typedef struct { @@ -69,8 +67,8 @@ private: } pdu_t; - block_queue pdu_q; - buffer_pool pool; + static_blocking_queue pdu_q; + buffer_pool pool; process_callback* callback; srslog::basic_logger& logger; diff --git a/lib/include/srslte/phy/ch_estimation/dmrs_sch.h b/lib/include/srslte/phy/ch_estimation/dmrs_sch.h index b3e92673c..620eb36ab 100644 --- a/lib/include/srslte/phy/ch_estimation/dmrs_sch.h +++ b/lib/include/srslte/phy/ch_estimation/dmrs_sch.h @@ -29,6 +29,12 @@ #define SRSLTE_DMRS_SCH_MAX_SYMBOLS 4 +/** + * @brief Helper macro for counting the number of subcarriers taken by DMRS in a PRB. + */ +#define SRSLTE_DMRS_SCH_SC(CDM_GROUPS, DMRS_TYPE) \ + (SRSLTE_MIN(SRSLTE_NRE, (CDM_GROUPS) * ((DMRS_TYPE) == srslte_dmrs_sch_type_1 ? 6 : 4))) + /** * @brief PDSCH DMRS estimator object * diff --git a/lib/include/srslte/phy/channel/channel.h b/lib/include/srslte/phy/channel/channel.h index 8fde01860..390159843 100644 --- a/lib/include/srslte/phy/channel/channel.h +++ b/lib/include/srslte/phy/channel/channel.h @@ -27,8 +27,8 @@ #include "fading.h" #include "hst.h" #include "rlf.h" -#include "srslte/common/log_filter.h" #include "srslte/phy/common/phy_common.h" +#include "srslte/srslog/srslog.h" #include #include diff --git a/lib/include/srslte/phy/phch/csi.h b/lib/include/srslte/phy/phch/csi.h index 25cf76123..ef5bacf5a 100644 --- a/lib/include/srslte/phy/phch/csi.h +++ b/lib/include/srslte/phy/phch/csi.h @@ -44,10 +44,18 @@ SRSLTE_API int srslte_csi_generate_reports(const srslte_csi_hl_cfg_t* cfg, * @param nof_reports Number of CSI reports in the list * @return The number of bits if the provided list is valid, SRSLTE_ERROR code otherwise */ -SRSLTE_API int srslte_csi_nof_bits(const srslte_csi_report_cfg_t* report_list, uint32_t nof_reports); +SRSLTE_API int srslte_csi_part1_nof_bits(const srslte_csi_report_cfg_t* report_list, uint32_t nof_reports); /** - * @brief Pack CSI part 1 bits for a PUCCH transmission + * @brief Checks if the report list contains part 2 CSI report + * @param report_list Report list + * @param nof_reports Number of reports in the list + * @return True if at least one report contains part 2, false otherwise + */ +SRSLTE_API bool srslte_csi_has_part2(const srslte_csi_report_cfg_t* report_list, uint32_t nof_reports); + +/** + * @brief Pack CSI part 1 bits for a PUCCH or PUSCH transmission * @param report_list Provides the CSI report list * @param nof_reports Number of CSI reports in the list * @param o_csi1 CSI bits @@ -60,6 +68,21 @@ SRSLTE_API int srslte_csi_part1_pack(const srslte_csi_report_cfg_t* report_cfg uint8_t* o_csi1, uint32_t max_o_csi1); +/** + *@brief Unpacks CSI part 1 bits for PUCCH or PUSCH transmission + * @param report_list Provides the CSI report list + * @param nof_reports Number of CSI reports in the list + * @param o_csi1 CSI bits + * @param max_o_csi1 Maximum number of CSI bits + * @param report_value + * @return SRSLTE_SUCCESS if provided data is valid, SRSLTE_ERROR code otherwise + */ +SRSLTE_API int srslte_csi_part1_unpack(const srslte_csi_report_cfg_t* report_cfg, + uint32_t nof_reports, + uint8_t* o_csi1, + uint32_t max_o_csi1, + srslte_csi_report_value_t* report_value); + /** * @brief Converts to string a given list of CSI reports * @param report_cfg Report configuration list diff --git a/lib/include/srslte/phy/phch/csi_cfg.h b/lib/include/srslte/phy/phch/csi_cfg.h index cc165c120..0e57ad3d4 100644 --- a/lib/include/srslte/phy/phch/csi_cfg.h +++ b/lib/include/srslte/phy/phch/csi_cfg.h @@ -139,6 +139,7 @@ typedef struct SRSLTE_API { // Resource set context uint32_t nof_ports; ///< Number of antenna ports uint32_t K_csi_rs; ///< Number of CSI-RS in the corresponding resource set + bool has_part2; ///< Set to true if the report has part 2 } srslte_csi_report_cfg_t; /** diff --git a/lib/include/srslte/phy/phch/phch_cfg_nr.h b/lib/include/srslte/phy/phch/phch_cfg_nr.h index efa9f182a..da3e9c3cb 100644 --- a/lib/include/srslte/phy/phch/phch_cfg_nr.h +++ b/lib/include/srslte/phy/phch/phch_cfg_nr.h @@ -32,6 +32,7 @@ #include "srslte/phy/common/phy_common_nr.h" #include "srslte/phy/phch/sch_cfg_nr.h" +#include "srslte/phy/phch/uci_cfg_nr.h" /** * @brief PDSCH DMRS type @@ -210,8 +211,13 @@ typedef struct SRSLTE_API { srslte_sch_cfg_t sch_cfg; ///< Common shared channel parameters - /// Uplink params - bool enable_transform_precoder; + /// PUSCH only parameters + srslte_uci_cfg_nr_t uci; ///< Uplink Control Information configuration + bool enable_transform_precoder; + float beta_harq_ack_offset; + float beta_csi_part1_offset; + float scaling; + bool freq_hopping_enabled; } srslte_sch_cfg_nr_t; #endif // SRSLTE_PHCH_CFG_NR_H diff --git a/lib/include/srslte/phy/phch/pucch_nr.h b/lib/include/srslte/phy/phch/pucch_nr.h index d02e6ef2f..0cfa8a569 100644 --- a/lib/include/srslte/phy/phch/pucch_nr.h +++ b/lib/include/srslte/phy/phch/pucch_nr.h @@ -51,6 +51,7 @@ typedef struct SRSLTE_API { */ typedef struct SRSLTE_API { uint32_t max_prb; + srslte_carrier_nr_t carrier; srslte_zc_sequence_lut_t r_uv_1prb; cf_t format1_w_i_m[SRSLTE_PUCCH_NR_FORMAT1_N_MAX][SRSLTE_PUCCH_NR_FORMAT1_N_MAX][SRSLTE_PUCCH_NR_FORMAT1_N_MAX]; srslte_modem_table_t bpsk; @@ -64,10 +65,19 @@ typedef struct SRSLTE_API { /** * @brief Initialises an NR-PUCCH encoder/decoder object * @param q Object + * @param args PUCCH configuration arguments * @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise */ SRSLTE_API int srslte_pucch_nr_init(srslte_pucch_nr_t* q, const srslte_pucch_nr_args_t* args); +/** + * @brief Initialises an NR-PUCCH encoder/decoder object + * @param q Object + * @param carrier + * @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise + */ +SRSLTE_API int srslte_pucch_nr_set_carrier(srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier); + /** * @brief Deallocates an NR-PUCCH encoder/decoder object * @param q Object @@ -113,7 +123,6 @@ SRSLTE_API int srslte_pucch_nr_alpha_idx(const srslte_carrier_nr_t* car * @brief Encode and writes NR-PUCCH format 0 in the resource grid * @remark Described in TS 38.211 clause 6.3.2.3 PUCCH format 0 * @param[in,out] q NR-PUCCH encoder/decoder object - * @param[in] carrier Serving cell and Uplink BWP configuration * @param[in] cfg PUCCH common configuration * @param[in] slot slot configuration * @param[in] resource PUCCH format 0 resource @@ -122,7 +131,6 @@ SRSLTE_API int srslte_pucch_nr_alpha_idx(const srslte_carrier_nr_t* car * @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise */ SRSLTE_API int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q, - const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, const srslte_slot_cfg_t* slot, srslte_pucch_nr_resource_t* resource, @@ -132,7 +140,6 @@ SRSLTE_API int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* /** * @brief Measures PUCCH format 0 in the resource grid * @param[in,out] q NR-PUCCH encoder/decoder object - * @param[in] carrier Serving cell and Uplink BWP configuration * @param[in] cfg PUCCH common configuration * @param[in] slot slot configuration * @param[in] resource PUCCH format 0 resource @@ -142,7 +149,6 @@ SRSLTE_API int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* * @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise */ SRSLTE_API int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q, - const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, const srslte_slot_cfg_t* slot, srslte_pucch_nr_resource_t* resource, @@ -165,7 +171,6 @@ SRSLTE_API cf_t srslte_pucch_nr_format1_w(const srslte_pucch_nr_t* q, uint32_t n * @brief Encodes and puts NR-PUCCH format 1 in the resource grid * @remark Described in TS 38.211 clause 6.3.2.4 PUCCH format 1 * @param[in,out] q NR-PUCCH encoder/decoder object - * @param[in] carrier Serving cell and Uplink BWP configuration * @param[in] cfg PUCCH common configuration * @param[in] slot slot configuration * @param[in] resource PUCCH format 1 resource @@ -175,7 +180,6 @@ SRSLTE_API cf_t srslte_pucch_nr_format1_w(const srslte_pucch_nr_t* q, uint32_t n * @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise */ SRSLTE_API int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q, - const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, @@ -186,7 +190,6 @@ SRSLTE_API int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* /** * @brief Decodes NR-PUCCH format 1 * @param[in,out] q NR-PUCCH encoder/decoder object - * @param[in] carrier Serving cell and Uplink BWP configuration * @param[in] cfg PUCCH common configuration * @param[in] slot slot configuration * @param[in] resource PUCCH format 2-4 resource @@ -197,7 +200,6 @@ SRSLTE_API int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* * @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise */ SRSLTE_API int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q, - const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, @@ -209,7 +211,6 @@ SRSLTE_API int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* /** * @brief Encoder NR-PUCCH formats 2, 3 and 4. The NR-PUCCH format is selected by resource->format. * @param[in,out] q NR-PUCCH encoder/decoder object - * @param[in] carrier Serving cell and Uplink BWP configuration * @param[in] cfg PUCCH common configuration * @param[in] slot slot configuration * @param[in] resource PUCCH format 1 resource @@ -219,7 +220,6 @@ SRSLTE_API int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* * @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise */ SRSLTE_API int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q, - const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, @@ -230,7 +230,6 @@ SRSLTE_API int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* /** * @brief Decode NR-PUCCH format 2, 3, and 4. The NR-PUCCH format is selected by resource->format. * @param q[in,out] q NR-PUCCH encoder/decoder - * @param[in] carrier Serving cell and Uplink BWP configuration * @param[in] cfg PUCCH common configuration * @param[in] slot slot configuration * @param[in] resource PUCCH format 2-4 resource @@ -241,7 +240,6 @@ SRSLTE_API int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* * @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise */ SRSLTE_API int srslte_pucch_nr_format_2_3_4_decode(srslte_pucch_nr_t* q, - const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, diff --git a/lib/include/srslte/phy/phch/pusch_nr.h b/lib/include/srslte/phy/phch/pusch_nr.h index d3103cdb6..58e2764fb 100644 --- a/lib/include/srslte/phy/phch/pusch_nr.h +++ b/lib/include/srslte/phy/phch/pusch_nr.h @@ -29,6 +29,7 @@ #include "srslte/phy/phch/phch_cfg_nr.h" #include "srslte/phy/phch/regs.h" #include "srslte/phy/phch/sch_nr.h" +#include "srslte/phy/phch/uci_nr.h" #include "srslte/phy/scrambling/scrambling.h" /** @@ -36,6 +37,7 @@ */ typedef struct SRSLTE_API { srslte_sch_nr_args_t sch; + srslte_uci_nr_args_t uci; bool measure_evm; bool measure_time; } srslte_pusch_nr_args_t; @@ -49,6 +51,7 @@ typedef struct SRSLTE_API { uint32_t max_cw; ///< Maximum number of allocated code words srslte_carrier_nr_t carrier; ///< NR carrier configuration srslte_sch_nr_t sch; ///< SCH Encoder/Decoder Object + srslte_uci_nr_t uci; ///< UCI Encoder/Decoder Object uint8_t* b[SRSLTE_MAX_CODEWORDS]; ///< SCH Encoded and scrambled data cf_t* d[SRSLTE_MAX_CODEWORDS]; ///< PDSCH modulated bits cf_t* x[SRSLTE_MAX_LAYERS_NR]; ///< PDSCH modulated bits @@ -56,15 +59,38 @@ typedef struct SRSLTE_API { srslte_evm_buffer_t* evm_buffer; bool meas_time_en; uint32_t meas_time_us; + srslte_uci_cfg_nr_t uci_cfg; ///< Internal UCI bits configuration + uint8_t* g_ulsch; ///< Temporal Encoded UL-SCH data + uint8_t* g_ack; ///< Temporal Encoded HARQ-ACK bits + uint8_t* g_csi1; ///< Temporal Encoded CSI part 1 bits + uint8_t* g_csi2; ///< Temporal Encoded CSI part 2 bits + uint32_t* pos_ulsch; ///< Reserved resource elements for HARQ-ACK multiplexing position + uint32_t* pos_ack; ///< Reserved resource elements for HARQ-ACK multiplexing position + uint32_t* pos_csi1; ///< Reserved resource elements for CSI part 1 multiplexing position + uint32_t* pos_csi2; ///< Reserved resource elements for CSI part 1 multiplexing position + bool uci_mux; ///< Set to true if PUSCH needs to multiplex UCI + uint32_t G_ack; ///< Number of encoded HARQ-ACK bits + uint32_t G_csi1; ///< Number of encoded CSI part 1 bits + uint32_t G_csi2; ///< Number of encoded CSI part 2 bits + uint32_t G_ulsch; ///< Number of encoded shared channel } srslte_pusch_nr_t; /** - * + * @brief Groups NR-PUSCH data for transmission */ typedef struct { - uint8_t* payload; - bool crc; - float evm; + uint8_t* payload; ///< SCH payload + srslte_uci_value_nr_t uci; ///< UCI payload +} srslte_pusch_data_nr_t; + +/** + * @brief Groups NR-PUSCH data for reception + */ +typedef struct { + uint8_t* payload; ///< SCH payload + srslte_uci_value_nr_t uci; ///< UCI payload + bool crc; ///< CRC match + float evm; ///< EVM measurement if configured through arguments } srslte_pusch_res_nr_t; SRSLTE_API int srslte_pusch_nr_init_gnb(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args); @@ -75,11 +101,11 @@ SRSLTE_API void srslte_pusch_nr_free(srslte_pusch_nr_t* q); SRSLTE_API int srslte_pusch_nr_set_carrier(srslte_pusch_nr_t* q, const srslte_carrier_nr_t* carrier); -SRSLTE_API int srslte_pusch_nr_encode(srslte_pusch_nr_t* q, - const srslte_sch_cfg_nr_t* cfg, - const srslte_sch_grant_nr_t* grant, - uint8_t* data[SRSLTE_MAX_TB], - cf_t* sf_symbols[SRSLTE_MAX_PORTS]); +SRSLTE_API int srslte_pusch_nr_encode(srslte_pusch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + const srslte_pusch_data_nr_t* data, + cf_t* sf_symbols[SRSLTE_MAX_PORTS]); SRSLTE_API int srslte_pusch_nr_decode(srslte_pusch_nr_t* q, const srslte_sch_cfg_nr_t* cfg, diff --git a/lib/include/srslte/phy/phch/ra_ul_nr.h b/lib/include/srslte/phy/phch/ra_ul_nr.h index 728d78cfe..49a37b370 100644 --- a/lib/include/srslte/phy/phch/ra_ul_nr.h +++ b/lib/include/srslte/phy/phch/ra_ul_nr.h @@ -61,7 +61,7 @@ SRSLTE_API int srslte_ra_ul_nr_time(const srslte_sch_hl_cfg_nr_t* cfg, * @return Returns SRSLTE_SUCCESS if the provided allocation is valid, otherwise it returns SRSLTE_ERROR code */ SRSLTE_API int -srslte_ra_ul_nr_pdsch_time_resource_default_A(uint32_t scs_cfg, uint32_t m, srslte_sch_grant_nr_t* grant); +srslte_ra_ul_nr_pusch_time_resource_default_A(uint32_t scs_cfg, uint32_t m, srslte_sch_grant_nr_t* grant); /** * @brief Calculates the number of PUSCH-DMRS CDM groups without data for DCI format 0_0 diff --git a/lib/include/srslte/phy/phch/sch_nr.h b/lib/include/srslte/phy/phch/sch_nr.h index bdec08466..4f100c2e6 100644 --- a/lib/include/srslte/phy/phch/sch_nr.h +++ b/lib/include/srslte/phy/phch/sch_nr.h @@ -78,27 +78,24 @@ typedef struct SRSLTE_API { * @brief Common SCH configuration */ typedef struct { - srslte_basegraph_t bg; ///< @brief Base graph - uint32_t Qm; ///< @brief Modulation order - uint32_t G; ///< Number of available bits - uint32_t A; ///< @brief Payload size, TBS - uint32_t L_tb; ///< @brief the number of the transport block parity bits (16 or 24 bits) - uint32_t L_cb; ///< @brief the number of the code block parity bits (0 or 24 bits) - uint32_t B; ///< @brief the number of bits in the transport block including TB CRC - uint32_t Bp; ///< @brief the number of bits in the transport block including CB and TB CRCs - uint32_t Kp; ///< @brief Number of payload bits of the code block including CB CRC - uint32_t Kr; ///< @brief Number of payload bits of the code block including CB CRC and filler bits - uint32_t F; ///< @brief Number of filler bits - uint32_t Nref; ///< @brief N_ref parameter described in TS 38.212 V15.9.0 5.4.2.1 - uint32_t Z; ///< @brief LDPC lifting size - uint32_t Nl; ///< @brief Number of transmission layers that the transport block is mapped onto - bool mask[SRSLTE_SCH_NR_MAX_NOF_CB_LDPC]; ///< Indicates what codeblocks shall be encoded/decoded - uint32_t C; ///< Number of codeblocks - uint32_t Cp; ///< Number of codeblocks that are actually transmitted - srslte_crc_t* crc_tb; ///< Selected CRC for transport block - srslte_ldpc_encoder_t* encoder; ///< @brief Points to the selected encoder (if valid) - srslte_ldpc_decoder_t* decoder; ///< @brief Points to the selected decoder (if valid) -} srslte_sch_nr_common_cfg_t; + srslte_basegraph_t bg; ///< @brief Base graph + uint32_t Qm; ///< @brief Modulation order + uint32_t G; ///< Number of available bits + uint32_t A; ///< @brief Payload size, TBS + uint32_t L_tb; ///< @brief the number of the transport block parity bits (16 or 24 bits) + uint32_t L_cb; ///< @brief the number of the code block parity bits (0 or 24 bits) + uint32_t B; ///< @brief the number of bits in the transport block including TB CRC + uint32_t Bp; ///< @brief the number of bits in the transport block including CB and TB CRCs + uint32_t Kp; ///< @brief Number of payload bits of the code block including CB CRC + uint32_t Kr; ///< @brief Number of payload bits of the code block including CB CRC and filler bits + uint32_t F; ///< @brief Number of filler bits + uint32_t Nref; ///< @brief N_ref parameter described in TS 38.212 V15.9.0 5.4.2.1 + uint32_t Z; ///< @brief LDPC lifting size + uint32_t Nl; ///< @brief Number of transmission layers that the transport block is mapped onto + bool mask[SRSLTE_SCH_NR_MAX_NOF_CB_LDPC]; ///< Indicates what codeblocks shall be encoded/decoded + uint32_t C; ///< Number of codeblocks + uint32_t Cp; ///< Number of codeblocks that are actually transmitted +} srslte_sch_nr_tb_info_t; /** * @brief Base graph selection from a provided transport block size and target rate @@ -119,10 +116,10 @@ SRSLTE_API srslte_basegraph_t srslte_sch_nr_select_basegraph(uint32_t tbs, doubl * @param cfg SCH object * @return */ -SRSLTE_API int srslte_sch_nr_fill_cfg(srslte_sch_nr_t* q, - const srslte_sch_cfg_t* sch_cfg, - const srslte_sch_tb_t* tb, - srslte_sch_nr_common_cfg_t* cfg); +SRSLTE_API int srslte_sch_nr_fill_tb_info(const srslte_carrier_nr_t* carrier, + const srslte_sch_cfg_t* sch_cfg, + const srslte_sch_tb_t* tb, + srslte_sch_nr_tb_info_t* cfg); /** * @brief Initialises an SCH object as transmitter diff --git a/lib/include/srslte/phy/phch/uci_cfg_nr.h b/lib/include/srslte/phy/phch/uci_cfg_nr.h index 1691834d2..2de4f4361 100644 --- a/lib/include/srslte/phy/phch/uci_cfg_nr.h +++ b/lib/include/srslte/phy/phch/uci_cfg_nr.h @@ -23,7 +23,7 @@ #define SRSLTE_UCI_CFG_NR_H #include "csi_cfg.h" -#include "srslte/phy/common/phy_common.h" +#include "srslte/phy/common/phy_common_nr.h" #include #include @@ -39,21 +39,41 @@ #define SRSLTE_UCI_NR_MAX_ACK_BITS 360 /** - * @brief Maximum number of Scheduling Request (SR) bits that can be carried in Uplink Control Information (UCI) message + * @brief Maximum number of Channel State Information part 1 (CSI1) bits that can be carried in Uplink Control + * Information (UCI) message */ -#define SRSLTE_UCI_NR_MAX_SR_BITS 10 +#define SRSLTE_UCI_NR_MAX_CSI1_BITS 360 /** - * @brief Maximum number of Channel State Information part 1 (CSI1) bits that can be carried in Uplink Control - * Information (UCI) message + * @brief Uplink Control Information bits configuration for PUCCH transmission */ -#define SRSLTE_UCI_NR_MAX_CSI1_BITS 10 +typedef struct { + uint16_t rnti; ///< RNTI + uint32_t resource_id; ///< PUCCH resource indicator field in the DCI format 1_0 or DCI format 1_1 + uint32_t n_cce_0; ///< index of a first CCE for the PDCCH reception + uint32_t N_cce; ///< number of CCEs in a CORESET of a PDCCH reception with DCI format 1_0 or 1_1 + uint32_t sr_resource_id; ///< Scheduling request resource identifier, only valid if positive SR + bool sr_positive_present; ///< Set to true if there is at least one positive SR +} srslte_uci_nr_pucch_cfg_t; /** - * @brief Maximum number of Channel State Information part 2 (CSI2) bits that can be carried in Uplink Control - * Information (UCI) message + * @brief Uplink Control Information bits configuration for PUSCH transmission */ -#define SRSLTE_UCI_NR_MAX_CSI2_BITS 10 +typedef struct { + uint32_t l0; ///< First OFDM symbol that does not carry DMRS of the PUSCH, after the first DMRS symbol(s) + uint32_t l1; ///< OFDM symbol index of the first OFDM symbol that does not carry DMRS + uint32_t M_pusch_sc[SRSLTE_NSYMB_PER_SLOT_NR]; ///< Number of potential RE for PUSCH transmission + uint32_t M_uci_sc[SRSLTE_NSYMB_PER_SLOT_NR]; ///< Number of potential RE for UCI transmission + uint32_t K_sum; ///< Sum of UL-SCH code block sizes, set to zero if no UL-SCH + srslte_mod_t modulation; ///< Modulation for the PUSCH + uint32_t nof_layers; ///< Number of layers for PUSCH + float R; ///< Code rate of the PUSCH + float alpha; ///< Higher layer parameter scaling + float beta_harq_ack_offset; + float beta_csi1_offset; + uint32_t nof_re; + bool csi_part2_present; +} srslte_uci_nr_pusch_cfg_t; /** * @brief Uplink Control Information (UCI) message configuration @@ -64,17 +84,10 @@ typedef struct SRSLTE_API { uint32_t o_sr; ///< Number of SR bits srslte_csi_report_cfg_t csi[SRSLTE_CSI_MAX_NOF_REPORT]; ///< CSI report configuration uint32_t nof_csi; ///< Number of CSI reports - - /// PUSCH only parameters - srslte_mod_t modulation; ///< Modulation - - /// PUCCH only parameters - uint16_t rnti; ///< RNTI - uint32_t pucch_resource_id; ///< PUCCH resource indicator field in the DCI format 1_0 or DCI format 1_1 - uint32_t n_cce_0; ///< index of a first CCE for the PDCCH reception - uint32_t N_cce; ///< number of CCEs in a CORESET of a PDCCH reception with DCI format 1_0 or 1_1 - uint32_t sr_resource_id; ///< Scheduling request resource identifier, only valid if positive SR - bool sr_positive_present; ///< Set to true if there is at least one positive SR + union { + srslte_uci_nr_pucch_cfg_t pucch; ///< Configuration for transmission in PUCCH + srslte_uci_nr_pusch_cfg_t pusch; ///< Configuration for transmission in PUSCH + }; } srslte_uci_cfg_nr_t; /** diff --git a/lib/include/srslte/phy/phch/uci_nr.h b/lib/include/srslte/phy/phch/uci_nr.h index 399391ebd..e094043fb 100644 --- a/lib/include/srslte/phy/phch/uci_nr.h +++ b/lib/include/srslte/phy/phch/uci_nr.h @@ -22,13 +22,14 @@ #ifndef SRSLTE_UCI_NR_H #define SRSLTE_UCI_NR_H +#include "srslte/phy/common/phy_common_nr.h" #include "srslte/phy/fec/crc.h" #include "srslte/phy/fec/polar/polar_code.h" #include "srslte/phy/fec/polar/polar_decoder.h" #include "srslte/phy/fec/polar/polar_encoder.h" #include "srslte/phy/fec/polar/polar_rm.h" +#include "srslte/phy/phch/phch_cfg_nr.h" #include "srslte/phy/phch/pucch_cfg_nr.h" -#include "uci_cfg.h" #include "uci_cfg_nr.h" #include #include @@ -39,6 +40,7 @@ typedef struct { bool disable_simd; ///< Disable Polar code SIMD float block_code_threshold; ///< Set normalised block code threshold (receiver only) + float one_bit_threshold; ///< Decode threshold for 1 bit (receiver only) } srslte_uci_nr_args_t; typedef struct { @@ -49,11 +51,12 @@ typedef struct { srslte_crc_t crc6; srslte_crc_t crc11; srslte_polar_code_t code; - uint8_t* bit_sequence; ///< UCI bit sequence - uint8_t* c; ///< UCI code-block prior encoding or after decoding - uint8_t* allocated; ///< Polar code intermediate - uint8_t* d; ///< Polar code encoded intermediate - float block_code_threshold; + uint8_t* bit_sequence; ///< UCI bit sequence + uint8_t* c; ///< UCI code-block prior encoding or after decoding + uint8_t* allocated; ///< Polar code intermediate + uint8_t* d; ///< Polar code encoded intermediate + float block_code_threshold; ///< Decode threshold for block code (3-11 bits) + float one_bit_threshold; ///< Decode threshold for 1 bit } srslte_uci_nr_t; /** @@ -123,6 +126,72 @@ SRSLTE_API int srslte_uci_nr_decode_pucch(srslte_uci_nr_t* q, int8_t* llr, srslte_uci_value_nr_t* value); +/** + * @brief Calculates total number of encoded bits for HARQ-ACK multiplexing in PUSCH + * @param[in] cfg PUSCH transmission configuration + * @return The number of encoded bits if successful, SRSLTE_ERROR code otherwise + */ +SRSLTE_API int srslte_uci_nr_pusch_ack_nof_bits(const srslte_uci_nr_pusch_cfg_t* cfg, uint32_t O_ack); + +/** + * @brief Encodes HARQ-ACK bits for PUSCH transmission + * @param[in,out] q NR-UCI object + * @param[in] cfg UCI configuration + * @param[in] value UCI value + * @param[out] o_ack Encoded ack bits + * @return The number of encoded bits if successful, SRSLTE_ERROR code otherwise + */ +SRSLTE_API int srslte_uci_nr_encode_pusch_ack(srslte_uci_nr_t* q, + const srslte_uci_cfg_nr_t* cfg, + const srslte_uci_value_nr_t* value, + uint8_t* o_ack); + +/** + * @brief Decodes HARQ-ACK bits for PUSCH transmission + * @param[in,out] q NR-UCI object + * @param[in] cfg UCI configuration + * @param[in] llr Provides softbits LLR + * @param[out] value UCI value + * @return SRSLTE_SUCCESS if the decoding process was successful, SRSLTE_ERROR code otherwise + */ +SRSLTE_API int srslte_uci_nr_decode_pusch_ack(srslte_uci_nr_t* q, + const srslte_uci_cfg_nr_t* cfg, + int8_t* llr, + srslte_uci_value_nr_t* value); + +/** + * @brief Calculates total number of encoded bits for CSI part 1 multiplexing in PUSCH + * @param[in] cfg UCI configuration + * @return The number of encoded bits if valid, SRSLTE_ERROR code otherwise + */ +SRSLTE_API int srslte_uci_nr_pusch_csi1_nof_bits(const srslte_uci_cfg_nr_t* cfg); + +/** + * @brief Encodes CSI part 1 bits for PUSCH transmission + * @param[in,out] q NR-UCI object + * @param[in] cfg UCI configuration + * @param[in] value UCI value + * @param[out] o_ack Encoded CSI part 1 bits + * @return The number of encoded bits if successful, SRSLTE_ERROR code otherwise + */ +SRSLTE_API int srslte_uci_nr_encode_pusch_csi1(srslte_uci_nr_t* q, + const srslte_uci_cfg_nr_t* cfg, + const srslte_uci_value_nr_t* value, + uint8_t* o); + +/** + * @brief Decodes CSI part 1 bits for PUSCH transmission + * @param[in,out] q NR-UCI object + * @param[in] cfg UCI configuration + * @param[in] llr Provides softbits LLR + * @param[out] value UCI value + * @return SRSLTE_SUCCESS if the decoding process was successful, SRSLTE_ERROR code otherwise + */ +SRSLTE_API int srslte_uci_nr_decode_pusch_csi1(srslte_uci_nr_t* q, + const srslte_uci_cfg_nr_t* cfg, + int8_t* llr, + srslte_uci_value_nr_t* value); + /** * @brief Calculates the total number of UCI bits * @param uci_cfg UCI configuration diff --git a/lib/include/srslte/phy/ue/ue_ul_nr.h b/lib/include/srslte/phy/ue/ue_ul_nr.h index c7abe4908..daedd4d4b 100644 --- a/lib/include/srslte/phy/ue/ue_ul_nr.h +++ b/lib/include/srslte/phy/ue/ue_ul_nr.h @@ -63,10 +63,10 @@ SRSLTE_API int srslte_ue_ul_nr_init(srslte_ue_ul_nr_t* q, cf_t* output, const sr SRSLTE_API int srslte_ue_ul_nr_set_carrier(srslte_ue_ul_nr_t* q, const srslte_carrier_nr_t* carrier); -SRSLTE_API int srslte_ue_ul_nr_encode_pusch(srslte_ue_ul_nr_t* q, - const srslte_slot_cfg_t* slot_cfg, - const srslte_sch_cfg_nr_t* pusch_cfg, - uint8_t* data_); +SRSLTE_API int srslte_ue_ul_nr_encode_pusch(srslte_ue_ul_nr_t* q, + const srslte_slot_cfg_t* slot_cfg, + const srslte_sch_cfg_nr_t* pusch_cfg, + const srslte_pusch_data_nr_t* data); SRSLTE_API int srslte_ue_ul_nr_encode_pucch(srslte_ue_ul_nr_t* q, const srslte_slot_cfg_t* slot_cfg, diff --git a/lib/include/srslte/phy/utils/vector.h b/lib/include/srslte/phy/utils/vector.h index e99cc75c1..981bdca44 100644 --- a/lib/include/srslte/phy/utils/vector.h +++ b/lib/include/srslte/phy/utils/vector.h @@ -49,6 +49,9 @@ extern "C" { #define SRSLTE_MAX(a, b) ((a) > (b) ? (a) : (b)) #define SRSLTE_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define SRSLTE_CEIL(NUM, DEN) (((NUM) + ((DEN)-1)) / (DEN)) +#define SRSLTE_FLOOR(NUM, DEN) ((NUM) / (DEN)) +#define SRSLTE_ROUND(NUM, DEN) ((uint32_t)round((double)(NUM) / (double)(DEN))) // Cumulative moving average #define SRSLTE_VEC_CMA(data, average, n) ((average) + ((data) - (average)) / ((n) + 1)) diff --git a/lib/include/srslte/radio/radio.h b/lib/include/srslte/radio/radio.h index 9888ba6e1..c58140760 100644 --- a/lib/include/srslte/radio/radio.h +++ b/lib/include/srslte/radio/radio.h @@ -24,12 +24,13 @@ #include "rf_buffer.h" #include "rf_timestamp.h" #include "srslte/common/interfaces_common.h" -#include "srslte/common/log_filter.h" #include "srslte/interfaces/radio_interfaces.h" #include "srslte/phy/resampling/resampler.h" #include "srslte/phy/rf/rf.h" #include "srslte/radio/radio_base.h" +#include "srslte/srslog/srslog.h" #include "srslte/srslte.h" + #include #include diff --git a/lib/include/srslte/radio/radio_base.h b/lib/include/srslte/radio/radio_base.h index 216367855..874c84dff 100644 --- a/lib/include/srslte/radio/radio_base.h +++ b/lib/include/srslte/radio/radio_base.h @@ -28,7 +28,6 @@ #define SRSLTE_RADIO_BASE_H #include "srslte/common/interfaces_common.h" -#include "srslte/common/logger.h" #include "srslte/radio/radio_metrics.h" namespace srslte { diff --git a/lib/include/srslte/radio/radio_null.h b/lib/include/srslte/radio/radio_null.h index d651c1fb4..016ee437a 100644 --- a/lib/include/srslte/radio/radio_null.h +++ b/lib/include/srslte/radio/radio_null.h @@ -28,8 +28,6 @@ #define SRSLTE_RADIO_NULL_H #include "radio_base.h" -#include "srslte/common/logger.h" -#include "srslte/common/logmap.h" #include "srslte/interfaces/radio_interfaces.h" #include "srslte/phy/rf/rf.h" #include "srslte/radio/radio.h" diff --git a/lib/include/srslte/rrc/rrc_cfg_utils.h b/lib/include/srslte/rrc/rrc_cfg_utils.h index 17025f4bc..e66e3cb65 100644 --- a/lib/include/srslte/rrc/rrc_cfg_utils.h +++ b/lib/include/srslte/rrc/rrc_cfg_utils.h @@ -24,7 +24,6 @@ #include "srslte/asn1/rrc_utils.h" #include "srslte/common/common.h" -#include "srslte/common/logmap.h" #include #include diff --git a/lib/include/srslte/srslog/detail/log_entry_metadata.h b/lib/include/srslte/srslog/detail/log_entry_metadata.h index af4bf654f..f23f30a2f 100644 --- a/lib/include/srslte/srslog/detail/log_entry_metadata.h +++ b/lib/include/srslte/srslog/detail/log_entry_metadata.h @@ -42,7 +42,7 @@ struct log_context { struct log_entry_metadata { std::chrono::high_resolution_clock::time_point tp; log_context context; - std::string fmtstring; + const char* fmtstring; fmt::dynamic_format_arg_store store; std::string log_name; char log_tag; diff --git a/lib/include/srslte/srslog/detail/support/memory_buffer.h b/lib/include/srslte/srslog/detail/support/memory_buffer.h index 44f683140..204251736 100644 --- a/lib/include/srslte/srslog/detail/support/memory_buffer.h +++ b/lib/include/srslte/srslog/detail/support/memory_buffer.h @@ -37,18 +37,22 @@ class memory_buffer public: memory_buffer(const char* buffer, size_t length) : - buffer(buffer), - length(length) + buffer(buffer), length(length) {} explicit memory_buffer(const std::string& s) : - buffer(s.data()), - length(s.size()) + buffer(s.data()), length(s.size()) {} /// Returns a pointer to the start of the memory block. const char* data() const { return buffer; } + /// Returns an iterator to the beginning of the buffer. + const char* begin() const { return buffer; } + + /// Returns an iterator to the end of the buffer. + const char* end() const { return buffer + length; } + /// Returns the size of the memory block. size_t size() const { return length; } }; diff --git a/lib/include/srslte/srslog/detail/support/work_queue.h b/lib/include/srslte/srslog/detail/support/work_queue.h index 62fc8a100..2eb3ae4f7 100644 --- a/lib/include/srslte/srslog/detail/support/work_queue.h +++ b/lib/include/srslte/srslog/detail/support/work_queue.h @@ -60,8 +60,8 @@ public: return false; } queue.push(value); - cond_var.signal(); cond_var.unlock(); + cond_var.signal(); return true; } @@ -77,8 +77,8 @@ public: return false; } queue.push(std::move(value)); - cond_var.signal(); cond_var.unlock(); + cond_var.signal(); return true; } diff --git a/lib/include/srslte/srslog/event_trace.h b/lib/include/srslte/srslog/event_trace.h index f91336ae7..e216ad0de 100644 --- a/lib/include/srslte/srslog/event_trace.h +++ b/lib/include/srslte/srslog/event_trace.h @@ -45,6 +45,13 @@ void event_trace_init(); /// all trace events. void event_trace_init(log_channel& c); +/// Initializes the event trace framework. +/// The event trace data will be written into the specified filename after +/// capacity bytes of data have been generated or at program exit. +/// Returns true on success, otherwise false. +bool event_trace_init(const std::string& filename, + std::size_t capacity = 1024 * 1024); + #ifdef ENABLE_SRSLOG_EVENT_TRACE /// Generates the begin phase of a duration event. @@ -54,8 +61,11 @@ void trace_duration_begin(const std::string& category, const std::string& name); void trace_duration_end(const std::string& category, const std::string& name); /// Generates a complete event. +#define SRSLOG_TRACE_COMBINE1(X, Y) X##Y +#define SRSLOG_TRACE_COMBINE(X, Y) SRSLOG_TRACE_COMBINE1(X, Y) #define trace_complete_event(C, N) \ - auto scoped_complete_event_variable = detail::scoped_complete_event(C, N) + auto SRSLOG_TRACE_COMBINE(scoped_complete_event, __LINE__) = \ + srslog::detail::scoped_complete_event(C, N) #else @@ -72,17 +82,15 @@ namespace detail { class scoped_complete_event { public: - scoped_complete_event(std::string cat, std::string n) : - category(std::move(cat)), - name(std::move(n)), - start(std::chrono::steady_clock::now()) + scoped_complete_event(const char* cat, const char* n) : + category(cat), name(n), start(std::chrono::steady_clock::now()) {} ~scoped_complete_event(); private: - const std::string category; - const std::string name; + const char* const category; + const char* const name; std::chrono::time_point start; }; diff --git a/lib/include/srslte/srslog/log_channel.h b/lib/include/srslte/srslog/log_channel.h index 0af220e96..acfb7911b 100644 --- a/lib/include/srslte/srslog/log_channel.h +++ b/lib/include/srslte/srslog/log_channel.h @@ -98,7 +98,7 @@ public: /// Builds the provided log entry and passes it to the backend. When the /// channel is disabled the log entry will be discarded. template - void operator()(const std::string& fmtstr, Args&&... args) + void operator()(const char* fmtstr, Args&&... args) { if (!enabled()) { return; @@ -106,7 +106,8 @@ public: // Populate the store with all incoming arguments. fmt::dynamic_format_arg_store store; - (void)std::initializer_list{(store.push_back(args), 0)...}; + (void)std::initializer_list{ + (store.push_back(std::forward(args)), 0)...}; // Send the log entry to the backend. log_formatter& formatter = log_sink.get_formatter(); @@ -130,7 +131,7 @@ public: template void operator()(const uint8_t* buffer, size_t len, - const std::string& fmtstr, + const char* fmtstr, Args&&... args) { if (!enabled()) { @@ -139,7 +140,8 @@ public: // Populate the store with all incoming arguments. fmt::dynamic_format_arg_store store; - (void)std::initializer_list{(store.push_back(args), 0)...}; + (void)std::initializer_list{ + (store.push_back(std::forward(args)), 0)...}; // Calculate the length to capture in the buffer. if (hex_max_size >= 0) @@ -182,7 +184,7 @@ public: }, {std::chrono::high_resolution_clock::now(), {ctx_value, should_print_context}, - "", + nullptr, {}, log_name, log_tag}}; @@ -192,9 +194,7 @@ public: /// Builds the provided log entry and passes it to the backend. When the /// channel is disabled the log entry will be discarded. template - void operator()(const context& ctx, - const std::string& fmtstr, - Args&&... args) + void operator()(const context& ctx, const char* fmtstr, Args&&... args) { if (!enabled()) { return; @@ -202,7 +202,8 @@ public: // Populate the store with all incoming arguments. fmt::dynamic_format_arg_store store; - (void)std::initializer_list{(store.push_back(args), 0)...}; + (void)std::initializer_list{ + (store.push_back(std::forward(args)), 0)...}; // Send the log entry to the backend. log_formatter& formatter = log_sink.get_formatter(); diff --git a/lib/include/srslte/srslog/logger.h b/lib/include/srslte/srslog/logger.h index 52985eb29..cf24fd5e6 100644 --- a/lib/include/srslte/srslog/logger.h +++ b/lib/include/srslte/srslog/logger.h @@ -37,7 +37,7 @@ class logger_impl : public T { static_assert(std::is_enum::value, "Expected enum type"); - using enum_base_type = typename std::underlying_type::type; + using enum_base_type = typename std::underlying_type::type; static constexpr unsigned size = static_cast(Enum::LAST) - 1; public: @@ -45,9 +45,7 @@ public: explicit logger_impl(std::string id, Args&&... args) : T{std::forward(args)...}, logger_id(std::move(id)), channels{&args...} { - static_assert( - sizeof...(args) == size, - "Number of levels in enum does not match number of log channels"); + static_assert(sizeof...(args) == size, "Number of levels in enum does not match number of log channels"); } logger_impl(const logger_impl& other) = delete; @@ -102,16 +100,16 @@ private: } private: - const std::string logger_id; + const std::string logger_id; const std::array channels; - mutable detail::mutex m; + mutable detail::mutex m; }; /// Type trait to detect if T is a logger. template struct is_logger : std::false_type {}; template -struct is_logger> : std::true_type {}; +struct is_logger > : std::true_type {}; } // namespace detail @@ -182,6 +180,24 @@ inline basic_levels str_to_basic_level(std::string s) return basic_levels::none; } +/// Translates a logger basic level to the corresponding string. +inline const char* basic_level_to_string(basic_levels level) +{ + switch (level) { + case basic_levels::debug: + return "DEBUG"; + case basic_levels::info: + return "INFO"; + case basic_levels::warning: + return "WARNING"; + case basic_levels::error: + return "ERROR"; + default: + break; + } + return "NONE"; +} + } // namespace srslog #endif // SRSLOG_LOGGER_H diff --git a/lib/include/srslte/upper/byte_buffer_queue.h b/lib/include/srslte/upper/byte_buffer_queue.h index d524dc2f7..c60fab47e 100644 --- a/lib/include/srslte/upper/byte_buffer_queue.h +++ b/lib/include/srslte/upper/byte_buffer_queue.h @@ -30,51 +30,43 @@ #ifndef SRSLTE_BYTE_BUFFERQUEUE_H #define SRSLTE_BYTE_BUFFERQUEUE_H +#include "srslte/adt/circular_buffer.h" #include "srslte/common/block_queue.h" #include "srslte/common/common.h" #include namespace srslte { -class byte_buffer_queue : public block_queue::call_mutexed_itf +class byte_buffer_queue { public: - byte_buffer_queue(int capacity = 128) : queue(capacity) { queue.set_mutexed_itf(this); } - // increase/decrease unread_bytes inside push/pop mutexed operations - void pushing(const unique_byte_buffer_t& msg) final { unread_bytes += msg->N_bytes; } - void popping(const unique_byte_buffer_t& msg) final - { - if (unread_bytes > msg->N_bytes) { - unread_bytes -= msg->N_bytes; - } else { - unread_bytes = 0; - } - } - void write(unique_byte_buffer_t msg) { queue.push(std::move(msg)); } + byte_buffer_queue(int capacity = 128) : queue(capacity, push_callback(unread_bytes), pop_callback(unread_bytes)) {} + + void write(unique_byte_buffer_t msg) { queue.push_blocking(std::move(msg)); } srslte::error_type try_write(unique_byte_buffer_t&& msg) { return queue.try_push(std::move(msg)); } - unique_byte_buffer_t read() { return queue.wait_pop(); } + unique_byte_buffer_t read() { return queue.pop_blocking(); } - bool try_read(unique_byte_buffer_t* msg) { return queue.try_pop(msg); } + bool try_read(unique_byte_buffer_t* msg) { return queue.try_pop(*msg); } - void resize(uint32_t capacity) { queue.resize(capacity); } + void resize(uint32_t capacity) { queue.set_size(capacity); } uint32_t size() { return (uint32_t)queue.size(); } uint32_t size_bytes() { return unread_bytes; } uint32_t size_tail_bytes() { - if (!queue.empty()) { - const unique_byte_buffer_t& m = queue.front(); - if (m.get()) { - return m->N_bytes; + uint32_t size_next = 0; + queue.try_call_on_front([&size_next](const unique_byte_buffer_t& front_val) { + if (front_val != nullptr) { + size_next += front_val->N_bytes; } - } - return 0; + }); + return size_next; } // This is a hack to reset N_bytes counter when queue is corrupted (see line 89) @@ -85,8 +77,19 @@ public: bool is_full() { return queue.full(); } private: - block_queue queue; - uint32_t unread_bytes = 0; + struct push_callback { + explicit push_callback(uint32_t& unread_bytes_) : unread_bytes(&unread_bytes_) {} + void operator()(const unique_byte_buffer_t& msg) { *unread_bytes += msg->N_bytes; } + uint32_t* unread_bytes; + }; + struct pop_callback { + explicit pop_callback(uint32_t& unread_bytes_) : unread_bytes(&unread_bytes_) {} + void operator()(const unique_byte_buffer_t& msg) { *unread_bytes -= std::min(msg->N_bytes, *unread_bytes); } + uint32_t* unread_bytes; + }; + + dyn_blocking_queue queue; + uint32_t unread_bytes = 0; }; } // namespace srslte diff --git a/lib/include/srslte/upper/gtpu.h b/lib/include/srslte/upper/gtpu.h index 4ce56703c..d6ab75d55 100644 --- a/lib/include/srslte/upper/gtpu.h +++ b/lib/include/srslte/upper/gtpu.h @@ -22,8 +22,9 @@ #ifndef SRSLTE_GTPU_H #define SRSLTE_GTPU_H +#include "srslte/common/byte_buffer.h" #include "srslte/common/common.h" -#include "srslte/common/logmap.h" +#include "srslte/srslog/srslog.h" #include namespace srslte { @@ -79,9 +80,9 @@ struct gtpu_header_t { std::vector ext_buffer; }; -bool gtpu_read_header(srslte::byte_buffer_t* pdu, gtpu_header_t* header, srslog::basic_logger& logger); -bool gtpu_write_header(gtpu_header_t* header, srslte::byte_buffer_t* pdu, srslog::basic_logger& logger); -std::string gtpu_ntoa(uint32_t addr); +bool gtpu_read_header(srslte::byte_buffer_t* pdu, gtpu_header_t* header, srslog::basic_logger& logger); +bool gtpu_write_header(gtpu_header_t* header, srslte::byte_buffer_t* pdu, srslog::basic_logger& logger); +void gtpu_ntoa(fmt::memory_buffer& buffer, uint32_t addr); inline bool gtpu_supported_flags_check(gtpu_header_t* header, srslog::basic_logger& logger) { diff --git a/lib/include/srslte/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index d59c5e964..b8f669628 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -23,7 +23,6 @@ #define SRSLTE_PDCP_H #include "srslte/common/common.h" -#include "srslte/common/log.h" #include "srslte/common/task_scheduler.h" #include "srslte/interfaces/ue_pdcp_interfaces.h" #include "srslte/upper/pdcp_entity_lte.h" @@ -68,8 +67,8 @@ public: void write_pdu_bcch_bch(unique_byte_buffer_t sdu) override; void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) override; void write_pdu_pcch(unique_byte_buffer_t sdu) override; - void notify_delivery(uint32_t lcid, const std::vector& pdcp_sn) override; - void notify_failure(uint32_t lcid, const std::vector& pdcp_sn) override; + void notify_delivery(uint32_t lcid, const pdcp_sn_vector_t& pdcp_sns) override; + void notify_failure(uint32_t lcid, const pdcp_sn_vector_t& pdcp_sns) override; // eNB-only methods std::map get_buffered_pdus(uint32_t lcid); diff --git a/lib/include/srslte/upper/pdcp_entity_base.h b/lib/include/srslte/upper/pdcp_entity_base.h index b60b01252..df54f0751 100644 --- a/lib/include/srslte/upper/pdcp_entity_base.h +++ b/lib/include/srslte/upper/pdcp_entity_base.h @@ -26,7 +26,6 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" #include "srslte/common/interfaces_common.h" -#include "srslte/common/logmap.h" #include "srslte/common/security.h" #include "srslte/common/task_scheduler.h" #include "srslte/common/threads.h" @@ -121,12 +120,12 @@ public: virtual void write_sdu(unique_byte_buffer_t sdu, int sn = -1) = 0; // RLC interface - virtual void write_pdu(unique_byte_buffer_t pdu) = 0; - virtual void notify_delivery(const std::vector& pdcp_sns) = 0; - virtual void notify_failure(const std::vector& pdcp_sns) = 0; + virtual void write_pdu(unique_byte_buffer_t pdu) = 0; + virtual void notify_delivery(const pdcp_sn_vector_t& pdcp_sns) = 0; + virtual void notify_failure(const pdcp_sn_vector_t& pdcp_sns) = 0; - virtual void get_bearer_state(pdcp_lte_state_t* state) = 0; - virtual void set_bearer_state(const pdcp_lte_state_t& state) = 0; + virtual void get_bearer_state(pdcp_lte_state_t* state) = 0; + virtual void set_bearer_state(const pdcp_lte_state_t& state, bool set_fmc) = 0; virtual std::map get_buffered_pdus() = 0; diff --git a/lib/include/srslte/upper/pdcp_entity_lte.h b/lib/include/srslte/upper/pdcp_entity_lte.h index 96f55dd9e..e22b95f2b 100644 --- a/lib/include/srslte/upper/pdcp_entity_lte.h +++ b/lib/include/srslte/upper/pdcp_entity_lte.h @@ -25,7 +25,6 @@ #include "srslte/adt/circular_array.h" #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/log.h" #include "srslte/common/security.h" #include "srslte/common/threads.h" #include "srslte/interfaces/ue_rrc_interfaces.h" @@ -57,10 +56,10 @@ public: // Getter for the number of discard timers. Used for debugging. size_t nof_discard_timers() const; - bool add_sdu(uint32_t sn, - const srslte::unique_byte_buffer_t& sdu, - uint32_t discard_timeout, - const std::function& callback); + bool add_sdu(uint32_t sn, + const srslte::unique_byte_buffer_t& sdu, + uint32_t discard_timeout, + srslte::move_callback callback); unique_byte_buffer_t& operator[](uint32_t sn) { @@ -129,8 +128,8 @@ public: // RLC interface void write_pdu(unique_byte_buffer_t pdu) override; - void notify_failure(const std::vector& pdcp_sns) override; - void notify_delivery(const std::vector& pdcp_sns) override; + void notify_failure(const pdcp_sn_vector_t& pdcp_sns) override; + void notify_delivery(const pdcp_sn_vector_t& pdcp_sns) override; // Config helpers bool check_valid_config(); @@ -147,7 +146,7 @@ public: // Internal state getters/setters void get_bearer_state(pdcp_lte_state_t* state) override; - void set_bearer_state(const pdcp_lte_state_t& state) override; + void set_bearer_state(const pdcp_lte_state_t& state, bool set_fmc) override; // Metrics helpers pdcp_bearer_metrics_t get_metrics() override; @@ -175,9 +174,31 @@ private: // Discard callback (discardTimer) class discard_callback; - // TX Queue + // Tx info queue uint32_t maximum_allocated_sns_window = 2048; std::unique_ptr undelivered_sdus; + + // Rx info queue + uint32_t fmc = 0; + uint32_t largest_rx_count = 0; + std::vector rx_counts_info; // Keeps the RX_COUNT for generation of the stauts report + void update_rx_counts_queue(uint32_t rx_count); + + /* + * Helper function to see if an SN is larger + */ + bool is_sn_larger(uint32_t sn1, uint32_t sn2) + { + int32_t diff = sn2 - sn1; + uint32_t nof_sns = 1u << cfg.sn_len; + if (diff > (int32_t)(nof_sns / 2)) { + return false; + } + if (diff <= 0 && diff > -((int32_t)(nof_sns / 2))) { + return false; + } + return true; + } }; // Discard callback (discardTimer) diff --git a/lib/include/srslte/upper/pdcp_entity_nr.h b/lib/include/srslte/upper/pdcp_entity_nr.h index d90a218cf..d4432ac84 100644 --- a/lib/include/srslte/upper/pdcp_entity_nr.h +++ b/lib/include/srslte/upper/pdcp_entity_nr.h @@ -26,7 +26,6 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" #include "srslte/common/interfaces_common.h" -#include "srslte/common/log.h" #include "srslte/common/security.h" #include "srslte/common/task_scheduler.h" #include "srslte/common/threads.h" @@ -60,8 +59,8 @@ public: // RLC interface void write_pdu(unique_byte_buffer_t pdu) final; - void notify_delivery(const std::vector& tx_count) final; - void notify_failure(const std::vector& tx_count) final; + void notify_delivery(const pdcp_sn_vector_t& pdcp_sns) final; + void notify_failure(const pdcp_sn_vector_t& pdcp_sns) final; // State variable setters (should be used only for testing) void set_tx_next(uint32_t tx_next_) { tx_next = tx_next_; } @@ -70,7 +69,7 @@ public: void set_rx_reord(uint32_t rx_reord_) { rx_reord = rx_reord_; } void get_bearer_state(pdcp_lte_state_t* state) override; - void set_bearer_state(const pdcp_lte_state_t& state) override; + void set_bearer_state(const pdcp_lte_state_t& state, bool set_fmc) override; void send_status_report() override {} pdcp_bearer_metrics_t get_metrics() override; diff --git a/lib/include/srslte/upper/rlc.h b/lib/include/srslte/upper/rlc.h index ca3ceef73..6f09956ad 100644 --- a/lib/include/srslte/upper/rlc.h +++ b/lib/include/srslte/upper/rlc.h @@ -24,7 +24,6 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/log.h" #include "srslte/common/task_scheduler.h" #include "srslte/interfaces/ue_pdcp_interfaces.h" #include "srslte/interfaces/ue_rlc_interfaces.h" diff --git a/lib/include/srslte/upper/rlc_am_base.h b/lib/include/srslte/upper/rlc_am_base.h index 6106934d2..8ce375b00 100644 --- a/lib/include/srslte/upper/rlc_am_base.h +++ b/lib/include/srslte/upper/rlc_am_base.h @@ -24,7 +24,6 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/log.h" #include "srslte/upper/byte_buffer_queue.h" #include "srslte/upper/rlc_common.h" #include diff --git a/lib/include/srslte/upper/rlc_am_lte.h b/lib/include/srslte/upper/rlc_am_lte.h index c9240aa78..a64b97561 100644 --- a/lib/include/srslte/upper/rlc_am_lte.h +++ b/lib/include/srslte/upper/rlc_am_lte.h @@ -26,9 +26,9 @@ #include "srslte/adt/circular_array.h" #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/log.h" #include "srslte/common/task_scheduler.h" #include "srslte/common/timeout.h" +#include "srslte/interfaces/pdcp_interface_types.h" #include "srslte/upper/byte_buffer_queue.h" #include "srslte/upper/rlc_am_base.h" #include "srslte/upper/rlc_common.h" @@ -51,12 +51,12 @@ struct rlc_amd_rx_pdu_segments_t { }; struct rlc_amd_tx_pdu_t { - rlc_amd_pdu_header_t header; - unique_byte_buffer_t buf; - std::vector pdcp_sns; - uint32_t retx_count; - uint32_t rlc_sn; - bool is_acked; + rlc_amd_pdu_header_t header; + unique_byte_buffer_t buf; + pdcp_sn_vector_t pdcp_sns; + uint32_t retx_count; + uint32_t rlc_sn; + bool is_acked; }; struct rlc_amd_retx_t { @@ -354,11 +354,11 @@ private: // Tx windows rlc_ringbuffer_t tx_window; - pdu_retx_queue retx_queue; - std::vector notify_info_vec; + pdu_retx_queue retx_queue; + pdcp_sn_vector_t notify_info_vec; // Mutexes - pthread_mutex_t mutex; + std::mutex mutex; }; // Receiver sub-class @@ -420,8 +420,8 @@ private: uint32_t vr_ms = 0; // Max status tx state. Highest possible value of SN for ACK_SN in status PDU. uint32_t vr_h = 0; // Highest rx state. SN following PDU with highest SN among rxed PDUs. - // Mutexes - pthread_mutex_t mutex; + // Mutex to protect members + std::mutex mutex; // Rx windows rlc_ringbuffer_t rx_window; @@ -477,8 +477,7 @@ uint32_t rlc_am_packed_length(rlc_amd_retx_t retx); bool rlc_am_is_valid_status_pdu(const rlc_status_pdu_t& status); bool rlc_am_is_pdu_segment(uint8_t* payload); std::string rlc_am_undelivered_sdu_info_to_string(const std::map& info_queue); -std::string rlc_am_status_pdu_to_string(rlc_status_pdu_t* status); -std::string rlc_amd_pdu_header_to_string(const rlc_amd_pdu_header_t& header); +void log_rlc_amd_pdu_header_to_string(srslog::log_channel& log_ch, const rlc_amd_pdu_header_t& header); bool rlc_am_start_aligned(const uint8_t fi); bool rlc_am_end_aligned(const uint8_t fi); bool rlc_am_is_unaligned(const uint8_t fi); diff --git a/lib/include/srslte/upper/rlc_am_nr.h b/lib/include/srslte/upper/rlc_am_nr.h index 91c193172..2f2354b24 100644 --- a/lib/include/srslte/upper/rlc_am_nr.h +++ b/lib/include/srslte/upper/rlc_am_nr.h @@ -24,7 +24,6 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/log.h" #include "srslte/upper/byte_buffer_queue.h" #include "srslte/upper/rlc_am_base.h" #include diff --git a/lib/include/srslte/upper/rlc_common.h b/lib/include/srslte/upper/rlc_common.h index dfe9e03ae..c4e57e9c0 100644 --- a/lib/include/srslte/upper/rlc_common.h +++ b/lib/include/srslte/upper/rlc_common.h @@ -22,8 +22,7 @@ #ifndef SRSLTE_RLC_COMMON_H #define SRSLTE_RLC_COMMON_H -#include "srslte/common/block_queue.h" -#include "srslte/common/logmap.h" +#include "srslte/adt/circular_buffer.h" #include "srslte/interfaces/rlc_interface_types.h" #include "srslte/upper/rlc_metrics.h" #include @@ -37,6 +36,7 @@ namespace srslte { #define RLC_AM_WINDOW_SIZE 512 #define RLC_MAX_SDU_SIZE ((1 << 11) - 1) // Length of LI field is 11bits +#define RLC_AM_MIN_DATA_PDU_SIZE (3) // AMD PDU with 10 bit SN (length of LI field is 11 bits) (No LI) typedef enum { RLC_FI_FIELD_START_AND_END_ALIGNED = 0, @@ -228,13 +228,13 @@ public: } pdu_t p; // Do not block - while (rx_pdu_resume_queue.try_pop(&p)) { + while (rx_pdu_resume_queue.try_pop(p)) { write_pdu(p.payload, p.nof_bytes); free(p.payload); } unique_byte_buffer_t s; - while (tx_sdu_resume_queue.try_pop(&s)) { + while (tx_sdu_resume_queue.try_pop(s)) { write_sdu(std::move(s)); } suspended = false; @@ -312,8 +312,8 @@ private: uint32_t nof_bytes; } pdu_t; - block_queue rx_pdu_resume_queue; - block_queue tx_sdu_resume_queue{256}; + static_blocking_queue rx_pdu_resume_queue; + static_blocking_queue tx_sdu_resume_queue; }; } // namespace srslte diff --git a/lib/include/srslte/upper/rlc_tm.h b/lib/include/srslte/upper/rlc_tm.h index a7b625f47..0a73634f5 100644 --- a/lib/include/srslte/upper/rlc_tm.h +++ b/lib/include/srslte/upper/rlc_tm.h @@ -24,7 +24,6 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/log.h" #include "srslte/upper/byte_buffer_queue.h" #include "srslte/upper/rlc_common.h" diff --git a/lib/include/srslte/upper/rlc_um_base.h b/lib/include/srslte/upper/rlc_um_base.h index aecc64b8b..d6b7c0d04 100644 --- a/lib/include/srslte/upper/rlc_um_base.h +++ b/lib/include/srslte/upper/rlc_um_base.h @@ -25,7 +25,6 @@ #include "srslte/adt/accumulators.h" #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/log.h" #include "srslte/common/task_scheduler.h" #include "srslte/upper/byte_buffer_queue.h" #include "srslte/upper/rlc_common.h" diff --git a/lib/include/srslte/upper/rlc_um_lte.h b/lib/include/srslte/upper/rlc_um_lte.h index 79e98e271..8ea5c4eb3 100644 --- a/lib/include/srslte/upper/rlc_um_lte.h +++ b/lib/include/srslte/upper/rlc_um_lte.h @@ -24,7 +24,6 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/log.h" #include "srslte/upper/byte_buffer_queue.h" #include "srslte/upper/rlc_um_base.h" #include diff --git a/lib/include/srslte/upper/rlc_um_nr.h b/lib/include/srslte/upper/rlc_um_nr.h index 9bf4d806e..a9aa82797 100644 --- a/lib/include/srslte/upper/rlc_um_nr.h +++ b/lib/include/srslte/upper/rlc_um_nr.h @@ -24,7 +24,6 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/log.h" #include "srslte/interfaces/ue_interfaces.h" #include "srslte/upper/byte_buffer_queue.h" #include "srslte/upper/rlc_um_base.h" diff --git a/lib/src/common/CMakeLists.txt b/lib/src/common/CMakeLists.txt index d44e9cb5a..0fdfe177b 100644 --- a/lib/src/common/CMakeLists.txt +++ b/lib/src/common/CMakeLists.txt @@ -28,9 +28,6 @@ set(SOURCES arch_select.cc crash_handler.cc gen_mch_tables.c liblte_security.cc - log_filter.cc - logmap.cc - logger_srslog_wrapper.cc mac_pcap.cc mac_pcap_base.cc nas_pcap.cc diff --git a/lib/src/common/log_filter.cc b/lib/src/common/log_filter.cc deleted file mode 100644 index 5c84c75b2..000000000 --- a/lib/src/common/log_filter.cc +++ /dev/null @@ -1,307 +0,0 @@ -/** - * Copyright 2013-2021 Software Radio Systems Limited - * - * This file is part of srsLTE. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "srslte/common/log_filter.h" -#include "srslte/srslog/srslog.h" - -namespace srslte { - -#define CHARS_FOR_HEX_DUMP(size) \ - (3 * size + size / 16 * 20) // 3 chars per byte, plus 20 per line for position and newline) - -log_filter::log_filter() : log() -{ - do_tti = false; - time_src = NULL; - time_format = TIME; - logger_h = NULL; -} - -/// Creates a log channel that writes to stdout. -static srslog::log_channel* create_or_get_default_logger() -{ - srslog::sink* s = srslog::create_stdout_sink(); - if (!s) { - s = srslog::find_sink("stdout"); - } - srslog::log_channel* log = srslog::create_log_channel("log_filter_default", *s); - if (!log) { - log = srslog::find_log_channel("log_filter_default"); - } - - srslog::init(); - - return log; -} - -log_filter::log_filter(std::string layer) : log() -{ - do_tti = false; - time_src = NULL; - time_format = TIME; - default_logger = std::unique_ptr(new srslog_wrapper(*create_or_get_default_logger())); - init(layer, default_logger.get(), do_tti); -} - -log_filter::log_filter(std::string layer, logger* logger_, bool tti) : log() -{ - do_tti = false; - time_src = NULL; - time_format = TIME; - - if (!logger_) { - default_logger = std::unique_ptr(new srslog_wrapper(*create_or_get_default_logger())); - logger_ = default_logger.get(); - } - - init(std::move(layer), logger_, tti); -} - -void log_filter::init(std::string layer, logger* logger_, bool tti) -{ - // strip trailing white spaces - size_t last_char_pos = layer.find_last_not_of(' '); - if (last_char_pos != layer.size() - 1) { - layer.erase(last_char_pos + 1, layer.size()); - } - service_name = std::move(layer); - logger_h = logger_; - do_tti = tti; -} - -void log_filter::all_log(srslte::LOG_LEVEL_ENUM level, - uint32_t tti, - char* msg, - const uint8_t* hex, - int size, - bool long_msg) -{ - char buffer_tti[16] = {}; - - if (logger_h) { - logger::unique_log_str_t log_str = nullptr; - - if (long_msg || hex) { - // For long messages, dynamically allocate a new log_str with enough size outside the pool. - uint32_t log_str_msg_len = sizeof(buffer_tti) + 20 + strlen(msg) + CHARS_FOR_HEX_DUMP(size); - log_str = logger::unique_log_str_t(new logger::log_str(nullptr, log_str_msg_len), logger::log_str_deleter()); - } else { - log_str = logger_h->allocate_unique_log_str(); - } - - if (log_str) { - if (do_tti) { - get_tti_str(tti, buffer_tti, sizeof(buffer_tti)); - } - - // Trim away a newline character at the end of the message. - if (msg[strlen(msg) - 1] == '\n') { - msg[strlen(msg) - 1] = '\0'; - } - - snprintf(log_str->str(), - log_str->get_buffer_size(), - "[%-4s] %s %s%s%s%s", - get_service_name().c_str(), - log_level_text_short[level], - do_tti ? buffer_tti : "", - add_string_en ? add_string_val.c_str() : "", - msg, - (hex_limit > 0 && hex && size > 0) ? hex_string(hex, size).c_str() : ""); - - logger_h->log(std::move(log_str)); - } else { - logger_h->log_char("Error in Log: Not enough buffers in pool\n"); - } - } -} - -#define all_log_expand(log_level) \ - do { \ - if (level >= log_level) { \ - char args_msg[char_buff_size]; \ - va_list args; \ - va_start(args, message); \ - if (vsnprintf(args_msg, char_buff_size, message, args) > 0) \ - all_log(log_level, tti, args_msg); \ - va_end(args); \ - } \ - } while (0) - -#define all_log_hex_expand(log_level) \ - do { \ - if (level >= log_level) { \ - char args_msg[char_buff_size]; \ - va_list args; \ - va_start(args, message); \ - if (vsnprintf(args_msg, char_buff_size, message, args) > 0) \ - all_log(log_level, tti, args_msg, hex, size); \ - va_end(args); \ - } \ - } while (0) - -void log_filter::error(const char* message, ...) -{ - all_log_expand(LOG_LEVEL_ERROR); -} - -void log_filter::warning(const char* message, ...) -{ - all_log_expand(LOG_LEVEL_WARNING); -} - -void log_filter::info(const char* message, ...) -{ - all_log_expand(LOG_LEVEL_INFO); -} - -void log_filter::info_long(const char* message, ...) -{ - if (level >= LOG_LEVEL_INFO) { - char* args_msg = NULL; - va_list args; - va_start(args, message); - if (vasprintf(&args_msg, message, args) > 0) - all_log(LOG_LEVEL_INFO, tti, args_msg, nullptr, strlen(args_msg), true); - va_end(args); - free(args_msg); - } -} - -void log_filter::debug(const char* message, ...) -{ - all_log_expand(LOG_LEVEL_DEBUG); -} - -void log_filter::debug_long(const char* message, ...) -{ - if (level >= LOG_LEVEL_DEBUG) { - char* args_msg = NULL; - va_list args; - va_start(args, message); - if (vasprintf(&args_msg, message, args) > 0) - all_log(LOG_LEVEL_DEBUG, tti, args_msg, nullptr, strlen(args_msg), true); - va_end(args); - free(args_msg); - } -} - -void log_filter::error_hex(const uint8_t* hex, int size, const char* message, ...) -{ - all_log_hex_expand(LOG_LEVEL_ERROR); -} - -void log_filter::warning_hex(const uint8_t* hex, int size, const char* message, ...) -{ - all_log_hex_expand(LOG_LEVEL_WARNING); -} - -void log_filter::info_hex(const uint8_t* hex, int size, const char* message, ...) -{ - all_log_hex_expand(LOG_LEVEL_INFO); -} - -void log_filter::debug_hex(const uint8_t* hex, int size, const char* message, ...) -{ - all_log_hex_expand(LOG_LEVEL_DEBUG); -} - -void log_filter::set_time_src(time_itf* source, time_format_t format) -{ - this->time_src = source; - this->time_format = format; -} -void log_filter::get_tti_str(const uint32_t tti_, char* buffer, const uint32_t buffer_len) -{ - snprintf(buffer, buffer_len, "[%5d] ", tti_); -} - -void log_filter::now_time(char* buffer, const uint32_t buffer_len) -{ - timeval rawtime = {}; - tm timeinfo = {}; - char us[16]; - - srslte_timestamp_t now; - uint64_t usec_epoch; - - if (buffer_len < 16) { - fprintf(stderr, "Error buffer provided for time too small\n"); - return; - } - - if (!time_src) { - gettimeofday(&rawtime, nullptr); - gmtime_r(&rawtime.tv_sec, &timeinfo); - - if (time_format == TIME) { - strftime(buffer, buffer_len, "%H:%M:%S.", &timeinfo); - snprintf(us, 16, "%06ld", rawtime.tv_usec); - uint32_t dest_len = (uint32_t)strlen(buffer); - strncat(buffer, us, buffer_len - dest_len - 1); - } else { - usec_epoch = rawtime.tv_sec * 1000000UL + rawtime.tv_usec; - snprintf(buffer, buffer_len, "%" PRIu64, usec_epoch); - } - } else { - now = time_src->get_time(); - - if (time_format == TIME) { - snprintf(buffer, buffer_len, "%ld:%06u", now.full_secs, (uint32_t)(now.frac_secs * 1e6)); - } else { - usec_epoch = now.full_secs * 1000000UL + (uint64_t)(now.frac_secs * 1e6); - snprintf(buffer, buffer_len, "%" PRIu64, usec_epoch); - } - } -} - -std::string log_filter::hex_string(const uint8_t* hex, int size) -{ - std::stringstream ss; - int c = 0; - - ss << '\n' << std::hex << std::setfill('0'); - if (hex_limit >= 0) { - size = (size > hex_limit) ? hex_limit : size; - } - while (c < size) { - ss << " " << std::setw(4) << static_cast(c) << ": "; - int tmp = (size - c < 16) ? size - c : 16; - for (int i = 0; i < tmp; i++) { - ss << std::setw(2) << static_cast(hex[c++]) << " "; - } - if (c != size) { - ss << "\n"; - } - } - - return ss.str(); -} - -} // namespace srslte diff --git a/lib/src/common/logger_srslog_wrapper.cc b/lib/src/common/logger_srslog_wrapper.cc deleted file mode 100644 index 338df2900..000000000 --- a/lib/src/common/logger_srslog_wrapper.cc +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright 2013-2021 Software Radio Systems Limited - * - * This file is part of srsLTE. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include "srslte/common/logger_srslog_wrapper.h" -#include "srslte/srslog/log_channel.h" - -using namespace srslte; - -void srslog_wrapper::log(unique_log_str_t msg) -{ - chan("%s", msg->str()); -} diff --git a/lib/src/common/logmap.cc b/lib/src/common/logmap.cc deleted file mode 100644 index 3ddd09d87..000000000 --- a/lib/src/common/logmap.cc +++ /dev/null @@ -1,129 +0,0 @@ -/** - * Copyright 2013-2021 Software Radio Systems Limited - * - * This file is part of srsLTE. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include "srslte/common/logmap.h" -#include "srslte/common/log_filter.h" -#include "srslte/srslog/srslog.h" - -using namespace srslte; - -log_ref::log_ref(const char* name) -{ - ptr_ = srslte::logmap::get(name).ptr_; -} - -/// Creates a log channel that writes to stdout. -static srslog::log_channel* create_or_get_default_logger() -{ - srslog::sink* s = srslog::create_stdout_sink(); - if (!s) { - s = srslog::find_sink("stdout"); - } - srslog::log_channel* log = srslog::create_log_channel("logmap_default", *s); - if (!log) { - log = srslog::find_log_channel("logmap_default"); - } - - srslog::init(); - - return log; -} - -logmap::logmap() -{ - stdout_channel = std::unique_ptr(new srslog_wrapper(*create_or_get_default_logger())); - default_logger = stdout_channel.get(); -} - -// Access to log map by servicename. If servicename does not exist, create a new log_filter with default cfg -// Access to the map is protected by a mutex -log_ref SRSLTE_EXPORT logmap::get(std::string servicename) -{ - logmap* pool = get_instance(); - // strip trailing white spaces - size_t last_char_pos = servicename.find_last_not_of(' '); - if (last_char_pos != servicename.size() - 1) { - servicename.erase(last_char_pos + 1, servicename.size()); - } - return pool->get_impl(std::move(servicename)); -} - -// register manually created log -void SRSLTE_EXPORT logmap::register_log(std::unique_ptr log_ptr) -{ - logmap* pool = get_instance(); - std::lock_guard lock(pool->mutex); - if (log_ptr != nullptr) { - pool->log_map[log_ptr->get_service_name()] = std::move(log_ptr); - } -} - -std::unique_ptr SRSLTE_EXPORT logmap::deregister_log(const std::string& servicename) -{ - logmap* pool = get_instance(); - std::unique_ptr ret; - std::lock_guard lock(pool->mutex); - auto it = pool->log_map.find(servicename); - if (it != pool->log_map.end()) { - ret = std::move(it->second); - pool->log_map.erase(it); - } - return ret; -} - -// set default logger -void SRSLTE_EXPORT logmap::set_default_logger(logger* logger_) -{ - logmap* pool = get_instance(); - std::lock_guard lock(pool->mutex); - pool->default_logger = logger_; -} - -// set default log level -void SRSLTE_EXPORT logmap::set_default_log_level(LOG_LEVEL_ENUM l) -{ - logmap* pool = get_instance(); - std::lock_guard lock(pool->mutex); - pool->default_log_level = l; -} - -// set default hex limit -void SRSLTE_EXPORT logmap::set_default_hex_limit(int hex_limit) -{ - logmap* pool = get_instance(); - std::lock_guard lock(pool->mutex); - pool->default_hex_limit = hex_limit; -} - -log_ref logmap::get_impl(std::string servicename) -{ - std::lock_guard lock(mutex); - auto it = log_map.find(servicename); - if (it == log_map.end()) { - // create a new logger with default cfg - std::unique_ptr filter(new log_filter{std::move(servicename), default_logger}); - filter->set_level(default_log_level); - filter->set_hex_limit(default_hex_limit); - auto ret = log_map.insert(std::make_pair(filter->get_service_name(), std::move(filter))); - return log_ref{&ret.first->second}; - } - return log_ref{&it->second}; -} diff --git a/lib/src/common/mac_pcap.cc b/lib/src/common/mac_pcap.cc index 29dc541f7..8858d153e 100644 --- a/lib/src/common/mac_pcap.cc +++ b/lib/src/common/mac_pcap.cc @@ -20,6 +20,7 @@ */ #include "srslte/common/mac_pcap.h" +#include "srslte/common/standard_streams.h" #include "srslte/common/threads.h" namespace srslte { @@ -67,7 +68,7 @@ uint32_t mac_pcap::close() // tell writer thread to stop running = false; pcap_pdu_t pdu = {}; - queue.push(std::move(pdu)); + queue.push_blocking(std::move(pdu)); } wait_thread_finish(); diff --git a/lib/src/common/mac_pcap_base.cc b/lib/src/common/mac_pcap_base.cc index 185b619b3..838f9749e 100644 --- a/lib/src/common/mac_pcap_base.cc +++ b/lib/src/common/mac_pcap_base.cc @@ -46,7 +46,7 @@ void mac_pcap_base::run_thread() { // blocking write until stopped while (running) { - pcap_pdu_t pdu = queue.wait_pop(); + pcap_pdu_t pdu = queue.pop_blocking(); { std::lock_guard lock(mutex); write_pdu(pdu); @@ -56,7 +56,7 @@ void mac_pcap_base::run_thread() // write remainder of queue std::lock_guard lock(mutex); pcap_pdu_t pdu = {}; - while (queue.try_pop(&pdu)) { + while (queue.try_pop(pdu)) { write_pdu(pdu); } } @@ -93,7 +93,9 @@ void mac_pcap_base::pack_and_queue(uint8_t* payload, // copy payload into PDU buffer memcpy(pdu.pdu->msg, payload, payload_len); pdu.pdu->N_bytes = payload_len; - queue.push(std::move(pdu)); + if (not queue.try_push(std::move(pdu))) { + logger.error("Failed to push message to pcap writer queue"); + } } else { logger.info("Dropping PDU in PCAP. No buffer available or not enough space (pdu_len=%d).", payload_len); } @@ -128,7 +130,9 @@ void mac_pcap_base::pack_and_queue_nr(uint8_t* payload, // copy payload into PDU buffer memcpy(pdu.pdu->msg, payload, payload_len); pdu.pdu->N_bytes = payload_len; - queue.push(std::move(pdu)); + if (not queue.try_push(std::move(pdu))) { + logger.error("Failed to push message to pcap writer queue"); + } } else { logger.info("Dropping PDU in NR PCAP. No buffer available or not enough space (pdu_len=%d).", payload_len); } diff --git a/lib/src/common/mac_pcap_net.cc b/lib/src/common/mac_pcap_net.cc index 2d91c0754..2f7aaf8b6 100644 --- a/lib/src/common/mac_pcap_net.cc +++ b/lib/src/common/mac_pcap_net.cc @@ -80,7 +80,7 @@ uint32_t mac_pcap_net::close() // tell writer thread to stop running = false; pcap_pdu_t pdu = {}; - queue.push(std::move(pdu)); + queue.push_blocking(std::move(pdu)); } wait_thread_finish(); diff --git a/lib/src/common/test/thread_pool_test.cc b/lib/src/common/test/thread_pool_test.cc index 56eaaef8f..a4c301bd1 100644 --- a/lib/src/common/test/thread_pool_test.cc +++ b/lib/src/common/test/thread_pool_test.cc @@ -18,12 +18,11 @@ * and at http://www.gnu.org/licenses/. * */ -#include -#include -#include -#include -#include -#include +#include "srslte/common/common.h" +#include "srslte/common/thread_pool.h" +#include "srslte/common/tti_sempahore.h" +#include "srslte/phy/utils/random.h" +#include "srslte/srslog/srslog.h" class dummy_radio { diff --git a/lib/src/mac/pdu.cc b/lib/src/mac/pdu.cc index ad3262a74..a3a7a48ca 100644 --- a/lib/src/mac/pdu.cc +++ b/lib/src/mac/pdu.cc @@ -24,6 +24,7 @@ #include #include +#include "srslte/common/standard_streams.h" #include "srslte/mac/pdu.h" extern "C" { @@ -208,11 +209,10 @@ bool lcid_t::is_sdu() const * SCH PDU *************************/ -std::string sch_pdu::to_string() +void sch_pdu::to_string(fmt::memory_buffer& buffer) { - std::stringstream ss; - ss << (is_ul() ? "UL " : "DL ") << pdu::to_string(); - return ss.str(); + fmt::format_to(buffer, "{}", is_ul() ? "UL" : "DL"); + pdu::to_string(buffer); } void sch_pdu::parse_packet(uint8_t* ptr) @@ -906,19 +906,18 @@ void sch_subh::read_payload(uint8_t** ptr) *ptr += nof_bytes; } -std::string sch_subh::to_string() +void sch_subh::to_string(fmt::memory_buffer& buffer) { - std::stringstream ss; if (is_sdu()) { - ss << "LCID=" << lcid << " len=" << nof_bytes; + fmt::format_to(buffer, "LCID={} len={}", lcid, nof_bytes); } else if (type == SCH_SUBH_TYPE) { if (parent->is_ul()) { switch ((ul_sch_lcid)lcid) { case ul_sch_lcid::CRNTI: - ss << "CRNTI: rnti=0x" << std::hex << get_c_rnti() << std::dec; + fmt::format_to(buffer, "CRNTI: rnti=0x{:x}", get_c_rnti()); break; case ul_sch_lcid::PHR_REPORT: - ss << "PHR: ph=" << get_phr(); + fmt::format_to(buffer, "PHR: ph={}", get_phr()); break; case ul_sch_lcid::TRUNC_BSR: case ul_sch_lcid::SHORT_BSR: @@ -927,18 +926,18 @@ std::string sch_subh::to_string() uint32_t buff_size_bytes[4] = {}; uint32_t lcg = get_bsr(buff_size_idx, buff_size_bytes); if (ul_sch_ce_type() == ul_sch_lcid::LONG_BSR) { - ss << "LBSR: b="; + fmt::format_to(buffer, "LBSR: b="); for (uint32_t i = 0; i < 4; i++) { - ss << buff_size_idx[i] << " "; + fmt::format_to(buffer, "{} ", buff_size_idx[i]); } } else if (ul_sch_ce_type() == ul_sch_lcid::SHORT_BSR) { - ss << "SBSR: lcg=" << lcg << " b=" << buff_size_idx[lcg]; + fmt::format_to(buffer, "SBSR: lcg={} b={}", lcg, buff_size_idx[lcg]); } else { - ss << "TBSR: lcg=" << lcg << " b=" << buff_size_idx[lcg]; + fmt::format_to(buffer, "TBSR: lcg={} b={}", lcg, buff_size_idx[lcg]); } } break; case ul_sch_lcid::PADDING: - ss << "PAD: len=" << get_payload_size(); + fmt::format_to(buffer, "PAD: len={}", get_payload_size()); break; default: // do nothing @@ -947,20 +946,20 @@ std::string sch_subh::to_string() } else { switch ((dl_sch_lcid)lcid) { case dl_sch_lcid::CON_RES_ID: - ss << "CON_RES: id=0x" << std::hex << get_con_res_id() << std::dec; + fmt::format_to(buffer, "CON_RES: id=0x{:x}", get_con_res_id()); break; case dl_sch_lcid::TA_CMD: - ss << "TA: ta=" << std::to_string(get_ta_cmd()); + fmt::format_to(buffer, "TA: ta={}", get_ta_cmd()); break; case dl_sch_lcid::SCELL_ACTIVATION_4_OCTET: case dl_sch_lcid::SCELL_ACTIVATION: - ss << "SCELL_ACT"; + fmt::format_to(buffer, "SCELL_ACT"); break; case dl_sch_lcid::DRX_CMD: - ss << "DRX"; + fmt::format_to(buffer, "DRX"); break; case dl_sch_lcid::PADDING: - ss << "PAD: len=" << get_payload_size(); + fmt::format_to(buffer, "PAD: len={}", get_payload_size()); break; default: break; @@ -969,16 +968,15 @@ std::string sch_subh::to_string() } else if (type == MCH_SUBH_TYPE) { switch ((mch_lcid)lcid) { case mch_lcid::MCH_SCHED_INFO: - ss << "MCH_SCHED_INFO"; + fmt::format_to(buffer, "MCH_SCHED_INFO"); break; case mch_lcid::PADDING: - ss << "PAD: len=" << get_payload_size(); + fmt::format_to(buffer, "PAD: len={}", get_payload_size()); break; default: break; } } - return ss.str(); } uint8_t sch_subh::buff_size_table(uint32_t buffer_size) @@ -1009,11 +1007,11 @@ uint8_t sch_subh::phr_report_table(float phr_value) return (uint8_t)floor(phr_value + 23); } -std::string rar_pdu::to_string() +void rar_pdu::to_string(fmt::memory_buffer& buffer) { std::string msg("MAC PDU for RAR: "); - msg += pdu::to_string(); - return msg; + fmt::format_to(buffer, "MAC PDU for RAR: "); + pdu::to_string(buffer); } rar_pdu::rar_pdu(uint32_t max_rars_, srslog::basic_logger& logger) : pdu(max_rars_, logger) @@ -1074,20 +1072,17 @@ bool rar_pdu::write_packet(uint8_t* ptr) return true; } -std::string rar_subh::to_string() +void rar_subh::to_string(fmt::memory_buffer& buffer) { - std::stringstream ss; if (type == RAPID) { - ss << "RAPID: " << preamble << ", Temp C-RNTI: " << temp_rnti << ", TA: " << ta << ", UL Grant: "; + fmt::format_to(buffer, "RAPID: {}, Temp C-RNTI: {}, TA: {}, UL Grant: ", preamble, temp_rnti, ta); } else { - ss << "Backoff Indicator: " << int32_t(((rar_pdu*)parent)->get_backoff()) << " "; + fmt::format_to(buffer, "Backoff Indicator: {} ", int32_t(((rar_pdu*)parent)->get_backoff())); } char tmp[16]; srslte_vec_sprint_hex(tmp, sizeof(tmp), grant, RAR_GRANT_LEN); - ss << tmp; - - return ss.str(); + fmt::format_to(buffer, "{}", tmp); } void rar_subh::init() diff --git a/lib/src/mac/pdu_queue.cc b/lib/src/mac/pdu_queue.cc index 63d0dbcd7..417389616 100644 --- a/lib/src/mac/pdu_queue.cc +++ b/lib/src/mac/pdu_queue.cc @@ -67,7 +67,9 @@ void pdu_queue::push(const uint8_t* ptr, uint32_t len, channel_t channel) pdu_t* pdu = (pdu_t*)ptr; pdu->len = len; pdu->channel = channel; - pdu_q.push(pdu); + if (!pdu_q.try_push(pdu)) { + logger.warning("Error pushing pdu: queue is full"); + } } else { logger.warning("Error pushing pdu: ptr is empty"); } @@ -78,7 +80,7 @@ bool pdu_queue::process_pdus() bool have_data = false; uint32_t cnt = 0; pdu_t* pdu; - while (pdu_q.try_pop(&pdu)) { + while (pdu_q.try_pop(pdu)) { if (callback) { callback->process_pdu(pdu->ptr, pdu->len, pdu->channel); } @@ -95,7 +97,7 @@ bool pdu_queue::process_pdus() void pdu_queue::reset() { pdu_t* pdu; - while (pdu_q.try_pop(&pdu)) { + while (pdu_q.try_pop(pdu)) { // nop } } diff --git a/lib/src/phy/ch_estimation/dmrs_sch.c b/lib/src/phy/ch_estimation/dmrs_sch.c index d6aafd738..b3df3b020 100644 --- a/lib/src/phy/ch_estimation/dmrs_sch.c +++ b/lib/src/phy/ch_estimation/dmrs_sch.c @@ -439,8 +439,7 @@ int srslte_dmrs_sch_get_N_prb(const srslte_dmrs_sch_cfg_t* dmrs_cfg, const srslt } // Get number of frequency domain resource elements used for DMRS - int nof_sc = SRSLTE_MIN(SRSLTE_NRE, - grant->nof_dmrs_cdm_groups_without_data * (dmrs_cfg->type == srslte_dmrs_sch_type_1 ? 6 : 4)); + int nof_sc = SRSLTE_DMRS_SCH_SC(grant->nof_dmrs_cdm_groups_without_data, dmrs_cfg->type); // Get number of symbols used for DMRS uint32_t symbols[SRSLTE_DMRS_SCH_MAX_SYMBOLS] = {}; diff --git a/lib/src/phy/fec/cbsegm.c b/lib/src/phy/fec/cbsegm.c index 792d7fd99..99240315a 100644 --- a/lib/src/phy/fec/cbsegm.c +++ b/lib/src/phy/fec/cbsegm.c @@ -23,6 +23,7 @@ #include "srslte/phy/fec/ldpc/base_graph.h" #include "srslte/phy/fec/turbo/turbodecoder_gen.h" #include "srslte/phy/utils/debug.h" +#include "srslte/phy/utils/vector.h" #include /** @@ -40,8 +41,6 @@ const uint32_t tc_cb_sizes[SRSLTE_NOF_TC_CB_SIZES] = { 3904, 3968, 4032, 4096, 4160, 4224, 4288, 4352, 4416, 4480, 4544, 4608, 4672, 4736, 4800, 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, 5504, 5568, 5632, 5696, 5760, 5824, 5888, 5952, 6016, 6080, 6144}; -#define CEIL(NUM, DEN) (((NUM) + ((DEN)-1)) / (DEN)) - /** * @brief Calculates the number of code blocks and the total size * @param[in] B Transport block size including TB CRC @@ -55,7 +54,7 @@ static void cbsegm_cb_size(uint32_t B, uint32_t Z, uint32_t* C, uint32_t* B_prim *C = 1; *B_prime = B; } else { - *C = CEIL(B, (Z - 24U)); + *C = SRSLTE_CEIL(B, (Z - 24U)); *B_prime = B + 24U * (*C); } } @@ -160,12 +159,12 @@ bool srslte_cbsegm_cbsize_isvalid(uint32_t size) static int cbsegm_ldpc_select_ls(uint32_t Kp, uint32_t K_b, uint32_t* Z_c, uint8_t* i_ls) { // Early return if the minimum required lift size is too high - if (CEIL(Kp, K_b) > MAX_LIFTSIZE) { + if (SRSLTE_CEIL(Kp, K_b) > MAX_LIFTSIZE) { return SRSLTE_ERROR; } // Iterate from the minimum required lift size to the maximum value - for (uint16_t Z = CEIL(Kp, K_b); Z <= MAX_LIFTSIZE; Z++) { + for (uint16_t Z = SRSLTE_CEIL(Kp, K_b); Z <= MAX_LIFTSIZE; Z++) { // Get index for a selected lifting size uint8_t i = get_ls_index(Z); diff --git a/lib/src/phy/fec/polar/polar_code.c b/lib/src/phy/fec/polar/polar_code.c index 274f3ce97..8b8017f0b 100644 --- a/lib/src/phy/fec/polar/polar_code.c +++ b/lib/src/phy/fec/polar/polar_code.c @@ -132,7 +132,7 @@ int get_code_params(srslte_polar_code_t* c, const uint16_t K, const uint16_t E, } if (K + nPC >= E) { - ERROR(" Rate-matched codeword length (E) not supported, choose E > %d", K + nPC); + ERROR(" Rate-matched codeword length (E=%d) not supported, choose E > %d", E, K + nPC); return -1; } diff --git a/lib/src/phy/phch/csi.c b/lib/src/phy/phch/csi.c index 7673617d9..09f7c9aea 100644 --- a/lib/src/phy/phch/csi.c +++ b/lib/src/phy/phch/csi.c @@ -21,6 +21,7 @@ #include "srslte/phy/phch/csi.h" #include "srslte/phy/utils/bit.h" #include "srslte/phy/utils/debug.h" +#include "srslte/phy/utils/vector.h" #include #define CSI_WIDEBAND_CSI_NOF_BITS 4 @@ -91,9 +92,9 @@ static uint32_t csi_wideband_cri_ri_pmi_cqi_nof_bits(const srslte_csi_report_cfg return 0; } -static int csi_wideband_cri_ri_pmi_cqi_pack(const srslte_csi_report_cfg_t* cfg, - const srslte_csi_report_value_t* value, - uint8_t* o_csi1) +static uint32_t csi_wideband_cri_ri_pmi_cqi_pack(const srslte_csi_report_cfg_t* cfg, + const srslte_csi_report_value_t* value, + uint8_t* o_csi1) { // Compute number of bits for CRI uint32_t nof_bits_cri = 0; @@ -110,6 +111,46 @@ static int csi_wideband_cri_ri_pmi_cqi_pack(const srslte_csi_report_cfg_t* cfg return nof_bits_cri + CSI_WIDEBAND_CSI_NOF_BITS; } +static uint32_t csi_wideband_cri_ri_pmi_cqi_unpack(const srslte_csi_report_cfg_t* cfg, + uint8_t* o_csi1, + srslte_csi_report_value_t* value) +{ + // Compute number of bits for CRI + uint32_t nof_bits_cri = 0; + if (cfg->K_csi_rs > 0) { + nof_bits_cri = (uint32_t)ceilf(log2f((float)cfg->K_csi_rs)); + } + + // Write wideband CQI + value->wideband_cri_ri_pmi_cqi.cqi = srslte_bit_pack(&o_csi1, CSI_WIDEBAND_CSI_NOF_BITS); + + // Compute number of bits for CRI and write + value->cri = srslte_bit_pack(&o_csi1, nof_bits_cri); + + return nof_bits_cri + CSI_WIDEBAND_CSI_NOF_BITS; +} + +static uint32_t csi_none_nof_bits(const srslte_csi_report_cfg_t* cfg) +{ + return cfg->K_csi_rs; +} + +static uint32_t +csi_none_pack(const srslte_csi_report_cfg_t* cfg, const srslte_csi_report_value_t* value, uint8_t* o_csi1) +{ + srslte_vec_u8_copy(o_csi1, (uint8_t*)value->none, cfg->K_csi_rs); + + return cfg->K_csi_rs; +} + +static uint32_t +csi_none_unpack(const srslte_csi_report_cfg_t* cfg, const uint8_t* o_csi1, srslte_csi_report_value_t* value) +{ + srslte_vec_u8_copy((uint8_t*)value->none, o_csi1, cfg->K_csi_rs); + + return cfg->K_csi_rs; +} + int srslte_csi_generate_reports(const srslte_csi_hl_cfg_t* cfg, uint32_t slot_idx, const srslte_csi_measurements_t measurements[SRSLTE_CSI_MAX_NOF_RESOURCES], @@ -161,7 +202,7 @@ int srslte_csi_generate_reports(const srslte_csi_hl_cfg_t* cfg, return (int)count; } -int srslte_csi_nof_bits(const srslte_csi_report_cfg_t* report_list, uint32_t nof_reports) +int srslte_csi_part1_nof_bits(const srslte_csi_report_cfg_t* report_list, uint32_t nof_reports) { uint32_t count = 0; @@ -175,12 +216,28 @@ int srslte_csi_nof_bits(const srslte_csi_report_cfg_t* report_list, uint32_t nof const srslte_csi_report_cfg_t* report = &report_list[i]; if (report->quantity && report->quantity == SRSLTE_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) { count += csi_wideband_cri_ri_pmi_cqi_nof_bits(report); + } else if (report->quantity == SRSLTE_CSI_REPORT_QUANTITY_NONE) { + count += csi_none_nof_bits(report); } } return (int)count; } +bool srslte_csi_has_part2(const srslte_csi_report_cfg_t* report_list, uint32_t nof_reports) +{ + if (report_list == NULL || nof_reports == 0) { + return false; + } + + for (uint32_t i = 0; i < nof_reports; i++) { + if (report_list[i].has_part2) { + return true; + } + } + return false; +} + int srslte_csi_part1_pack(const srslte_csi_report_cfg_t* report_cfg, const srslte_csi_report_value_t* report_value, uint32_t nof_reports, @@ -193,7 +250,7 @@ int srslte_csi_part1_pack(const srslte_csi_report_cfg_t* report_cfg, return SRSLTE_ERROR_INVALID_INPUTS; } - int n = srslte_csi_nof_bits(report_cfg, nof_reports); + int n = srslte_csi_part1_nof_bits(report_cfg, nof_reports); if (n > (int)max_o_csi1) { ERROR("The maximum number of CSI bits (%d) is not enough to accommodate %d bits", max_o_csi1, n); return SRSLTE_ERROR; @@ -203,6 +260,42 @@ int srslte_csi_part1_pack(const srslte_csi_report_cfg_t* report_cfg, if (report_cfg[i].freq_cfg == SRSLTE_CSI_REPORT_FREQ_WIDEBAND && report_cfg[i].quantity == SRSLTE_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) { count += csi_wideband_cri_ri_pmi_cqi_pack(&report_cfg[i], &report_value[i], &o_csi1[count]); + } else if (report_cfg[i].quantity == SRSLTE_CSI_REPORT_QUANTITY_NONE) { + count += csi_none_pack(&report_cfg[i], &report_value[i], &o_csi1[count]); + } else { + ERROR("CSI frequency (%d) and quantity (%d) combination is not implemented", + report_cfg[i].freq_cfg, + report_cfg[i].quantity); + } + } + + return (int)count; +} + +int srslte_csi_part1_unpack(const srslte_csi_report_cfg_t* report_cfg, + uint32_t nof_reports, + uint8_t* o_csi1, + uint32_t max_o_csi1, + srslte_csi_report_value_t* report_value) +{ + uint32_t count = 0; + + if (report_cfg == NULL || report_value == NULL || o_csi1 == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + int n = srslte_csi_part1_nof_bits(report_cfg, nof_reports); + if (n > (int)max_o_csi1) { + ERROR("The maximum number of CSI bits (%d) is not enough to accommodate %d bits", max_o_csi1, n); + return SRSLTE_ERROR; + } + + for (uint32_t i = 0; i < nof_reports && count < max_o_csi1; i++) { + if (report_cfg[i].freq_cfg == SRSLTE_CSI_REPORT_FREQ_WIDEBAND && + report_cfg[i].quantity == SRSLTE_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) { + count += csi_wideband_cri_ri_pmi_cqi_unpack(&report_cfg[i], &o_csi1[count], &report_value[i]); + } else if (report_cfg[i].quantity == SRSLTE_CSI_REPORT_QUANTITY_NONE) { + count += csi_none_unpack(&report_cfg[i], &o_csi1[count], &report_value[i]); } else { ERROR("CSI frequency (%d) and quantity (%d) combination is not implemented", report_cfg[i].freq_cfg, @@ -224,6 +317,10 @@ uint32_t srslte_csi_str(const srslte_csi_report_cfg_t* report_cfg, if (report_cfg[i].freq_cfg == SRSLTE_CSI_REPORT_FREQ_WIDEBAND && report_cfg[i].quantity == SRSLTE_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) { len = srslte_print_check(str, str_len, len, ", cqi=%d", report_value[i].wideband_cri_ri_pmi_cqi.cqi); + } else if (report_cfg[i].quantity == SRSLTE_CSI_REPORT_QUANTITY_NONE) { + char tmp[20] = {}; + srslte_vec_sprint_bin(tmp, sizeof(tmp), report_value[i].none, report_cfg->K_csi_rs); + len = srslte_print_check(str, str_len, len, ", csi=%s", tmp); } } return len; diff --git a/lib/src/phy/phch/pdsch_nr.c b/lib/src/phy/phch/pdsch_nr.c index 07f64ef6d..24c353c92 100644 --- a/lib/src/phy/phch/pdsch_nr.c +++ b/lib/src/phy/phch/pdsch_nr.c @@ -203,7 +203,7 @@ static void srslte_pdsch_re_cp(cf_t* sf_symbols, cf_t* symbols, uint32_t count, * As a RB is 12 RE wide, positions marked as 1 will be used for the 1st CDM group, and the same with group 2: * * +---+---+---+---+---+---+---+---+---+---+---+---+ - * | 1 | 1 | 2 | 2 | 1 | 1 | 2 | 2 | 1 | 1 | 2 | 2 | + * | 1 | 2 | 1 | 2 | 1 | 2 | 1 | 2 | 1 | 2 | 1 | 2 | * +---+---+---+---+---+---+---+---+---+---+---+---+ * -- k --> * diff --git a/lib/src/phy/phch/pucch_nr.c b/lib/src/phy/phch/pucch_nr.c index ac50df13f..72cc40859 100644 --- a/lib/src/phy/phch/pucch_nr.c +++ b/lib/src/phy/phch/pucch_nr.c @@ -183,6 +183,17 @@ int srslte_pucch_nr_init(srslte_pucch_nr_t* q, const srslte_pucch_nr_args_t* arg return SRSLTE_SUCCESS; } +int srslte_pucch_nr_set_carrier(srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier) +{ + if (q == NULL || carrier == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + q->carrier = *carrier; + + return SRSLTE_SUCCESS; +} + void srslte_pucch_nr_free(srslte_pucch_nr_t* q) { if (q == NULL) { @@ -210,14 +221,13 @@ void srslte_pucch_nr_free(srslte_pucch_nr_t* q) } int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q, - const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, const srslte_slot_cfg_t* slot, srslte_pucch_nr_resource_t* resource, uint32_t m_cs, cf_t* slot_symbols) { - if (carrier == NULL || cfg == NULL || slot == NULL || resource == NULL || slot_symbols == NULL) { + if (cfg == NULL || slot == NULL || resource == NULL || slot_symbols == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } @@ -228,7 +238,7 @@ int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q, uint32_t u = 0; uint32_t v = 0; - if (srslte_pucch_nr_group_sequence(carrier, cfg, &u, &v) < SRSLTE_SUCCESS) { + if (srslte_pucch_nr_group_sequence(&q->carrier, cfg, &u, &v) < SRSLTE_SUCCESS) { ERROR("Error getting group sequence"); return SRSLTE_ERROR; } @@ -237,8 +247,8 @@ int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q, for (uint32_t l = 0; l < resource->nof_symbols; l++) { // Get Alpha index uint32_t alpha_idx = 0; - if (srslte_pucch_nr_alpha_idx(carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, m_cs, &alpha_idx) < - SRSLTE_SUCCESS) { + if (srslte_pucch_nr_alpha_idx( + &q->carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, m_cs, &alpha_idx) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } @@ -250,7 +260,7 @@ int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q, } // Get start of the sequence in resource grid - cf_t* slot_symbols_ptr = &slot_symbols[(carrier->nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE]; + cf_t* slot_symbols_ptr = &slot_symbols[(q->carrier.nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE]; // Copy sequence in grid srslte_vec_cf_copy(slot_symbols_ptr, r_uv, SRSLTE_NRE); @@ -260,7 +270,6 @@ int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q, } int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q, - const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, const srslte_slot_cfg_t* slot, srslte_pucch_nr_resource_t* resource, @@ -268,7 +277,7 @@ int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q, const cf_t* slot_symbols, srslte_pucch_nr_measure_t* measure) { - if (carrier == NULL || cfg == NULL || slot == NULL || resource == NULL || slot_symbols == NULL || measure == NULL) { + if (cfg == NULL || slot == NULL || resource == NULL || slot_symbols == NULL || measure == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } @@ -279,7 +288,7 @@ int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q, uint32_t u = 0; uint32_t v = 0; - if (srslte_pucch_nr_group_sequence(carrier, cfg, &u, &v) < SRSLTE_SUCCESS) { + if (srslte_pucch_nr_group_sequence(&q->carrier, cfg, &u, &v) < SRSLTE_SUCCESS) { ERROR("Error getting group sequence"); return SRSLTE_ERROR; } @@ -290,8 +299,8 @@ int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q, for (uint32_t l = 0; l < resource->nof_symbols; l++) { // Get Alpha index uint32_t alpha_idx = 0; - if (srslte_pucch_nr_alpha_idx(carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, m_cs, &alpha_idx) < - SRSLTE_SUCCESS) { + if (srslte_pucch_nr_alpha_idx( + &q->carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, m_cs, &alpha_idx) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } @@ -304,7 +313,7 @@ int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q, // Get start of the sequence in resource grid const cf_t* slot_symbols_ptr = - &slot_symbols[(carrier->nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE]; + &slot_symbols[(q->carrier.nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE]; // Measure EPRE and average epre += srslte_vec_avg_power_cf(slot_symbols_ptr, SRSLTE_NRE) / resource->nof_symbols; @@ -369,7 +378,6 @@ cf_t srslte_pucch_nr_format1_w(const srslte_pucch_nr_t* q, uint32_t n_pucch, uin } int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q, - const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, @@ -377,7 +385,7 @@ int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q, uint32_t nof_bits, cf_t* slot_symbols) { - if (carrier == NULL || cfg == NULL || slot == NULL || resource == NULL || b == NULL || slot_symbols == NULL) { + if (q == NULL || cfg == NULL || slot == NULL || resource == NULL || b == NULL || slot_symbols == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } @@ -402,7 +410,7 @@ int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q, // Get group sequence uint32_t u = 0; uint32_t v = 0; - if (srslte_pucch_nr_group_sequence(carrier, cfg, &u, &v) < SRSLTE_SUCCESS) { + if (srslte_pucch_nr_group_sequence(&q->carrier, cfg, &u, &v) < SRSLTE_SUCCESS) { ERROR("Error getting group sequence"); return SRSLTE_ERROR; } @@ -413,11 +421,11 @@ int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q, uint32_t l_prime = resource->start_symbol_idx; for (uint32_t l = 1, m = 0; l < resource->nof_symbols; l += 2, m++) { // Get start of the sequence in resource grid - cf_t* slot_symbols_ptr = &slot_symbols[(carrier->nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE]; + cf_t* slot_symbols_ptr = &slot_symbols[(q->carrier.nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE]; // Get Alpha index uint32_t alpha_idx = 0; - if (srslte_pucch_nr_alpha_idx(carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, 0, &alpha_idx) < + if (srslte_pucch_nr_alpha_idx(&q->carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, 0, &alpha_idx) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } @@ -448,7 +456,6 @@ int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q, } int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q, - const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, @@ -459,6 +466,11 @@ int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q, { uint32_t m_cs = 0; + if (q == NULL || cfg == NULL || slot == NULL || resource == NULL || chest_res == NULL || b == NULL || + slot_symbols == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + if (srslte_pucch_nr_cfg_resource_valid(resource) < SRSLTE_SUCCESS) { ERROR("Invalid PUCCH format 1 resource"); return SRSLTE_SUCCESS; @@ -475,7 +487,7 @@ int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q, // Get group sequence uint32_t u = 0; uint32_t v = 0; - if (srslte_pucch_nr_group_sequence(carrier, cfg, &u, &v) < SRSLTE_SUCCESS) { + if (srslte_pucch_nr_group_sequence(&q->carrier, cfg, &u, &v) < SRSLTE_SUCCESS) { ERROR("Error getting group sequence"); return SRSLTE_ERROR; } @@ -486,8 +498,8 @@ int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q, uint32_t l_prime = resource->start_symbol_idx; for (uint32_t l = 1, m = 0; l < resource->nof_symbols; l += 2, m++) { // Get start of the sequence in resource grid - cf_t* slot_symbols_ptr = &slot_symbols[(carrier->nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE]; - cf_t* ce_ptr = &chest_res->ce[(carrier->nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE]; + cf_t* slot_symbols_ptr = &slot_symbols[(q->carrier.nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE]; + cf_t* ce_ptr = &chest_res->ce[(q->carrier.nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE]; // Equalise x = w(i) * d' * r_uv(n) cf_t x[SRSLTE_NRE]; @@ -495,8 +507,8 @@ int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q, // Get Alpha index uint32_t alpha_idx = 0; - if (srslte_pucch_nr_alpha_idx(carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, m_cs, &alpha_idx) < - SRSLTE_SUCCESS) { + if (srslte_pucch_nr_alpha_idx( + &q->carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, m_cs, &alpha_idx) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } @@ -535,7 +547,7 @@ static uint32_t pucch_nr_format2_cinit(const srslte_carrier_nr_t* carri { uint32_t n_id = (pucch_cfg->scrambling_id_present) ? pucch_cfg->scrambling_id_present : carrier->id; - return ((uint32_t)uci_cfg->rnti << 15U) + n_id; + return ((uint32_t)uci_cfg->pucch.rnti << 15U) + n_id; } // Implements TS 38.211 section 6.3.2.5 PUCCH format 2 @@ -639,7 +651,6 @@ static int pucch_nr_format2_decode(srslte_pucch_nr_t* q, } int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q, - const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, @@ -648,8 +659,8 @@ int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q, cf_t* slot_symbols) { // Validate input pointers - if (q == NULL || carrier == NULL || cfg == NULL || slot == NULL || resource == NULL || uci_cfg == NULL || - uci_value == NULL || slot_symbols == NULL) { + if (q == NULL || cfg == NULL || slot == NULL || resource == NULL || uci_cfg == NULL || uci_value == NULL || + slot_symbols == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } @@ -662,7 +673,7 @@ int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q, // Modulate PUCCH switch (resource->format) { case SRSLTE_PUCCH_NR_FORMAT_2: - return pucch_nr_format2_encode(q, carrier, cfg, resource, uci_cfg, slot_symbols); + return pucch_nr_format2_encode(q, &q->carrier, cfg, resource, uci_cfg, slot_symbols); case SRSLTE_PUCCH_NR_FORMAT_3: case SRSLTE_PUCCH_NR_FORMAT_4: ERROR("Not implemented"); @@ -676,7 +687,6 @@ int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q, } int srslte_pucch_nr_format_2_3_4_decode(srslte_pucch_nr_t* q, - const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, @@ -686,8 +696,8 @@ int srslte_pucch_nr_format_2_3_4_decode(srslte_pucch_nr_t* q, srslte_uci_value_nr_t* uci_value) { // Validate input pointers - if (q == NULL || carrier == NULL || cfg == NULL || slot == NULL || resource == NULL || uci_cfg == NULL || - chest_res == NULL || uci_value == NULL || slot_symbols == NULL) { + if (q == NULL || cfg == NULL || slot == NULL || resource == NULL || uci_cfg == NULL || chest_res == NULL || + uci_value == NULL || slot_symbols == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } @@ -695,7 +705,8 @@ int srslte_pucch_nr_format_2_3_4_decode(srslte_pucch_nr_t* q, int8_t* llr = (int8_t*)q->b; switch (resource->format) { case SRSLTE_PUCCH_NR_FORMAT_2: - if (pucch_nr_format2_decode(q, carrier, cfg, resource, uci_cfg, chest_res, slot_symbols, llr) < SRSLTE_SUCCESS) { + if (pucch_nr_format2_decode(q, &q->carrier, cfg, resource, uci_cfg, chest_res, slot_symbols, llr) < + SRSLTE_SUCCESS) { ERROR("Demodulating PUCCH format 2"); return SRSLTE_ERROR; } diff --git a/lib/src/phy/phch/pusch_nr.c b/lib/src/phy/phch/pusch_nr.c index e597112a0..0a8f5bcaa 100644 --- a/lib/src/phy/phch/pusch_nr.c +++ b/lib/src/phy/phch/pusch_nr.c @@ -23,7 +23,9 @@ #include "srslte/phy/mimo/layermap.h" #include "srslte/phy/mimo/precoding.h" #include "srslte/phy/modem/demod_soft.h" +#include "srslte/phy/phch/csi.h" #include "srslte/phy/phch/ra_nr.h" +#include "srslte/phy/phch/uci_cfg.h" int pusch_nr_init_common(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args) { @@ -37,6 +39,29 @@ int pusch_nr_init_common(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* arg } } + if (srslte_uci_nr_init(&q->uci, &args->uci) < SRSLTE_SUCCESS) { + ERROR("Initialising UCI"); + return SRSLTE_ERROR; + } + + q->g_ulsch = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); + q->g_ack = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); + q->g_csi1 = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); + q->g_csi2 = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); + if (q->g_ack == NULL || q->g_csi1 == NULL || q->g_csi2 == NULL || q->g_ulsch == NULL) { + ERROR("Malloc"); + return SRSLTE_ERROR; + } + + q->pos_ulsch = srslte_vec_u32_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); + q->pos_ack = srslte_vec_u32_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); + q->pos_csi1 = srslte_vec_u32_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); + q->pos_csi2 = srslte_vec_u32_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); + if (q->pos_ack == NULL || q->pos_csi1 == NULL || q->pos_csi2 == NULL || q->pos_ulsch == NULL) { + ERROR("Malloc"); + return SRSLTE_ERROR; + } + return SRSLTE_SUCCESS; } @@ -68,7 +93,7 @@ int srslte_pusch_nr_init_gnb(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* return SRSLTE_ERROR; } - if (srslte_sch_nr_init_rx(&q->sch, &args->sch)) { + if (srslte_sch_nr_init_rx(&q->sch, &args->sch) < SRSLTE_SUCCESS) { ERROR("Initialising SCH"); return SRSLTE_ERROR; } @@ -155,6 +180,32 @@ void srslte_pusch_nr_free(srslte_pusch_nr_t* q) return; } + if (q->g_ulsch != NULL) { + free(q->g_ulsch); + } + if (q->g_ack != NULL) { + free(q->g_ack); + } + if (q->g_csi1 != NULL) { + free(q->g_csi1); + } + if (q->g_csi2 != NULL) { + free(q->g_csi2); + } + + if (q->pos_ulsch != NULL) { + free(q->pos_ulsch); + } + if (q->pos_ack != NULL) { + free(q->pos_ack); + } + if (q->pos_csi1 != NULL) { + free(q->pos_csi1); + } + if (q->pos_csi2 != NULL) { + free(q->pos_csi2); + } + for (uint32_t cw = 0; cw < SRSLTE_MAX_CODEWORDS; cw++) { if (q->b[cw]) { free(q->b[cw]); @@ -166,6 +217,7 @@ void srslte_pusch_nr_free(srslte_pusch_nr_t* q) } srslte_sch_nr_free(&q->sch); + srslte_uci_nr_free(&q->uci); for (uint32_t i = 0; i < SRSLTE_MAX_LAYERS_NR; i++) { if (q->x[i]) { @@ -180,6 +232,8 @@ void srslte_pusch_nr_free(srslte_pusch_nr_t* q) if (q->evm_buffer != NULL) { srslte_evm_free(q->evm_buffer); } + + SRSLTE_MEM_ZERO(q, srslte_pusch_nr_t, 1); } /** @@ -424,11 +478,354 @@ pusch_nr_cinit(const srslte_carrier_nr_t* carrier, const srslte_sch_cfg_nr_t* cf return cinit; } -static inline int pusch_nr_encode_codeword(srslte_pusch_nr_t* q, - const srslte_sch_cfg_nr_t* cfg, - const srslte_sch_tb_t* tb, - const uint8_t* data, - uint16_t rnti) +static inline int pusch_nr_fill_uci_cfg(srslte_pusch_nr_t* q, const srslte_sch_cfg_nr_t* cfg) +{ + if (cfg->grant.nof_prb == 0) { + ERROR("Invalid number of PRB (%d)", cfg->grant.nof_prb); + return SRSLTE_ERROR; + } + + // Initially, copy all fields + q->uci_cfg = cfg->uci; + + // Reset UCI PUSCH configuration + SRSLTE_MEM_ZERO(&q->uci_cfg.pusch, srslte_uci_nr_pusch_cfg_t, 1); + + // Get DMRS symbol indexes + uint32_t nof_dmrs_l = 0; + uint32_t dmrs_l[SRSLTE_DMRS_SCH_MAX_SYMBOLS] = {}; + int n = srslte_dmrs_sch_get_symbols_idx(&cfg->dmrs, &cfg->grant, dmrs_l); + if (n < SRSLTE_SUCCESS) { + return SRSLTE_ERROR; + } + nof_dmrs_l = (uint32_t)n; + + // Find OFDM symbol index of the first OFDM symbol after the first set of consecutive OFDM symbol(s) carrying DMRS + // Starts at first OFDM symbol carrying DMRS + for (uint32_t l = dmrs_l[0], dmrs_l_idx = 0; l < cfg->grant.S + cfg->grant.L; l++) { + // Check if it is not carrying DMRS... + if (l != dmrs_l[dmrs_l_idx]) { + // Set value and stop iterating + q->uci_cfg.pusch.l0 = l; + break; + } + + // Move to the next DMRS OFDM symbol index + if (dmrs_l_idx < nof_dmrs_l) { + dmrs_l_idx++; + } + } + + // Find OFDM symbol index of the first OFDM symbol that does not carry DMRS + // Starts at first OFDM symbol of the PUSCH transmission + for (uint32_t l = cfg->grant.S, dmrs_l_idx = 0; l < cfg->grant.S + cfg->grant.L; l++) { + // Check if it is not carrying DMRS... + if (l != dmrs_l[dmrs_l_idx]) { + q->uci_cfg.pusch.l1 = l; + break; + } + + // Move to the next DMRS OFDM symbol index + if (dmrs_l_idx < nof_dmrs_l) { + dmrs_l_idx++; + } + } + + // Number of DMRS per PRB + uint32_t n_sc_dmrs = SRSLTE_DMRS_SCH_SC(cfg->grant.nof_dmrs_cdm_groups_without_data, cfg->dmrs.type); + + // Set UCI RE number of candidates per OFDM symbol according to TS 38.312 6.3.2.4.2.1 + for (uint32_t l = 0, dmrs_l_idx = 0; l < SRSLTE_NSYMB_PER_SLOT_NR; l++) { + // Skip if OFDM symbol is outside of the PUSCH transmission + if (l < cfg->grant.S || l >= (cfg->grant.S + cfg->grant.L)) { + q->uci_cfg.pusch.M_pusch_sc[l] = 0; + q->uci_cfg.pusch.M_uci_sc[l] = 0; + continue; + } + + // OFDM symbol carries DMRS + if (l == dmrs_l[dmrs_l_idx]) { + // Calculate PUSCH RE candidates + q->uci_cfg.pusch.M_pusch_sc[l] = cfg->grant.nof_prb * (SRSLTE_NRE - n_sc_dmrs); + + // The Number of RE candidates for UCI are 0 + q->uci_cfg.pusch.M_uci_sc[l] = 0; + + // Advance DMRS symbol index + dmrs_l_idx++; + + // Skip to next symbol + continue; + } + + // Number of RE for Phase Tracking Reference Signals (PT-RS) + uint32_t M_ptrs_sc = 0; // Not implemented yet + + // Number of RE given by the grant + q->uci_cfg.pusch.M_pusch_sc[l] = cfg->grant.nof_prb * SRSLTE_NRE; + + // Calculate the number of UCI candidates + q->uci_cfg.pusch.M_uci_sc[l] = q->uci_cfg.pusch.M_pusch_sc[l] - M_ptrs_sc; + } + + // Generate SCH Transport block information + srslte_sch_nr_tb_info_t sch_tb_info = {}; + if (srslte_sch_nr_fill_tb_info(&q->carrier, &cfg->sch_cfg, &cfg->grant.tb[0], &sch_tb_info) < SRSLTE_SUCCESS) { + ERROR("Generating TB info"); + return SRSLTE_ERROR; + } + + // Calculate the sum of codeblock sizes + for (uint32_t i = 0; i < sch_tb_info.C; i++) { + // Accumulate codeblock size if mask is enabled + q->uci_cfg.pusch.K_sum += (sch_tb_info.mask[i]) ? sch_tb_info.Kr : 0; + } + + // Set other PUSCH parameters + q->uci_cfg.pusch.modulation = cfg->grant.tb[0].mod; + q->uci_cfg.pusch.nof_layers = cfg->grant.nof_layers; + q->uci_cfg.pusch.R = (float)cfg->grant.tb[0].R; + q->uci_cfg.pusch.alpha = cfg->scaling; + q->uci_cfg.pusch.beta_harq_ack_offset = cfg->beta_harq_ack_offset; + q->uci_cfg.pusch.beta_csi1_offset = cfg->beta_csi_part1_offset; + q->uci_cfg.pusch.nof_re = cfg->grant.tb[0].nof_re; + + return SRSLTE_SUCCESS; +} + +// Implements TS 38.212 6.2.7 Data and control multiplexing (for NR-PUSCH) +static int pusch_nr_gen_mux_uci(srslte_pusch_nr_t* q, const srslte_uci_cfg_nr_t* cfg) +{ + // Decide whether UCI shall be multiplexed + q->uci_mux = (q->G_ack > 0 || q->G_csi1 > 0 || q->G_csi2 > 0); + + // Check if UCI multiplexing is NOT required + if (!q->uci_mux) { + return SRSLTE_SUCCESS; + } + + // Bit positions + uint32_t* pos_ulsch = q->pos_ulsch; // coded bits for UL-SCH + uint32_t* pos_ack = q->pos_ack; // coded bits for HARQ-ACK + uint32_t* pos_csi1 = q->pos_csi1; // coded bits for CSI part 1 + uint32_t* pos_csi2 = q->pos_csi2; // coded bits for CSI part 2 + + // Key OFDM symbol indexes + uint32_t l1 = + cfg->pusch.l0; // First OFDM symbol that does not carry DMRS of the PUSCH, after the first DMRS symbol(s) + uint32_t l1_csi = cfg->pusch.l1; // OFDM symbol index of the first OFDM symbol that does not carry DMRS + + // Number of UCI bits + uint32_t G_ack = q->G_ack; + uint32_t G_csi1 = q->G_csi1; + uint32_t G_csi2 = q->G_csi2; + + // Other... + uint32_t Nl = cfg->pusch.nof_layers; + uint32_t Qm = srslte_mod_bits_x_symbol(cfg->pusch.modulation); + + // if the number of HARQ-ACK information bits to be transmitted on PUSCH is 0, 1 or 2 bits + uint32_t G_ack_rvd = 0; + if (cfg->o_ack <= 2) { + // the number of reserved resource elements for potential HARQ-ACK transmission is calculated according to Clause + // 6.3.2.4.2.1, by setting O_ACK = 2 ; + G_ack_rvd = srslte_uci_nr_pusch_ack_nof_bits(&q->uci_cfg.pusch, 2); + + // Disable non reserved HARQ-ACK bits + G_ack = 0; + } + + // Counters + uint32_t m_ack_count = 0; + uint32_t m_csi1_count = 0; + uint32_t m_csi2_count = 0; + uint32_t m_ulsch_count = 0; + uint32_t m_all_count = 0; + + for (uint32_t l = 0; l < SRSLTE_NSYMB_PER_SLOT_NR; l++) { + // Skip if symbol has potential for data + if (cfg->pusch.M_pusch_sc[l] == 0) { + continue; + } + + // Put UL-SCH only if this OFDM symbol has no potential for UCI + if (cfg->pusch.M_uci_sc[l] == 0) { + for (uint32_t i = 0; i < cfg->pusch.M_pusch_sc[l] * Qm * Nl; i++) { + pos_ulsch[m_ulsch_count++] = m_all_count++; + } + continue; + } + + uint32_t M_ulsch_sc = cfg->pusch.M_pusch_sc[l]; + uint32_t M_uci_sc = cfg->pusch.M_uci_sc[l]; + uint32_t M_uci_rvd = 0; + + // Compute HARQ-ACK bits multiplexing + uint32_t ack_d = 0; + uint32_t ack_m_re_count = 0; + if (l >= l1) { + if (cfg->o_ack <= 2 && m_ack_count < G_ack_rvd) { + ack_d = 1; + ack_m_re_count = M_ulsch_sc; + if (G_ack_rvd - m_ack_count < M_uci_sc * Nl * Qm) { + ack_d = (M_uci_sc * Nl * Qm) / (G_ack_rvd - m_ack_count); + ack_m_re_count = SRSLTE_CEIL(G_ack_rvd - m_ack_count, Nl * Qm); + } + M_uci_rvd = ack_m_re_count; + } else if (m_ack_count < G_ack) { + ack_d = 1; + ack_m_re_count = M_ulsch_sc; + if (G_ack - m_ack_count < M_uci_sc * Nl * Qm) { + ack_d = (M_uci_sc * Nl * Qm) / (G_ack - m_ack_count); + ack_m_re_count = SRSLTE_CEIL(G_ack - m_ack_count, Nl * Qm); + } + M_uci_sc -= ack_m_re_count; + } + } + + // Compute CSI part 1 bits multiplexing + uint32_t csi1_d = 0; + uint32_t csi1_m_re_count = 0; + if (l >= l1_csi && M_uci_sc > M_uci_rvd && m_csi1_count < G_csi1) { + csi1_d = 1; + csi1_m_re_count = M_uci_sc - M_uci_rvd; + if (G_csi1 - m_csi1_count < (M_uci_sc - M_uci_rvd) * Nl * Qm) { + csi1_d = ((M_uci_sc - M_uci_rvd) * Nl * Qm) / (G_csi1 - m_csi1_count); + csi1_m_re_count = SRSLTE_CEIL(G_csi1 - m_csi1_count, Nl * Qm); + } + M_uci_sc -= csi1_m_re_count; + } + + // Compute CSI part 2 bits multiplexing + uint32_t csi2_d = 0; + uint32_t csi2_m_re_count = 0; + if (l >= l1_csi && M_uci_sc > M_uci_rvd && m_csi2_count < G_csi2) { + csi2_d = 1; + csi2_m_re_count = M_uci_sc - M_uci_rvd; + if (G_csi2 - m_csi2_count < (M_uci_sc - M_uci_rvd) * Nl * Qm) { + csi2_d = ((M_uci_sc - M_uci_rvd) * Nl * Qm) / (G_csi2 - m_csi2_count); + csi2_m_re_count = SRSLTE_CEIL(G_csi2 - m_csi2_count, Nl * Qm); + } + M_uci_sc -= csi2_m_re_count; + } + + // Leave the rest for UL-SCH + uint32_t ulsch_m_re_count = M_uci_sc; + + for (uint32_t i = 0, csi1_i = 0, csi2_i = 0; i < cfg->pusch.M_pusch_sc[l]; i++) { + // Check if RE is reserved for ACK + bool reserved = false; + if (ack_m_re_count != 0 && i % ack_d == 0 && m_ack_count < G_ack_rvd) { + reserved = true; + } + + if (ack_m_re_count != 0 && i % ack_d == 0 && m_ack_count < G_ack) { + for (uint32_t j = 0; j < Nl * Qm; j++) { + pos_ack[m_ack_count++] = m_all_count + j; + } + ack_m_re_count--; + } else if (!reserved && csi1_m_re_count != 0 && csi1_i % csi1_d == 0 && m_csi1_count < G_csi1) { + for (uint32_t j = 0; j < Nl * Qm; j++) { + pos_csi1[m_csi1_count++] = m_all_count + j; + } + csi1_m_re_count--; + csi1_i++; + } else if (!reserved && csi2_m_re_count != 0 && csi2_i % csi2_d == 0 && m_csi2_count < G_csi2) { + for (uint32_t j = 0; j < Nl * Qm; j++) { + pos_csi2[m_csi2_count++] = m_all_count + j; + } + csi2_m_re_count--; + csi1_i++; + csi2_i++; + } else { + for (uint32_t j = 0; j < Nl * Qm; j++) { + pos_ulsch[m_ulsch_count++] = m_all_count + j; + } + ulsch_m_re_count--; + if (!reserved) { + csi1_i++; + csi2_i++; + } + } + + // Set reserved bits only if there are ACK bits + if (reserved) { + if (cfg->o_ack > 0) { + for (uint32_t j = 0; j < Nl * Qm; j++) { + pos_ack[m_ack_count++] = m_all_count + j; + } + } else { + m_ack_count += Nl * Qm; + } + ack_m_re_count--; + } + + // Increment all bit counter + m_all_count += Nl * Qm; + } + + // Assert that all RE have been allocated + if (ack_m_re_count != 0) { + ERROR("ack_m_re_count=%d", ack_m_re_count); + } + if (csi1_m_re_count != 0) { + ERROR("csi1_m_re_count=%d", csi1_m_re_count); + } + if (csi2_m_re_count != 0) { + ERROR("csi2_m_re_count=%d", csi2_m_re_count); + } + if (ulsch_m_re_count != 0) { + ERROR("ulsch_m_re_count=%d", ulsch_m_re_count); + } + } + + // Update UL-SCH number of encoded bits + q->G_ulsch = m_ulsch_count; + + // Assert Number of bits + if (G_ack_rvd != 0 && G_ack_rvd != m_ack_count && cfg->o_ack > 0) { + ERROR("Not matched %d!=%d", G_ack_rvd, m_ack_count); + } + if (G_ack != 0 && G_ack != m_ack_count) { + ERROR("Not matched %d!=%d", G_ack, m_ack_count); + } + q->G_csi1 = m_csi1_count; + if (G_csi1 != 0 && G_csi1 != m_csi1_count) { + ERROR("Not matched %d!=%d", G_csi1, m_csi1_count); + } + if (G_csi2 != 0 && G_csi2 != m_csi2_count) { + ERROR("Not matched %d!=%d", G_csi2, m_csi2_count); + } + + // Print debug information if configured for ity + if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) { + if (m_ulsch_count != 0) { + DEBUG("UL-SCH bit positions:"); + srslte_vec_fprint_i(stdout, (int*)pos_ulsch, m_ulsch_count); + } + if (m_ack_count != 0 && cfg->o_ack > 0) { + DEBUG("HARQ-ACK bit positions [%d]:", m_ack_count); + srslte_vec_fprint_i(stdout, (int*)pos_ack, m_ack_count); + } + if (m_csi1_count != 0) { + DEBUG("CSI part 1 bit positions [%d]:", m_csi1_count); + srslte_vec_fprint_i(stdout, (int*)pos_csi1, m_csi1_count); + } + if (m_csi2_count != 0) { + DEBUG("CSI part 2 bit positions [%d]:", m_csi2_count); + srslte_vec_fprint_i(stdout, (int*)pos_csi2, m_csi2_count); + } + } + + return SRSLTE_SUCCESS; +} + +static inline int pusch_nr_encode_codeword(srslte_pusch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_tb_t* tb, + const uint8_t* data, + const srslte_uci_value_nr_t* uci, + uint16_t rnti) { // Early return if TB is not enabled if (!tb->enabled) { @@ -447,20 +844,87 @@ static inline int pusch_nr_encode_codeword(srslte_pusch_nr_t* q, return SRSLTE_ERROR_OUT_OF_BOUNDS; } + // Encode HARQ-ACK bits + int E_uci_ack = srslte_uci_nr_encode_pusch_ack(&q->uci, &q->uci_cfg, uci, q->g_ack); + if (E_uci_ack < SRSLTE_SUCCESS) { + ERROR("Error encoding HARQ-ACK bits"); + return SRSLTE_ERROR; + } + q->G_ack = (uint32_t)E_uci_ack; + + // Encode CSI part 1 + int E_uci_csi1 = srslte_uci_nr_encode_pusch_csi1(&q->uci, &q->uci_cfg, uci, q->g_csi1); + if (E_uci_csi1 < SRSLTE_SUCCESS) { + ERROR("Error encoding HARQ-ACK bits"); + return SRSLTE_ERROR; + } + q->G_csi1 = (uint32_t)E_uci_csi1; + + // Encode CSI part 2 + // ... Not implemented + q->G_csi2 = 0; + + // Generate PUSCH UCI/UL-SCH multiplexing + if (pusch_nr_gen_mux_uci(q, &q->uci_cfg) < SRSLTE_SUCCESS) { + ERROR("Error generating PUSCH mux tables"); + return SRSLTE_ERROR; + } + // Encode SCH - if (srslte_ulsch_nr_encode(&q->sch, &cfg->sch_cfg, tb, data, q->b[tb->cw_idx]) < SRSLTE_SUCCESS) { - ERROR("Error in DL-SCH encoding"); + if (srslte_ulsch_nr_encode(&q->sch, &cfg->sch_cfg, tb, data, q->g_ulsch) < SRSLTE_SUCCESS) { + ERROR("Error in SCH encoding"); return SRSLTE_ERROR; } + // Multiplex UL-SCH with UCI only if it is necessary + uint8_t* b = q->g_ulsch; + if (q->uci_mux) { + // Change b location + b = q->b[tb->cw_idx]; + + // Multiplex UL-SCH + for (uint32_t i = 0; i < q->G_ulsch; i++) { + b[q->pos_ulsch[i]] = q->g_ulsch[i]; + } + + // Multiplex CSI part 1 + for (uint32_t i = 0; i < q->G_csi1; i++) { + b[q->pos_csi1[i]] = q->g_csi1[i]; + } + + // Multiplex CSI part 2 + for (uint32_t i = 0; i < q->G_csi2; i++) { + b[q->pos_csi2[i]] = q->g_csi2[i]; + } + + // Multiplex HARQ-ACK + for (uint32_t i = 0; i < q->G_ack; i++) { + b[q->pos_ack[i]] = q->g_ack[i]; + } + } + if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) { DEBUG("b="); - srslte_vec_fprint_b(stdout, q->b[tb->cw_idx], tb->nof_bits); + srslte_vec_fprint_b(stdout, b, tb->nof_bits); } // 7.3.1.1 Scrambling uint32_t cinit = pusch_nr_cinit(&q->carrier, cfg, rnti, tb->cw_idx); - srslte_sequence_apply_bit(q->b[tb->cw_idx], q->b[tb->cw_idx], tb->nof_bits, cinit); + srslte_sequence_apply_bit(b, q->b[tb->cw_idx], tb->nof_bits, cinit); + + // Special Scrambling condition + if (q->uci_cfg.o_ack <= 2) { + for (uint32_t i = 0; i < q->G_ack; i++) { + uint32_t idx = q->pos_ack[i]; + if (q->g_ack[i] == (uint8_t)UCI_BIT_REPETITION) { + if (idx != 0) { + q->b[tb->cw_idx][idx] = q->b[tb->cw_idx][idx - 1]; + } + } else if (q->g_ack[i] == (uint8_t)UCI_BIT_PLACEHOLDER) { + q->b[tb->cw_idx][idx] = 1; + } + } + } // 7.3.1.2 Modulation srslte_mod_modulate(&q->modem_tables[tb->mod], q->b[tb->cw_idx], q->d[tb->cw_idx], tb->nof_bits); @@ -473,11 +937,11 @@ static inline int pusch_nr_encode_codeword(srslte_pusch_nr_t* q, return SRSLTE_SUCCESS; } -int srslte_pusch_nr_encode(srslte_pusch_nr_t* q, - const srslte_sch_cfg_nr_t* cfg, - const srslte_sch_grant_nr_t* grant, - uint8_t* data[SRSLTE_MAX_TB], - cf_t* sf_symbols[SRSLTE_MAX_PORTS]) +int srslte_pusch_nr_encode(srslte_pusch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + const srslte_pusch_data_nr_t* data, + cf_t* sf_symbols[SRSLTE_MAX_PORTS]) { // Check input pointers if (!q || !cfg || !grant || !data || !sf_symbols) { @@ -495,12 +959,19 @@ int srslte_pusch_nr_encode(srslte_pusch_nr_t* q, return SRSLTE_ERROR; } + // Fill UCI configuration for PUSCH configuration + if (pusch_nr_fill_uci_cfg(q, cfg) < SRSLTE_SUCCESS) { + ERROR("Error filling UCI configuration for PUSCH"); + return SRSLTE_ERROR; + } + // 7.3.1.1 and 7.3.1.2 uint32_t nof_cw = 0; for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { nof_cw += grant->tb[tb].enabled ? 1 : 0; - if (pusch_nr_encode_codeword(q, cfg, &grant->tb[tb], data[tb], grant->rnti) < SRSLTE_SUCCESS) { + if (pusch_nr_encode_codeword(q, cfg, &grant->tb[tb], data[tb].payload, &data[0].uci, grant->rnti) < + SRSLTE_SUCCESS) { ERROR("Error encoding TB %d", tb); return SRSLTE_ERROR; } @@ -568,6 +1039,32 @@ static inline int pusch_nr_decode_codeword(srslte_pusch_nr_t* q, srslte_vec_fprint_c(stdout, q->d[tb->cw_idx], tb->nof_re); } + // Calculate HARQ-ACK bits + int n = srslte_uci_nr_pusch_ack_nof_bits(&q->uci_cfg.pusch, q->uci_cfg.o_ack); + if (n < SRSLTE_SUCCESS) { + ERROR("Calculating G_ack"); + return SRSLTE_ERROR; + } + q->G_ack = (uint32_t)n; + + // Calculate CSI part 1 bits + n = srslte_uci_nr_pusch_csi1_nof_bits(&q->uci_cfg); + if (n < SRSLTE_SUCCESS) { + ERROR("Calculating G_csi1"); + return SRSLTE_ERROR; + } + q->G_csi1 = (uint32_t)n; + + // Calculate CSI part 2 bits + // ... Not implemented + q->G_csi2 = 0; + + // Generate PUSCH UCI/UL-SCH multiplexing + if (pusch_nr_gen_mux_uci(q, &q->uci_cfg) < SRSLTE_SUCCESS) { + ERROR("Error generating PUSCH mux tables"); + return SRSLTE_ERROR; + } + // Demodulation int8_t* llr = (int8_t*)q->b[tb->cw_idx]; if (srslte_demod_soft_demodulate_b(tb->mod, q->d[tb->cw_idx], llr, tb->nof_re)) { @@ -579,23 +1076,76 @@ static inline int pusch_nr_decode_codeword(srslte_pusch_nr_t* q, res->evm = srslte_evm_run_b(q->evm_buffer, &q->modem_tables[tb->mod], q->d[tb->cw_idx], llr, tb->nof_bits); } - // Change LLR sign - for (uint32_t i = 0; i < tb->nof_bits; i++) { - llr[i] = -llr[i]; - } - // Descrambling srslte_sequence_apply_c(llr, llr, tb->nof_bits, pusch_nr_cinit(&q->carrier, cfg, rnti, tb->cw_idx)); if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) { DEBUG("b="); - srslte_vec_fprint_b(stdout, q->b[tb->cw_idx], tb->nof_bits); + srslte_vec_fprint_bs(stdout, llr, tb->nof_bits); } - // Decode SCH - if (srslte_ulsch_nr_decode(&q->sch, &cfg->sch_cfg, tb, llr, res->payload, &res->crc) < SRSLTE_SUCCESS) { - ERROR("Error in DL-SCH encoding"); - return SRSLTE_ERROR; + // Demultiplex UCI only if necessary + if (q->uci_mux) { + // Demultiplex UL-SCH, change sign + int8_t* g_ulsch = (int8_t*)q->g_ulsch; + for (uint32_t i = 0; i < q->G_ulsch; i++) { + g_ulsch[i] = -llr[q->pos_ulsch[i]]; + } + for (uint32_t i = q->G_ulsch; i < tb->nof_bits; i++) { + g_ulsch[i] = 0; + } + + // Demultiplex HARQ-ACK + int8_t* g_ack = (int8_t*)q->g_ack; + for (uint32_t i = 0; i < q->G_ack; i++) { + g_ack[i] = llr[q->pos_ack[i]]; + } + + // Demultiplex CSI part 1 + int8_t* g_csi1 = (int8_t*)q->g_csi1; + for (uint32_t i = 0; i < q->G_csi1; i++) { + g_csi1[i] = llr[q->pos_csi1[i]]; + } + + // Demultiplex CSI part 2 + int8_t* g_csi2 = (int8_t*)q->g_csi2; + for (uint32_t i = 0; i < q->G_csi2; i++) { + g_csi2[i] = llr[q->pos_csi2[i]]; + } + + // Decode HARQ-ACK + if (q->G_ack) { + if (srslte_uci_nr_decode_pusch_ack(&q->uci, &q->uci_cfg, g_ack, &res->uci)) { + ERROR("Error in UCI decoding"); + return SRSLTE_ERROR; + } + } + + // Decode CSI part 1 + if (q->G_csi1) { + if (srslte_uci_nr_decode_pusch_csi1(&q->uci, &q->uci_cfg, g_csi1, &res->uci)) { + ERROR("Error in UCI decoding"); + return SRSLTE_ERROR; + } + } + + // Decode CSI part 2 + // ... Not implemented + + // Change LLR pointer + llr = g_ulsch; + } else { + for (uint32_t i = 0; i < tb->nof_bits; i++) { + llr[i] *= -1; + } + } + + // Decode Ul-SCH + if (tb->nof_bits != 0) { + if (srslte_ulsch_nr_decode(&q->sch, &cfg->sch_cfg, tb, llr, res->payload, &res->crc) < SRSLTE_SUCCESS) { + ERROR("Error in SCH decoding"); + return SRSLTE_ERROR; + } } return SRSLTE_SUCCESS; @@ -618,6 +1168,18 @@ int srslte_pusch_nr_decode(srslte_pusch_nr_t* q, gettimeofday(&t[1], NULL); } + // Check number of layers + if (q->max_layers < grant->nof_layers) { + ERROR("Error number of layers (%d) exceeds configured maximum (%d)", grant->nof_layers, q->max_layers); + return SRSLTE_ERROR; + } + + // Fill UCI configuration for PUSCH configuration + if (pusch_nr_fill_uci_cfg(q, cfg) < SRSLTE_SUCCESS) { + ERROR("Error filling UCI configuration for PUSCH"); + return SRSLTE_ERROR; + } + uint32_t nof_cw = 0; for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { nof_cw += grant->tb[tb].enabled ? 1 : 0; diff --git a/lib/src/phy/phch/ra_nr.c b/lib/src/phy/phch/ra_nr.c index 01c6e9364..b13df3846 100644 --- a/lib/src/phy/phch/ra_nr.c +++ b/lib/src/phy/phch/ra_nr.c @@ -319,16 +319,13 @@ int srslte_ra_dl_nr_slot_nof_re(const srslte_sch_cfg_nr_t* pdsch_cfg, const srsl return SRSLTE_MIN(SRSLTE_MAX_NRE_NR, n_re_prime) * n_prb; } -#define CEIL(NUM, DEN) (((NUM) + ((DEN)-1)) / (DEN)) -#define FLOOR(NUM, DEN) ((NUM) / (DEN)) -#define ROUND(NUM, DEN) ((uint32_t)round((NUM) / (DEN))) #define POW2(N) (1U << (N)) static uint32_t ra_nr_tbs_from_n_info3(uint32_t n_info) { // quantized intermediate number of information bits uint32_t n = (uint32_t)SRSLTE_MAX(3.0, floor(log2(n_info)) - 6.0); - uint32_t n_info_prime = SRSLTE_MAX(ra_nr_tbs_table[0], POW2(n) * FLOOR(n_info, POW2(n))); + uint32_t n_info_prime = SRSLTE_MAX(ra_nr_tbs_table[0], POW2(n) * SRSLTE_FLOOR(n_info, POW2(n))); // use Table 5.1.3.2-1 find the closest TBS that is not less than n_info_prime for (uint32_t i = 0; i < RA_NR_TBS_SIZE_TABLE; i++) { @@ -344,19 +341,19 @@ static uint32_t ra_nr_tbs_from_n_info4(uint32_t n_info, double R) { // quantized intermediate number of information bits uint32_t n = (uint32_t)(floor(log2(n_info - 24.0)) - 5.0); - uint32_t n_info_prime = SRSLTE_MAX(3840, POW2(n) * ROUND(n_info - 24.0, POW2(n))); + uint32_t n_info_prime = SRSLTE_MAX(3840, POW2(n) * SRSLTE_ROUND(n_info - 24.0, POW2(n))); if (R <= 0.25) { - uint32_t C = CEIL(n_info_prime + 24U, 3816U); - return 8U * C * CEIL(n_info_prime + 24U, 8U * C) - 24U; + uint32_t C = SRSLTE_CEIL(n_info_prime + 24U, 3816U); + return 8U * C * SRSLTE_CEIL(n_info_prime + 24U, 8U * C) - 24U; } if (n_info_prime > 8424) { - uint32_t C = CEIL(n_info_prime + 24U, 8424U); - return 8U * C * CEIL(n_info_prime + 24U, 8U * C) - 24U; + uint32_t C = SRSLTE_CEIL(n_info_prime + 24U, 8424U); + return 8U * C * SRSLTE_CEIL(n_info_prime + 24U, 8U * C) - 24U; } - return 8U * CEIL(n_info_prime + 24U, 8U) - 24U; + return 8U * SRSLTE_CEIL(n_info_prime + 24U, 8U) - 24U; } /** diff --git a/lib/src/phy/phch/ra_ul_nr.c b/lib/src/phy/phch/ra_ul_nr.c index 23c53db6e..08b1ad7bd 100644 --- a/lib/src/phy/phch/ra_ul_nr.c +++ b/lib/src/phy/phch/ra_ul_nr.c @@ -51,7 +51,7 @@ static const ue_ra_time_resource_t ue_ul_default_A_lut[16] = {{srslte_sch_mappin {srslte_sch_mapping_type_A, 3, 0, 14}, {srslte_sch_mapping_type_A, 3, 0, 10}}; -int srslte_ra_ul_nr_pdsch_time_resource_default_A(uint32_t scs_cfg, uint32_t m, srslte_sch_grant_nr_t* grant) +int srslte_ra_ul_nr_pusch_time_resource_default_A(uint32_t scs_cfg, uint32_t m, srslte_sch_grant_nr_t* grant) { uint32_t j[4] = {1, 1, 2, 3}; @@ -150,7 +150,7 @@ int srslte_ra_ul_nr_time(const srslte_sch_hl_cfg_nr_t* cfg, if (ss_type == srslte_search_space_type_rar) { // Row 1 if (cfg->nof_common_time_ra == 0) { - srslte_ra_ul_nr_pdsch_time_resource_default_A(cfg->scs_cfg, m, grant); + srslte_ra_ul_nr_pusch_time_resource_default_A(cfg->scs_cfg, m, grant); } else if (m < SRSLTE_MAX_NOF_DL_ALLOCATION && m < cfg->nof_common_time_ra) { ra_ul_nr_time_hl(&cfg->common_time_ra[m], grant); } else { @@ -163,7 +163,7 @@ int srslte_ra_ul_nr_time(const srslte_sch_hl_cfg_nr_t* cfg, SRSLTE_SEARCH_SPACE_IS_COMMON(ss_type) && coreset_id == 0) { // Row 2 if (cfg->nof_common_time_ra == 0) { - srslte_ra_ul_nr_pdsch_time_resource_default_A(cfg->scs_cfg, m, grant); + srslte_ra_ul_nr_pusch_time_resource_default_A(cfg->scs_cfg, m, grant); } else if (m < SRSLTE_MAX_NOF_DL_ALLOCATION) { ra_ul_nr_time_hl(&cfg->common_time_ra[m], grant); } @@ -177,7 +177,7 @@ int srslte_ra_ul_nr_time(const srslte_sch_hl_cfg_nr_t* cfg, } else if (cfg->nof_common_time_ra > 0) { ra_ul_nr_time_hl(&cfg->common_time_ra[m], grant); } else { - srslte_ra_ul_nr_pdsch_time_resource_default_A(cfg->scs_cfg, m, grant); + srslte_ra_ul_nr_pusch_time_resource_default_A(cfg->scs_cfg, m, grant); } } else { ERROR("Unhandled case"); @@ -382,7 +382,7 @@ int srslte_ra_ul_nr_pucch_format_2_3_min_prb(const srslte_pucch_nr_resource_t* r } // Compute total number of UCI bits - uint32_t O_total = uci_cfg->o_ack + uci_cfg->o_sr + srslte_csi_nof_bits(uci_cfg->csi, uci_cfg->nof_csi); + uint32_t O_total = uci_cfg->o_ack + uci_cfg->o_sr + srslte_csi_part1_nof_bits(uci_cfg->csi, uci_cfg->nof_csi); // Add CRC bits if any O_total += srslte_uci_nr_crc_len(O_total); @@ -470,9 +470,9 @@ int srslte_ra_ul_nr_pucch_resource(const srslte_pucch_nr_hl_cfg_t* pucch_cfg, // - At least one positive SR // - up to 2 HARQ-ACK // - No CSI report - if (uci_cfg->sr_positive_present > 0 && uci_cfg->o_ack <= SRSLTE_PUCCH_NR_FORMAT1_MAX_NOF_BITS && + if (uci_cfg->pucch.sr_positive_present > 0 && uci_cfg->o_ack <= SRSLTE_PUCCH_NR_FORMAT1_MAX_NOF_BITS && uci_cfg->nof_csi == 0) { - uint32_t sr_resource_id = uci_cfg->sr_resource_id; + uint32_t sr_resource_id = uci_cfg->pucch.sr_resource_id; if (sr_resource_id >= SRSLTE_PUCCH_MAX_NOF_SR_RESOURCES) { ERROR("SR resource ID (%d) exceeds the maximum ID (%d)", sr_resource_id, SRSLTE_PUCCH_MAX_NOF_SR_RESOURCES); return SRSLTE_ERROR; @@ -495,7 +495,7 @@ int srslte_ra_ul_nr_pucch_resource(const srslte_pucch_nr_hl_cfg_t* pucch_cfg, // - More than 2 HARQ-ACK // - No CSI report if (uci_cfg->o_sr > 0 && uci_cfg->o_ack > SRSLTE_PUCCH_NR_FORMAT1_MAX_NOF_BITS && uci_cfg->nof_csi == 0) { - return ra_ul_nr_pucch_resource_hl(pucch_cfg, O_uci, uci_cfg->pucch_resource_id, resource); + return ra_ul_nr_pucch_resource_hl(pucch_cfg, O_uci, uci_cfg->pucch.resource_id, resource); } // Use format 2, 3 or 4 CSI report resource from higher layers @@ -511,10 +511,10 @@ int srslte_ra_ul_nr_pucch_resource(const srslte_pucch_nr_hl_cfg_t* pucch_cfg, // a PUCCH resource set is provided by pucch-ResourceCommon through an index to a row of Table 9.2.1-1 for size // transmission of HARQ-ACK information on PUCCH in an initial UL BWP of N BWP PRBs. if (!pucch_cfg->enabled) { - uint32_t r_pucch = (2 * uci_cfg->n_cce_0) + 2 * uci_cfg->pucch_resource_id; + uint32_t r_pucch = (2 * uci_cfg->pucch.n_cce_0) + 2 * uci_cfg->pucch.resource_id; return ra_ul_nr_pucch_resource_default(r_pucch, resource); } - return ra_ul_nr_pucch_resource_hl(pucch_cfg, O_uci, uci_cfg->pucch_resource_id, resource); + return ra_ul_nr_pucch_resource_hl(pucch_cfg, O_uci, uci_cfg->pucch.resource_id, resource); } uint32_t srslte_ra_ul_nr_nof_sr_bits(uint32_t K) diff --git a/lib/src/phy/phch/sch_nr.c b/lib/src/phy/phch/sch_nr.c index a26f9d973..d84839fe4 100644 --- a/lib/src/phy/phch/sch_nr.c +++ b/lib/src/phy/phch/sch_nr.c @@ -74,10 +74,10 @@ uint32_t sch_nr_n_prb_lbrm(uint32_t nof_prb) return 273; } -int srslte_sch_nr_fill_cfg(srslte_sch_nr_t* q, - const srslte_sch_cfg_t* sch_cfg, - const srslte_sch_tb_t* tb, - srslte_sch_nr_common_cfg_t* cfg) +int srslte_sch_nr_fill_tb_info(const srslte_carrier_nr_t* carrier, + const srslte_sch_cfg_t* sch_cfg, + const srslte_sch_tb_t* tb, + srslte_sch_nr_tb_info_t* cfg) { if (!sch_cfg || !tb || !cfg) { return SRSLTE_ERROR_INVALID_INPUTS; @@ -120,10 +120,10 @@ int srslte_sch_nr_fill_cfg(srslte_sch_nr_t* q, cfg->Nl = tb->N_L; // Calculate Nref - uint32_t N_re_lbrm = 156 * sch_nr_n_prb_lbrm(q->carrier.nof_prb); + uint32_t N_re_lbrm = 156 * sch_nr_n_prb_lbrm(carrier->nof_prb); double TCR_lbrm = 948.0 / 1024.0; uint32_t Qm_lbrm = (sch_cfg->mcs_table == srslte_mcs_table_256qam) ? 8 : 6; - uint32_t TBS_LRBM = srslte_ra_nr_tbs(N_re_lbrm, 1.0, TCR_lbrm, Qm_lbrm, q->carrier.max_mimo_layers); + uint32_t TBS_LRBM = srslte_ra_nr_tbs(N_re_lbrm, 1.0, TCR_lbrm, Qm_lbrm, carrier->max_mimo_layers); double R = 2.0 / 3.0; cfg->Nref = ceil(TBS_LRBM / (cbsegm.C * R)); @@ -137,22 +137,12 @@ int srslte_sch_nr_fill_cfg(srslte_sch_nr_t* q, cfg->C = cbsegm.C; cfg->Cp = cbsegm.C; - // Select encoder - cfg->encoder = (bg == BG1) ? q->encoder_bg1[cfg->Z] : q->encoder_bg2[cfg->Z]; - - // Select decoder - cfg->decoder = (bg == BG1) ? q->decoder_bg1[cfg->Z] : q->decoder_bg2[cfg->Z]; - - // Select CRC for TB - cfg->crc_tb = (cbsegm.L_tb == 24) ? &q->crc_tb_24 : &q->crc_tb_16; - return SRSLTE_SUCCESS; } -#define CEIL(NUM, DEN) (((NUM) + ((DEN)-1)) / (DEN)) #define MOD(NUM, DEN) ((NUM) % (DEN)) -static inline uint32_t sch_nr_get_E(const srslte_sch_nr_common_cfg_t* cfg, uint32_t j) +static inline uint32_t sch_nr_get_E(const srslte_sch_nr_tb_info_t* cfg, uint32_t j) { if (cfg->Nl == 0 || cfg->Qm == 0 || cfg->Cp == 0) { ERROR("Invalid Nl (%d), Qm (%d) or Cp (%d)", cfg->Nl, cfg->Qm, cfg->Cp); @@ -162,7 +152,7 @@ static inline uint32_t sch_nr_get_E(const srslte_sch_nr_common_cfg_t* cfg, uint3 if (j <= (cfg->Cp - MOD(cfg->G / (cfg->Nl * cfg->Qm), cfg->Cp) - 1)) { return cfg->Nl * cfg->Qm * (cfg->G / (cfg->Nl * cfg->Qm * cfg->Cp)); } - return cfg->Nl * cfg->Qm * CEIL(cfg->G, cfg->Nl * cfg->Qm * cfg->Cp); + return cfg->Nl * cfg->Qm * SRSLTE_CEIL(cfg->G, cfg->Nl * cfg->Qm * cfg->Cp); } static inline int sch_nr_init_common(srslte_sch_nr_t* q) @@ -225,21 +215,23 @@ int srslte_sch_nr_init_tx(srslte_sch_nr_t* q, const srslte_sch_nr_args_t* args) continue; } - q->encoder_bg1[ls] = calloc(1, sizeof(srslte_ldpc_encoder_t)); + q->encoder_bg1[ls] = SRSLTE_MEM_ALLOC(srslte_ldpc_encoder_t, 1); if (!q->encoder_bg1[ls]) { ERROR("Error: calloc"); return SRSLTE_ERROR; } + SRSLTE_MEM_ZERO(q->encoder_bg1[ls], srslte_ldpc_encoder_t, 1); if (srslte_ldpc_encoder_init(q->encoder_bg1[ls], encoder_type, BG1, ls) < SRSLTE_SUCCESS) { ERROR("Error: initialising BG1 LDPC encoder for ls=%d", ls); return SRSLTE_ERROR; } - q->encoder_bg2[ls] = calloc(1, sizeof(srslte_ldpc_encoder_t)); + q->encoder_bg2[ls] = SRSLTE_MEM_ALLOC(srslte_ldpc_encoder_t, 1); if (!q->encoder_bg2[ls]) { return SRSLTE_ERROR; } + SRSLTE_MEM_ZERO(q->encoder_bg2[ls], srslte_ldpc_encoder_t, 1); if (srslte_ldpc_encoder_init(q->encoder_bg2[ls], encoder_type, BG2, ls) < SRSLTE_SUCCESS) { ERROR("Error: initialising BG2 LDPC encoder for ls=%d", ls); @@ -387,19 +379,23 @@ static inline int sch_nr_encode(srslte_sch_nr_t* q, const uint8_t* input_ptr = data; uint8_t* output_ptr = e_bits; - srslte_sch_nr_common_cfg_t cfg = {}; - if (srslte_sch_nr_fill_cfg(q, sch_cfg, tb, &cfg) < SRSLTE_SUCCESS) { + srslte_sch_nr_tb_info_t cfg = {}; + if (srslte_sch_nr_fill_tb_info(&q->carrier, sch_cfg, tb, &cfg) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } + // Select encoder and CRC + srslte_ldpc_encoder_t* encoder = (cfg.bg == BG1) ? q->encoder_bg1[cfg.Z] : q->encoder_bg2[cfg.Z]; + srslte_crc_t* crc_tb = (cfg.L_tb == 24) ? &q->crc_tb_24 : &q->crc_tb_16; + // Check encoder - if (cfg.encoder == NULL) { + if (encoder == NULL) { ERROR("Error: encoder for lifting size Z=%d not found (tbs=%d)", cfg.Z, tb->tbs); return SRSLTE_ERROR; } // Check CRC for TB - if (cfg.crc_tb == NULL) { + if (crc_tb == NULL) { ERROR("Error: CRC for TB not found"); return SRSLTE_ERROR; } @@ -413,16 +409,16 @@ static inline int sch_nr_encode(srslte_sch_nr_t* q, return SRSLTE_ERROR; } - if (tb->softbuffer.tx->max_cb_size < (cfg.encoder->liftN - 2 * cfg.Z)) { + if (tb->softbuffer.tx->max_cb_size < (encoder->liftN - 2 * cfg.Z)) { ERROR("Soft-buffer code-block maximum size insufficient (max_cb_size=%d) for a TBS=%d, requires %d.", tb->softbuffer.tx->max_cb_size, tb->tbs, - (cfg.encoder->liftN - 2 * cfg.Z)); + (encoder->liftN - 2 * cfg.Z)); return SRSLTE_ERROR; } // Calculate TB CRC - uint32_t checksum_tb = srslte_crc_checksum_byte(cfg.crc_tb, data, tb->tbs); + uint32_t checksum_tb = srslte_crc_checksum_byte(crc_tb, data, tb->tbs); if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) { DEBUG("tb="); srslte_vec_fprint_byte(stdout, data, tb->tbs / 8); @@ -477,11 +473,11 @@ static inline int sch_nr_encode(srslte_sch_nr_t* q, } // Encode code block - srslte_ldpc_encoder_encode(cfg.encoder, q->temp_cb, rm_buffer, cfg.Kr); + srslte_ldpc_encoder_encode(encoder, q->temp_cb, rm_buffer, cfg.Kr); if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) { DEBUG("encoded="); - srslte_vec_fprint_b(stdout, rm_buffer, cfg.encoder->liftN - 2 * cfg.encoder->ls); + srslte_vec_fprint_b(stdout, rm_buffer, encoder->liftN - 2 * encoder->ls); } } @@ -525,25 +521,29 @@ int sch_nr_decode(srslte_sch_nr_t* q, int8_t* input_ptr = e_bits; - srslte_sch_nr_common_cfg_t cfg = {}; - if (srslte_sch_nr_fill_cfg(q, sch_cfg, tb, &cfg) < SRSLTE_SUCCESS) { + srslte_sch_nr_tb_info_t cfg = {}; + if (srslte_sch_nr_fill_tb_info(&q->carrier, sch_cfg, tb, &cfg) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } + // Select encoder and CRC + srslte_ldpc_decoder_t* decoder = (cfg.bg == BG1) ? q->decoder_bg1[cfg.Z] : q->decoder_bg2[cfg.Z]; + srslte_crc_t* crc_tb = (cfg.L_tb == 24) ? &q->crc_tb_24 : &q->crc_tb_16; + // Check decoder - if (cfg.decoder == NULL) { + if (decoder == NULL) { ERROR("Error: decoder for lifting size Z=%d not found", cfg.Z); return SRSLTE_ERROR; } // Check CRC for TB - if (cfg.crc_tb == NULL) { + if (crc_tb == NULL) { ERROR("Error: CRC for TB not found"); return SRSLTE_ERROR; } // Soft-buffer number of code-block protection - if (tb->softbuffer.rx->max_cb < cfg.Cp || tb->softbuffer.rx->max_cb_size < (cfg.decoder->liftN - 2 * cfg.Z)) { + if (tb->softbuffer.rx->max_cb < cfg.Cp || tb->softbuffer.rx->max_cb_size < (decoder->liftN - 2 * cfg.Z)) { return SRSLTE_ERROR; } @@ -593,7 +593,7 @@ int sch_nr_decode(srslte_sch_nr_t* q, srslte_ldpc_rm_rx_c(&q->rx_rm, input_ptr, rm_buffer, E, cfg.F, cfg.bg, cfg.Z, tb->rv, tb->mod, cfg.Nref); // Decode - srslte_ldpc_decoder_decode_c(cfg.decoder, rm_buffer, q->temp_cb); + srslte_ldpc_decoder_decode_c(decoder, rm_buffer, q->temp_cb); // Compute CB CRC uint32_t cb_len = cfg.Kp - cfg.L_cb; @@ -657,7 +657,7 @@ int sch_nr_decode(srslte_sch_nr_t* q, } // Calculate TB CRC from packed data - uint32_t checksum1 = srslte_crc_checksum_byte(cfg.crc_tb, data, tb->tbs); + uint32_t checksum1 = srslte_crc_checksum_byte(crc_tb, data, tb->tbs); *crc_ok = (checksum1 == checksum2 && !all_zeros); SCH_INFO_RX("TB: TBS=%d; CRC={%06x, %06x}", tb->tbs, checksum1, checksum2); diff --git a/lib/src/phy/phch/test/CMakeLists.txt b/lib/src/phy/phch/test/CMakeLists.txt index 43f7d3715..1435d638a 100644 --- a/lib/src/phy/phch/test/CMakeLists.txt +++ b/lib/src/phy/phch/test/CMakeLists.txt @@ -643,6 +643,17 @@ add_nr_test(pdsch_nr_test pdsch_nr_test -p 6 -m 20) add_executable(pusch_nr_test pusch_nr_test.c) target_link_libraries(pusch_nr_test srslte_phy) add_nr_test(pusch_nr_test pusch_nr_test -p 6 -m 20) +add_nr_test(pusch_nr_ack1_test pusch_nr_test -p 50 -m 20 -A 1) +add_nr_test(pusch_nr_ack2_test pusch_nr_test -p 50 -m 20 -A 2) +add_nr_test(pusch_nr_ack4_test pusch_nr_test -p 50 -m 20 -A 4) +add_nr_test(pusch_nr_ack20_test pusch_nr_test -p 50 -m 20 -A 20) +add_nr_test(pusch_nr_csi4_test pusch_nr_test -p 50 -m 20 -C 4) +add_nr_test(pusch_nr_csi20_test pusch_nr_test -p 50 -m 20 -C 20) +add_nr_test(pusch_nr_ack1_csi4_test pusch_nr_test -p 50 -m 20 -A 1 -C 4) +add_nr_test(pusch_nr_ack2_csi4_test pusch_nr_test -p 50 -m 20 -A 2 -C 4) +add_nr_test(pusch_nr_ack4_csi4_test pusch_nr_test -p 50 -m 20 -A 4 -C 4) +add_nr_test(pusch_nr_ack20_csi4_test pusch_nr_test -p 50 -m 20 -A 20 -C 4) + add_executable(pdcch_nr_test pdcch_nr_test.c) target_link_libraries(pdcch_nr_test srslte_phy) diff --git a/lib/src/phy/phch/test/pucch_nr_test.c b/lib/src/phy/phch/test/pucch_nr_test.c index 711722949..f4acc0b7e 100644 --- a/lib/src/phy/phch/test/pucch_nr_test.c +++ b/lib/src/phy/phch/test/pucch_nr_test.c @@ -62,15 +62,14 @@ static int test_pucch_format0(srslte_pucch_nr_t* pucch, const srslte_pucch_nr_co for (resource.initial_cyclic_shift = 0; resource.initial_cyclic_shift <= 11; resource.initial_cyclic_shift++) { for (uint32_t m_cs = 0; m_cs <= 6; m_cs += 2) { - TESTASSERT(srslte_pucch_nr_format0_encode(pucch, &carrier, cfg, &slot, &resource, m_cs, slot_symbols) == + TESTASSERT(srslte_pucch_nr_format0_encode(pucch, cfg, &slot, &resource, m_cs, slot_symbols) == SRSLTE_SUCCESS); // Measure PUCCH format 0 for all possible values of m_cs for (uint32_t m_cs_test = 0; m_cs_test <= 6; m_cs_test += 2) { srslte_pucch_nr_measure_t measure = {}; TESTASSERT(srslte_pucch_nr_format0_measure( - pucch, &carrier, cfg, &slot, &resource, m_cs_test, slot_symbols, &measure) == - SRSLTE_SUCCESS); + pucch, cfg, &slot, &resource, m_cs_test, slot_symbols, &measure) == SRSLTE_SUCCESS); if (m_cs == m_cs_test) { TESTASSERT(fabsf(measure.epre - 1) < 0.001); @@ -124,8 +123,8 @@ static int test_pucch_format1(srslte_pucch_nr_t* pucch, } // Encode PUCCH - TESTASSERT(srslte_pucch_nr_format1_encode( - pucch, &carrier, cfg, &slot, &resource, b, nof_bits, slot_symbols) == SRSLTE_SUCCESS); + TESTASSERT(srslte_pucch_nr_format1_encode(pucch, cfg, &slot, &resource, b, nof_bits, slot_symbols) == + SRSLTE_SUCCESS); // Put DMRS TESTASSERT(srslte_dmrs_pucch_format1_put(pucch, &carrier, cfg, &slot, &resource, slot_symbols) == @@ -146,7 +145,7 @@ static int test_pucch_format1(srslte_pucch_nr_t* pucch, // Decode PUCCH uint8_t b_rx[SRSLTE_PUCCH_NR_FORMAT1_MAX_NOF_BITS]; TESTASSERT(srslte_pucch_nr_format1_decode( - pucch, &carrier, cfg, &slot, &resource, chest_res, slot_symbols, b_rx, nof_bits) == + pucch, cfg, &slot, &resource, chest_res, slot_symbols, b_rx, nof_bits) == SRSLTE_SUCCESS); // Check received bits @@ -211,8 +210,7 @@ static int test_pucch_format2(srslte_pucch_nr_t* pucch, // Encode PUCCH TESTASSERT(srslte_pucch_nr_format_2_3_4_encode( - pucch, &carrier, cfg, &slot, &resource, &uci_cfg, &uci_value, slot_symbols) == - SRSLTE_SUCCESS); + pucch, cfg, &slot, &resource, &uci_cfg, &uci_value, slot_symbols) == SRSLTE_SUCCESS); // Put DMRS TESTASSERT(srslte_dmrs_pucch_format2_put(pucch, &carrier, cfg, &slot, &resource, slot_symbols) == @@ -235,10 +233,9 @@ static int test_pucch_format2(srslte_pucch_nr_t* pucch, // Decode PUCCH srslte_uci_value_nr_t uci_value_rx = {}; - TESTASSERT( - srslte_pucch_nr_format_2_3_4_decode( - pucch, &carrier, cfg, &slot, &resource, &uci_cfg, chest_res, slot_symbols, &uci_value_rx) == - SRSLTE_SUCCESS); + TESTASSERT(srslte_pucch_nr_format_2_3_4_decode( + pucch, cfg, &slot, &resource, &uci_cfg, chest_res, slot_symbols, &uci_value_rx) == + SRSLTE_SUCCESS); TESTASSERT(uci_value_rx.valid == true); @@ -320,6 +317,11 @@ int main(int argc, char** argv) goto clean_exit; } + if (srslte_pucch_nr_set_carrier(&pucch, &carrier) < SRSLTE_SUCCESS) { + ERROR("PUCCH set carrier"); + goto clean_exit; + } + if (srslte_chest_ul_res_init(&chest_res, carrier.nof_prb)) { ERROR("Chest UL"); goto clean_exit; diff --git a/lib/src/phy/phch/test/pusch_nr_test.c b/lib/src/phy/phch/test/pusch_nr_test.c index e7e515222..5c12b3631 100644 --- a/lib/src/phy/phch/test/pusch_nr_test.c +++ b/lib/src/phy/phch/test/pusch_nr_test.c @@ -36,11 +36,12 @@ static srslte_carrier_nr_t carrier = { 1 // max_mimo_layers }; -static uint32_t n_prb = 0; // Set to 0 for steering -static uint32_t mcs = 30; // Set to 30 for steering -static srslte_sch_cfg_nr_t pusch_cfg = {}; -static srslte_sch_grant_nr_t pusch_grant = {}; -static uint16_t rnti = 0x1234; +static uint32_t n_prb = 0; // Set to 0 for steering +static uint32_t mcs = 30; // Set to 30 for steering +static srslte_sch_cfg_nr_t pusch_cfg = {}; +static uint16_t rnti = 0x1234; +static uint32_t nof_ack_bits = 0; +static uint32_t nof_csi_bits = 0; void usage(char* prog) { @@ -50,13 +51,15 @@ void usage(char* prog) printf("\t-T Provide MCS table (64qam, 256qam, 64qamLowSE) [Default %s]\n", srslte_mcs_table_to_str(pusch_cfg.sch_cfg.mcs_table)); printf("\t-L Provide number of layers [Default %d]\n", carrier.max_mimo_layers); + printf("\t-A Provide a number of HARQ-ACK bits [Default %d]\n", nof_ack_bits); + printf("\t-C Provide a number of CSI bits [Default %d]\n", nof_csi_bits); printf("\t-v [set srslte_verbose to debug, default none]\n"); } int parse_args(int argc, char** argv) { int opt; - while ((opt = getopt(argc, argv, "pmTLv")) != -1) { + while ((opt = getopt(argc, argv, "pmTLACv")) != -1) { switch (opt) { case 'p': n_prb = (uint32_t)strtol(argv[optind], NULL, 10); @@ -70,6 +73,12 @@ int parse_args(int argc, char** argv) case 'L': carrier.max_mimo_layers = (uint32_t)strtol(argv[optind], NULL, 10); break; + case 'A': + nof_ack_bits = (uint32_t)strtol(argv[optind], NULL, 10); + break; + case 'C': + nof_csi_bits = (uint32_t)strtol(argv[optind], NULL, 10); + break; case 'v': srslte_verbose++; break; @@ -84,16 +93,15 @@ int parse_args(int argc, char** argv) int main(int argc, char** argv) { - int ret = SRSLTE_ERROR; - srslte_pusch_nr_t pusch_tx = {}; - srslte_pusch_nr_t pusch_rx = {}; - srslte_chest_dl_res_t chest = {}; - srslte_pusch_res_nr_t pusch_res[SRSLTE_MAX_TB] = {}; - srslte_random_t rand_gen = srslte_random_init(1234); + int ret = SRSLTE_ERROR; + srslte_pusch_nr_t pusch_tx = {}; + srslte_pusch_nr_t pusch_rx = {}; + srslte_chest_dl_res_t chest = {}; + srslte_random_t rand_gen = srslte_random_init(1234); - uint8_t* data_tx[SRSLTE_MAX_TB] = {}; - uint8_t* data_rx[SRSLTE_MAX_CODEWORDS] = {}; - cf_t* sf_symbols[SRSLTE_MAX_LAYERS_NR] = {}; + srslte_pusch_data_nr_t data_tx[SRSLTE_MAX_TB] = {}; + srslte_pusch_res_nr_t data_rx[SRSLTE_MAX_CODEWORDS] = {}; + cf_t* sf_symbols[SRSLTE_MAX_LAYERS_NR] = {}; // Set default PUSCH configuration pusch_cfg.sch_cfg.mcs_table = srslte_mcs_table_64qam; @@ -135,14 +143,12 @@ int main(int argc, char** argv) } for (uint32_t i = 0; i < pusch_tx.max_cw; i++) { - data_tx[i] = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); - data_rx[i] = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); - if (data_tx[i] == NULL || data_rx[i] == NULL) { + data_tx[i].payload = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); + data_rx[i].payload = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); + if (data_tx[i].payload == NULL || data_rx[i].payload == NULL) { ERROR("Error malloc"); goto clean_exit; } - - pusch_res[i].payload = data_rx[i]; } srslte_softbuffer_tx_t softbuffer_tx = {}; @@ -161,20 +167,20 @@ int main(int argc, char** argv) } // Use grant default A time resources with m=0 - if (srslte_ra_ul_nr_pdsch_time_resource_default_A(carrier.numerology, 0, &pusch_grant) < SRSLTE_SUCCESS) { + if (srslte_ra_ul_nr_pusch_time_resource_default_A(carrier.numerology, 0, &pusch_cfg.grant) < SRSLTE_SUCCESS) { ERROR("Error loading default grant"); goto clean_exit; } // Load number of DMRS CDM groups without data - if (srslte_ra_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(&pusch_cfg, &pusch_grant) < SRSLTE_SUCCESS) { + if (srslte_ra_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(&pusch_cfg, &pusch_cfg.grant) < SRSLTE_SUCCESS) { ERROR("Error loading number of DMRS CDM groups without data"); goto clean_exit; } - pusch_grant.nof_layers = carrier.max_mimo_layers; - pusch_grant.dci_format = srslte_dci_format_nr_1_0; - pusch_grant.rnti = rnti; + pusch_cfg.grant.nof_layers = carrier.max_mimo_layers; + pusch_cfg.grant.dci_format = srslte_dci_format_nr_1_0; + pusch_cfg.grant.rnti = rnti; uint32_t n_prb_start = 1; uint32_t n_prb_end = carrier.nof_prb + 1; @@ -190,6 +196,10 @@ int main(int argc, char** argv) mcs_end = SRSLTE_MIN(mcs + 1, mcs_end); } + pusch_cfg.scaling = 0.5f; + pusch_cfg.beta_harq_ack_offset = 2.0f; + pusch_cfg.beta_csi_part1_offset = 2.0f; + if (srslte_chest_dl_res_init(&chest, carrier.nof_prb) < SRSLTE_SUCCESS) { ERROR("Initiating chest"); goto clean_exit; @@ -198,65 +208,91 @@ int main(int argc, char** argv) for (n_prb = n_prb_start; n_prb < n_prb_end; n_prb++) { for (mcs = mcs_start; mcs < mcs_end; mcs++) { for (uint32_t n = 0; n < SRSLTE_MAX_PRB_NR; n++) { - pusch_grant.prb_idx[n] = (n < n_prb); + pusch_cfg.grant.prb_idx[n] = (n < n_prb); } + pusch_cfg.grant.nof_prb = n_prb; - pusch_grant.dci_format = srslte_dci_format_nr_0_0; - if (srslte_ra_nr_fill_tb(&pusch_cfg, &pusch_grant, mcs, &pusch_grant.tb[0]) < SRSLTE_SUCCESS) { + pusch_cfg.grant.dci_format = srslte_dci_format_nr_0_0; + if (srslte_ra_nr_fill_tb(&pusch_cfg, &pusch_cfg.grant, mcs, &pusch_cfg.grant.tb[0]) < SRSLTE_SUCCESS) { ERROR("Error filing tb"); goto clean_exit; } + // Generate SCH payload for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { // Skip TB if no allocated - if (data_tx[tb] == NULL) { + if (data_tx[tb].payload == NULL) { continue; } - for (uint32_t i = 0; i < pusch_grant.tb[tb].tbs; i++) { - data_tx[tb][i] = (uint8_t)srslte_random_uniform_int_dist(rand_gen, 0, UINT8_MAX); + for (uint32_t i = 0; i < pusch_cfg.grant.tb[tb].tbs; i++) { + data_tx[tb].payload[i] = (uint8_t)srslte_random_uniform_int_dist(rand_gen, 0, UINT8_MAX); + } + pusch_cfg.grant.tb[tb].softbuffer.tx = &softbuffer_tx; + } + + // Generate HARQ ACK bits + if (nof_ack_bits > 0) { + pusch_cfg.uci.o_ack = nof_ack_bits; + for (uint32_t i = 0; i < nof_ack_bits; i++) { + data_tx->uci.ack[i] = (uint8_t)srslte_random_uniform_int_dist(rand_gen, 0, 1); + } + } + + // Generate CSI report bits + uint8_t csi_report_tx[SRSLTE_UCI_NR_MAX_CSI1_BITS] = {}; + uint8_t csi_report_rx[SRSLTE_UCI_NR_MAX_CSI1_BITS] = {}; + if (nof_csi_bits > 0) { + pusch_cfg.uci.csi[0].quantity = SRSLTE_CSI_REPORT_QUANTITY_NONE; + pusch_cfg.uci.csi[0].K_csi_rs = nof_csi_bits; + pusch_cfg.uci.nof_csi = 1; + data_tx->uci.csi[0].none = csi_report_tx; + for (uint32_t i = 0; i < nof_csi_bits; i++) { + csi_report_tx[i] = (uint8_t)srslte_random_uniform_int_dist(rand_gen, 0, 1); } - pusch_grant.tb[tb].softbuffer.tx = &softbuffer_tx; + + data_rx->uci.csi[0].none = csi_report_rx; } - if (srslte_pusch_nr_encode(&pusch_tx, &pusch_cfg, &pusch_grant, data_tx, sf_symbols) < SRSLTE_SUCCESS) { + if (srslte_pusch_nr_encode(&pusch_tx, &pusch_cfg, &pusch_cfg.grant, data_tx, sf_symbols) < SRSLTE_SUCCESS) { ERROR("Error encoding"); goto clean_exit; } for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { - pusch_grant.tb[tb].softbuffer.rx = &softbuffer_rx; - srslte_softbuffer_rx_reset(pusch_grant.tb[tb].softbuffer.rx); + pusch_cfg.grant.tb[tb].softbuffer.rx = &softbuffer_rx; + srslte_softbuffer_rx_reset(pusch_cfg.grant.tb[tb].softbuffer.rx); } - for (uint32_t i = 0; i < pusch_grant.tb->nof_re; i++) { + for (uint32_t i = 0; i < pusch_cfg.grant.tb->nof_re; i++) { chest.ce[0][0][i] = 1.0f; } - chest.nof_re = pusch_grant.tb->nof_re; + chest.nof_re = pusch_cfg.grant.tb->nof_re; - if (srslte_pusch_nr_decode(&pusch_rx, &pusch_cfg, &pusch_grant, &chest, sf_symbols, pusch_res) < SRSLTE_SUCCESS) { + if (srslte_pusch_nr_decode(&pusch_rx, &pusch_cfg, &pusch_cfg.grant, &chest, sf_symbols, data_rx) < + SRSLTE_SUCCESS) { ERROR("Error encoding"); goto clean_exit; } - if (pusch_res->evm > 0.001f) { - ERROR("Error PUSCH EVM is too high %f", pusch_res->evm); + if (data_rx[0].evm > 0.001f) { + ERROR("Error PUSCH EVM is too high %f", data_rx[0].evm); goto clean_exit; } float mse = 0.0f; - uint32_t nof_re = srslte_ra_dl_nr_slot_nof_re(&pusch_cfg, &pusch_grant); - for (uint32_t i = 0; i < pusch_grant.nof_layers; i++) { + uint32_t nof_re = srslte_ra_dl_nr_slot_nof_re(&pusch_cfg, &pusch_cfg.grant); + for (uint32_t i = 0; i < pusch_cfg.grant.nof_layers; i++) { for (uint32_t j = 0; j < nof_re; j++) { mse += cabsf(pusch_tx.d[i][j] - pusch_rx.d[i][j]); } } - if (nof_re * pusch_grant.nof_layers > 0) { - mse = mse / (nof_re * pusch_grant.nof_layers); + if (nof_re * pusch_cfg.grant.nof_layers > 0) { + mse = mse / (nof_re * pusch_cfg.grant.nof_layers); } if (mse > 0.001) { ERROR("MSE error (%f) is too high", mse); - for (uint32_t i = 0; i < pusch_grant.nof_layers; i++) { + for (uint32_t i = 0; i < pusch_cfg.grant.nof_layers; i++) { printf("d_tx[%d]=", i); srslte_vec_fprint_c(stdout, pusch_tx.d[i], nof_re); printf("d_rx[%d]=", i); @@ -265,21 +301,55 @@ int main(int argc, char** argv) goto clean_exit; } - if (!pusch_res[0].crc) { - ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pusch_grant.tb[0].tbs); + // Validate UL-SCH CRC check + if (!data_rx[0].crc) { + ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pusch_cfg.grant.tb[0].tbs); goto clean_exit; } - if (memcmp(data_tx[0], data_rx[0], pusch_grant.tb[0].tbs / 8) != 0) { - ERROR("Failed to match Tx/Rx data; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pusch_grant.tb[0].tbs); + // Validate UL-SCH payload + if (memcmp(data_tx[0].payload, data_rx[0].payload, pusch_cfg.grant.tb[0].tbs / 8) != 0) { + ERROR("Failed to match Tx/Rx data; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pusch_cfg.grant.tb[0].tbs); printf("Tx data: "); - srslte_vec_fprint_byte(stdout, data_tx[0], pusch_grant.tb[0].tbs / 8); + srslte_vec_fprint_byte(stdout, data_tx[0].payload, pusch_cfg.grant.tb[0].tbs / 8); printf("Rx data: "); - srslte_vec_fprint_byte(stdout, data_rx[0], pusch_grant.tb[0].tbs / 8); + srslte_vec_fprint_byte(stdout, data_tx[0].payload, pusch_cfg.grant.tb[0].tbs / 8); goto clean_exit; } - printf("n_prb=%d; mcs=%d; TBS=%d; EVM=%f; PASSED!\n", n_prb, mcs, pusch_grant.tb[0].tbs, pusch_res[0].evm); + // Validate UCI is decoded successfully + if (nof_ack_bits > 0 || nof_csi_bits > 0) { + if (!data_rx[0].uci.valid) { + ERROR("UCI data was not decoded ok"); + goto clean_exit; + } + } + + // Validate HARQ-ACK is decoded successfully + if (nof_ack_bits > 0) { + if (memcmp(data_tx[0].uci.ack, data_rx[0].uci.ack, nof_ack_bits) != 0) { + ERROR("UCI HARQ-ACK bits are unmatched"); + printf("Tx data: "); + srslte_vec_fprint_byte(stdout, data_tx[0].uci.ack, nof_ack_bits); + printf("Rx data: "); + srslte_vec_fprint_byte(stdout, data_rx[0].uci.ack, nof_ack_bits); + goto clean_exit; + } + } + + // Validate CSI is decoded successfully + if (nof_csi_bits > 0) { + if (memcmp(data_tx[0].uci.csi[0].none, data_rx[0].uci.csi[0].none, nof_csi_bits) != 0) { + ERROR("UCI CSI bits are unmatched"); + printf("Tx data: "); + srslte_vec_fprint_byte(stdout, data_tx[0].uci.csi[0].none, nof_csi_bits); + printf("Rx data: "); + srslte_vec_fprint_byte(stdout, data_rx[0].uci.csi[0].none, nof_csi_bits); + goto clean_exit; + } + } + + printf("n_prb=%d; mcs=%d; TBS=%d; EVM=%f; PASSED!\n", n_prb, mcs, pusch_cfg.grant.tb[0].tbs, data_rx[0].evm); } } @@ -291,11 +361,11 @@ clean_exit: srslte_pusch_nr_free(&pusch_tx); srslte_pusch_nr_free(&pusch_rx); for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { - if (data_tx[i]) { - free(data_tx[i]); + if (data_tx[i].payload) { + free(data_tx[i].payload); } - if (data_rx[i]) { - free(data_rx[i]); + if (data_rx[i].payload) { + free(data_rx[i].payload); } } for (uint32_t i = 0; i < SRSLTE_MAX_LAYERS_NR; i++) { diff --git a/lib/src/phy/phch/uci_nr.c b/lib/src/phy/phch/uci_nr.c index 5f0e5461f..b8254795c 100644 --- a/lib/src/phy/phch/uci_nr.c +++ b/lib/src/phy/phch/uci_nr.c @@ -26,16 +26,16 @@ #include "srslte/phy/phch/uci_cfg.h" #include "srslte/phy/utils/bit.h" #include "srslte/phy/utils/vector.h" -#include #define UCI_NR_INFO_TX(...) INFO("UCI-NR Tx: " __VA_ARGS__) #define UCI_NR_INFO_RX(...) INFO("UCI-NR Rx: " __VA_ARGS__) #define UCI_NR_MAX_L 11U #define UCI_NR_POLAR_MAX 2048U -#define UCI_NR_POLAR_RM_IBIL 0 +#define UCI_NR_POLAR_RM_IBIL 1 #define UCI_NR_PUCCH_POLAR_N_MAX 10 #define UCI_NR_BLOCK_DEFAULT_CORR_THRESHOLD 0.5f +#define UCI_NR_ONE_BIT_CORR_THRESHOLD 0.5f uint32_t srslte_uci_nr_crc_len(uint32_t A) { @@ -123,6 +123,11 @@ int srslte_uci_nr_init(srslte_uci_nr_t* q, const srslte_uci_nr_args_t* args) } else { q->block_code_threshold = UCI_NR_BLOCK_DEFAULT_CORR_THRESHOLD; } + if (isnormal(args->one_bit_threshold)) { + q->one_bit_threshold = args->one_bit_threshold; + } else { + q->one_bit_threshold = UCI_NR_ONE_BIT_CORR_THRESHOLD; + } return SRSLTE_SUCCESS; } @@ -199,7 +204,7 @@ static int uci_nr_unpack_ack_sr(const srslte_uci_cfg_nr_t* cfg, uint8_t* sequenc static int uci_nr_A(const srslte_uci_cfg_nr_t* cfg) { - int o_csi = srslte_csi_nof_bits(cfg->csi, cfg->nof_csi); + int o_csi = srslte_csi_part1_nof_bits(cfg->csi, cfg->nof_csi); // 6.3.1.1.1 HARQ-ACK/SR only UCI bit sequence generation if (o_csi == 0) { @@ -216,9 +221,9 @@ static int uci_nr_A(const srslte_uci_cfg_nr_t* cfg) return SRSLTE_ERROR; } -static int uci_nr_packing(const srslte_uci_cfg_nr_t* cfg, const srslte_uci_value_nr_t* value, uint8_t* sequence) +static int uci_nr_pack_pucch(const srslte_uci_cfg_nr_t* cfg, const srslte_uci_value_nr_t* value, uint8_t* sequence) { - int o_csi = srslte_csi_nof_bits(cfg->csi, cfg->nof_csi); + int o_csi = srslte_csi_part1_nof_bits(cfg->csi, cfg->nof_csi); // 6.3.1.1.1 HARQ-ACK/SR only UCI bit sequence generation if (o_csi == 0) { @@ -235,9 +240,9 @@ static int uci_nr_packing(const srslte_uci_cfg_nr_t* cfg, const srslte_uci_value return SRSLTE_ERROR; } -static int uci_nr_unpacking(const srslte_uci_cfg_nr_t* cfg, uint8_t* sequence, srslte_uci_value_nr_t* value) +static int uci_nr_unpack_pucch(const srslte_uci_cfg_nr_t* cfg, uint8_t* sequence, srslte_uci_value_nr_t* value) { - int o_csi = srslte_csi_nof_bits(cfg->csi, cfg->nof_csi); + int o_csi = srslte_csi_part1_nof_bits(cfg->csi, cfg->nof_csi); // 6.3.1.1.1 HARQ-ACK/SR only UCI bit sequence generation if (o_csi == 0) { @@ -260,7 +265,7 @@ static int uci_nr_encode_1bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg uint32_t i = 0; srslte_uci_bit_type_t c0 = (q->bit_sequence[0] == 0) ? UCI_BIT_0 : UCI_BIT_1; - switch (cfg->modulation) { + switch (cfg->pusch.modulation) { case SRSLTE_MOD_BPSK: while (i < E) { o[i++] = c0; @@ -269,39 +274,39 @@ static int uci_nr_encode_1bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg case SRSLTE_MOD_QPSK: while (i < E) { o[i++] = c0; - o[i++] = UCI_BIT_REPETITION; + o[i++] = (uint8_t)UCI_BIT_REPETITION; } break; case SRSLTE_MOD_16QAM: while (i < E) { o[i++] = c0; - o[i++] = UCI_BIT_REPETITION; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_REPETITION; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; } break; case SRSLTE_MOD_64QAM: while (i < E) { while (i < E) { o[i++] = c0; - o[i++] = UCI_BIT_REPETITION; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_REPETITION; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; } } break; case SRSLTE_MOD_256QAM: while (i < E) { o[i++] = c0; - o[i++] = UCI_BIT_REPETITION; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_REPETITION; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; } break; case SRSLTE_MOD_NITEMS: @@ -310,17 +315,69 @@ static int uci_nr_encode_1bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg return SRSLTE_ERROR; } + if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) { + UCI_NR_INFO_TX("One bit encoded NR-UCI; o="); + srslte_vec_fprint_b(stdout, o, E); + } + return E; } +static int uci_nr_decode_1_bit(srslte_uci_nr_t* q, + const srslte_uci_cfg_nr_t* cfg, + uint32_t A, + const int8_t* llr, + uint32_t E, + bool* decoded_ok) +{ + uint32_t Qm = srslte_mod_bits_x_symbol(cfg->pusch.modulation); + if (Qm == 0) { + ERROR("Invalid modulation (%s)", srslte_mod_string(cfg->pusch.modulation)); + return SRSLTE_ERROR; + } + + // Correlate LLR + float corr = 0.0f; + float pwr = 0.0f; + for (uint32_t i = 0; i < E; i += Qm) { + float t = (float)llr[i]; + corr += t; + pwr += t * t; + } + + // Normalise correlation + float norm_corr = Qm * corr / (E * sqrtf(pwr)); + + // Take decoded decision with threshold + *decoded_ok = (norm_corr > q->one_bit_threshold); + + // Save decoded bit + q->bit_sequence[0] = (corr < 0) ? 0 : 1; + + if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) { + UCI_NR_INFO_RX("One bit decoding NR-UCI llr="); + srslte_vec_fprint_bs(stdout, llr, E); + UCI_NR_INFO_RX("One bit decoding NR-UCI A=%d; E=%d; pwr=%f; corr=%f; norm=%f; thr=%f; %s", + A, + E, + pwr, + corr, + norm_corr, + q->block_code_threshold, + *decoded_ok ? "OK" : "KO"); + } + + return SRSLTE_SUCCESS; +} + static int uci_nr_encode_2bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, uint8_t* o, uint32_t E) { - uint32_t i = 0; - srslte_uci_bit_type_t c0 = (q->bit_sequence[0] == 0) ? UCI_BIT_0 : UCI_BIT_1; - srslte_uci_bit_type_t c1 = (q->bit_sequence[1] == 0) ? UCI_BIT_0 : UCI_BIT_1; - srslte_uci_bit_type_t c2 = ((q->bit_sequence[0] ^ q->bit_sequence[1]) == 0) ? UCI_BIT_0 : UCI_BIT_1; + uint32_t i = 0; + uint8_t c0 = (uint8_t)((q->bit_sequence[0] == 0) ? UCI_BIT_0 : UCI_BIT_1); + uint8_t c1 = (uint8_t)((q->bit_sequence[1] == 0) ? UCI_BIT_0 : UCI_BIT_1); + uint8_t c2 = (uint8_t)(((q->bit_sequence[0] ^ q->bit_sequence[1]) == 0) ? UCI_BIT_0 : UCI_BIT_1); - switch (cfg->modulation) { + switch (cfg->pusch.modulation) { case SRSLTE_MOD_BPSK: case SRSLTE_MOD_QPSK: while (i < E) { @@ -333,38 +390,38 @@ static int uci_nr_encode_2bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg while (i < E) { o[i++] = c0; o[i++] = c1; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; o[i++] = c2; o[i++] = c0; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; o[i++] = c1; o[i++] = c2; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; } break; case SRSLTE_MOD_64QAM: while (i < E) { o[i++] = c0; o[i++] = c1; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; o[i++] = c2; o[i++] = c0; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; o[i++] = c1; o[i++] = c2; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; } break; case SRSLTE_MOD_256QAM: @@ -372,28 +429,28 @@ static int uci_nr_encode_2bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg while (i < E) { o[i++] = c0; o[i++] = c1; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; o[i++] = c2; o[i++] = c0; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; o[i++] = c1; o[i++] = c2; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; - o[i++] = UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; + o[i++] = (uint8_t)UCI_BIT_PLACEHOLDER; } break; case SRSLTE_MOD_NITEMS: @@ -402,9 +459,68 @@ static int uci_nr_encode_2bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg return SRSLTE_ERROR; } + if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) { + UCI_NR_INFO_TX("Two bit encoded NR-UCI; E=%d; o=", E); + srslte_vec_fprint_b(stdout, o, E); + } + return E; } +static int uci_nr_decode_2_bit(srslte_uci_nr_t* q, + const srslte_uci_cfg_nr_t* cfg, + uint32_t A, + const int8_t* llr, + uint32_t E, + bool* decoded_ok) +{ + uint32_t Qm = srslte_mod_bits_x_symbol(cfg->pusch.modulation); + if (Qm == 0) { + ERROR("Invalid modulation (%s)", srslte_mod_string(cfg->pusch.modulation)); + return SRSLTE_ERROR; + } + + // Correlate LLR + float corr[3] = {}; + if (Qm == 1) { + for (uint32_t i = 0; i < E / Qm; i++) { + corr[i % 3] = llr[i]; + } + } else { + for (uint32_t i = 0, j = 0; i < E; i += Qm) { + corr[(j++) % 3] = llr[i + 0]; + corr[(j++) % 3] = llr[i + 1]; + } + } + + // Take decoded decision + bool c0 = corr[0] > 0.0f; + bool c1 = corr[1] > 0.0f; + bool c2 = corr[2] > 0.0f; + + // Check redundancy bit + *decoded_ok = (c2 == (c0 ^ c1)); + + // Save decoded bits + q->bit_sequence[0] = c0 ? 1 : 0; + q->bit_sequence[1] = c1 ? 1 : 0; + + if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) { + UCI_NR_INFO_RX("Two bit decoding NR-UCI llr="); + srslte_vec_fprint_bs(stdout, llr, E); + UCI_NR_INFO_RX("Two bit decoding NR-UCI A=%d; E=%d; Qm=%d; c0=%d; c1=%d; c2=%d %s", + A, + E, + Qm, + c0, + c1, + c2, + *decoded_ok ? "OK" : "KO"); + } + + return SRSLTE_SUCCESS; +} + static int uci_nr_encode_3_11_bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, uint32_t A, uint8_t* o, uint32_t E) { @@ -438,6 +554,7 @@ static int uci_nr_decode_3_11_bit(srslte_uci_nr_t* q, // Compute average LLR power float pwr = srslte_vec_avg_power_bf(llr, E); if (!isnormal(pwr)) { + ERROR("Received all zeros"); return SRSLTE_ERROR; } @@ -466,8 +583,6 @@ static int uci_nr_decode_3_11_bit(srslte_uci_nr_t* q, return SRSLTE_SUCCESS; } -#define CEIL(NUM, DEN) (((NUM) + ((DEN)-1)) / (DEN)) - static int uci_nr_encode_11_1706_bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, uint32_t A, uint8_t* o, uint32_t E_uci) { @@ -486,12 +601,13 @@ uci_nr_encode_11_1706_bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, ui if (I_seg == 1) { C = 2; } - uint32_t A_prime = CEIL(A, C) * C; + uint32_t A_prime = SRSLTE_CEIL(A, C) * C; // Get polar code uint32_t K_r = A_prime / C + L; uint32_t E_r = E_uci / C; if (srslte_polar_code_get(&q->code, K_r, E_r, UCI_NR_PUCCH_POLAR_N_MAX) < SRSLTE_SUCCESS) { + ERROR("Error computing Polar code"); return SRSLTE_ERROR; } @@ -533,12 +649,17 @@ uci_nr_encode_11_1706_bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, ui return SRSLTE_ERROR; } + if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) { + UCI_NR_INFO_TX("Polar encoded %d/%d ", r, C); + srslte_vec_fprint_byte(stdout, q->d, q->code.N); + } + // Rate matching srslte_polar_rm_tx(&q->rm_tx, q->d, &o[E_r * r], q->code.n, E_r, K_r, UCI_NR_POLAR_RM_IBIL); if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) { - UCI_NR_INFO_TX("Polar cw %d/%d ", r, C); - srslte_vec_fprint_byte(stdout, &o[E_r * r], q->code.N); + UCI_NR_INFO_TX("Polar RM cw %d/%d ", r, C); + srslte_vec_fprint_byte(stdout, &o[E_r * r], E_r); } } @@ -569,7 +690,7 @@ static int uci_nr_decode_11_1706_bit(srslte_uci_nr_t* q, if (I_seg == 1) { C = 2; } - uint32_t A_prime = CEIL(A, C) * C; + uint32_t A_prime = SRSLTE_CEIL(A, C) * C; // Get polar code uint32_t K_r = A_prime / C + L; @@ -638,23 +759,8 @@ static int uci_nr_decode_11_1706_bit(srslte_uci_nr_t* q, return SRSLTE_SUCCESS; } -static int uci_nr_encode(srslte_uci_nr_t* q, - const srslte_uci_cfg_nr_t* uci_cfg, - const srslte_uci_value_nr_t* uci_value, - uint8_t* o, - uint32_t E_uci) +static int uci_nr_encode(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* uci_cfg, uint32_t A, uint8_t* o, uint32_t E_uci) { - if (q == NULL || uci_cfg == NULL || uci_value == NULL || o == NULL) { - return SRSLTE_ERROR_INVALID_INPUTS; - } - - // 6.3.1.1 UCI bit sequence generation - int A = uci_nr_packing(uci_cfg, uci_value, q->bit_sequence); - if (A < SRSLTE_SUCCESS) { - ERROR("Generating bit sequence"); - return SRSLTE_ERROR; - } - // 5.3.3.1 Encoding of 1-bit information if (A == 1) { return uci_nr_encode_1bit(q, uci_cfg, o, E_uci); @@ -681,42 +787,35 @@ static int uci_nr_encode(srslte_uci_nr_t* q, static int uci_nr_decode(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* uci_cfg, int8_t* llr, + uint32_t A, uint32_t E_uci, - srslte_uci_value_nr_t* uci_value) + bool* valid) { - if (q == NULL || uci_cfg == NULL || uci_value == NULL || llr == NULL) { + if (q == NULL || uci_cfg == NULL || valid == NULL || llr == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } - // 6.3.1.1 UCI bit sequence generation - int A = uci_nr_A(uci_cfg); - if (A < SRSLTE_SUCCESS) { - ERROR("Error getting number of bits"); - return SRSLTE_ERROR; - } - // Decode LLR if (A == 1) { - ERROR("Not implemented"); + if (uci_nr_decode_1_bit(q, uci_cfg, A, llr, E_uci, valid) < SRSLTE_SUCCESS) { + return SRSLTE_ERROR; + } } else if (A == 2) { - ERROR("Not implemented"); + if (uci_nr_decode_2_bit(q, uci_cfg, A, llr, E_uci, valid) < SRSLTE_SUCCESS) { + return SRSLTE_ERROR; + } } else if (A <= 11) { - if (uci_nr_decode_3_11_bit(q, uci_cfg, A, llr, E_uci, &uci_value->valid) < SRSLTE_SUCCESS) { + if (uci_nr_decode_3_11_bit(q, uci_cfg, A, llr, E_uci, valid) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } } else if (A < SRSLTE_UCI_NR_MAX_NOF_BITS) { - if (uci_nr_decode_11_1706_bit(q, uci_cfg, A, llr, E_uci, &uci_value->valid) < SRSLTE_SUCCESS) { + if (uci_nr_decode_11_1706_bit(q, uci_cfg, A, llr, E_uci, valid) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } } else { ERROR("Invalid number of bits (A=%d)", A); } - // Unpack bits - if (uci_nr_unpacking(uci_cfg, q->bit_sequence, uci_value) < SRSLTE_SUCCESS) { - return SRSLTE_ERROR; - } - return SRSLTE_SUCCESS; } @@ -779,7 +878,14 @@ int srslte_uci_nr_encode_pucch(srslte_uci_nr_t* q, return SRSLTE_ERROR; } - return uci_nr_encode(q, uci_cfg, value, o, E_uci); + // 6.3.1.1 UCI bit sequence generation + int A = uci_nr_pack_pucch(uci_cfg, value, q->bit_sequence); + if (A < SRSLTE_SUCCESS) { + ERROR("Generating bit sequence"); + return SRSLTE_ERROR; + } + + return uci_nr_encode(q, uci_cfg, A, o, E_uci); } int srslte_uci_nr_decode_pucch(srslte_uci_nr_t* q, @@ -795,10 +901,29 @@ int srslte_uci_nr_decode_pucch(srslte_uci_nr_t* q, int E_uci = uci_nr_pucch_E_uci(pucch_resource_cfg, uci_cfg, E_tot); if (E_uci < SRSLTE_SUCCESS) { + ERROR("Error calculating number of encoded PUCCH UCI bits"); return SRSLTE_ERROR; } - return uci_nr_decode(q, uci_cfg, llr, E_uci, value); + // 6.3.1.1 UCI bit sequence generation + int A = uci_nr_A(uci_cfg); + if (A < SRSLTE_SUCCESS) { + ERROR("Error getting number of bits"); + return SRSLTE_ERROR; + } + + if (uci_nr_decode(q, uci_cfg, llr, A, E_uci, &value->valid) < SRSLTE_SUCCESS) { + ERROR("Error decoding UCI bits"); + return SRSLTE_ERROR; + } + + // Unpack bits + if (uci_nr_unpack_pucch(uci_cfg, q->bit_sequence, value) < SRSLTE_SUCCESS) { + ERROR("Error unpacking PUCCH UCI bits"); + return SRSLTE_ERROR; + } + + return SRSLTE_SUCCESS; } uint32_t srslte_uci_nr_total_bits(const srslte_uci_cfg_nr_t* uci_cfg) @@ -807,14 +932,14 @@ uint32_t srslte_uci_nr_total_bits(const srslte_uci_cfg_nr_t* uci_cfg) return 0; } - return uci_cfg->o_ack + uci_cfg->o_sr + srslte_csi_nof_bits(uci_cfg->csi, uci_cfg->nof_csi); + return uci_cfg->o_ack + uci_cfg->o_sr + srslte_csi_part1_nof_bits(uci_cfg->csi, uci_cfg->nof_csi); } uint32_t srslte_uci_nr_info(const srslte_uci_data_nr_t* uci_data, char* str, uint32_t str_len) { uint32_t len = 0; - len = srslte_print_check(str, str_len, len, "rnti=0x%x", uci_data->cfg.rnti); + len = srslte_print_check(str, str_len, len, "rnti=0x%x", uci_data->cfg.pucch.rnti); if (uci_data->cfg.o_ack > 0) { char str2[10]; @@ -832,3 +957,257 @@ uint32_t srslte_uci_nr_info(const srslte_uci_data_nr_t* uci_data, char* str, uin return len; } + +static int uci_nr_pusch_Q_prime_ack(const srslte_uci_nr_pusch_cfg_t* cfg, uint32_t O_ack) +{ + if (cfg == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + uint32_t L_ack = srslte_uci_nr_crc_len(O_ack); // Number of CRC bits + uint32_t Qm = srslte_mod_bits_x_symbol(cfg->modulation); // modulation order of the PUSCH + + uint32_t M_uci_sum = 0; + uint32_t M_uci_l0_sum = 0; + for (uint32_t l = 0; l < SRSLTE_NSYMB_PER_SLOT_NR; l++) { + M_uci_sum += cfg->M_uci_sc[l]; + if (l >= cfg->l0) { + M_uci_l0_sum += cfg->M_uci_sc[l]; + } + } + + if (!isnormal(cfg->R)) { + ERROR("Invalid Rate (%f)", cfg->R); + return SRSLTE_ERROR; + } + + if (cfg->K_sum == 0) { + return (int)SRSLTE_MIN(ceilf(((O_ack + L_ack) * cfg->beta_harq_ack_offset) / (Qm * cfg->R)), + cfg->alpha * M_uci_l0_sum); + } + return (int)SRSLTE_MIN(ceilf(((O_ack + L_ack) * cfg->beta_harq_ack_offset * M_uci_sum) / cfg->K_sum), + cfg->alpha * M_uci_l0_sum); +} + +int srslte_uci_nr_pusch_ack_nof_bits(const srslte_uci_nr_pusch_cfg_t* cfg, uint32_t O_ack) +{ + // Check inputs + if (cfg == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + if (cfg->nof_layers == 0) { + ERROR("Invalid number of layers (%d)", cfg->nof_layers); + return SRSLTE_ERROR; + } + + int Q_ack_prime = uci_nr_pusch_Q_prime_ack(cfg, O_ack); + if (Q_ack_prime < SRSLTE_SUCCESS) { + ERROR("Error calculating number of RE"); + return Q_ack_prime; + } + + return (int)(Q_ack_prime * cfg->nof_layers * srslte_mod_bits_x_symbol(cfg->modulation)); +} + +int srslte_uci_nr_encode_pusch_ack(srslte_uci_nr_t* q, + const srslte_uci_cfg_nr_t* cfg, + const srslte_uci_value_nr_t* value, + uint8_t* o) +{ + int A = cfg->o_ack; + + // Check inputs + if (q == NULL || cfg == NULL || value == NULL || o == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + // 6.3.2.1 UCI bit sequence generation + // 6.3.2.1.1 HARQ-ACK + bool has_csi_part2 = srslte_csi_has_part2(cfg->csi, cfg->nof_csi); + if (cfg->pusch.K_sum == 0 && cfg->nof_csi > 1 && !has_csi_part2 && A < 2) { + q->bit_sequence[0] = (A == 0) ? 0 : value->ack[0]; + q->bit_sequence[1] = 0; + A = 2; + } else if (A == 0) { + UCI_NR_INFO_TX("No HARQ-ACK to mux"); + return SRSLTE_SUCCESS; + } else { + srslte_vec_u8_copy(q->bit_sequence, value->ack, cfg->o_ack); + } + + // Compute total of encoded bits according to 6.3.2.4 Rate matching + int E_uci = srslte_uci_nr_pusch_ack_nof_bits(&cfg->pusch, A); + if (E_uci < SRSLTE_SUCCESS) { + ERROR("Error calculating number of encoded bits"); + return SRSLTE_ERROR; + } + + return uci_nr_encode(q, cfg, A, o, E_uci); +} + +int srslte_uci_nr_decode_pusch_ack(srslte_uci_nr_t* q, + const srslte_uci_cfg_nr_t* cfg, + int8_t* llr, + srslte_uci_value_nr_t* value) +{ + int A = cfg->o_ack; + + // Check inputs + if (q == NULL || cfg == NULL || llr == NULL || value == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + // 6.3.2.1 UCI bit sequence generation + // 6.3.2.1.1 HARQ-ACK + bool has_csi_part2 = srslte_csi_has_part2(cfg->csi, cfg->nof_csi); + if (cfg->pusch.K_sum == 0 && cfg->nof_csi > 1 && !has_csi_part2 && cfg->o_ack < 2) { + A = 2; + } + + // Compute total of encoded bits according to 6.3.2.4 Rate matching + int E_uci = srslte_uci_nr_pusch_ack_nof_bits(&cfg->pusch, A); + if (E_uci < SRSLTE_SUCCESS) { + ERROR("Error calculating number of encoded bits"); + return SRSLTE_ERROR; + } + + // Decode + if (uci_nr_decode(q, cfg, llr, A, E_uci, &value->valid) < SRSLTE_SUCCESS) { + ERROR("Error decoding UCI"); + return SRSLTE_ERROR; + } + + // Unpack + srslte_vec_u8_copy(value->ack, q->bit_sequence, A); + + return SRSLTE_SUCCESS; +} + +static int uci_nr_pusch_Q_prime_csi1(const srslte_uci_nr_pusch_cfg_t* cfg, uint32_t O_csi1, uint32_t O_ack) +{ + if (cfg == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + uint32_t L_ack = srslte_uci_nr_crc_len(O_csi1); // Number of CRC bits + uint32_t Qm = srslte_mod_bits_x_symbol(cfg->modulation); // modulation order of the PUSCH + + int Q_prime_ack = uci_nr_pusch_Q_prime_ack(cfg, SRSLTE_MAX(2, O_ack)); + if (Q_prime_ack < SRSLTE_ERROR) { + ERROR("Calculating Q_prime_ack"); + return SRSLTE_ERROR; + } + + uint32_t M_uci_sum = 0; + for (uint32_t l = 0; l < SRSLTE_NSYMB_PER_SLOT_NR; l++) { + M_uci_sum += cfg->M_uci_sc[l]; + } + + if (!isnormal(cfg->R)) { + ERROR("Invalid Rate (%f)", cfg->R); + return SRSLTE_ERROR; + } + + if (cfg->K_sum == 0) { + if (cfg->csi_part2_present) { + return (int)SRSLTE_MIN(ceilf(((O_csi1 + L_ack) * cfg->beta_csi1_offset) / (Qm * cfg->R)), + cfg->alpha * M_uci_sum - Q_prime_ack); + } + return (int)(M_uci_sum - Q_prime_ack); + } + return (int)SRSLTE_MIN(ceilf(((O_csi1 + L_ack) * cfg->beta_csi1_offset * M_uci_sum) / cfg->K_sum), + ceilf(cfg->alpha * M_uci_sum) - Q_prime_ack); +} + +int srslte_uci_nr_pusch_csi1_nof_bits(const srslte_uci_cfg_nr_t* cfg) +{ + // Check inputs + if (cfg == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + int O_csi1 = srslte_csi_part1_nof_bits(cfg->csi, cfg->nof_csi); + if (O_csi1 < SRSLTE_SUCCESS) { + ERROR("Errpr calculating CSI part 1 number of bits"); + return SRSLTE_ERROR; + } + uint32_t O_ack = SRSLTE_MAX(2, cfg->o_ack); + + int Q_csi1_prime = uci_nr_pusch_Q_prime_csi1(&cfg->pusch, (uint32_t)O_csi1, O_ack); + if (Q_csi1_prime < SRSLTE_SUCCESS) { + ERROR("Error calculating number of RE"); + return Q_csi1_prime; + } + + return (int)(Q_csi1_prime * cfg->pusch.nof_layers * srslte_mod_bits_x_symbol(cfg->pusch.modulation)); +} + +int srslte_uci_nr_encode_pusch_csi1(srslte_uci_nr_t* q, + const srslte_uci_cfg_nr_t* cfg, + const srslte_uci_value_nr_t* value, + uint8_t* o) +{ + // Check inputs + if (q == NULL || cfg == NULL || value == NULL || o == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + int A = srslte_csi_part1_pack(cfg->csi, value->csi, cfg->nof_csi, q->bit_sequence, SRSLTE_UCI_NR_MAX_NOF_BITS); + if (A < SRSLTE_SUCCESS) { + ERROR("Error packing CSI part 1 report"); + return SRSLTE_ERROR; + } + + if (A == 0) { + UCI_NR_INFO_TX("No CSI part 1 to mux"); + return SRSLTE_SUCCESS; + } + + // Compute total of encoded bits according to 6.3.2.4 Rate matching + int E_uci = srslte_uci_nr_pusch_csi1_nof_bits(cfg); + if (E_uci < SRSLTE_SUCCESS) { + ERROR("Error calculating number of encoded bits"); + return SRSLTE_ERROR; + } + + return uci_nr_encode(q, cfg, A, o, E_uci); +} + +int srslte_uci_nr_decode_pusch_csi1(srslte_uci_nr_t* q, + const srslte_uci_cfg_nr_t* cfg, + int8_t* llr, + srslte_uci_value_nr_t* value) +{ + // Check inputs + if (q == NULL || cfg == NULL || llr == NULL || value == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + // Compute total of encoded bits according to 6.3.2.4 Rate matching + int E_uci = srslte_uci_nr_pusch_csi1_nof_bits(cfg); + if (E_uci < SRSLTE_SUCCESS) { + ERROR("Error calculating number of encoded bits"); + return SRSLTE_ERROR; + } + + int A = srslte_csi_part1_nof_bits(cfg->csi, cfg->nof_csi); + if (A < SRSLTE_SUCCESS) { + ERROR("Error getting number of CSI part 1 bits"); + return SRSLTE_ERROR; + } + + // Decode + if (uci_nr_decode(q, cfg, llr, (uint32_t)A, (uint32_t)E_uci, &value->valid) < SRSLTE_SUCCESS) { + ERROR("Error decoding UCI"); + return SRSLTE_ERROR; + } + + // Unpack + if (srslte_csi_part1_unpack(cfg->csi, cfg->nof_csi, q->bit_sequence, A, value->csi) < SRSLTE_SUCCESS) { + ERROR("Error unpacking CSI"); + return SRSLTE_ERROR; + } + + return SRSLTE_SUCCESS; +} \ No newline at end of file diff --git a/lib/src/phy/ue/ue_dl_nr.c b/lib/src/phy/ue/ue_dl_nr.c index ec389d175..aa0429cfa 100644 --- a/lib/src/phy/ue/ue_dl_nr.c +++ b/lib/src/phy/ue/ue_dl_nr.c @@ -583,8 +583,8 @@ static int ue_dl_nr_gen_ack_type2(const srslte_ue_dl_nr_harq_ack_cfg_t* cfg, } else { if (ack->present) { // Load ACK resource data into UCI info - uci_data->cfg.pucch_resource_id = ack_info->cc[c].m[m].resource.pucch_resource_id; - uci_data->cfg.rnti = ack_info->cc[c].m[m].resource.rnti; + uci_data->cfg.pucch.resource_id = ack_info->cc[c].m[m].resource.pucch_resource_id; + uci_data->cfg.pucch.rnti = ack_info->cc[c].m[m].resource.rnti; if (V_DL_CDAI <= V_temp) { j = j + 1; diff --git a/lib/src/phy/ue/ue_ul_nr.c b/lib/src/phy/ue/ue_ul_nr.c index a37ff5898..8fb4611a4 100644 --- a/lib/src/phy/ue/ue_ul_nr.c +++ b/lib/src/phy/ue/ue_ul_nr.c @@ -91,6 +91,11 @@ int srslte_ue_ul_nr_set_carrier(srslte_ue_ul_nr_t* q, const srslte_carrier_nr_t* return SRSLTE_ERROR; } + if (srslte_pucch_nr_set_carrier(&q->pucch, carrier) < SRSLTE_SUCCESS) { + ERROR("Setting PUSCH carrier"); + return SRSLTE_ERROR; + } + if (srslte_dmrs_sch_set_carrier(&q->dmrs, carrier)) { ERROR("Setting DMRS carrier"); return SRSLTE_ERROR; @@ -99,16 +104,13 @@ int srslte_ue_ul_nr_set_carrier(srslte_ue_ul_nr_t* q, const srslte_carrier_nr_t* return SRSLTE_SUCCESS; } -int srslte_ue_ul_nr_encode_pusch(srslte_ue_ul_nr_t* q, - const srslte_slot_cfg_t* slot_cfg, - const srslte_sch_cfg_nr_t* pusch_cfg, - uint8_t* data_) +int srslte_ue_ul_nr_encode_pusch(srslte_ue_ul_nr_t* q, + const srslte_slot_cfg_t* slot_cfg, + const srslte_sch_cfg_nr_t* pusch_cfg, + const srslte_pusch_data_nr_t* data) { - uint8_t* data[SRSLTE_MAX_TB] = {}; - data[0] = data_; - // Check inputs - if (q == NULL || pusch_cfg == NULL || data_ == NULL) { + if (q == NULL || pusch_cfg == NULL || data == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } @@ -167,7 +169,7 @@ static int ue_ul_nr_encode_pucch_format1(srslte_ue_ul_nr_t* q, return SRSLTE_ERROR; } - return srslte_pucch_nr_format1_encode(&q->pucch, &q->carrier, cfg, slot, resource, b, nof_bits, q->sf_symbols[0]); + return srslte_pucch_nr_format1_encode(&q->pucch, cfg, slot, resource, b, nof_bits, q->sf_symbols[0]); } int srslte_ue_ul_nr_encode_pucch(srslte_ue_ul_nr_t* q, @@ -201,7 +203,7 @@ int srslte_ue_ul_nr_encode_pucch(srslte_ue_ul_nr_t* q, return SRSLTE_ERROR; } if (srslte_pucch_nr_format_2_3_4_encode( - &q->pucch, &q->carrier, cfg, slot_cfg, resource, &uci_data->cfg, &uci_data->value, q->sf_symbols[0]) < + &q->pucch, cfg, slot_cfg, resource, &uci_data->cfg, &uci_data->value, q->sf_symbols[0]) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index 45c6229f4..b050efc7f 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -20,6 +20,7 @@ */ #include "srslte/radio/radio.h" +#include "srslte/common/standard_streams.h" #include "srslte/common/string_helpers.h" #include "srslte/config.h" #include @@ -297,10 +298,13 @@ bool radio::rx_now(rf_buffer_interface& buffer, rf_timestamp_interface& rxd_time if (ratio > 1 && nof_samples > rx_buffer[0].size()) { // This is a corner case that could happen during sample rate change transitions, as it does not have a negative // impact, log it as info. - logger.info(fmt::format("Rx number of samples ({}/{}) exceeds buffer size ({})\n", - buffer.get_nof_samples(), - buffer.get_nof_samples() * ratio, - rx_buffer[0].size())); + fmt::memory_buffer buff; + fmt::format_to(buff, + "Rx number of samples ({}/{}) exceeds buffer size ({})", + buffer.get_nof_samples(), + buffer.get_nof_samples() * ratio, + rx_buffer[0].size()); + logger.info("%s", to_c_str(buff)); // Limit number of samples to receive nof_samples = rx_buffer[0].size(); @@ -415,10 +419,13 @@ bool radio::tx(rf_buffer_interface& buffer, const rf_timestamp_interface& tx_tim if (ratio > 1 && nof_samples * ratio > tx_buffer[0].size()) { // This is a corner case that could happen during sample rate change transitions, as it does not have a negative // impact, log it as info. - logger.info(fmt::format("Tx number of samples ({}/{}) exceeds buffer size ({})\n", - buffer.get_nof_samples(), - buffer.get_nof_samples() * ratio, - tx_buffer[0].size())); + fmt::memory_buffer buff; + fmt::format_to(buff, + "Tx number of samples ({}/{}) exceeds buffer size ({})\n", + buffer.get_nof_samples(), + buffer.get_nof_samples() * ratio, + tx_buffer[0].size()); + logger.info("%s", to_c_str(buff)); // Limit number of samples to transmit nof_samples = tx_buffer[0].size() / ratio; diff --git a/lib/src/srslog/backend_worker.cpp b/lib/src/srslog/backend_worker.cpp index c8a5f992e..909f378ea 100644 --- a/lib/src/srslog/backend_worker.cpp +++ b/lib/src/srslog/backend_worker.cpp @@ -97,14 +97,11 @@ void backend_worker::process_log_entry(detail::log_entry&& entry) return; } - fmt::memory_buffer fmt_buffer; - assert(entry.format_func && "Invalid format function"); + fmt_buffer.clear(); entry.format_func(std::move(entry.metadata), fmt_buffer); - const auto str = fmt::to_string(fmt_buffer); - detail::memory_buffer buffer(str); - if (auto err_str = entry.s->write(buffer)) { + if (auto err_str = entry.s->write({fmt_buffer.data(), fmt_buffer.size()})) { err_handler(err_str.get_error()); } } diff --git a/lib/src/srslog/backend_worker.h b/lib/src/srslog/backend_worker.h index ffa8a6212..ea8ab463b 100644 --- a/lib/src/srslog/backend_worker.h +++ b/lib/src/srslog/backend_worker.h @@ -120,6 +120,7 @@ private: }; std::once_flag start_once_flag; std::thread worker_thread; + fmt::memory_buffer fmt_buffer; }; } // namespace srslog diff --git a/lib/src/srslog/event_trace.cpp b/lib/src/srslog/event_trace.cpp index 7f7ced5a9..3479a9169 100644 --- a/lib/src/srslog/event_trace.cpp +++ b/lib/src/srslog/event_trace.cpp @@ -20,6 +20,7 @@ */ #include "srslte/srslog/event_trace.h" +#include "sinks/single_write_file_sink.h" #include "srslte/srslog/srslog.h" #include @@ -32,6 +33,9 @@ using namespace srslog; /// Log channel where event traces will get sent. static log_channel* tracer = nullptr; +/// Tracer sink name. +static constexpr char sink_name[] = "srslog_trace_sink"; + void srslog::event_trace_init() { // Nothing to do if the user previously set a custom channel or this is not @@ -59,6 +63,30 @@ void srslog::event_trace_init(log_channel& c) } } +bool srslog::event_trace_init(const std::string& filename, std::size_t capacity) +{ + // Nothing to do if the user previously set a custom channel or this is not + // the first time this function is called. + if (tracer) { + return false; + } + + auto tracer_sink = std::unique_ptr(new single_write_file_sink( + filename, capacity, get_default_log_formatter())); + if (!install_custom_sink(sink_name, std::move(tracer_sink))) { + return false; + } + + if (sink* s = find_sink(sink_name)) { + log_channel& c = + fetch_log_channel("event_trace_channel", *s, {"TRACE", '\0', false}); + tracer = &c; + return true; + } + + return false; +} + /// Fills in the input buffer with the current time. static void format_time(char* buffer, size_t len) { @@ -113,10 +141,7 @@ srslog::detail::scoped_complete_event::~scoped_complete_event() std::chrono::duration_cast(end - start) .count(); - char fmt_time[24]; - format_time(fmt_time, sizeof(fmt_time)); - (*tracer)("[%s] [TID:%0u] Complete event \"%s\" (duration %lld us): %s", - fmt_time, + (*tracer)("[TID:%0u] Complete event \"%s\" (duration %lld us): %s", (unsigned)::pthread_self(), category, diff, diff --git a/lib/src/srslog/formatters/json_formatter.cpp b/lib/src/srslog/formatters/json_formatter.cpp index f99179392..83a3a8dd6 100644 --- a/lib/src/srslog/formatters/json_formatter.cpp +++ b/lib/src/srslog/formatters/json_formatter.cpp @@ -58,7 +58,7 @@ void json_formatter::format_context_begin(const detail::log_entry_metadata& md, fmt::format_to(buffer, "{{\n"); push_scope(size); - if (!md.fmtstring.empty()) { + if (md.fmtstring) { fmt::format_to(buffer, " \"log_entry\": \"{}\",\n", fmt::vsprintf(md.fmtstring, std::move(md.store))); diff --git a/lib/src/srslog/formatters/text_formatter.cpp b/lib/src/srslog/formatters/text_formatter.cpp index 58244887f..339d53e48 100644 --- a/lib/src/srslog/formatters/text_formatter.cpp +++ b/lib/src/srslog/formatters/text_formatter.cpp @@ -99,13 +99,16 @@ void text_formatter::format_context_begin(const detail::log_entry_metadata& md, unsigned size, fmt::memory_buffer& buffer) { - do_one_line_ctx_format = !md.fmtstring.empty(); + // Entries without a log message are printed using a richer format. + do_one_line_ctx_format = md.fmtstring; format_metadata(md, buffer); if (do_one_line_ctx_format) { + assert(scope_stack.empty() && "Stack should be empty"); fmt::format_to(buffer, "["); return; } + fmt::format_to(buffer, "Context dump for \"{}\"\n", ctx_name); } @@ -113,10 +116,12 @@ void text_formatter::format_context_end(const detail::log_entry_metadata& md, const std::string& ctx_name, fmt::memory_buffer& buffer) { - if (do_one_line_ctx_format) { - fmt::format_to(buffer, "]: {}\n", fmt::vsprintf(md.fmtstring, md.store)); + if (!do_one_line_ctx_format) { return; } + + fmt::format_to(buffer, "]: {}\n", fmt::vsprintf(md.fmtstring, md.store)); + assert(scope_stack.empty() && "Stack should be empty"); } void text_formatter::format_metric_set_begin(const std::string& set_name, @@ -124,21 +129,26 @@ void text_formatter::format_metric_set_begin(const std::string& set_name, unsigned level, fmt::memory_buffer& buffer) { - /*if (do_one_line_ctx_format) { - fmt::format_to(buffer, "{}", is_first ? "[" : " ["); + if (do_one_line_ctx_format) { + scope_stack.emplace_back(size, set_name); + fmt::format_to(buffer, "["); return; } - fmt::format_to(buffer, " {}\n", set_name);*/ + + fmt::format_to( + buffer, "{: <{}}> Set: {}\n", ' ', get_indents(level), set_name); } void text_formatter::format_metric_set_end(const std::string& set_name, unsigned level, fmt::memory_buffer& buffer) { - if (do_one_line_ctx_format) { - fmt::format_to(buffer, "]"); + if (!do_one_line_ctx_format) { return; } + + scope_stack.pop_back(); + fmt::format_to(buffer, "]"); } void text_formatter::format_metric(const std::string& metric_name, @@ -148,22 +158,37 @@ void text_formatter::format_metric(const std::string& metric_name, unsigned level, fmt::memory_buffer& buffer) { - //:TODO: re-enable - /*if (do_one_line_ctx_format) { + if (do_one_line_ctx_format) { + consume_element(); fmt::format_to(buffer, - "{}{}_{}: {}{}{}", - ctx.is_first_metric ? "" : ", ", - ctx.set_name, - ctx.metric_name, - ctx.metric_value, - ctx.metric_units.empty() ? "" : " ", - ctx.metric_units); + "{}_{}: {}{}{}{}", + get_current_set_name(), + metric_name, + metric_value, + metric_units.empty() ? "" : " ", + metric_units, + needs_comma() ? ", " : ""); return; } + fmt::format_to(buffer, - " {}: {}{}{}\n", - ctx.metric_name, - ctx.metric_value, - ctx.metric_units.empty() ? "" : " ", - ctx.metric_units);*/ + "{: <{}}{}: {}{}{}\n", + ' ', + get_indents(level), + metric_name, + metric_value, + metric_units.empty() ? "" : " ", + metric_units); +} + +void text_formatter::format_list_begin(const std::string& list_name, + unsigned size, + unsigned level, + fmt::memory_buffer& buffer) +{ + if (do_one_line_ctx_format) { + return; + } + fmt::format_to( + buffer, "{: <{}}> List: {}\n", ' ', get_indents(level), list_name); } diff --git a/lib/src/srslog/formatters/text_formatter.h b/lib/src/srslog/formatters/text_formatter.h index 83e19ec56..0118a7078 100644 --- a/lib/src/srslog/formatters/text_formatter.h +++ b/lib/src/srslog/formatters/text_formatter.h @@ -27,11 +27,11 @@ namespace srslog { /// Plain text formatter implementation class. -//:TODO: this class needs refactoring to be compatible with multiple nesting of -// metrics. class text_formatter : public log_formatter { public: + text_formatter() { scope_stack.reserve(16); } + std::unique_ptr clone() const override; void format(detail::log_entry_metadata&& metadata, @@ -59,17 +59,12 @@ private: void format_list_begin(const std::string& list_name, unsigned size, unsigned level, - fmt::memory_buffer& buffer) override - { - //:TODO: implement me - } + fmt::memory_buffer& buffer) override; void format_list_end(const std::string& list_name, unsigned level, fmt::memory_buffer& buffer) override - { - //:TODO: implement me - } + {} void format_metric(const std::string& metric_name, const std::string& metric_value, @@ -78,9 +73,47 @@ private: unsigned level, fmt::memory_buffer& buffer) override; + /// Returns the set name of current scope. + const std::string& get_current_set_name() const + { + assert(!scope_stack.empty() && "Empty scope stack"); + return scope_stack.back().set_name; + } + + /// Consumes an element in the current scope. + void consume_element() + { + assert(!scope_stack.empty() && "Consuming element in void scope"); + assert(scope_stack.back().size && "No more elements to consume"); + --scope_stack.back().size; + } + + /// Returns true if the current element needs a comma. + bool needs_comma() const + { + assert(!scope_stack.empty() && "No scope exists"); + return scope_stack.back().size; + } + + /// Returns the number of indentations required for the input nesting level. + unsigned get_indents(unsigned level) const { return level * 2; } + +private: + /// Keeps track of some state required for formatting. + struct scope { + scope(unsigned size, std::string set_name) : + size(size), set_name(std::move(set_name)) + {} + /// Number of elements this scope holds. + unsigned size; + /// Set name in this scope. + std::string set_name; + }; + private: /// Flags that the formatting should take place into a single line. bool do_one_line_ctx_format = false; + std::vector scope_stack; }; } // namespace srslog diff --git a/lib/src/srslog/sinks/file_sink.h b/lib/src/srslog/sinks/file_sink.h index 935ceaacb..c91b8421c 100644 --- a/lib/src/srslog/sinks/file_sink.h +++ b/lib/src/srslog/sinks/file_sink.h @@ -37,8 +37,8 @@ public: size_t max_size, std::unique_ptr f) : sink(std::move(f)), - base_filename(std::move(name)), - max_size((max_size == 0) ? 0 : std::max(max_size, 4 * 1024)) + max_size((max_size == 0) ? 0 : std::max(max_size, 4 * 1024)), + base_filename(std::move(name)) {} file_sink(const file_sink& other) = delete; diff --git a/lib/src/srslog/sinks/single_write_file_sink.h b/lib/src/srslog/sinks/single_write_file_sink.h new file mode 100644 index 000000000..37485e9e0 --- /dev/null +++ b/lib/src/srslog/sinks/single_write_file_sink.h @@ -0,0 +1,90 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 SRSLOG_SINGLE_WRITE_FILE_SINK_H +#define SRSLOG_SINGLE_WRITE_FILE_SINK_H + +#include "file_utils.h" +#include "srslte/srslog/sink.h" + +namespace srslog { + +/// This class is a wrapper of a file handle that stores the input data into an +/// internal buffer and writes its contents to the file once the buffer is full +/// or in object destruction. +class single_write_file_sink : public sink +{ +public: + single_write_file_sink(std::string filename, + std::size_t capacity, + std::unique_ptr f) : + sink(std::move(f)), filename(std::move(filename)) + { + buffer.reserve(capacity); + } + + ~single_write_file_sink() override + { + if (!is_written) { + write_contents(); + } + } + + single_write_file_sink(const single_write_file_sink& other) = delete; + single_write_file_sink& + operator=(const single_write_file_sink& other) = delete; + + detail::error_string write(detail::memory_buffer input_buffer) override + { + // Nothing to do when the contents have been already written. + if (is_written) { + return {}; + } + + if (has_room_for(input_buffer.size())) { + buffer.insert(buffer.end(), input_buffer.begin(), input_buffer.end()); + return {}; + } + + return write_contents(); + } + + detail::error_string flush() override { return handler.flush(); } + +private: + /// Returns true if the internal buffer has room for the specified input size, + /// otherwise returns false. + bool has_room_for(std::size_t s) const + { + return s + buffer.size() < buffer.capacity(); + } + + /// Writes the buffer contents into the file. + detail::error_string write_contents() + { + is_written = true; + if (auto err_str = handler.create(filename)) { + return err_str; + } + return handler.write(detail::memory_buffer(buffer.data(), buffer.size())); + } + +private: + const std::string filename; + file_utils::file handler; + std::vector buffer; + bool is_written = false; +}; + +} // namespace srslog + +#endif // SRSLOG_SINGLE_WRITE_FILE_SINK_H diff --git a/lib/src/upper/gtpu.cc b/lib/src/upper/gtpu.cc index 6d8182567..4a607d3da 100644 --- a/lib/src/upper/gtpu.cc +++ b/lib/src/upper/gtpu.cc @@ -187,7 +187,7 @@ bool gtpu_read_header(srslte::byte_buffer_t* pdu, gtpu_header_t* header, srslog: } // Helper function to return a string from IPv4 address for easy printing -std::string gtpu_ntoa(uint32_t addr) +void gtpu_ntoa(fmt::memory_buffer& buffer, uint32_t addr) { char tmp_str[INET_ADDRSTRLEN + 1] = {}; struct in_addr tmp_addr = {}; @@ -195,9 +195,10 @@ std::string gtpu_ntoa(uint32_t addr) tmp_addr.s_addr = addr; const char* tmp_ptr = inet_ntop(AF_INET, &tmp_addr, tmp_str, INET_ADDRSTRLEN); if (tmp_ptr == NULL) { - return std::string("Invalid IPv4 address"); + fmt::format_to(buffer, "Invalid IPv4 address"); + } else { + fmt::format_to(buffer, "{}", tmp_str); } - return std::string(tmp_str); } } // namespace srslte diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index 68cffb55c..eed81842d 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -246,7 +246,7 @@ bool pdcp::set_bearer_state(uint32_t lcid, const srslte::pdcp_lte_state_t& state if (not valid_lcid(lcid)) { return false; } - pdcp_array[lcid]->set_bearer_state(state); + pdcp_array[lcid]->set_bearer_state(state, true); return true; } @@ -294,7 +294,7 @@ void pdcp::write_pdu_mch(uint32_t lcid, unique_byte_buffer_t sdu) } } -void pdcp::notify_delivery(uint32_t lcid, const std::vector& pdcp_sns) +void pdcp::notify_delivery(uint32_t lcid, const pdcp_sn_vector_t& pdcp_sns) { if (valid_lcid(lcid)) { pdcp_array.at(lcid)->notify_delivery(pdcp_sns); @@ -303,7 +303,7 @@ void pdcp::notify_delivery(uint32_t lcid, const std::vector& pdcp_sns) } } -void pdcp::notify_failure(uint32_t lcid, const std::vector& pdcp_sns) +void pdcp::notify_failure(uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sns) { if (valid_lcid(lcid)) { pdcp_array.at(lcid)->notify_failure(pdcp_sns); diff --git a/lib/src/upper/pdcp_entity_lte.cc b/lib/src/upper/pdcp_entity_lte.cc index 155ed03e7..a5716df36 100644 --- a/lib/src/upper/pdcp_entity_lte.cc +++ b/lib/src/upper/pdcp_entity_lte.cc @@ -22,6 +22,7 @@ #include "srslte/upper/pdcp_entity_lte.h" #include "srslte/common/int_helpers.h" #include "srslte/common/security.h" +#include "srslte/common/standard_streams.h" #include "srslte/interfaces/ue_gw_interfaces.h" #include "srslte/interfaces/ue_rlc_interfaces.h" #include @@ -82,6 +83,7 @@ pdcp_entity_lte::pdcp_entity_lte(srsue::rlc_interface_pdcp* rlc_, if (is_drb() and not rlc->rb_is_um(lcid)) { undelivered_sdus = std::unique_ptr(new undelivered_sdus_queue(task_sched)); + rx_counts_info.reserve(reordering_window); } // Check supported config @@ -412,10 +414,65 @@ void pdcp_entity_lte::handle_am_drb_pdu(srslte::unique_byte_buffer_t pdu) // Update info on last PDU submitted to upper layers st.last_submitted_pdcp_rx_sn = sn; + // Store Rx SN/COUNT + update_rx_counts_queue(count); + // Pass to upper layers gw->write_pdu(lcid, std::move(pdu)); } +void pdcp_entity_lte::update_rx_counts_queue(uint32_t rx_count) +{ + if (rx_count < fmc) { + return; + } + + // Update largest RX_COUNT + if (rx_count > largest_rx_count) { + largest_rx_count = rx_count; + } + + // The received COUNT is the first missing COUNT + if (rx_count == fmc) { + fmc++; + // Update the queue for the Status report bitmap, if first missing count changed + while (not rx_counts_info.empty() && rx_counts_info.back() == fmc) { + rx_counts_info.pop_back(); + fmc++; + } + } else { + rx_counts_info.push_back(rx_count); + std::sort(rx_counts_info.begin(), rx_counts_info.end(), std::greater()); + } + + // If the size of the rx_vector_info is getting very large + // Consider the FMC as lost and update the vector. + if (rx_counts_info.size() > reordering_window) { + logger.debug("Queue too large. Updating. Old FMC=%d, Old back=%d, old queue_size=%d", + fmc, + rx_counts_info.back(), + rx_counts_info.size()); + fmc = rx_counts_info.back(); + while (not rx_counts_info.empty() && rx_counts_info.back() == fmc) { + rx_counts_info.pop_back(); + fmc++; + } + logger.debug("Queue too large. Updating. New FMC=%d, new back=%d, new queue_size=%d", + fmc, + rx_counts_info.back(), + rx_counts_info.size()); + } + + if (rx_counts_info.empty()) { + logger.info("Updated RX_COUNT info with SDU COUNT=%d, queue_size=%d, FMC=%d", rx_count, rx_counts_info.size(), fmc); + } else { + logger.info("Updated RX_COUNT info with SDU COUNT=%d, queue_size=%d, FMC=%d, back=%d", + rx_count, + rx_counts_info.size(), + fmc, + rx_counts_info.back()); + } +} /**************************************************************************** * Control handler functions (Status Report) * Ref: 3GPP TS 36.323 v10.1.0 Section 5.1.3 @@ -442,15 +499,10 @@ void pdcp_entity_lte::send_status_report() } // Get First Missing Segment (FMS) - uint32_t fms = 0; - if (undelivered_sdus->empty()) { - fms = st.next_pdcp_tx_sn; - } else { - fms = undelivered_sdus->get_fms(); - } + uint32_t fms = SN(fmc); // Get Last Missing Segment - uint32_t lms = undelivered_sdus->get_lms(); + uint32_t nof_sns_in_bitmap = rx_counts_info.size(); // Allocate Status Report PDU unique_byte_buffer_t pdu = make_byte_buffer(); @@ -459,7 +511,7 @@ void pdcp_entity_lte::send_status_report() return; } - logger.debug("Status report: FMS=%d, LMS=%d", fms, lms); + logger.debug("Status report: FMS=%d, Nof SNs in bitmap=%d", fms, nof_sns_in_bitmap); // Set control bit and type of PDU pdu->msg[0] = ((uint8_t)PDCP_DC_FIELD_CONTROL_PDU << 7) | ((uint8_t)PDCP_PDU_TYPE_STATUS_REPORT << 4); @@ -482,33 +534,29 @@ void pdcp_entity_lte::send_status_report() } // Add bitmap of missing PDUs, if necessary - if (not undelivered_sdus->empty()) { + if (not rx_counts_info.empty()) { // First check size of bitmap - int32_t diff = lms - (fms - 1); + int32_t diff = largest_rx_count - (fmc - 1); uint32_t nof_sns = 1u << cfg.sn_len; - if (diff > (int32_t)(nof_sns / 2)) { - logger.info("FMS and LMS are very far apart. Not generating status report. LMS=%d FMS=%d", lms, fms); + if (diff < 0) { + logger.info("FMS and LMS are very far apart. Not generating status report. Largest RX COUNT=%d FMS=%d", + largest_rx_count, + fms); return; } - if (diff <= 0 && diff > -((int32_t)(nof_sns / 2))) { - logger.info("FMS and LMS are very far apart. Not generating status report. LMS=%d FMS=%d", lms, fms); - return; - } - uint32_t sn_diff = (diff > 0) ? diff : nof_sns + diff; - uint32_t bitmap_sz = std::ceil((float)(sn_diff) / 8); + uint32_t bitmap_sz = std::ceil((float)(diff) / 8); memset(&pdu->msg[pdu->N_bytes], 0, bitmap_sz); logger.debug( "Setting status report bitmap. Last missing SN=%d, Last SN acked in sequence=%d, Bitmap size in bytes=%d", - lms, + largest_rx_count, fms - 1, bitmap_sz); - for (uint32_t offset = 0; offset < sn_diff; ++offset) { - uint32_t sn = (fms + 1 + offset) % (1u << cfg.sn_len); - if (undelivered_sdus->has_sdu(sn)) { - uint32_t bit_offset = offset % 8; - uint32_t byte_offset = offset / 8; - pdu->msg[pdu->N_bytes + byte_offset] |= 1 << (7 - bit_offset); - } + for (uint32_t rx_count : rx_counts_info) { + logger.debug("Setting bitmap for RX_COUNT=%d", rx_count); + uint32_t offset = rx_count - (fmc + 1); + uint32_t bit_offset = offset % 8; + uint32_t byte_offset = offset / 8; + pdu->msg[pdu->N_bytes + byte_offset] |= 1 << (7 - bit_offset); } pdu->N_bytes += bitmap_sz; } @@ -583,6 +631,7 @@ void pdcp_entity_lte::handle_status_report_pdu(unique_byte_buffer_t pdu) undelivered_sdus->clear_sdu(sn); } } + /**************************************************************************** * TX PDUs Queue Helper ***************************************************************************/ @@ -661,7 +710,7 @@ void pdcp_entity_lte::discard_callback::operator()(uint32_t timer_id) /**************************************************************************** * Handle delivery/failure notifications from RLC ***************************************************************************/ -void pdcp_entity_lte::notify_delivery(const std::vector& pdcp_sns) +void pdcp_entity_lte::notify_delivery(const pdcp_sn_vector_t& pdcp_sns) { if (not is_drb()) { return; @@ -691,7 +740,7 @@ void pdcp_entity_lte::notify_delivery(const std::vector& pdcp_sns) } } -void pdcp_entity_lte::notify_failure(const std::vector& pdcp_sns) +void pdcp_entity_lte::notify_failure(const pdcp_sn_vector_t& pdcp_sns) { if (not is_drb()) { return; @@ -746,9 +795,12 @@ void pdcp_entity_lte::get_bearer_state(pdcp_lte_state_t* state) *state = st; } -void pdcp_entity_lte::set_bearer_state(const pdcp_lte_state_t& state) +void pdcp_entity_lte::set_bearer_state(const pdcp_lte_state_t& state, bool set_fmc) { st = state; + if (set_fmc) { + fmc = COUNT(st.rx_hfn, st.last_submitted_pdcp_rx_sn); + } } std::map pdcp_entity_lte::get_buffered_pdus() @@ -791,10 +843,10 @@ undelivered_sdus_queue::undelivered_sdus_queue(srslte::task_sched_handle task_sc } } -bool undelivered_sdus_queue::add_sdu(uint32_t sn, - const srslte::unique_byte_buffer_t& sdu, - uint32_t discard_timeout, - const std::function& callback) +bool undelivered_sdus_queue::add_sdu(uint32_t sn, + const srslte::unique_byte_buffer_t& sdu, + uint32_t discard_timeout, + srslte::move_callback callback) { assert(not has_sdu(sn) && "Cannot add repeated SNs"); @@ -833,7 +885,7 @@ bool undelivered_sdus_queue::add_sdu(uint32_t sn, sdus[sn].sdu->N_bytes = sdu->N_bytes; memcpy(sdus[sn].sdu->msg, sdu->msg, sdu->N_bytes); if (discard_timeout > 0) { - sdus[sn].discard_timer.set(discard_timeout, callback); + sdus[sn].discard_timer.set(discard_timeout, std::move(callback)); sdus[sn].discard_timer.run(); } sdus[sn].sdu->set_timestamp(); // Metrics diff --git a/lib/src/upper/pdcp_entity_nr.cc b/lib/src/upper/pdcp_entity_nr.cc index 7aee3e3ba..82d684156 100644 --- a/lib/src/upper/pdcp_entity_nr.cc +++ b/lib/src/upper/pdcp_entity_nr.cc @@ -212,12 +212,12 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu) } // Notification of delivery/failure -void pdcp_entity_nr::notify_delivery(const std::vector& pdcp_sns) +void pdcp_entity_nr::notify_delivery(const pdcp_sn_vector_t& pdcp_sns) { logger.debug("Received delivery notification from RLC. Nof SNs=%ld", pdcp_sns.size()); } -void pdcp_entity_nr::notify_failure(const std::vector& pdcp_sns) +void pdcp_entity_nr::notify_failure(const pdcp_sn_vector_t& pdcp_sns) { logger.debug("Received failure notification from RLC. Nof SNs=%ld", pdcp_sns.size()); } @@ -295,7 +295,7 @@ void pdcp_entity_nr::get_bearer_state(pdcp_lte_state_t* state) // TODO } -void pdcp_entity_nr::set_bearer_state(const pdcp_lte_state_t& state) +void pdcp_entity_nr::set_bearer_state(const pdcp_lte_state_t& state, bool set_fmc) { // TODO } diff --git a/lib/src/upper/rlc_am_lte.cc b/lib/src/upper/rlc_am_lte.cc index cafc775d0..55d64e08e 100644 --- a/lib/src/upper/rlc_am_lte.cc +++ b/lib/src/upper/rlc_am_lte.cc @@ -20,9 +20,10 @@ */ #include "srslte/upper/rlc_am_lte.h" +#include "srslte/common/string_helpers.h" #include "srslte/interfaces/ue_pdcp_interfaces.h" #include "srslte/interfaces/ue_rrc_interfaces.h" - +#include "srslte/srslog/event_trace.h" #include #define MOD 1024 @@ -33,6 +34,42 @@ namespace srslte { +/******************************* + * Helper methods + ******************************/ + +/** + * Logs Status PDU into provided log channel, using fmt_str as format string + */ +template +void log_rlc_am_status_pdu_to_string(srslog::log_channel& log_ch, + const char* fmt_str, + rlc_status_pdu_t* status, + Args&&... args) +{ + if (not log_ch.enabled()) { + return; + } + fmt::memory_buffer buffer; + fmt::format_to(buffer, "ACK_SN = {}, N_nack = {}", status->ack_sn, status->N_nack); + if (status->N_nack > 0) { + fmt::format_to(buffer, ", NACK_SN = "); + for (uint32_t i = 0; i < status->N_nack; ++i) { + if (status->nacks[i].has_so) { + fmt::format_to( + buffer, "[{} {}:{}]", status->nacks[i].nack_sn, status->nacks[i].so_start, status->nacks[i].so_end); + } else { + fmt::format_to(buffer, "[{}]", status->nacks[i].nack_sn); + } + } + } + log_ch(fmt_str, std::forward(args)..., to_c_str(buffer)); +} + +/******************************* + * rlc_am_lte class + ******************************/ + rlc_am_lte::rlc_am_lte(srslog::basic_logger& logger, uint32_t lcid_, srsue::pdcp_interface_rlc* pdcp_, @@ -182,13 +219,10 @@ rlc_am_lte::rlc_am_lte_tx::rlc_am_lte_tx(rlc_am_lte* parent_) : poll_retx_timer(parent_->timers->get_unique_timer()), status_prohibit_timer(parent_->timers->get_unique_timer()) { - pthread_mutex_init(&mutex, NULL); - notify_info_vec.reserve(RLC_AM_WINDOW_SIZE); } rlc_am_lte::rlc_am_lte_tx::~rlc_am_lte_tx() { - pthread_mutex_destroy(&mutex); } void rlc_am_lte::rlc_am_lte_tx::set_bsr_callback(bsr_callback_t callback) @@ -198,7 +232,14 @@ void rlc_am_lte::rlc_am_lte_tx::set_bsr_callback(bsr_callback_t callback) bool rlc_am_lte::rlc_am_lte_tx::configure(const rlc_config_t& cfg_) { - // TODO: add config checks + if (cfg_.tx_queue_length > MAX_SDUS_PER_RLC_PDU) { + logger.error("Configuring Tx queue length of %d PDUs too big. Maximum value is %d.", + cfg_.tx_queue_length, + MAX_SDUS_PER_RLC_PDU); + return false; + } + + // TODO: add more config checks cfg = cfg_.am; // check timers @@ -228,7 +269,7 @@ void rlc_am_lte::rlc_am_lte_tx::stop() { empty_queue(); - pthread_mutex_lock(&mutex); + std::lock_guard lock(mutex); tx_enabled = false; @@ -256,13 +297,11 @@ void rlc_am_lte::rlc_am_lte_tx::stop() // Drop all SDU info in queue undelivered_sdu_info_queue.clear(); - - pthread_mutex_unlock(&mutex); } void rlc_am_lte::rlc_am_lte_tx::empty_queue() { - pthread_mutex_lock(&mutex); + std::lock_guard lock(mutex); // deallocate all SDUs in transmit queue while (tx_sdu_queue.size() > 0) { @@ -271,8 +310,6 @@ void rlc_am_lte::rlc_am_lte_tx::empty_queue() // deallocate SDU that is currently processed tx_sdu.reset(); - - pthread_mutex_unlock(&mutex); } void rlc_am_lte::rlc_am_lte_tx::reestablish() @@ -316,7 +353,7 @@ void rlc_am_lte::rlc_am_lte_tx::check_sn_reached_max_retx(uint32_t sn) uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state() { - pthread_mutex_lock(&mutex); + std::lock_guard lock(mutex); uint32_t n_bytes = 0; uint32_t n_sdus = 0; @@ -375,22 +412,19 @@ uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state() logger.debug("%s Total buffer state - %d SDUs (%d B)", RB_NAME, n_sdus, n_bytes); } - pthread_mutex_unlock(&mutex); return n_bytes; } int rlc_am_lte::rlc_am_lte_tx::write_sdu(unique_byte_buffer_t sdu) { - pthread_mutex_lock(&mutex); + std::lock_guard lock(mutex); if (!tx_enabled) { - pthread_mutex_unlock(&mutex); return SRSLTE_ERROR; } if (sdu.get() == nullptr) { logger.warning("NULL SDU pointer in write_sdu()"); - pthread_mutex_unlock(&mutex); return SRSLTE_ERROR; } @@ -411,7 +445,6 @@ int rlc_am_lte::rlc_am_lte_tx::write_sdu(unique_byte_buffer_t sdu) RB_NAME, ret.error()->N_bytes, tx_sdu_queue.size()); - pthread_mutex_unlock(&mutex); return SRSLTE_ERROR; } @@ -421,12 +454,10 @@ int rlc_am_lte::rlc_am_lte_tx::write_sdu(unique_byte_buffer_t sdu) if (undelivered_sdu_info_queue.has_pdcp_sn(sdu_pdcp_sn)) { logger.error("PDCP SDU info already exists. SN=%d", sdu_pdcp_sn); - pthread_mutex_unlock(&mutex); return SRSLTE_ERROR; } undelivered_sdu_info_queue.add_pdcp_sdu(sdu_pdcp_sn); - pthread_mutex_unlock(&mutex); return SRSLTE_SUCCESS; } @@ -445,12 +476,10 @@ bool rlc_am_lte::rlc_am_lte_tx::sdu_queue_is_full() int rlc_am_lte::rlc_am_lte_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes) { - pthread_mutex_lock(&mutex); - - int pdu_size = 0; + std::lock_guard lock(mutex); if (not tx_enabled) { - goto unlock_and_exit; + return 0; } logger.debug("MAC opportunity - %d bytes", nof_bytes); @@ -458,13 +487,12 @@ int rlc_am_lte::rlc_am_lte_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes) if (not tx_enabled) { logger.debug("RLC entity not active. Not generating PDU."); - goto unlock_and_exit; + return 0; } // Tx STATUS if requested if (do_status() && not status_prohibit_timer.is_running()) { - pdu_size = build_status_pdu(payload, nof_bytes); - goto unlock_and_exit; + return build_status_pdu(payload, nof_bytes); } // Section 5.2.2.3 in TS 36.311, if tx_window is full and retx_queue empty, retransmit PDU @@ -474,23 +502,19 @@ int rlc_am_lte::rlc_am_lte_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes) // RETX if required if (not retx_queue.empty()) { - pdu_size = build_retx_pdu(payload, nof_bytes); + int32_t pdu_size = build_retx_pdu(payload, nof_bytes); if (pdu_size > 0) { - goto unlock_and_exit; + return pdu_size; } } // Build a PDU from SDUs - pdu_size = build_data_pdu(payload, nof_bytes); - -unlock_and_exit: - pthread_mutex_unlock(&mutex); - return pdu_size; + return build_data_pdu(payload, nof_bytes); } void rlc_am_lte::rlc_am_lte_tx::timer_expired(uint32_t timeout_id) { - pthread_mutex_lock(&mutex); + std::unique_lock lock(mutex); if (poll_retx_timer.is_valid() && poll_retx_timer.id() == timeout_id) { logger.debug("%s Poll reTx timer expired after %dms", RB_NAME, poll_retx_timer.duration()); // Section 5.2.2.3 in TS 36.311, schedule PDU for retransmission if @@ -500,7 +524,8 @@ void rlc_am_lte::rlc_am_lte_tx::timer_expired(uint32_t timeout_id) retransmit_pdu(); } } - pthread_mutex_unlock(&mutex); + + lock.unlock(); if (bsr_callback) { bsr_callback(parent->lcid, get_buffer_state(), 0); @@ -571,9 +596,9 @@ bool rlc_am_lte::rlc_am_lte_tx::poll_required() int rlc_am_lte::rlc_am_lte_tx::build_status_pdu(uint8_t* payload, uint32_t nof_bytes) { int pdu_len = parent->rx.get_status_pdu(&tx_status, nof_bytes); - logger.debug("%s", rlc_am_status_pdu_to_string(&tx_status).c_str()); + log_rlc_am_status_pdu_to_string(logger.debug, "%s", &tx_status); if (pdu_len > 0 && nof_bytes >= static_cast(pdu_len)) { - logger.info("%s Tx status PDU - %s", RB_NAME, rlc_am_status_pdu_to_string(&tx_status).c_str()); + log_rlc_am_status_pdu_to_string(logger.info, "%s Tx status PDU - %s", &tx_status, RB_NAME); parent->rx.reset_status(); @@ -661,7 +686,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_retx_pdu(uint8_t* payload, uint32_t nof_byt tx_window[retx.sn].buf->N_bytes, tx_window[retx.sn].retx_count + 1, cfg.max_retx_thresh); - logger.debug("%s", rlc_amd_pdu_header_to_string(new_header).c_str()); + log_rlc_amd_pdu_header_to_string(logger.debug, new_header); debug_state(); return (ptr - payload) + tx_window[retx.sn].buf->N_bytes; @@ -862,6 +887,14 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt return 0; } + if (nof_bytes < RLC_AM_MIN_DATA_PDU_SIZE) { + logger.info("%s Cannot build data PDU - %d bytes available but at least %d bytes are required ", + RB_NAME, + nof_bytes, + RLC_AM_MIN_DATA_PDU_SIZE); + return 0; + } + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); if (pdu == NULL) { #ifdef RLC_AM_BUFFER_DEBUG @@ -884,22 +917,20 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt header.fi = RLC_FI_FIELD_START_AND_END_ALIGNED; header.sn = vt_s; + // insert newly assigned SN into window and use reference for in-place operations + // NOTE: from now on, we can't return from this function anymore before increasing vt_s + rlc_amd_tx_pdu_t& tx_pdu = tx_window.add_pdu(header.sn); + tx_pdu.pdcp_sns.clear(); + uint32_t head_len = rlc_am_packed_length(&header); uint32_t to_move = 0; uint32_t last_li = 0; uint32_t pdu_space = SRSLTE_MIN(nof_bytes, pdu->get_tailroom()); uint8_t* pdu_ptr = pdu->msg; - if (pdu_space <= head_len) { - logger.info( - "%s Cannot build a PDU - %d bytes available, %d bytes required for header", RB_NAME, nof_bytes, head_len); - return 0; - } - logger.debug("%s Building PDU - pdu_space: %d, head_len: %d ", RB_NAME, pdu_space, head_len); // Check for SDU segment - std::vector pdcp_sns; if (tx_sdu != nullptr) { to_move = ((pdu_space - head_len) >= tx_sdu->N_bytes) ? tx_sdu->N_bytes : pdu_space - head_len; memcpy(pdu_ptr, tx_sdu->msg, to_move); @@ -911,7 +942,11 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt if (undelivered_sdu_info_queue.has_pdcp_sn(tx_sdu->md.pdcp_sn)) { pdcp_sdu_info_t& pdcp_sdu = undelivered_sdu_info_queue[tx_sdu->md.pdcp_sn]; pdcp_sdu.rlc_sn_info_list.push_back({header.sn, false}); - pdcp_sns.push_back(tx_sdu->md.pdcp_sn); + if (not tx_pdu.pdcp_sns.full()) { + tx_pdu.pdcp_sns.push_back(tx_sdu->md.pdcp_sn); + } else { + logger.warning("Cant't store PDCP_SN=%d for delivery notification.", tx_sdu->md.pdcp_sn); + } if (tx_sdu->N_bytes == 0) { pdcp_sdu.fully_txed = true; } @@ -964,7 +999,11 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt if (undelivered_sdu_info_queue.has_pdcp_sn(tx_sdu->md.pdcp_sn)) { pdcp_sdu_info_t& pdcp_sdu = undelivered_sdu_info_queue[tx_sdu->md.pdcp_sn]; pdcp_sdu.rlc_sn_info_list.push_back({header.sn, false}); - pdcp_sns.push_back(tx_sdu->md.pdcp_sn); + if (not tx_pdu.pdcp_sns.full()) { + tx_pdu.pdcp_sns.push_back(tx_sdu->md.pdcp_sn); + } else { + logger.warning("Cant't store PDCP_SN=%d for delivery notification.", tx_sdu->md.pdcp_sn); + } if (tx_sdu->N_bytes == 0) { pdcp_sdu.fully_txed = true; } @@ -993,7 +1032,6 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt // Make sure, at least one SDU (segment) has been added until this point if (pdu->N_bytes == 0) { logger.error("Generated empty RLC PDU."); - return 0; } if (tx_sdu != NULL) { @@ -1016,26 +1054,23 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt } } - // Set SN - header.sn = vt_s; + // Update Tx window vt_s = (vt_s + 1) % MOD; - // Place PDU in tx_window, write header and TX - tx_window.add_pdu(header.sn); - tx_window[header.sn].buf = std::move(pdu); - tx_window[header.sn].header = header; - tx_window[header.sn].is_acked = false; - tx_window[header.sn].retx_count = 0; - tx_window[header.sn].rlc_sn = header.sn; - tx_window[header.sn].pdcp_sns = std::move(pdcp_sns); - const byte_buffer_t* buffer_ptr = tx_window[header.sn].buf.get(); + // Write final header and TX + tx_pdu.buf = std::move(pdu); + tx_pdu.header = header; + tx_pdu.is_acked = false; + tx_pdu.retx_count = 0; + tx_pdu.rlc_sn = header.sn; + const byte_buffer_t* buffer_ptr = tx_pdu.buf.get(); uint8_t* ptr = payload; rlc_am_write_data_pdu_header(&header, &ptr); memcpy(ptr, buffer_ptr->msg, buffer_ptr->N_bytes); int total_len = (ptr - payload) + buffer_ptr->N_bytes; logger.info(payload, total_len, "%s Tx PDU SN=%d (%d B)", RB_NAME, header.sn, total_len); - logger.debug("%s", rlc_amd_pdu_header_to_string(header).c_str()); + log_rlc_amd_pdu_header_to_string(logger.debug, header); debug_state(); return total_len; @@ -1047,14 +1082,14 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no return; } - pthread_mutex_lock(&mutex); + std::unique_lock lock(mutex); logger.info(payload, nof_bytes, "%s Rx control PDU", RB_NAME); rlc_status_pdu_t status; rlc_am_read_status_pdu(payload, nof_bytes, &status); - logger.info("%s Rx Status PDU: %s", RB_NAME, rlc_am_status_pdu_to_string(&status).c_str()); + log_rlc_am_status_pdu_to_string(logger.info, "%s Rx Status PDU: %s", &status, RB_NAME); // Sec 5.2.2.2, stop poll reTx timer if status PDU comprises a positive _or_ negative acknowledgement // for the RLC data PDU with sequence number poll_sn @@ -1083,10 +1118,10 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no if (!retx_queue.has_sn(i)) { rlc_amd_retx_t& retx = retx_queue.push(); assert(tx_window[i].rlc_sn == i); - retx.sn = i; - retx.is_segment = false; - retx.so_start = 0; - retx.so_end = pdu.buf->N_bytes; + retx.sn = i; + retx.is_segment = false; + retx.so_start = 0; + retx.so_end = pdu.buf->N_bytes; if (status.nacks[j].has_so) { // sanity check @@ -1152,7 +1187,7 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no debug_state(); - pthread_mutex_unlock(&mutex); + lock.unlock(); // Notify PDCP without holding Tx mutex if (not notify_info_vec.empty()) { @@ -1176,7 +1211,7 @@ void rlc_am_lte::rlc_am_lte_tx::update_notification_ack_info(const rlc_amd_tx_pd if (not tx_window.has_sn(tx_pdu.header.sn)) { return; } - std::vector& pdcp_sns = tx_window[tx_pdu.header.sn].pdcp_sns; + pdcp_sn_vector_t& pdcp_sns = tx_window[tx_pdu.header.sn].pdcp_sns; for (uint32_t pdcp_sn : pdcp_sns) { // Iterate over all SNs that were TX'ed auto& info = undelivered_sdu_info_queue[pdcp_sn]; @@ -1193,7 +1228,11 @@ void rlc_am_lte::rlc_am_lte_tx::update_notification_ack_info(const rlc_amd_tx_pd info.rlc_sn_info_list.end(), [](rlc_sn_info_t rlc_sn_info) { return rlc_sn_info.is_acked; }); if (info.fully_acked) { - notify_info_vec.push_back(pdcp_sn); + if (not notify_info_vec.full()) { + notify_info_vec.push_back(pdcp_sn); + } else { + logger.warning("Can't notify delivery of PDCP_SN=%d.", pdcp_sn); + } } } } @@ -1287,13 +1326,10 @@ rlc_am_lte::rlc_am_lte_rx::rlc_am_lte_rx(rlc_am_lte* parent_) : pool(byte_buffer_pool::get_instance()), logger(parent_->logger), reordering_timer(parent_->timers->get_unique_timer()) -{ - pthread_mutex_init(&mutex, NULL); -} +{} rlc_am_lte::rlc_am_lte_rx::~rlc_am_lte_rx() { - pthread_mutex_destroy(&mutex); } bool rlc_am_lte::rlc_am_lte_rx::configure(rlc_am_config_t cfg_) @@ -1322,7 +1358,7 @@ void rlc_am_lte::rlc_am_lte_rx::reestablish() void rlc_am_lte::rlc_am_lte_rx::stop() { - pthread_mutex_lock(&mutex); + std::lock_guard lock(mutex); if (parent->timers != nullptr && reordering_timer.is_valid()) { reordering_timer.stop(); @@ -1344,8 +1380,6 @@ void rlc_am_lte::rlc_am_lte_rx::stop() // Drop all messages in RX window rx_window.clear(); - - pthread_mutex_unlock(&mutex); } /** Called from stack thread when MAC has received a new RLC PDU @@ -1359,7 +1393,7 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b std::map::iterator it; logger.info(payload, nof_bytes, "%s Rx data PDU SN=%d (%d B)", RB_NAME, header.sn, nof_bytes); - logger.debug("%s", rlc_amd_pdu_header_to_string(header).c_str()); + log_rlc_amd_pdu_header_to_string(logger.debug, header); // sanity check for segments not exceeding PDU length if (header.N_li > 0) { @@ -1393,7 +1427,7 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b // Write to rx window rlc_amd_rx_pdu_t& pdu = rx_window.add_pdu(header.sn); - pdu.buf = srslte::make_byte_buffer(); + pdu.buf = srslte::make_byte_buffer(); if (pdu.buf == NULL) { #ifdef RLC_AM_BUFFER_DEBUG srslte::console("Fatal Error: Couldn't allocate PDU in handle_data_pdu().\n"); @@ -1485,7 +1519,7 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu_segment(uint8_t* pa nof_bytes, header.so, header.N_li); - logger.debug("%s", rlc_amd_pdu_header_to_string(header).c_str()); + log_rlc_amd_pdu_header_to_string(logger.debug, header); // Check inside rx window if (!inside_rx_window(header.sn)) { @@ -1708,10 +1742,9 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus() void rlc_am_lte::rlc_am_lte_rx::reset_status() { - pthread_mutex_lock(&mutex); + std::lock_guard lock(mutex); do_status = false; poll_received = false; - pthread_mutex_unlock(&mutex); } bool rlc_am_lte::rlc_am_lte_rx::get_do_status() @@ -1724,19 +1757,16 @@ void rlc_am_lte::rlc_am_lte_rx::write_pdu(uint8_t* payload, const uint32_t nof_b if (nof_bytes < 1) { return; } - pthread_mutex_lock(&mutex); if (rlc_am_is_control_pdu(payload)) { - // unlock mutex and pass to Tx subclass - pthread_mutex_unlock(&mutex); parent->tx.handle_control_pdu(payload, nof_bytes); } else { + std::lock_guard lock(mutex); rlc_amd_pdu_header_t header = {}; uint32_t payload_len = nof_bytes; rlc_am_read_data_pdu_header(&payload, &payload_len, &header); if (payload_len > nof_bytes) { logger.info("Dropping corrupted PDU (%d B). Remaining length after header %d B.", nof_bytes, payload_len); - pthread_mutex_unlock(&mutex); return; } if (header.rf) { @@ -1744,26 +1774,19 @@ void rlc_am_lte::rlc_am_lte_rx::write_pdu(uint8_t* payload, const uint32_t nof_b } else { handle_data_pdu(payload, payload_len, header); } - pthread_mutex_unlock(&mutex); } } uint32_t rlc_am_lte::rlc_am_lte_rx::get_rx_buffered_bytes() { - uint32_t buff_size = 0; - pthread_mutex_lock(&mutex); - buff_size = rx_window.get_buffered_bytes(); - pthread_mutex_unlock(&mutex); - return buff_size; + std::lock_guard lock(mutex); + return rx_window.get_buffered_bytes(); } uint32_t rlc_am_lte::rlc_am_lte_rx::get_sdu_rx_latency_ms() { - uint32_t latency = 0; - pthread_mutex_lock(&mutex); - latency = sdu_rx_latency_ms.value(); - pthread_mutex_unlock(&mutex); - return latency; + std::lock_guard lock(mutex); + return sdu_rx_latency_ms.value(); } /** @@ -1773,7 +1796,7 @@ uint32_t rlc_am_lte::rlc_am_lte_rx::get_sdu_rx_latency_ms() */ void rlc_am_lte::rlc_am_lte_rx::timer_expired(uint32_t timeout_id) { - pthread_mutex_lock(&mutex); + std::lock_guard lock(mutex); if (reordering_timer.is_valid() and reordering_timer.id() == timeout_id) { logger.debug("%s reordering timeout expiry - updating vr_ms (was %d)", RB_NAME, vr_ms); @@ -1794,13 +1817,12 @@ void rlc_am_lte::rlc_am_lte_rx::timer_expired(uint32_t timeout_id) debug_state(); } - pthread_mutex_unlock(&mutex); } // Called from Tx object to pack status PDU that doesn't exceed a given size int rlc_am_lte::rlc_am_lte_rx::get_status_pdu(rlc_status_pdu_t* status, const uint32_t max_pdu_size) { - pthread_mutex_lock(&mutex); + std::lock_guard lock(mutex); status->N_nack = 0; status->ack_sn = vr_r; // start with lower edge of the rx window @@ -1839,14 +1861,13 @@ int rlc_am_lte::rlc_am_lte_rx::get_status_pdu(rlc_status_pdu_t* status, const ui i = (i + 1) % MOD; } - pthread_mutex_unlock(&mutex); return rlc_am_packed_length(status); } // Called from Tx object to obtain length of the full status PDU int rlc_am_lte::rlc_am_lte_rx::get_status_pdu_length() { - pthread_mutex_lock(&mutex); + std::lock_guard lock(mutex); rlc_status_pdu_t status = {}; status.ack_sn = vr_ms; uint32_t i = vr_r; @@ -1856,7 +1877,6 @@ int rlc_am_lte::rlc_am_lte_rx::get_status_pdu_length() } i = (i + 1) % MOD; } - pthread_mutex_unlock(&mutex); return rlc_am_packed_length(&status); } @@ -1949,8 +1969,8 @@ bool rlc_am_lte::rlc_am_lte_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t* logger.debug("Starting header reconstruction of %zd segments", pdu->segments.size()); // Reconstruct li fields - uint16_t count = 0; - uint16_t carryover = 0; + uint16_t count = 0; + uint16_t carryover = 0; uint16_t consumed_bytes = 0; // rolling sum of all allocated LIs during segment reconstruction for (it = pdu->segments.begin(); it != pdu->segments.end(); ++it) { @@ -1962,7 +1982,10 @@ bool rlc_am_lte::rlc_am_lte_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t* total_pdu_offset += it->header.li[k]; } - logger.debug(" - (total_pdu_offset=%d, consumed_bytes=%d, header.li[i]=%d)",total_pdu_offset, consumed_bytes, header.li[i]); + logger.debug(" - (total_pdu_offset=%d, consumed_bytes=%d, header.li[i]=%d)", + total_pdu_offset, + consumed_bytes, + header.li[i]); if (total_pdu_offset > header.li[i] && total_pdu_offset > consumed_bytes) { header.li[header.N_li] = total_pdu_offset - consumed_bytes; consumed_bytes = total_pdu_offset; @@ -2343,25 +2366,6 @@ bool rlc_am_is_pdu_segment(uint8_t* payload) return ((*(payload) >> 6) & 0x01) == 1; } -std::string rlc_am_status_pdu_to_string(rlc_status_pdu_t* status) -{ - std::stringstream ss; - ss << "ACK_SN = " << status->ack_sn; - ss << ", N_nack = " << status->N_nack; - if (status->N_nack > 0) { - ss << ", NACK_SN = "; - for (uint32_t i = 0; i < status->N_nack; i++) { - if (status->nacks[i].has_so) { - ss << "[" << status->nacks[i].nack_sn << " " << status->nacks[i].so_start << ":" << status->nacks[i].so_end - << "]"; - } else { - ss << "[" << status->nacks[i].nack_sn << "]"; - } - } - } - return ss.str(); -} - std::string rlc_am_undelivered_sdu_info_to_string(const std::map& info_queue) { std::string str = "\n"; @@ -2384,26 +2388,32 @@ std::string rlc_am_undelivered_sdu_info_to_string(const std::map 0) { - ss << " ("; - for (uint32_t i = 0; i < header.N_li; i++) { - ss << header.li[i] << ", "; + fmt::format_to(buffer, " ({}", header.li[0]); + for (uint32_t i = 1; i < header.N_li; ++i) { + fmt::format_to(buffer, ", {}", header.li[i]); } - ss << ")"; + fmt::format_to(buffer, ")"); } - ss << "]"; - return ss.str(); + fmt::format_to(buffer, "]"); + + log_ch("%s", to_c_str(buffer)); } bool rlc_am_start_aligned(const uint8_t fi) diff --git a/lib/test/adt/CMakeLists.txt b/lib/test/adt/CMakeLists.txt index 90565338b..9883e858a 100644 --- a/lib/test/adt/CMakeLists.txt +++ b/lib/test/adt/CMakeLists.txt @@ -53,3 +53,7 @@ add_test(bounded_vector_test bounded_vector_test) add_executable(mem_pool_test mem_pool_test.cc) target_link_libraries(mem_pool_test srslte_common) add_test(mem_pool_test mem_pool_test) + +add_executable(circular_buffer_test circular_buffer_test.cc) +target_link_libraries(circular_buffer_test srslte_common) +add_test(circular_buffer_test circular_buffer_test) diff --git a/lib/test/adt/bounded_bitset_test.cc b/lib/test/adt/bounded_bitset_test.cc index 25771fdaf..efcc5d600 100644 --- a/lib/test/adt/bounded_bitset_test.cc +++ b/lib/test/adt/bounded_bitset_test.cc @@ -37,7 +37,6 @@ int test_zero_bitset() TESTASSERT(mask2.max_size() == 25); TESTASSERT(mask2.size() == 23); - TESTASSERT(mask2.size() == 23); TESTASSERT(mask2.count() == 0); TESTASSERT(mask2.none()); TESTASSERT(not mask2.any()); @@ -104,7 +103,7 @@ int test_bitset_bitwise_oper() try { mask2 |= mask; } catch (srslte::bad_type_access& c) { - printf("Received exception \"%s\"\n", c.what()); + printf("Received exception \"%s\" (as expected)\n", c.what()); caught = true; } TESTASSERT(caught); @@ -113,11 +112,87 @@ int test_bitset_bitwise_oper() return SRSLTE_SUCCESS; } +int test_bitset_print() +{ + { + srslte::bounded_bitset<100> bitset(100); + bitset.set(0); + bitset.set(5); + + TESTASSERT(fmt::format("{:x}", bitset) == "0000000000000000000000021"); + TESTASSERT(fmt::format("{:b}", bitset) == + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100001"); + + bitset.set(99); + TESTASSERT(fmt::format("{:x}", bitset) == "8000000000000000000000021"); + TESTASSERT(fmt::format("{:b}", bitset) == + "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100001"); + } + + { + srslte::bounded_bitset<100> bitset(25); + bitset.set(0); + bitset.set(4); + + TESTASSERT(fmt::format("{:x}", bitset) == "0000011"); + TESTASSERT(fmt::format("{:b}", bitset) == "0000000000000000000010001"); + + bitset.set(24); + TESTASSERT(fmt::format("{:x}", bitset) == "1000011"); + TESTASSERT(fmt::format("{:b}", bitset) == "1000000000000000000010001"); + } + + return SRSLTE_SUCCESS; +} + +int test_bitset_resize() +{ + { + srslte::bounded_bitset<100> bitset; + TESTASSERT(bitset.none() and bitset.size() == 0); + + bitset.resize(100); + TESTASSERT(bitset.none() and bitset.size() == 100); + bitset.fill(0, 100); + TESTASSERT(bitset.all() and bitset.size() == 100); + + bitset.resize(25); + TESTASSERT(bitset.to_uint64() == 0x1ffffff); + TESTASSERT(bitset.all() and bitset.size() == 25); // keeps the data it had for the non-erased bits + + bitset.resize(100); + TESTASSERT(bitset.count() == 25 and bitset.size() == 100); + } + + { + // TEST: Reverse case + srslte::bounded_bitset<100, true> bitset; + TESTASSERT(bitset.none() and bitset.size() == 0); + + bitset.resize(100); + TESTASSERT(bitset.none() and bitset.size() == 100); + bitset.fill(0, 100); + TESTASSERT(bitset.all() and bitset.size() == 100); + + bitset.resize(25); + TESTASSERT(bitset.to_uint64() == 0x1ffffff); + TESTASSERT(bitset.all() and bitset.size() == 25); // keeps the data it had for the non-erased bits + + bitset.resize(100); + TESTASSERT(bitset.count() == 25 and bitset.size() == 100); + } + + return SRSLTE_SUCCESS; +} + int main() { TESTASSERT(test_zero_bitset() == SRSLTE_SUCCESS); TESTASSERT(test_ones_bitset() == SRSLTE_SUCCESS); TESTASSERT(test_bitset_set() == SRSLTE_SUCCESS); TESTASSERT(test_bitset_bitwise_oper() == SRSLTE_SUCCESS); + TESTASSERT(test_bitset_print() == SRSLTE_SUCCESS); + TESTASSERT(test_bitset_resize() == SRSLTE_SUCCESS); + printf("Success\n"); return 0; } diff --git a/lib/test/adt/circular_buffer_test.cc b/lib/test/adt/circular_buffer_test.cc new file mode 100644 index 000000000..a2a7e1387 --- /dev/null +++ b/lib/test/adt/circular_buffer_test.cc @@ -0,0 +1,125 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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. + * + */ + +#include "srslte/adt/circular_buffer.h" +#include "srslte/common/test_common.h" + +namespace srslte { + +int test_static_circular_buffer() +{ + static_circular_buffer circ_buffer; + TESTASSERT(circ_buffer.max_size() == 10); + TESTASSERT(circ_buffer.empty() and not circ_buffer.full() and circ_buffer.size() == 0); + + // push until full + for (size_t i = 0; i < circ_buffer.max_size(); ++i) { + TESTASSERT(circ_buffer.size() == i and not circ_buffer.full()); + circ_buffer.push(i); + TESTASSERT(not circ_buffer.empty()); + } + TESTASSERT(circ_buffer.size() == 10 and circ_buffer.full()); + + // test iterator + int count = 0; + for (int& it : circ_buffer) { + TESTASSERT(it == count); + count++; + } + TESTASSERT(*circ_buffer.begin() == circ_buffer.top()); + + // pop until empty + for (size_t i = 0; i < circ_buffer.max_size(); ++i) { + TESTASSERT(circ_buffer.size() == circ_buffer.max_size() - i and not circ_buffer.empty()); + TESTASSERT(circ_buffer.top() == (int)i); + circ_buffer.pop(); + } + TESTASSERT(circ_buffer.empty() and circ_buffer.size() == 0); + + // test iteration with wrap-around in memory + for (size_t i = 0; i < circ_buffer.max_size(); ++i) { + circ_buffer.push(i); + } + for (size_t i = 0; i < circ_buffer.max_size() / 2; ++i) { + circ_buffer.pop(); + } + circ_buffer.push(circ_buffer.max_size()); + circ_buffer.push(circ_buffer.max_size() + 1); + TESTASSERT(circ_buffer.size() == circ_buffer.max_size() / 2 + 2); + count = circ_buffer.max_size() / 2; + for (int& it : circ_buffer) { + TESTASSERT(it == count); + count++; + } + + return SRSLTE_SUCCESS; +} + +int test_queue_block_api() +{ + dyn_blocking_queue queue(100); + + std::thread t([&queue]() { + int count = 0; + while (true) { + int val = queue.pop_blocking(); + if (queue.is_stopped()) { + break; + } + assert(val == count); + count++; + } + }); + + for (int i = 0; i < 10000; ++i) { + queue.push_blocking(i); + } + + queue.stop(); + t.join(); + return SRSLTE_SUCCESS; +} + +int test_queue_block_api_2() +{ + std::thread t; + + { + dyn_blocking_queue queue(100); + + t = std::thread([&queue]() { + int count = 0; + while (queue.push_blocking(count++)) { + } + }); + + for (int i = 0; i < 10000; ++i) { + TESTASSERT(queue.pop_blocking() == i); + } + + // queue dtor called + } + + t.join(); + return SRSLTE_SUCCESS; +} + +} // namespace srslte + +int main() +{ + TESTASSERT(srslte::test_static_circular_buffer() == SRSLTE_SUCCESS); + TESTASSERT(srslte::test_queue_block_api() == SRSLTE_SUCCESS); + TESTASSERT(srslte::test_queue_block_api_2() == SRSLTE_SUCCESS); + srslte::console("Success\n"); + return SRSLTE_SUCCESS; +} \ No newline at end of file diff --git a/lib/test/adt/span_test.cc b/lib/test/adt/span_test.cc index da3a5e92d..071131865 100644 --- a/lib/test/adt/span_test.cc +++ b/lib/test/adt/span_test.cc @@ -20,6 +20,7 @@ */ #include "srslte/adt/span.h" +#include "srslte/common/byte_buffer.h" #include "srslte/common/test_common.h" int test_span_access() diff --git a/lib/test/asn1/asn1_utils_test.cc b/lib/test/asn1/asn1_utils_test.cc index 264e92c89..0b5ea00a4 100644 --- a/lib/test/asn1/asn1_utils_test.cc +++ b/lib/test/asn1/asn1_utils_test.cc @@ -31,6 +31,8 @@ using namespace asn1; std::random_device rd; std::mt19937 g(rd()); +srslte::log_sink_spy* test_spy = nullptr; + int test_arrays() { /* Test Ext Array */ @@ -595,13 +597,14 @@ int test_enum() TESTASSERT(e == e2); // Test fail path - srslte::scoped_log null_log("ASN1"); + TESTASSERT(test_spy->get_error_counter() == 0 and test_spy->get_warning_counter() == 0); bref = bit_ref(&buffer[0], sizeof(buffer)); bref2 = cbit_ref(&buffer[0], sizeof(buffer)); e = EnumTest::nulltype; TESTASSERT(pack_enum(bref, e) == SRSASN_ERROR_ENCODE_FAIL); buffer[0] = 255; TESTASSERT(unpack_enum(e, bref2) == SRSASN_ERROR_DECODE_FAIL); + TESTASSERT(test_spy->get_error_counter() == 2 and test_spy->get_warning_counter() == 0); return 0; } @@ -652,8 +655,18 @@ int test_big_integers() int main() { - srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG); - auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); + // Setup the log spy to intercept error and warning log entries. + if (!srslog::install_custom_sink( + srslte::log_sink_spy::name(), + std::unique_ptr(new srslte::log_sink_spy(srslog::get_default_log_formatter())))) { + return SRSLTE_ERROR; + } + test_spy = static_cast(srslog::find_sink(srslte::log_sink_spy::name())); + if (!test_spy) { + return SRSLTE_ERROR; + } + + auto& asn1_logger = srslog::fetch_basic_logger("ASN1", *test_spy, false); asn1_logger.set_level(srslog::basic_levels::debug); asn1_logger.set_hex_dump_max_size(-1); diff --git a/lib/test/asn1/ngap_test.cc b/lib/test/asn1/ngap_test.cc index e484dbeac..d69d7aa03 100644 --- a/lib/test/asn1/ngap_test.cc +++ b/lib/test/asn1/ngap_test.cc @@ -346,7 +346,6 @@ int test_session_res_setup_request() int main() { - srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG); auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); asn1_logger.set_level(srslog::basic_levels::debug); asn1_logger.set_hex_dump_max_size(-1); diff --git a/lib/test/asn1/rrc_nr_utils_test.cc b/lib/test/asn1/rrc_nr_utils_test.cc index 63bedf229..c59b82b48 100644 --- a/lib/test/asn1/rrc_nr_utils_test.cc +++ b/lib/test/asn1/rrc_nr_utils_test.cc @@ -25,8 +25,6 @@ #include "srslte/asn1/rrc_nr.h" #include "srslte/asn1/rrc_nr_utils.h" #include "srslte/common/common.h" -#include "srslte/common/log.h" -#include "srslte/common/logmap.h" #include "srslte/common/test_common.h" using namespace srslte; @@ -79,7 +77,6 @@ int test_mac_rach_common_config() int main() { - srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG); auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); asn1_logger.set_level(srslog::basic_levels::debug); asn1_logger.set_hex_dump_max_size(-1); diff --git a/lib/test/asn1/rrc_test.cc b/lib/test/asn1/rrc_test.cc index da4b3da12..f54f2741e 100644 --- a/lib/test/asn1/rrc_test.cc +++ b/lib/test/asn1/rrc_test.cc @@ -702,7 +702,6 @@ int test_rrc_conn_reconf_r15_3() int main() { - srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG); auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); asn1_logger.set_level(srslog::basic_levels::debug); asn1_logger.set_hex_dump_max_size(-1); diff --git a/lib/test/asn1/s1ap_test.cc b/lib/test/asn1/s1ap_test.cc index 1fd1dbdc1..db21b6230 100644 --- a/lib/test/asn1/s1ap_test.cc +++ b/lib/test/asn1/s1ap_test.cc @@ -364,10 +364,6 @@ int test_paging() int main() { - srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG); - srslte::logmap::set_default_hex_limit(4096); - TESTASSERT(srslte::logmap::get("ASN1")->get_level() == srslte::LOG_LEVEL_DEBUG); - // Setup the log spy to intercept error and warning log entries. if (!srslog::install_custom_sink( srslte::log_sink_spy::name(), diff --git a/lib/test/asn1/srslte_asn1_nas_test.cc b/lib/test/asn1/srslte_asn1_nas_test.cc index 41aa21f63..fcf5643cd 100644 --- a/lib/test/asn1/srslte_asn1_nas_test.cc +++ b/lib/test/asn1/srslte_asn1_nas_test.cc @@ -20,13 +20,10 @@ */ #include "srslte/asn1/liblte_mme.h" -#include "srslte/common/log_filter.h" #include "srslte/srslog/srslog.h" #include -#include #include #include -#include #define TESTASSERT(cond) \ { \ diff --git a/lib/test/asn1/srslte_asn1_rrc_dl_ccch_test.cc b/lib/test/asn1/srslte_asn1_rrc_dl_ccch_test.cc index b9e54623a..c73431264 100644 --- a/lib/test/asn1/srslte_asn1_rrc_dl_ccch_test.cc +++ b/lib/test/asn1/srslte_asn1_rrc_dl_ccch_test.cc @@ -21,7 +21,6 @@ #include "srslte/asn1/rrc/dl_ccch_msg.h" #include "srslte/common/bcd_helpers.h" -#include "srslte/common/log_filter.h" #include using namespace asn1; @@ -124,4 +123,4 @@ int main(int argc, char** argv) TESTASSERT(rrc_reestablishment_reject_test() == 0); return 0; -} \ No newline at end of file +} diff --git a/lib/test/asn1/srslte_asn1_rrc_dl_dcch_test.cc b/lib/test/asn1/srslte_asn1_rrc_dl_dcch_test.cc index 89ec48123..dd7cfa03d 100644 --- a/lib/test/asn1/srslte_asn1_rrc_dl_dcch_test.cc +++ b/lib/test/asn1/srslte_asn1_rrc_dl_dcch_test.cc @@ -21,7 +21,6 @@ #include "srslte/asn1/rrc/dl_dcch_msg.h" #include "srslte/common/bcd_helpers.h" -#include "srslte/common/log_filter.h" #include using namespace asn1; diff --git a/lib/test/asn1/srslte_asn1_rrc_mcch_test.cc b/lib/test/asn1/srslte_asn1_rrc_mcch_test.cc index e860e5bd6..0ef89e45b 100644 --- a/lib/test/asn1/srslte_asn1_rrc_mcch_test.cc +++ b/lib/test/asn1/srslte_asn1_rrc_mcch_test.cc @@ -22,7 +22,6 @@ #include "srslte/asn1/rrc.h" #include "srslte/asn1/rrc_utils.h" #include "srslte/common/bcd_helpers.h" -#include "srslte/common/log_filter.h" #include "srslte/interfaces/rrc_interface_types.h" #include diff --git a/lib/test/asn1/srslte_asn1_rrc_meas_test.cc b/lib/test/asn1/srslte_asn1_rrc_meas_test.cc index 82efbf9cb..6d1466ded 100644 --- a/lib/test/asn1/srslte_asn1_rrc_meas_test.cc +++ b/lib/test/asn1/srslte_asn1_rrc_meas_test.cc @@ -22,10 +22,8 @@ #include "srslte/asn1/rrc/ul_dcch_msg.h" #include "srslte/asn1/rrc_utils.h" #include "srslte/common/bcd_helpers.h" -#include "srslte/common/log_filter.h" #include "srslte/interfaces/rrc_interface_types.h" #include -#include #define TESTASSERT(cond) \ { \ diff --git a/lib/test/asn1/srslte_asn1_rrc_nr_test.cc b/lib/test/asn1/srslte_asn1_rrc_nr_test.cc index d9c8a98e4..41c356cfb 100644 --- a/lib/test/asn1/srslte_asn1_rrc_nr_test.cc +++ b/lib/test/asn1/srslte_asn1_rrc_nr_test.cc @@ -288,13 +288,15 @@ int test_cell_group_config() asn1::rrc_nr::rach_cfg_common_s& rach_cfg_common = cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common.setup(); - + TESTASSERT(rach_cfg_common.rach_cfg_generic.prach_cfg_idx == 16); TESTASSERT(rach_cfg_common.rach_cfg_generic.msg1_fdm == asn1::rrc_nr::rach_cfg_generic_s::msg1_fdm_opts::one); TESTASSERT(rach_cfg_common.rach_cfg_generic.zero_correlation_zone_cfg == 0); TESTASSERT(rach_cfg_common.rach_cfg_generic.preamb_rx_target_pwr == -110); - TESTASSERT(rach_cfg_common.rach_cfg_generic.preamb_trans_max == asn1::rrc_nr::rach_cfg_generic_s::preamb_trans_max_opts::n7); - TESTASSERT(rach_cfg_common.rach_cfg_generic.pwr_ramp_step == asn1::rrc_nr::rach_cfg_generic_s::pwr_ramp_step_opts::db4); + TESTASSERT(rach_cfg_common.rach_cfg_generic.preamb_trans_max == + asn1::rrc_nr::rach_cfg_generic_s::preamb_trans_max_opts::n7); + TESTASSERT(rach_cfg_common.rach_cfg_generic.pwr_ramp_step == + asn1::rrc_nr::rach_cfg_generic_s::pwr_ramp_step_opts::db4); TESTASSERT(rach_cfg_common.rach_cfg_generic.ra_resp_win == asn1::rrc_nr::rach_cfg_generic_s::ra_resp_win_opts::sl10); TESTASSERT(rach_cfg_common.ssb_per_rach_occasion_and_cb_preambs_per_ssb_present == true); @@ -306,7 +308,6 @@ int test_cell_group_config() int main() { - srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG); auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); asn1_logger.set_level(srslog::basic_levels::debug); asn1_logger.set_hex_dump_max_size(-1); @@ -322,7 +323,7 @@ int main() TESTASSERT(test_ue_rrc_reconfiguration() == SRSLTE_SUCCESS); TESTASSERT(test_radio_bearer_config() == SRSLTE_SUCCESS); TESTASSERT(test_cell_group_config() == SRSLTE_SUCCESS); - + srslog::flush(); printf("Success\n"); return 0; diff --git a/lib/test/asn1/srslte_asn1_rrc_ul_dcch_test.cc b/lib/test/asn1/srslte_asn1_rrc_ul_dcch_test.cc index f08ccdd8e..0052fe544 100644 --- a/lib/test/asn1/srslte_asn1_rrc_ul_dcch_test.cc +++ b/lib/test/asn1/srslte_asn1_rrc_ul_dcch_test.cc @@ -21,7 +21,6 @@ #include "../../../srsue/hdr/stack/rrc/rrc.h" // for rrc_args_t #include "srslte/asn1/rrc/ul_dcch_msg.h" -#include "srslte/common/log_filter.h" #include "srslte/common/mac_pcap.h" #include @@ -178,4 +177,4 @@ int main(int argc, char** argv) pcap.close(); #endif return 0; -} \ No newline at end of file +} diff --git a/lib/test/common/CMakeLists.txt b/lib/test/common/CMakeLists.txt index fe88db7ef..07b69ba86 100644 --- a/lib/test/common/CMakeLists.txt +++ b/lib/test/common/CMakeLists.txt @@ -51,9 +51,6 @@ add_executable(test_f12345 test_f12345.cc) target_link_libraries(test_f12345 srslte_common ${CMAKE_THREAD_LIBS_INIT}) add_test(test_f12345 test_f12345) -add_executable(log_filter_test log_filter_test.cc) -target_link_libraries(log_filter_test srslte_phy srslte_common srslte_phy ${SEC_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) - add_executable(timeout_test timeout_test.cc) target_link_libraries(timeout_test srslte_phy ${CMAKE_THREAD_LIBS_INIT}) @@ -63,7 +60,7 @@ target_link_libraries(bcd_helpers_test srslte_common) add_executable(stack_procedure_test stack_procedure_test.cc) add_test(stack_procedure_test stack_procedure_test) -add_executable(queue_test queue_test.cc) +add_executable(queue_test multiqueue_test.cc) target_link_libraries(queue_test srslte_common ${CMAKE_THREAD_LIBS_INIT}) add_test(queue_test queue_test) @@ -75,10 +72,6 @@ add_executable(network_utils_test network_utils_test.cc) target_link_libraries(network_utils_test srslte_common ${SCTP_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) add_test(network_utils_test network_utils_test) -add_executable(test_common_test test_common_test.cc) -target_link_libraries(test_common_test srslte_common) -add_test(test_common_test test_common_test) - add_executable(tti_point_test tti_point_test.cc) target_link_libraries(tti_point_test srslte_common) add_test(tti_point_test tti_point_test) @@ -102,4 +95,4 @@ add_executable(pnf_bridge pnf_bridge.cc) target_link_libraries(pnf_bridge srslte_common ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) add_executable(mac_pcap_net_test mac_pcap_net_test.cc) -target_link_libraries(mac_pcap_net_test srslte_common ${SCTP_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) \ No newline at end of file +target_link_libraries(mac_pcap_net_test srslte_common ${SCTP_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) diff --git a/lib/test/common/choice_type_test.cc b/lib/test/common/choice_type_test.cc index 77e4f881d..fbd843744 100644 --- a/lib/test/common/choice_type_test.cc +++ b/lib/test/common/choice_type_test.cc @@ -20,6 +20,7 @@ */ #include "srslte/adt/choice_type.h" +#include "srslte/common/buffer_pool.h" #include "srslte/common/test_common.h" struct C { diff --git a/lib/test/common/log_filter_test.cc b/lib/test/common/log_filter_test.cc deleted file mode 100644 index 8e4cd8214..000000000 --- a/lib/test/common/log_filter_test.cc +++ /dev/null @@ -1,228 +0,0 @@ -/** - * Copyright 2013-2021 Software Radio Systems Limited - * - * This file is part of srsLTE. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#define NTHREADS 100 -#define NMSGS 100 - -#include "srslte/common/log_filter.h" -#include "srslte/common/logger_srslog_wrapper.h" -#include "srslte/common/logmap.h" -#include "srslte/common/test_common.h" -#include "srslte/srslog/srslog.h" -#include - -using namespace srslte; - -typedef struct { - logger* l; - int thread_id; -} args_t; - -void* thread_loop(void* a) -{ - args_t* args = (args_t*)a; - char buf[100]; - - sprintf(buf, "LAYER%d", args->thread_id); - log_filter filter(buf, args->l); - filter.set_level(LOG_LEVEL_INFO); - - for (int i = 0; i < NMSGS; i++) { - filter.error("Thread %d: %d", args->thread_id, i); - filter.warning("Thread %d: %d", args->thread_id, i); - filter.info("Thread %d: %d", args->thread_id, i); - filter.debug("Thread %d: %d", args->thread_id, i); - } - return NULL; -} - -void* thread_loop_hex(void* a) -{ - args_t* args = (args_t*)a; - char buf[100]; - uint8_t hex[100]; - - for (int i = 0; i < 100; i++) { - hex[i] = i & 0xFF; - } - sprintf(buf, "LAYER%d", args->thread_id); - log_filter filter(buf, args->l); - filter.set_level(LOG_LEVEL_DEBUG); - filter.set_hex_limit(32); - - for (int i = 0; i < NMSGS; i++) { - filter.error_hex(hex, 100, "Thread %d: %d", args->thread_id, i); - filter.warning_hex(hex, 100, "Thread %d: %d", args->thread_id, i); - filter.info_hex(hex, 100, "Thread %d: %d", args->thread_id, i); - filter.debug_hex(hex, 100, "Thread %d: %d", args->thread_id, i); - } - return NULL; -} - -void write(std::string filename) -{ - srslog::sink* s = srslog::create_file_sink(filename); - srslog::log_channel* chan = srslog::create_log_channel("write", *s); - srslte::srslog_wrapper l(*chan); - - pthread_t threads[NTHREADS]; - args_t args[NTHREADS]; - for (int i = 0; i < NTHREADS; i++) { - args[i].l = &l; - args[i].thread_id = i; - pthread_create(&threads[i], NULL, &thread_loop_hex, &args[i]); - } - for (int i = 0; i < NTHREADS; i++) { - pthread_join(threads[i], NULL); - } -} - -bool read(std::string filename) -{ - bool pass = true; - bool written[NTHREADS][NMSGS]; - int thread, msg; - - for (int i = 0; i < NTHREADS; i++) { - for (int j = 0; j < NMSGS; j++) { - written[i][j] = false; - } - } - FILE* f = fopen(filename.c_str(), "r"); - if (f != NULL) { - while (fscanf(f, "Thread %d: %d\n", &thread, &msg)) { - written[thread][msg] = true; - } - fclose(f); - } - for (int i = 0; i < NTHREADS; i++) { - for (int j = 0; j < NMSGS; j++) { - if (!written[i][j]) - pass = false; - } - } - return pass; -} - -int basic_hex_test() -{ - srslog::sink* s = srslog::find_sink("stdout"); - if (!s) { - return SRSLTE_ERROR; - } - srslog::log_channel* chan = srslog::create_log_channel("basic_hex_test", *s); - if (!chan) { - return SRSLTE_ERROR; - } - srslte::srslog_wrapper l(*chan); - - log_filter filter("layer", &l); - filter.set_level(LOG_LEVEL_DEBUG); - filter.set_hex_limit(500); - - const uint32_t hex_len = 497; - - uint8_t hex[hex_len]; - for (uint32_t i = 0; i < hex_len; i++) { - hex[i] = i & 0xFF; - } - - filter.debug_hex(hex, hex_len, "This is the long hex msg (%d B)\n", hex_len); - filter.debug("This is a message after the long hex msg that should not be cut\n"); - - return SRSLTE_SUCCESS; -} - -int test_log_singleton() -{ - srslte::logmap::set_default_log_level(LOG_LEVEL_DEBUG); - - // TEST: Check if default setters are working - srslte::log_ref log1 = srslte::logmap::get("LAYER1"); - TESTASSERT(log1->get_service_name() == "LAYER1"); - TESTASSERT(log1->get_level() == LOG_LEVEL_DEBUG); - - // TEST: register logger manually. Verify log_ref stays valid after overwrite - std::unique_ptr log_ptr2(new srslte::log_filter("LAYER2")); - log_ptr2->set_level(LOG_LEVEL_WARNING); - srslte::log_ref old_ref = srslte::logmap::get("LAYER2"); - TESTASSERT(old_ref->get_level() == LOG_LEVEL_DEBUG); - srslte::logmap::register_log(std::move(log_ptr2)); - srslte::log_ref new_ref = srslte::logmap::get("LAYER2"); - TESTASSERT(new_ref->get_level() == LOG_LEVEL_WARNING); - TESTASSERT(old_ref == new_ref); - - // TEST: padding working correctly - TESTASSERT(srslte::logmap::get("MAC").get() == srslte::logmap::get("MAC ").get()); - - log1->info("logmap test finished successfully\n"); - return SRSLTE_SUCCESS; -} - -int test_log_ref() -{ - // Check if trailing whitespaces are correctly removed - srslte::log_ref t1_log{"T1"}; - TESTASSERT(t1_log->get_service_name() == "T1"); - TESTASSERT(t1_log.get() == srslte::logmap::get("T1").get()); - TESTASSERT(t1_log.get() == srslte::logmap::get("T1 ").get()); - { - scoped_log null_log{"T2"}; - TESTASSERT(null_log->get_service_name() == "T2"); - } - - return SRSLTE_SUCCESS; -} - -int full_test() -{ - std::string f("log.txt"); - write(f); -#if 0 - bool result = read(f); - remove(f.c_str()); - if(result) { - printf("Passed\n"); - exit(0); - }else{ - printf("Failed\n;"); - exit(1); - } -#endif - - return SRSLTE_SUCCESS; -} - -int main(int argc, char** argv) -{ - // Setup logging. - srslog::sink* log_sink = srslog::create_stdout_sink(); - if (!log_sink) { - return SRSLTE_ERROR; - } - - TESTASSERT(basic_hex_test() == SRSLTE_SUCCESS); - TESTASSERT(full_test() == SRSLTE_SUCCESS); - TESTASSERT(test_log_singleton() == SRSLTE_SUCCESS); - TESTASSERT(test_log_ref() == SRSLTE_SUCCESS); - - return SRSLTE_SUCCESS; -} diff --git a/lib/test/common/queue_test.cc b/lib/test/common/multiqueue_test.cc similarity index 100% rename from lib/test/common/queue_test.cc rename to lib/test/common/multiqueue_test.cc diff --git a/lib/test/common/network_utils_test.cc b/lib/test/common/network_utils_test.cc index 05a52c3ee..024c8d35e 100644 --- a/lib/test/common/network_utils_test.cc +++ b/lib/test/common/network_utils_test.cc @@ -19,7 +19,6 @@ * */ -#include "srslte/common/log_filter.h" #include "srslte/common/network_utils.h" #include diff --git a/lib/test/common/test_common_test.cc b/lib/test/common/test_common_test.cc deleted file mode 100644 index b94837077..000000000 --- a/lib/test/common/test_common_test.cc +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Copyright 2013-2021 Software Radio Systems Limited - * - * This file is part of srsLTE. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include "srslte/common/test_common.h" - -using srslte::nullsink_log; -using srslte::scoped_log; - -int test_nullsink_log() -{ - // Description: Test nullsink_log that only stores the last log message in a local std::string that can be checked - // This logger is useful to confirm that a certain action produced an expected error/warning, - // without contaminating the console/log file, and to check what error message was stored - scoped_log null_log("TEST"); - - TESTASSERT(srslte::logmap::get("TEST").get() == null_log.get()); - TESTASSERT(null_log->error_counter == 0); - TESTASSERT(null_log->last_log_level == srslte::LOG_LEVEL_NONE); - TESTASSERT(null_log->last_log_msg.empty()); - null_log->error("ERROR MESSAGE"); // This message should not be seen in the console - TESTASSERT(null_log->error_counter == 1); - TESTASSERT(null_log->last_log_level == srslte::LOG_LEVEL_ERROR); - TESTASSERT(null_log->last_log_msg == "ERROR MESSAGE"); - - return SRSLTE_SUCCESS; -} - -int test_log_scoping() -{ - // Description: Test whether we can use different global TEST loggers in different scopes - // on scope exit the previous logger should be recovered - // This behavior is useful for the cases we have one generic logger for all tests, but in a specific test - // we want to use a different one - scoped_log log1("TEST"); - TESTASSERT(srslte::logmap::get("TEST").get() == log1.get()); - - log1->error("message1"); - log1->error("message2"); - TESTASSERT(log1->last_log_msg == "message2"); - TESTASSERT(log1->error_counter == 2); - - { - // the global test log should be overwriten here, and used by TESTASSERT macro - scoped_log log2("TEST"); - TESTASSERT(srslte::logmap::get("TEST").get() == log2.get()); - TESTASSERT(log2->error_counter == 0); - log2->error("error message in logger2\n"); - TESTASSERT(log2->last_log_msg == "error message in logger2\n"); - TESTASSERT(log2->error_counter == 1); - } - // the last logger should be recovered - - TESTASSERT(srslte::logmap::get("TEST").get() == log1.get()); - TESTASSERT(log1->error_counter == 2); - return 0; -} - -int main() -{ - TESTASSERT(test_nullsink_log() == 0); - TESTASSERT(test_log_scoping() == 0); - return 0; -} diff --git a/lib/test/mac/mac_pdu_nr_test.cc b/lib/test/mac/mac_pdu_nr_test.cc index a1d8b88fa..5a9953228 100644 --- a/lib/test/mac/mac_pdu_nr_test.cc +++ b/lib/test/mac/mac_pdu_nr_test.cc @@ -19,7 +19,6 @@ * */ -#include "srslte/common/log_filter.h" #include "srslte/common/mac_pcap.h" #include "srslte/common/test_common.h" #include "srslte/config.h" diff --git a/lib/test/mac/pdu_test.cc b/lib/test/mac/pdu_test.cc index e5b546ca2..290202f66 100644 --- a/lib/test/mac/pdu_test.cc +++ b/lib/test/mac/pdu_test.cc @@ -21,7 +21,6 @@ #include "srslte/common/common.h" #include "srslte/common/interfaces_common.h" -#include "srslte/common/logmap.h" #include "srslte/common/mac_pcap.h" #include "srslte/common/test_common.h" #include "srslte/mac/pdu.h" @@ -63,7 +62,9 @@ int mac_rar_pdu_unpack_test1() srslte::rar_pdu rar_pdu_msg; rar_pdu_msg.init_rx(sizeof(rar_pdu_tv1)); rar_pdu_msg.parse_packet(rar_pdu_tv1); - std::cout << rar_pdu_msg.to_string() << std::endl; + fmt::memory_buffer buffer; + rar_pdu_msg.to_string(buffer); + std::cout << fmt::to_string(buffer) << std::endl; TESTASSERT(not rar_pdu_msg.has_backoff()); TESTASSERT(rar_pdu_msg.nof_subh() == 1); @@ -81,7 +82,9 @@ int mac_rar_pdu_unpack_test2() srslte::rar_pdu rar_pdu_msg; rar_pdu_msg.init_rx(sizeof(rar_pdu_tv2)); rar_pdu_msg.parse_packet(rar_pdu_tv2); - std::cout << rar_pdu_msg.to_string() << std::endl; + fmt::memory_buffer buffer; + rar_pdu_msg.to_string(buffer); + std::cout << fmt::to_string(buffer) << std::endl; TESTASSERT(rar_pdu_msg.nof_subh() == 2); TESTASSERT(rar_pdu_msg.has_backoff()); @@ -110,7 +113,9 @@ int mac_rar_pdu_unpack_test3() TESTASSERT(rar_pdu_msg.parse_packet(rar_pdu) != SRSLTE_SUCCESS); TESTASSERT(rar_pdu_msg.nof_subh() == 0); - std::cout << rar_pdu_msg.to_string() << std::endl; + fmt::memory_buffer buffer; + rar_pdu_msg.to_string(buffer); + std::cout << fmt::to_string(buffer) << std::endl; return SRSLTE_SUCCESS; } @@ -509,8 +514,9 @@ int mac_sch_pdu_pack_test6() for (uint32_t i = 0; i < 4; i++) { TESTASSERT(buff_size_rx[i] == buff_size_tx[i]); } - - mac_logger.info("%s", pdu.to_string().c_str()); + fmt::memory_buffer str_buffer; + pdu.to_string(str_buffer); + mac_logger.info("%s", fmt::to_string(str_buffer)); // log mac_logger.info(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):", buffer.N_bytes); @@ -539,7 +545,9 @@ int mac_sch_pdu_pack_test6() // write PDU pdu.write_packet(mac_logger); - mac_logger.info("%s", pdu.to_string().c_str()); + str_buffer.clear(); + pdu.to_string(str_buffer); + mac_logger.info("%s", fmt::to_string(str_buffer)); TESTASSERT(memcmp(buffer.msg, tv2, buffer.N_bytes) == 0); @@ -592,7 +600,9 @@ int mac_sch_pdu_pack_test6() // write PDU pdu.write_packet(mac_logger); - mac_logger.info("%s", pdu.to_string().c_str()); + str_buffer.clear(); + pdu.to_string(str_buffer); + mac_logger.info("%s", fmt::to_string(str_buffer)); TESTASSERT(memcmp(buffer.msg, tv3, buffer.N_bytes) == 0); @@ -1008,7 +1018,9 @@ int mac_sch_pdu_unpack_test3() } } - std::cout << pdu.to_string() << std::endl; + fmt::memory_buffer buffer; + pdu.to_string(buffer); + std::cout << fmt::to_string(buffer) << std::endl; #if HAVE_PCAP pcap_handle->write_dl_crnti(tv, sizeof(tv), 0x1001, true, 1, 0); diff --git a/lib/test/srslog/CMakeLists.txt b/lib/test/srslog/CMakeLists.txt index b0df68db0..b28b560c9 100644 --- a/lib/test/srslog/CMakeLists.txt +++ b/lib/test/srslog/CMakeLists.txt @@ -54,11 +54,10 @@ add_definitions(-DENABLE_SRSLOG_EVENT_TRACE) target_link_libraries(tracer_test srslog) add_test(tracer_test tracer_test) -#:TODO: re-enable test. -#add_executable(text_formatter_test text_formatter_test.cpp) -#target_include_directories(text_formatter_test PUBLIC ../../) -#target_link_libraries(text_formatter_test srslog) -#add_test(text_formatter_test text_formatter_test) +add_executable(text_formatter_test text_formatter_test.cpp) +target_include_directories(text_formatter_test PUBLIC ../../) +target_link_libraries(text_formatter_test srslog) +add_test(text_formatter_test text_formatter_test) add_executable(json_formatter_test json_formatter_test.cpp) target_include_directories(json_formatter_test PUBLIC ../../) diff --git a/lib/test/srslog/json_formatter_test.cpp b/lib/test/srslog/json_formatter_test.cpp index bfc444b0e..d4d836d3d 100644 --- a/lib/test/srslog/json_formatter_test.cpp +++ b/lib/test/srslog/json_formatter_test.cpp @@ -91,7 +91,7 @@ static bool when_log_entry_with_only_basic_context_is_passed_then_context_is_formatted() { auto entry = build_log_entry_metadata(); - entry.fmtstring = ""; + entry.fmtstring = nullptr; basic_ctx_t ctx("UL Context"); ctx.get().write(-55.1); @@ -182,7 +182,7 @@ when_log_entry_with_only_complex_context_is_passed_then_context_is_formatted() { complex_ctx_t ctx("UL Context"); auto entry = build_log_entry_metadata(); - entry.fmtstring = ""; + entry.fmtstring = nullptr; ctx.get().emplace_back(); ctx.at(0).get().emplace_back(); @@ -269,7 +269,7 @@ static bool when_context_with_empty_list_is_passed_then_list_object_is_empty() { list_ctx_t ctx("UL Context"); auto entry = build_log_entry_metadata(); - entry.fmtstring = ""; + entry.fmtstring = nullptr; fmt::memory_buffer buffer; json_formatter{}.format_ctx(ctx, std::move(entry), buffer); diff --git a/lib/test/srslog/log_channel_test.cpp b/lib/test/srslog/log_channel_test.cpp index 3c7b6dbd8..412201e58 100644 --- a/lib/test/srslog/log_channel_test.cpp +++ b/lib/test/srslog/log_channel_test.cpp @@ -98,8 +98,7 @@ when_logging_in_log_channel_then_log_entry_is_pushed_into_the_backend() test_dummies::sink_dummy s; log_channel log("id", s, backend); - std::string fmtstring = "test"; - log(fmtstring, 42, "Hello"); + log("test", 42, "Hello"); ASSERT_EQ(backend.push_invocation_count(), 1); @@ -113,8 +112,7 @@ static bool when_logging_in_disabled_log_channel_then_log_entry_is_ignored() log_channel log("id", s, backend); log.set_enabled(false); - std::string fmtstring = "test"; - log(fmtstring, 42, "Hello"); + log("test", 42, "Hello"); ASSERT_EQ(backend.push_invocation_count(), 0); @@ -131,11 +129,10 @@ static bool when_logging_then_filled_in_log_entry_is_pushed_into_the_backend() log_channel log("id", s, backend, {name, tag, true}); - std::string fmtstring = "test"; uint32_t ctx = 10; log.set_context(ctx); - log(fmtstring, 42, "Hello"); + log("test", 42, "Hello"); ASSERT_EQ(backend.push_invocation_count(), 1); @@ -145,7 +142,7 @@ static bool when_logging_then_filled_in_log_entry_is_pushed_into_the_backend() ASSERT_NE(entry.metadata.tp.time_since_epoch().count(), 0); ASSERT_EQ(entry.metadata.context.value, ctx); ASSERT_EQ(entry.metadata.context.enabled, true); - ASSERT_EQ(entry.metadata.fmtstring, fmtstring); + ASSERT_EQ(entry.metadata.fmtstring, std::string("test")); ASSERT_EQ(entry.metadata.log_name, name); ASSERT_EQ(entry.metadata.log_tag, tag); ASSERT_EQ(entry.metadata.hex_dump.empty(), true); @@ -164,13 +161,12 @@ when_logging_with_hex_dump_then_filled_in_log_entry_is_pushed_into_the_backend() log_channel log("id", s, backend, {name, tag, true}); - std::string fmtstring = "test"; uint32_t ctx = 4; log.set_context(ctx); log.set_hex_dump_max_size(4); uint8_t hex[] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; - log(hex, sizeof(hex), fmtstring, 42, "Hello"); + log(hex, sizeof(hex), "test", 42, "Hello"); ASSERT_EQ(backend.push_invocation_count(), 1); @@ -180,7 +176,7 @@ when_logging_with_hex_dump_then_filled_in_log_entry_is_pushed_into_the_backend() ASSERT_NE(entry.metadata.tp.time_since_epoch().count(), 0); ASSERT_EQ(entry.metadata.context.value, ctx); ASSERT_EQ(entry.metadata.context.enabled, true); - ASSERT_EQ(entry.metadata.fmtstring, fmtstring); + ASSERT_EQ(entry.metadata.fmtstring, std::string("test")); ASSERT_EQ(entry.metadata.log_name, name); ASSERT_EQ(entry.metadata.log_tag, tag); ASSERT_EQ(entry.metadata.hex_dump.size(), 4); @@ -202,11 +198,9 @@ when_hex_array_length_is_less_than_hex_log_max_size_then_array_length_is_used() log_channel log("id", s, backend); - std::string fmtstring = "test"; - log.set_hex_dump_max_size(10); uint8_t hex[] = {0, 1, 2}; - log(hex, sizeof(hex), fmtstring, 42, "Hello"); + log(hex, sizeof(hex), "test", 42, "Hello"); ASSERT_EQ(backend.push_invocation_count(), 1); @@ -273,10 +267,9 @@ when_logging_with_context_and_message_then_filled_in_log_entry_is_pushed_into_th uint32_t ctx_value = 4; log.set_context(ctx_value); - std::string fmtstring = "test"; my_ctx ctx("myctx"); - log(ctx, fmtstring, 10, 3.3); + log(ctx, "test", 10, 3.3); ASSERT_EQ(backend.push_invocation_count(), 1); @@ -286,7 +279,7 @@ when_logging_with_context_and_message_then_filled_in_log_entry_is_pushed_into_th ASSERT_NE(entry.metadata.tp.time_since_epoch().count(), 0); ASSERT_EQ(entry.metadata.context.value, ctx_value); ASSERT_EQ(entry.metadata.context.enabled, true); - ASSERT_EQ(entry.metadata.fmtstring, fmtstring); + ASSERT_EQ(entry.metadata.fmtstring, std::string("test")); ASSERT_EQ(entry.metadata.log_name, name); ASSERT_EQ(entry.metadata.log_tag, tag); ASSERT_EQ(entry.metadata.hex_dump.empty(), true); diff --git a/lib/test/srslog/text_formatter_test.cpp b/lib/test/srslog/text_formatter_test.cpp index f79fc51fd..e5bf49fe3 100644 --- a/lib/test/srslog/text_formatter_test.cpp +++ b/lib/test/srslog/text_formatter_test.cpp @@ -119,41 +119,120 @@ static bool when_log_entry_with_hex_dump_is_passed_then_hex_dump_is_formatted() namespace { DECLARE_METRIC("SNR", snr_t, float, "dB"); DECLARE_METRIC("PWR", pwr_t, int, "dBm"); -DECLARE_METRIC("CenterFreq", cfreq_t, unsigned, "MHz"); -DECLARE_METRIC_SET("RF", myset1, snr_t, pwr_t, cfreq_t); +DECLARE_METRIC_SET("RF", rf_set, snr_t, pwr_t); DECLARE_METRIC("Throughput", thr_t, float, "MB/s"); DECLARE_METRIC("Address", ip_addr_t, std::string, ""); -DECLARE_METRIC_SET("Network", myset2, thr_t, ip_addr_t); +DECLARE_METRIC_LIST("Antennas", antenna_list_t, std::vector); +DECLARE_METRIC_SET("ue_container", ue_set, thr_t, ip_addr_t, antenna_list_t); -using ctx_t = srslog::build_context_type; +DECLARE_METRIC("type", entry_type_t, std::string, ""); +DECLARE_METRIC("sector_id", sector_id_t, unsigned, ""); +DECLARE_METRIC_LIST("ue_list", ue_list_t, std::vector); +DECLARE_METRIC_SET("sector_metrics", + sector_set, + entry_type_t, + sector_id_t, + ue_list_t); + +DECLARE_METRIC_LIST("sector_list", sector_list_t, std::vector); + +using complex_ctx_t = srslog::build_context_type; } // namespace +/// Builds an instance of a complex context object filled in with some random +/// data. +static complex_ctx_t build_complex_context() +{ + complex_ctx_t ctx("Complex Context"); + + ctx.get().emplace_back(); + ctx.at(0).write("event"); + ctx.at(0).write(1); + + ctx.at(0).get().emplace_back(); + ctx.at(0).at(0).write(1.2); + ctx.at(0).at(0).write("10.20.30.40"); + + ctx.at(0).get().emplace_back(); + ctx.at(0).at(1).write(10.2); + ctx.at(0).at(1).write("10.20.30.41"); + + ctx.at(0) + .at(0) + .get() + .emplace_back(); + ctx.at(0).at(0).at(0).write( + 5.1); + ctx.at(0).at(0).at(0).write( + -11.5); + + ctx.at(0) + .at(0) + .get() + .emplace_back(); + ctx.at(0).at(0).at(1).write( + 10.1); + ctx.at(0).at(0).at(1).write( + -20.5); + + ctx.at(0) + .at(1) + .get() + .emplace_back(); + ctx.at(0).at(1).at(0).write( + 20.1); + ctx.at(0).at(1).at(0).write( + -30.5); + ctx.at(0) + .at(1) + .get() + .emplace_back(); + ctx.at(0).at(1).at(1).write( + 30.1); + ctx.at(0).at(1).at(1).write( + -40.5); + + return ctx; +} + static bool when_log_entry_with_only_context_is_passed_then_context_is_formatted() { + auto ctx = build_complex_context(); auto entry = build_log_entry_metadata(); - entry.fmtstring = ""; - ctx_t ctx("UL Context"); - - ctx.get().write(-55.1); - ctx.get().write(-10); - ctx.get().write(1500); - ctx.get().write(150.01); - ctx.get().write("192.168.1.0"); + entry.fmtstring = nullptr; fmt::memory_buffer buffer; text_formatter{}.format_ctx(ctx, std::move(entry), buffer); std::string result = fmt::to_string(buffer); - std::string expected = - "00:00:00.050000 [ABC ] [Z] [ 10] Context dump for \"UL Context\"\n" - " RF\n" - " SNR: -55.1 dB\n" - " PWR: -10 dBm\n" - " CenterFreq: 1500 MHz\n" - " Network\n" - " Throughput: 150.01 MB/s\n" - " Address: 192.168.1.0\n"; + std::string expected = "00:00:00.050000 [ABC ] [Z] [ 10] Context dump for " + "\"Complex Context\"\n" + " > List: sector_list\n" + " > Set: sector_metrics\n" + " type: event\n" + " sector_id: 1\n" + " > List: ue_list\n" + " > Set: ue_container\n" + " Throughput: 1.2 MB/s\n" + " Address: 10.20.30.40\n" + " > List: Antennas\n" + " > Set: RF\n" + " SNR: 5.1 dB\n" + " PWR: -11 dBm\n" + " > Set: RF\n" + " SNR: 10.1 dB\n" + " PWR: -20 dBm\n" + " > Set: ue_container\n" + " Throughput: 10.2 MB/s\n" + " Address: 10.20.30.41\n" + " > List: Antennas\n" + " > Set: RF\n" + " SNR: 20.1 dB\n" + " PWR: -30 dBm\n" + " > Set: RF\n" + " SNR: 30.1 dB\n" + " PWR: -40 dBm\n"; ASSERT_EQ(result, expected); @@ -164,21 +243,18 @@ static bool when_log_entry_with_context_and_message_is_passed_then_context_is_formatted() { auto entry = build_log_entry_metadata(); - ctx_t ctx("UL Context"); - - ctx.get().write(-55.1); - ctx.get().write(-10); - ctx.get().write(1500); - ctx.get().write(150.01); - ctx.get().write("192.168.1.0"); + auto ctx = build_complex_context(); fmt::memory_buffer buffer; text_formatter{}.format_ctx(ctx, std::move(entry), buffer); std::string result = fmt::to_string(buffer); std::string expected = - "00:00:00.050000 [ABC ] [Z] [ 10] [[RF_SNR: -55.1 dB, RF_PWR: -10 dBm, " - "RF_CenterFreq: 1500 MHz] [Network_Throughput: 150.01 MB/s, " - "Network_Address: 192.168.1.0]]: Text 88\n"; + "00:00:00.050000 [ABC ] [Z] [ 10] [[sector_metrics_type: event, " + "sector_metrics_sector_id: 1, [ue_container_Throughput: 1.2 MB/s, " + "ue_container_Address: 10.20.30.40, [RF_SNR: 5.1 dB, RF_PWR: -11 " + "dBm][RF_SNR: 10.1 dB, RF_PWR: -20 dBm]][ue_container_Throughput: 10.2 " + "MB/s, ue_container_Address: 10.20.30.41, [RF_SNR: 20.1 dB, RF_PWR: -30 " + "dBm][RF_SNR: 30.1 dB, RF_PWR: -40 dBm]]]]: Text 88\n"; ASSERT_EQ(result, expected); diff --git a/lib/test/upper/pdcp_base_test.h b/lib/test/upper/pdcp_base_test.h index 803da7c95..179db9613 100644 --- a/lib/test/upper/pdcp_base_test.h +++ b/lib/test/upper/pdcp_base_test.h @@ -23,7 +23,6 @@ #define SRSLTE_PDCP_BASE_TEST_H #include "srslte/common/buffer_pool.h" -#include "srslte/common/log_filter.h" #include "srslte/common/security.h" #include "srslte/common/test_common.h" #include "srslte/interfaces/pdcp_interface_types.h" diff --git a/lib/test/upper/pdcp_lte_test.h b/lib/test/upper/pdcp_lte_test.h index 6cdc345fa..b83312eb0 100644 --- a/lib/test/upper/pdcp_lte_test.h +++ b/lib/test/upper/pdcp_lte_test.h @@ -76,7 +76,7 @@ public: pdcp.enable_encryption(srslte::DIRECTION_TXRX); } - void set_pdcp_initial_state(const srslte::pdcp_lte_state_t& init_state) { pdcp.set_bearer_state(init_state); } + void set_pdcp_initial_state(const srslte::pdcp_lte_state_t& init_state) { pdcp.set_bearer_state(init_state, false); } rlc_dummy rlc; rrc_dummy rrc; diff --git a/lib/test/upper/pdcp_lte_test_discard_sdu.cc b/lib/test/upper/pdcp_lte_test_discard_sdu.cc index fdd735439..651d81232 100644 --- a/lib/test/upper/pdcp_lte_test_discard_sdu.cc +++ b/lib/test/upper/pdcp_lte_test_discard_sdu.cc @@ -54,7 +54,8 @@ int test_tx_sdu_notify(const srslte::pdcp_lte_state_t& init_state, TESTASSERT(out_pdu->N_bytes == 4); TESTASSERT(pdcp->nof_discard_timers() == 1); // One timer should be running - std::vector sns_notified = {0}; + srslte::pdcp_sn_vector_t sns_notified; + sns_notified.push_back(0); pdcp->notify_delivery(sns_notified); TESTASSERT(pdcp->nof_discard_timers() == 0); // Timer should have been difused after @@ -112,7 +113,8 @@ int test_tx_sdu_discard(const srslte::pdcp_lte_state_t& init_state, TESTASSERT(pdcp->nof_discard_timers() == 0); // Timer should have been difused after expiry TESTASSERT(rlc->discard_count == 1); // RLC should be notified of discard - std::vector sns_notified = {0}; + srslte::pdcp_sn_vector_t sns_notified; + sns_notified.push_back(0); pdcp->notify_delivery(sns_notified); // PDCP should not find PDU to notify. return 0; } diff --git a/lib/test/upper/pdcp_lte_test_status_report.cc b/lib/test/upper/pdcp_lte_test_status_report.cc index c415d9d97..4a00b8acc 100644 --- a/lib/test/upper/pdcp_lte_test_status_report.cc +++ b/lib/test/upper/pdcp_lte_test_status_report.cc @@ -26,40 +26,61 @@ */ int test_tx_status_report(const srslte::pdcp_lte_state_t& init_state, srslog::basic_logger& logger) { - srslte::pdcp_config_t cfg = {1, - srslte::PDCP_RB_IS_DRB, - srslte::SECURITY_DIRECTION_UPLINK, - srslte::SECURITY_DIRECTION_DOWNLINK, - srslte::PDCP_SN_LEN_12, - srslte::pdcp_t_reordering_t::ms500, - srslte::pdcp_discard_timer_t::ms500, - true}; - - pdcp_lte_test_helper pdcp_hlp(cfg, sec_cfg, logger); - srslte::pdcp_entity_lte* pdcp = &pdcp_hlp.pdcp; - rlc_dummy* rlc = &pdcp_hlp.rlc; - srsue::stack_test_dummy* stack = &pdcp_hlp.stack; - - pdcp_hlp.set_pdcp_initial_state(init_state); + srslte::pdcp_config_t cfg_tx = {1, + srslte::PDCP_RB_IS_DRB, + srslte::SECURITY_DIRECTION_UPLINK, + srslte::SECURITY_DIRECTION_DOWNLINK, + srslte::PDCP_SN_LEN_12, + srslte::pdcp_t_reordering_t::ms500, + srslte::pdcp_discard_timer_t::ms500, + true}; + + srslte::pdcp_config_t cfg_rx = {1, + srslte::PDCP_RB_IS_DRB, + srslte::SECURITY_DIRECTION_DOWNLINK, + srslte::SECURITY_DIRECTION_UPLINK, + srslte::PDCP_SN_LEN_12, + srslte::pdcp_t_reordering_t::ms500, + srslte::pdcp_discard_timer_t::ms500, + true}; + + // Setup TX + pdcp_lte_test_helper pdcp_hlp_tx(cfg_tx, sec_cfg, logger); + srslte::pdcp_entity_lte* pdcp_tx = &pdcp_hlp_tx.pdcp; + rlc_dummy* rlc_tx = &pdcp_hlp_tx.rlc; + srsue::stack_test_dummy* stack_tx = &pdcp_hlp_tx.stack; + pdcp_hlp_tx.set_pdcp_initial_state(init_state); + + // Setup RX + pdcp_lte_test_helper pdcp_hlp_rx(cfg_tx, sec_cfg, logger); + srslte::pdcp_entity_lte* pdcp_rx = &pdcp_hlp_tx.pdcp; + rlc_dummy* rlc_rx = &pdcp_hlp_tx.rlc; + srsue::stack_test_dummy* stack_rx = &pdcp_hlp_tx.stack; + pdcp_hlp_rx.set_pdcp_initial_state(init_state); + + // Tmp variable to hold the PDCP PDU srslte::unique_byte_buffer_t out_pdu = srslte::make_byte_buffer(); // Write 256 SDUs and notify imediatly -> FMS 0001 0000 0001 for (uint32_t i = 0; i < 257; i++) { srslte::unique_byte_buffer_t sdu = srslte::make_byte_buffer(); + srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer(); sdu->append_bytes(sdu1, sizeof(sdu1)); - pdcp->write_sdu(std::move(sdu)); - pdcp->notify_delivery({i}); + pdcp_tx->write_sdu(std::move(sdu)); + pdcp_tx->notify_delivery({i}); + rlc_tx->get_last_sdu(pdu); + pdcp_rx->write_pdu(std::move(pdu)); } // Check undelivered SDUs queue size - TESTASSERT(pdcp->nof_discard_timers() == 0); // 0 timers should be running + TESTASSERT(pdcp_tx->nof_discard_timers() == 0); // 0 timers should be running on TX // Generate the status report - pdcp->send_status_report(); - rlc->get_last_sdu(out_pdu); + pdcp_rx->send_status_report(); + rlc_rx->get_last_sdu(out_pdu); logger.debug(out_pdu->msg, out_pdu->N_bytes, "Status PDU:"); - // Check status PDU + // Check status PDU. We received up to /* * | D/C | TYPE | FMS | -> | 0 | 0 | 0001 | * | FMS | -> | 00000001 | @@ -71,33 +92,36 @@ int test_tx_status_report(const srslte::pdcp_lte_state_t& init_state, srslog::ba // Write another 16 SDUs but don't notify SN=257, SN=258, SN=271 and SN=272 for (uint32_t i = 257; i < 273; i++) { srslte::unique_byte_buffer_t sdu = srslte::make_byte_buffer(); + srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer(); sdu->append_bytes(sdu1, sizeof(sdu1)); - pdcp->write_sdu(std::move(sdu)); + pdcp_tx->write_sdu(std::move(sdu)); if (i != 257 && i != 258 && i != 271 && i != 272) { - pdcp->notify_delivery({i}); + pdcp_tx->notify_delivery({i}); + rlc_tx->get_last_sdu(pdu); + pdcp_rx->write_pdu(std::move(pdu)); } } // Check undelivered SDUs queue size - TESTASSERT(pdcp->nof_discard_timers() == 4); + TESTASSERT(pdcp_tx->nof_discard_timers() == 4); // Generate the status report - pdcp->send_status_report(); - rlc->get_last_sdu(out_pdu); + pdcp_tx->send_status_report(); + rlc_tx->get_last_sdu(out_pdu); logger.debug(out_pdu->msg, out_pdu->N_bytes, "Status PDU:"); // Check status PDU /* * | D/C | TYPE | FMS | -> | 0 | 0 | 0001 | * | FMS | -> | 00000001 | - * | bitmap | -> | 11000000 | + * | bitmap | -> | 01111111 | * | bitmap (cont.) | -> | 00000011 | */ TESTASSERT(out_pdu->N_bytes == 4); - TESTASSERT(out_pdu->msg[0] == 0b00000001); + TESTASSERT(out_pdu->msg[0] == 0b00000001); // FMS = 257 TESTASSERT(out_pdu->msg[1] == 0b00000001); - TESTASSERT(out_pdu->msg[2] == 0b10000000); - TESTASSERT(out_pdu->msg[3] == 0b00000110); + TESTASSERT(out_pdu->msg[2] == 0b01111111); // FMS + 1 is missing + TESTASSERT(out_pdu->msg[3] == 0b11111000); // return 0; } @@ -106,37 +130,61 @@ int test_tx_status_report(const srslte::pdcp_lte_state_t& init_state, srslog::ba */ int test_tx_wraparound_status_report(const srslte::pdcp_lte_state_t& init_state, srslog::basic_logger& logger) { - srslte::pdcp_config_t cfg = {1, - srslte::PDCP_RB_IS_DRB, - srslte::SECURITY_DIRECTION_UPLINK, - srslte::SECURITY_DIRECTION_DOWNLINK, - srslte::PDCP_SN_LEN_12, - srslte::pdcp_t_reordering_t::ms500, - srslte::pdcp_discard_timer_t::ms500, - true}; + srslte::pdcp_config_t cfg_tx = {1, + srslte::PDCP_RB_IS_DRB, + srslte::SECURITY_DIRECTION_UPLINK, + srslte::SECURITY_DIRECTION_DOWNLINK, + srslte::PDCP_SN_LEN_12, + srslte::pdcp_t_reordering_t::ms500, + srslte::pdcp_discard_timer_t::ms500, + true}; + + srslte::pdcp_config_t cfg_rx = {1, + srslte::PDCP_RB_IS_DRB, + srslte::SECURITY_DIRECTION_DOWNLINK, + srslte::SECURITY_DIRECTION_UPLINK, + srslte::PDCP_SN_LEN_12, + srslte::pdcp_t_reordering_t::ms500, + srslte::pdcp_discard_timer_t::ms500, + true}; + + // Setup TX + pdcp_lte_test_helper pdcp_hlp_tx(cfg_tx, sec_cfg, logger); + srslte::pdcp_entity_lte* pdcp_tx = &pdcp_hlp_tx.pdcp; + rlc_dummy* rlc_tx = &pdcp_hlp_tx.rlc; + srsue::stack_test_dummy* stack_tx = &pdcp_hlp_tx.stack; + pdcp_hlp_tx.set_pdcp_initial_state(init_state); + + // Setup RX + pdcp_lte_test_helper pdcp_hlp_rx(cfg_tx, sec_cfg, logger); + srslte::pdcp_entity_lte* pdcp_rx = &pdcp_hlp_tx.pdcp; + rlc_dummy* rlc_rx = &pdcp_hlp_tx.rlc; + srsue::stack_test_dummy* stack_rx = &pdcp_hlp_tx.stack; + pdcp_hlp_rx.set_pdcp_initial_state(init_state); - pdcp_lte_test_helper pdcp_hlp(cfg, sec_cfg, logger); - srslte::pdcp_entity_lte* pdcp = &pdcp_hlp.pdcp; - rlc_dummy* rlc = &pdcp_hlp.rlc; - srsue::stack_test_dummy* stack = &pdcp_hlp.stack; - - pdcp_hlp.set_pdcp_initial_state(init_state); srslte::unique_byte_buffer_t out_pdu = srslte::make_byte_buffer(); // Write 256 SDUs and notify imediatly -> FMS 1111 1111 0000 for (uint32_t i = 0; i < 4080; i++) { srslte::unique_byte_buffer_t sdu = srslte::make_byte_buffer(); + srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer(); + if (sdu == nullptr or pdu == nullptr) { + logger.error("Could not allocate byte buffer"); + return SRSLTE_ERROR; + } sdu->append_bytes(sdu1, sizeof(sdu1)); - pdcp->write_sdu(std::move(sdu)); - pdcp->notify_delivery({i}); + pdcp_tx->write_sdu(std::move(sdu)); + pdcp_tx->notify_delivery({i}); + rlc_tx->get_last_sdu(pdu); + pdcp_rx->write_pdu(std::move(pdu)); } // Check undelivered SDUs queue size - TESTASSERT(pdcp->nof_discard_timers() == 0); // 0 timers should be running + TESTASSERT(pdcp_tx->nof_discard_timers() == 0); // 0 timers should be running // Generate the status report - pdcp->send_status_report(); - rlc->get_last_sdu(out_pdu); + pdcp_rx->send_status_report(); + rlc_rx->get_last_sdu(out_pdu); logger.debug(out_pdu->msg, out_pdu->N_bytes, "Status PDU:"); // Check status PDU @@ -151,19 +199,26 @@ int test_tx_wraparound_status_report(const srslte::pdcp_lte_state_t& init_state, // Write another 32 SDUs but don't notify SN=4080, SN=4081, SN=14 and SN=15 for (uint32_t i = 4080; i < 4112; i++) { srslte::unique_byte_buffer_t sdu = srslte::make_byte_buffer(); + srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer(); + if (sdu == nullptr or pdu == nullptr) { + logger.error("Could not allocate byte buffer"); + return SRSLTE_ERROR; + } sdu->append_bytes(sdu1, sizeof(sdu1)); - pdcp->write_sdu(std::move(sdu)); + pdcp_tx->write_sdu(std::move(sdu)); if (i != 4080 && i != 4081 && i != 4110 && i != 4111) { - pdcp->notify_delivery({i % 4096}); + pdcp_tx->notify_delivery({i % 4096}); + rlc_tx->get_last_sdu(pdu); + pdcp_rx->write_pdu(std::move(pdu)); } } // Check undelivered SDUs queue size - TESTASSERT(pdcp->nof_discard_timers() == 4); + TESTASSERT(pdcp_tx->nof_discard_timers() == 4); // Generate the status report - pdcp->send_status_report(); - rlc->get_last_sdu(out_pdu); + pdcp_rx->send_status_report(); + rlc_rx->get_last_sdu(out_pdu); logger.debug(out_pdu->msg, out_pdu->N_bytes, "Status PDU:"); // Check status PDU @@ -176,10 +231,10 @@ int test_tx_wraparound_status_report(const srslte::pdcp_lte_state_t& init_state, TESTASSERT(out_pdu->N_bytes == 6); TESTASSERT(out_pdu->msg[0] == 0b00001111); TESTASSERT(out_pdu->msg[1] == 0b11110000); - TESTASSERT(out_pdu->msg[2] == 0b10000000); - TESTASSERT(out_pdu->msg[3] == 0b00000000); - TESTASSERT(out_pdu->msg[4] == 0b00000000); - TESTASSERT(out_pdu->msg[5] == 0b00000110); + TESTASSERT(out_pdu->msg[2] == 0b01111111); + TESTASSERT(out_pdu->msg[3] == 0b11111111); + TESTASSERT(out_pdu->msg[4] == 0b11111111); + TESTASSERT(out_pdu->msg[5] == 0b11111000); return 0; } /* @@ -242,20 +297,6 @@ int test_rx_status_report(const srslte::pdcp_lte_state_t& init_state, srslog::ba pdcp->write_pdu(std::move(status_pdu)); TESTASSERT(pdcp->nof_discard_timers() == 1); - - // Check if the SDUs were correctly discarded with the status report - pdcp->send_status_report(); - rlc->get_last_sdu(out_pdu); - logger.debug(out_pdu->msg, out_pdu->N_bytes, "Status PDU:"); - - // Check status PDU, only 271 is missing => FMS = 271 - /* - * | D/C | TYPE | FMS | -> | 0 | 0 | 0001 | - * | FMS | -> | 00001111 | - */ - TESTASSERT(out_pdu->N_bytes == 3); - TESTASSERT(out_pdu->msg[0] == 0b00000001); - TESTASSERT(out_pdu->msg[1] == 0b00001111); return 0; } @@ -268,7 +309,8 @@ int run_all_tests() logger.set_hex_dump_max_size(128); // This is the normal initial state. All state variables are set to zero - srslte::pdcp_lte_state_t normal_init_state = {}; + srslte::pdcp_lte_state_t normal_init_state = {}; + normal_init_state.last_submitted_pdcp_rx_sn = 4095; TESTASSERT(test_tx_status_report(normal_init_state, logger) == 0); TESTASSERT(test_tx_wraparound_status_report(normal_init_state, logger) == 0); diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index 03d68f446..84b511c58 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -19,7 +19,7 @@ * */ -#include "srslte/common/log_filter.h" +#include "srslte/common/buffer_pool.h" #include "srslte/common/rlc_pcap.h" #include "srslte/common/test_common.h" #include "srslte/common/threads.h" @@ -61,7 +61,7 @@ public: void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) {} void write_pdu_pcch(unique_byte_buffer_t sdu) {} void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) {} - void notify_delivery(uint32_t lcid, const std::vector& pdcp_sn_vec) + void notify_delivery(uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sn_vec) { assert(lcid == 1); for (uint32_t pdcp_sn : pdcp_sn_vec) { @@ -71,7 +71,7 @@ public: notified_counts[pdcp_sn] += 1; } } - void notify_failure(uint32_t lcid, const std::vector& pdcp_sn_vec) + void notify_failure(uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sn_vec) { assert(lcid == 1); // TODO @@ -2464,7 +2464,7 @@ int header_reconstruction_test(srslte::log_sink_message_spy& spy) /// 13:35:16.337011 [RLC_1] [I] DRB1 Tx PDU SN=277 (20 B) /// 0000: 9d 15 80 20 0a 23 23 24 24 24 24 24 24 24 24 24 /// 0010: 24 25 25 25 - /// 13:35:16.337016 [RLC_1] [D] [Data PDU, RF=0, P=0, FI=1, SN=277, LSF=0, SO=0, N_li=2 (2, 10, )] + /// 13:35:16.337016 [RLC_1] [D] [Data PDU, RF=0, P=0, FI=1, SN=277, LSF=0, SO=0, N_li=2 (2, 10)] // 2nd retransmission with SO=9 std::array tv2 = {0xdd, 0x15, 0x80, 0x09, 0x00, 0x30, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25}; @@ -2505,7 +2505,7 @@ int header_reconstruction_test(srslte::log_sink_message_spy& spy) rlc1.write_pdu(pdu_tv3.msg, pdu_tv3.N_bytes); // Check RLC re-assembled message header - TESTASSERT(spy.has_message("[Data PDU, RF=0, P=0, FI=1, SN=277, LSF=0, SO=0, N_li=2 (2, 10, )]")); + TESTASSERT(spy.has_message("[Data PDU, RF=0, P=0, FI=1, SN=277, LSF=0, SO=0, N_li=2 (2, 10)]")); #if HAVE_PCAP pcap.close(); @@ -2569,7 +2569,7 @@ int header_reconstruction_test2(srslte::log_sink_message_spy& spy) rlc1.write_pdu(pdu_tv3.msg, pdu_tv3.N_bytes); // Check RLC re-assembled message header - TESTASSERT(spy.has_message("[Data PDU, RF=0, P=0, FI=1, SN=199, LSF=0, SO=0, N_li=2 (3, 10, )]")); + TESTASSERT(spy.has_message("[Data PDU, RF=0, P=0, FI=1, SN=199, LSF=0, SO=0, N_li=2 (3, 10)]")); #if HAVE_PCAP pcap.close(); @@ -2585,7 +2585,7 @@ int header_reconstruction_test3(srslte::log_sink_message_spy& spy) // 11:13:25.994566 [RLC_1] [I] DRB1 Tx PDU SN=206 (18 B) // 0000: 8c ce 00 a0 db db db db db db db db db db dc dc // 0010: dc dc - // 11:13:25.994571 [RLC_1] [D] [Data PDU, RF=0, P=0, FI=1, SN=206, LSF=0, SO=0, N_li=1 (10, )] + // 11:13:25.994571 [RLC_1] [D] [Data PDU, RF=0, P=0, FI=1, SN=206, LSF=0, SO=0, N_li=1 (10)] // 11:13:25.995744 [RLC_1] [I] DRB1 Retx PDU segment SN=206 [so=8] (12 B) (attempt 2/16) // 0000: dc ce 80 08 00 20 db db dc dc dc dc @@ -2631,7 +2631,7 @@ int header_reconstruction_test3(srslte::log_sink_message_spy& spy) rlc1.write_pdu(pdu_tv1.msg, pdu_tv1.N_bytes); // Check RLC re-assembled message header - TESTASSERT(spy.has_message("[Data PDU, RF=0, P=0, FI=1, SN=206, LSF=0, SO=0, N_li=1 (10, )]")); + TESTASSERT(spy.has_message("[Data PDU, RF=0, P=0, FI=1, SN=206, LSF=0, SO=0, N_li=1 (10)]")); #if HAVE_PCAP pcap.close(); @@ -2646,20 +2646,20 @@ int header_reconstruction_test4(srslte::log_sink_message_spy& spy) // 15:32:20.667043 [RLC_1] [I] DRB1 Tx PDU SN=172 (22 B) // 0000: 9c ac 80 10 0a af b0 b0 b0 b0 b0 b0 b0 b0 b0 b0 // 0010: b1 b1 b1 b1 b1 b1 - // 15:32:20.667048 [RLC_1] [D] [Data PDU, RF=0, P=0, FI=1, SN=172, LSF=0, SO=0, N_li=2 (1, 10, )] + // 15:32:20.667048 [RLC_1] [D] [Data PDU, RF=0, P=0, FI=1, SN=172, LSF=0, SO=0, N_li=2 (1, 10)] // 15:32:20.668094 [RLC_1] [I] DRB1 Retx PDU segment SN=172 [so=0] (14 B) (attempt 2/16) // 0000: dc ac 00 00 00 10 af b0 b0 b0 b0 b0 b0 b0 // 15:32:20.668100 [RLC_2] [I] DRB1 Rx data PDU segment of SN=172 (8 B), SO=0, N_li=1 // 0000: af b0 b0 b0 b0 b0 b0 b0 - // 15:32:20.668105 [RLC_2] [D] [Data PDU, RF=1, P=0, FI=1, SN=172, LSF=0, SO=0, N_li=1 (1, )] + // 15:32:20.668105 [RLC_2] [D] [Data PDU, RF=1, P=0, FI=1, SN=172, LSF=0, SO=0, N_li=1 (1)] std::array tv1 = {0xdc, 0xac, 0x00, 0x00, 0x00, 0x10, 0xaf, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0}; // 15:32:20.668497 [RLC_1] [I] DRB1 Retx PDU segment SN=172 [so=0] (12 B) (attempt 3/16) // 0000: fc ac 00 00 00 10 af b0 b0 b0 b0 b0 // 15:32:20.668502 [RLC_2] [I] DRB1 Rx data PDU segment of SN=172 (6 B), SO=0, N_li=1 // 0000: af b0 b0 b0 b0 b0 - // 15:32:20.668507 [RLC_2] [D] [Data PDU, RF=1, P=1, FI=1, SN=172, LSF=0, SO=0, N_li=1 (1, )] + // 15:32:20.668507 [RLC_2] [D] [Data PDU, RF=1, P=1, FI=1, SN=172, LSF=0, SO=0, N_li=1 (1)] std::array tv2 = {0xfc, 0xac, 0x00, 0x00, 0x00, 0x10, 0xaf, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0}; // 15:32:20.668575 [RLC_1] [I] DRB1 Retx PDU segment SN=172 [so=6] (7 B) (attempt 3/16) @@ -2674,7 +2674,7 @@ int header_reconstruction_test4(srslte::log_sink_message_spy& spy) // 0000: dc ac 80 09 00 20 b0 b0 b1 b1 b1 b1 b1 b1 // 15:32:20.668671 [RLC_2] [I] DRB1 Rx data PDU segment of SN=172 (8 B), SO=9, N_li=1 // 0000: b0 b0 b1 b1 b1 b1 b1 b1 - // 15:32:20.668675 [RLC_2] [D] [Data PDU, RF=1, P=0, FI=1, SN=172, LSF=1, SO=9, N_li=1 (2, )] + // 15:32:20.668675 [RLC_2] [D] [Data PDU, RF=1, P=0, FI=1, SN=172, LSF=1, SO=9, N_li=1 (2)] std::array tv4 = {0xdc, 0xac, 0x80, 0x09, 0x00, 0x20, 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1}; byte_buffer_t pdu_tv1; @@ -2721,7 +2721,7 @@ int header_reconstruction_test4(srslte::log_sink_message_spy& spy) rlc1.write_pdu(pdu_tv4.msg, pdu_tv4.N_bytes); // Check RLC re-assembled message header - TESTASSERT(spy.has_message("[Data PDU, RF=0, P=0, FI=1, SN=172, LSF=0, SO=0, N_li=2 (1, 10, )]")); + TESTASSERT(spy.has_message("[Data PDU, RF=0, P=0, FI=1, SN=172, LSF=0, SO=0, N_li=2 (1, 10)]")); #if HAVE_PCAP pcap.close(); @@ -2736,7 +2736,7 @@ int header_reconstruction_test5(srslte::log_sink_message_spy& spy) // 18:46:22.372858 [RLC_1] [I] DRB1 Tx PDU SN=222 (22 B) // 0000: bc de 80 30 0a ee ee ee ef ef ef ef ef ef ef ef // 0010: ef ef f0 f0 f0 f0 - // 18:46:22.372863 [RLC_1] [D] [Data PDU, RF=0, P=1, FI=1, SN=222, LSF=0, SO=0, N_li=2 (3, 10, )] + // 18:46:22.372863 [RLC_1] [D] [Data PDU, RF=0, P=1, FI=1, SN=222, LSF=0, SO=0, N_li=2 (3, 10)] // 18:46:22.373623 [RLC_1] [I] DRB1 Retx PDU segment SN=222 [so=0] (7 B) (attempt 2/16) // 0000: d0 de 00 00 ee ee ee @@ -2797,7 +2797,7 @@ int header_reconstruction_test5(srslte::log_sink_message_spy& spy) rlc1.write_pdu(pdu_tv2.msg, pdu_tv2.N_bytes); // Check RLC re-assembled message header - TESTASSERT(spy.has_message("[Data PDU, RF=0, P=0, FI=1, SN=222, LSF=0, SO=0, N_li=2 (3, 10, )]")); + TESTASSERT(spy.has_message("[Data PDU, RF=0, P=0, FI=1, SN=222, LSF=0, SO=0, N_li=2 (3, 10)]")); #if HAVE_PCAP pcap.close(); @@ -2812,7 +2812,7 @@ int header_reconstruction_test6(srslte::log_sink_message_spy& spy) // 21:50:12.709646 [RLC_1] [I] DRB1 Tx PDU SN=509 (20 B) // 0000: 9d fd 80 40 0a b1 b1 b1 b1 b2 b2 b2 b2 b2 b2 b2 // 0010: b2 b2 b2 b3 - // 21:50:12.709653 [RLC_1] [D] [Data PDU, RF=0, P=0, FI=1, SN=509, LSF=0, SO=0, N_li=2 (4, 10, )]] + // 21:50:12.709653 [RLC_1] [D] [Data PDU, RF=0, P=0, FI=1, SN=509, LSF=0, SO=0, N_li=2 (4, 10)]] // 21:50:12.711022 [RLC_1] [I] DRB1 Retx PDU segment SN=509 [so=0] (5 B) (attempt 3/16) // 0000: d9 fd 00 00 b1 @@ -2833,7 +2833,7 @@ int header_reconstruction_test6(srslte::log_sink_message_spy& spy) // 0010: b3 // 21:50:12.711210 [RLC_2] [I] DRB1 Rx data PDU segment of SN=509 (11 B), SO=4, N_li=1 // 0000: b2 b2 b2 b2 b2 b2 b2 b2 b2 b2 b3 - // 21:50:12.711216 [RLC_2] [D] [Data PDU, RF=1, P=1, FI=1, SN=509, LSF=1, SO=4, N_li=1 (10, )] + // 21:50:12.711216 [RLC_2] [D] [Data PDU, RF=1, P=1, FI=1, SN=509, LSF=1, SO=4, N_li=1 (10)] std::array tv2 = { 0xed, 0xfd, 0x80, 0x04, 0x00, 0xa0, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb3}; @@ -2876,7 +2876,7 @@ int header_reconstruction_test6(srslte::log_sink_message_spy& spy) rlc1.write_pdu(pdu_tv2.msg, pdu_tv2.N_bytes); // Check RLC re-assembled message header - TESTASSERT(spy.has_message("[Data PDU, RF=0, P=1, FI=1, SN=509, LSF=0, SO=0, N_li=2 (4, 10, )]")); + TESTASSERT(spy.has_message("[Data PDU, RF=0, P=1, FI=1, SN=509, LSF=0, SO=0, N_li=2 (4, 10)]")); #if HAVE_PCAP pcap.close(); @@ -2891,7 +2891,7 @@ int header_reconstruction_test7(srslte::log_sink_message_spy& spy) // 22:14:54.646530 [RLC_1] [I] DRB1 Tx PDU SN=282 (19 B) // 0000: 9d 1a 80 10 0a 28 29 29 29 29 29 29 29 29 29 29 // 0010: 2a 2a 2a - // 22:14:54.646535 [RLC_1] [D] [Data PDU, RF=0, P=0, FI=1, SN=282, LSF=0, SO=0, N_li=2 (1, 10, )] + // 22:14:54.646535 [RLC_1] [D] [Data PDU, RF=0, P=0, FI=1, SN=282, LSF=0, SO=0, N_li=2 (1, 10)] // 22:14:54.648484 [RLC_1] [I] DRB1 Retx PDU segment SN=282 [so=2] (6 B) (attempt 2/16) // 0000: f9 1a 00 02 29 29 @@ -2979,7 +2979,7 @@ int header_reconstruction_test7(srslte::log_sink_message_spy& spy) rlc1.write_pdu(pdu_tv4.msg, pdu_tv4.N_bytes); // Check RLC re-assembled message header - TESTASSERT(spy.has_message("[Data PDU, RF=0, P=0, FI=1, SN=282, LSF=0, SO=0, N_li=2 (1, 10, )]")); + TESTASSERT(spy.has_message("[Data PDU, RF=0, P=0, FI=1, SN=282, LSF=0, SO=0, N_li=2 (1, 10)]")); #if HAVE_PCAP pcap.close(); @@ -2995,14 +2995,14 @@ int header_reconstruction_test8(srslte::log_sink_message_spy& spy) // 0000: b5 a7 80 38 0a 00 a0 77 77 77 78 78 78 78 78 78 // 0010: 78 78 78 78 79 79 79 79 79 79 79 79 79 79 7a 7a // 0020: 7a 7a 7a 7a 7a 7a 7a 7a - // 21:23:34.407724 [RLC_1] [D] [Data PDU, RF=0, P=1, FI=1, SN=423, LSF=0, SO=0, N_li=3 (3, 10, 10, )] + // 21:23:34.407724 [RLC_1] [D] [Data PDU, RF=0, P=1, FI=1, SN=423, LSF=0, SO=0, N_li=3 (3, 10, 10)] // 21:23:34.408815 [RLC_1] [I] DRB1 Retx PDU segment SN=423 [so=0] (18 B) (attempt 2/8) // 0000: fd a7 00 00 00 30 77 77 77 78 78 78 78 78 78 78 // 0010: 78 78 // 21:23:34.408822 [RLC_2] [I] DRB1 Rx data PDU segment of SN=423 (12 B), SO=0, N_li=1 // 0000: 77 77 77 78 78 78 78 78 78 78 78 78 - // 21:23:34.408828 [RLC_2] [D] [Data PDU, RF=1, P=1, FI=1, SN=423, LSF=0, SO=0, N_li=1 (3, )] + // 21:23:34.408828 [RLC_2] [D] [Data PDU, RF=1, P=1, FI=1, SN=423, LSF=0, SO=0, N_li=1 (3)] std::array tv0 = { 0xfd, 0xa7, 0x00, 0x00, 0x00, 0x30, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78}; @@ -3011,7 +3011,7 @@ int header_reconstruction_test8(srslte::log_sink_message_spy& spy) // 0010: 79 // 21:23:34.408919 [RLC_2] [I] DRB1 Rx data PDU segment of SN=423 (11 B), SO=12, N_li=1 // 0000: 78 79 79 79 79 79 79 79 79 79 79 - // 21:23:34.408925 [RLC_2] [D] [Data PDU, RF=1, P=1, FI=1, SN=423, LSF=0, SO=12, N_li=1 (1, )] + // 21:23:34.408925 [RLC_2] [D] [Data PDU, RF=1, P=1, FI=1, SN=423, LSF=0, SO=12, N_li=1 (1)] std::array tv1 = { 0xf5, 0xa7, 0x00, 0x0c, 0x00, 0x10, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79}; @@ -3020,7 +3020,7 @@ int header_reconstruction_test8(srslte::log_sink_message_spy& spy) // 0010: 78 78 78 // 21:23:34.409433 [RLC_2] [I] DRB1 Rx data PDU segment of SN=423 (13 B), SO=0, N_li=1 // 0000: 77 77 77 78 78 78 78 78 78 78 78 78 78 - // 21:23:34.409440 [RLC_2] [D] [Data PDU, RF=1, P=1, FI=1, SN=423, LSF=0, SO=0, N_li=1 (3, )] + // 21:23:34.409440 [RLC_2] [D] [Data PDU, RF=1, P=1, FI=1, SN=423, LSF=0, SO=0, N_li=1 (3)] std::array tv2 = { 0xf5, 0xa7, 0x00, 0x00, 0x00, 0x30, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78}; @@ -3030,7 +3030,7 @@ int header_reconstruction_test8(srslte::log_sink_message_spy& spy) // 21:23:34.409531 [RLC_2] [I] DRB1 Rx data PDU segment of SN=423 (20 B), SO=13, N_li=1 // 0000: 79 79 79 79 79 79 79 79 79 79 7a 7a 7a 7a 7a 7a // 0010: 7a 7a 7a 7a - // 21:23:34.409537 [RLC_2] [D] [Data PDU, RF=1, P=1, FI=0, SN=423, LSF=1, SO=13, N_li=1 (10, )] + // 21:23:34.409537 [RLC_2] [D] [Data PDU, RF=1, P=1, FI=0, SN=423, LSF=1, SO=13, N_li=1 (10)] std::array tv3 = {0xe5, 0xa7, 0x80, 0x0d, 0x00, 0xa0, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a}; @@ -3080,7 +3080,7 @@ int header_reconstruction_test8(srslte::log_sink_message_spy& spy) rlc1.write_pdu(pdu_tv3.msg, pdu_tv3.N_bytes); // Check RLC re-assembled message header - TESTASSERT(spy.has_message("[Data PDU, RF=0, P=1, FI=1, SN=423, LSF=0, SO=0, N_li=3 (3, 10, 10, )]")); + TESTASSERT(spy.has_message("[Data PDU, RF=0, P=1, FI=1, SN=423, LSF=0, SO=0, N_li=3 (3, 10, 10)]")); return SRSLTE_SUCCESS; } @@ -3424,10 +3424,6 @@ bool reestablish_test() int main(int argc, char** argv) { - srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG); - srslte::logmap::set_default_hex_limit(4096); - TESTASSERT(srslte::logmap::get("RLC_AM_1")->get_level() == srslte::LOG_LEVEL_DEBUG); - // Setup the log message spy to intercept error and warning log entries from RLC if (!srslog::install_custom_sink(srslte::log_sink_message_spy::name(), std::unique_ptr( @@ -3445,6 +3441,8 @@ int main(int argc, char** argv) auto& logger_rrc2 = srslog::fetch_basic_logger("RLC_AM_2", *spy, false); logger_rrc1.set_hex_dump_max_size(100); logger_rrc2.set_hex_dump_max_size(100); + logger_rrc1.set_level(srslog::basic_levels::debug); + logger_rrc2.set_level(srslog::basic_levels::debug); // start log backend srslog::init(); @@ -3615,4 +3613,4 @@ int main(int argc, char** argv) }; return SRSLTE_SUCCESS; -} \ No newline at end of file +} diff --git a/lib/test/upper/rlc_common_test.cc b/lib/test/upper/rlc_common_test.cc index e6d7f3b18..bc0721592 100644 --- a/lib/test/upper/rlc_common_test.cc +++ b/lib/test/upper/rlc_common_test.cc @@ -19,7 +19,6 @@ * */ -#include "srslte/common/log_filter.h" #include "srslte/upper/rlc.h" #include @@ -55,8 +54,8 @@ public: } sdus[n_sdus++] = std::move(sdu); } - void notify_delivery(uint32_t lcid, const std::vector& pdcp_sn) {} - void notify_failure(uint32_t lcid, const std::vector& pdcp_sn) {} + void notify_delivery(uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sn) {} + void notify_failure(uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sn) {} void write_pdu_bcch_bch(unique_byte_buffer_t sdu) {} void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) {} void write_pdu_pcch(unique_byte_buffer_t sdu) {} diff --git a/lib/test/upper/rlc_stress_test.cc b/lib/test/upper/rlc_stress_test.cc index 0386f37a7..3907bb06d 100644 --- a/lib/test/upper/rlc_stress_test.cc +++ b/lib/test/upper/rlc_stress_test.cc @@ -19,8 +19,8 @@ * */ +#include "srslte/common/block_queue.h" #include "srslte/common/crash_handler.h" -#include "srslte/common/log_filter.h" #include "srslte/common/rlc_pcap.h" #include "srslte/common/test_common.h" #include "srslte/common/threads.h" @@ -112,7 +112,7 @@ void parse_args(stress_test_args_t* args, int argc, char* argv[]) ("pdu_drop_rate", bpo::value(&args->pdu_drop_rate)->default_value(0.1), "Rate at which RLC PDUs are dropped") ("pdu_cut_rate", bpo::value(&args->pdu_cut_rate)->default_value(0.0), "Rate at which RLC PDUs are chopped in length") ("pdu_duplicate_rate", bpo::value(&args->pdu_duplicate_rate)->default_value(0.0), "Rate at which RLC PDUs are duplicated") - ("loglevel", bpo::value(&args->log_level)->default_value(srslte::LOG_LEVEL_DEBUG), "Log level (1=Error,2=Warning,3=Info,4=Debug)") + ("loglevel", bpo::value(&args->log_level)->default_value((int)srslog::basic_levels::debug), "Log level (1=Error,2=Warning,3=Info,4=Debug)") ("singletx", bpo::value(&args->single_tx)->default_value(false), "If set to true, only one node is generating data") ("pcap", bpo::value(&args->write_pcap)->default_value(false), "Whether to write all RLC PDU to PCAP file") ("zeroseed", bpo::value(&args->zero_seed)->default_value(false), "Whether to initialize random seed to zero") @@ -138,7 +138,9 @@ void parse_args(stress_test_args_t* args, int argc, char* argv[]) if (args->log_level > 4) { args->log_level = 4; - printf("Set log level to %d (%s)\n", args->log_level, srslte::log_level_text[args->log_level]); + printf("Set log level to %d (%s)\n", + args->log_level, + srslog::basic_level_to_string(static_cast(args->log_level))); } // convert mode to upper case @@ -375,9 +377,9 @@ public: void write_pdu_bcch_bch(unique_byte_buffer_t sdu) {} void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) {} void write_pdu_pcch(unique_byte_buffer_t sdu) {} - void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t sdu) {} - void notify_delivery(uint32_t lcid, const std::vector& pdcp_sns) {} - void notify_failure(uint32_t lcid, const std::vector& pdcp_sns) {} + void write_pdu_mch(uint32_t lcid_, srslte::unique_byte_buffer_t sdu) {} + void notify_delivery(uint32_t lcid_, const srslte::pdcp_sn_vector_t& pdcp_sns) {} + void notify_failure(uint32_t lcid_, const srslte::pdcp_sn_vector_t& pdcp_sns) {} // RRC interface void max_retx_attempted() @@ -439,7 +441,6 @@ private: uint8_t next_expected_sdu = 0; uint64_t rx_pdus = 0; uint32_t lcid = 0; - srslte::log_filter log; srslog::basic_logger& logger; std::string name; @@ -468,7 +469,7 @@ void stress_test(stress_test_args_t args) if (args.rat == "LTE") { if (args.mode == "AM") { // config RLC AM bearer - cnfg_ = rlc_config_t::default_rlc_am_config(); + cnfg_ = rlc_config_t::default_rlc_am_config(); cnfg_.am.max_retx_thresh = args.max_retx; } else if (args.mode == "UM") { // config UM bearer diff --git a/lib/test/upper/rlc_test_common.h b/lib/test/upper/rlc_test_common.h index 97d6dd530..745c028d1 100644 --- a/lib/test/upper/rlc_test_common.h +++ b/lib/test/upper/rlc_test_common.h @@ -60,8 +60,8 @@ public: void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) {} void write_pdu_pcch(unique_byte_buffer_t sdu) {} void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t sdu) { sdus.push_back(std::move(sdu)); } - void notify_delivery(uint32_t lcid, const std::vector& pdcp_sns) {} - void notify_failure(uint32_t lcid, const std::vector& pdcp_sns) {} + void notify_delivery(uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sns) {} + void notify_failure(uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sns) {} // RRC interface void max_retx_attempted() {} diff --git a/lib/test/upper/rlc_um_nr_test.cc b/lib/test/upper/rlc_um_nr_test.cc index 52531f7f3..a6d3e90db 100644 --- a/lib/test/upper/rlc_um_nr_test.cc +++ b/lib/test/upper/rlc_um_nr_test.cc @@ -20,7 +20,6 @@ */ #include "rlc_test_common.h" -#include "srslte/common/log_filter.h" #include "srslte/config.h" #include "srslte/interfaces/ue_pdcp_interfaces.h" #include "srslte/upper/rlc.h" diff --git a/lib/test/upper/rlc_um_test.cc b/lib/test/upper/rlc_um_test.cc index 3f60c0fac..ab9cde2ac 100644 --- a/lib/test/upper/rlc_um_test.cc +++ b/lib/test/upper/rlc_um_test.cc @@ -20,7 +20,6 @@ */ #include "rlc_test_common.h" -#include "srslte/common/log_filter.h" #include "srslte/upper/rlc_um_lte.h" #include diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index 7b700858f..e8dcc7b97 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -169,7 +169,8 @@ enable = false # ##################################################################### [scheduler] -#sched_policy = time_pf +#policy = time_pf +#policy_args = 2 #max_aggr_level = -1 #pdsch_mcs = -1 #pdsch_max_mcs = -1 @@ -177,6 +178,7 @@ enable = false #pusch_max_mcs = 16 #min_nof_ctrl_symbols = 1 #max_nof_ctrl_symbols = 3 +#pucch_multiplex_enable = false ##################################################################### # eMBMS configuration options @@ -294,6 +296,9 @@ enable = false # metrics_period_secs: Sets the period at which metrics are requested from the eNB. # metrics_csv_enable: Write eNB metrics to CSV file. # metrics_csv_filename: File path to use for CSV metrics. +# tracing_enable: Write source code tracing information to a file. +# tracing_filename: File path to use for tracing information. +# tracing_buffcapacity: Maximum capacity in bytes the tracing framework can store. # pregenerate_signals: Pregenerate uplink signals after attach. Improves CPU performance. # tx_amplitude: Transmit amplitude factor (set 0-1 to reduce PAPR) # rrc_inactivity_timer Inactivity timeout used to remove UE context from RRC (in milliseconds). @@ -313,6 +318,9 @@ enable = false #report_json_filename = /tmp/enb_report.json #alarms_log_enable = true #alarms_filename = /tmp/enb_alarms.log +#tracing_enable = true +#tracing_filename = /tmp/enb_tracing.log +#tracing_buffcapacity = 1000000 #pregenerate_signals = false #tx_amplitude = 0.6 #rrc_inactivity_timer = 30000 diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index f4089a559..e25ff59c9 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -40,11 +40,9 @@ #include "srsenb/hdr/stack/enb_stack_base.h" #include "srsenb/hdr/stack/rrc/rrc_config.h" -#include "srslte/system/sys_metrics_processor.h" #include "srslte/common/bcd_helpers.h" #include "srslte/common/buffer_pool.h" #include "srslte/common/interfaces_common.h" -#include "srslte/common/log_filter.h" #include "srslte/common/mac_pcap.h" #include "srslte/common/security.h" #include "srslte/interfaces/enb_command_interface.h" @@ -52,6 +50,7 @@ #include "srslte/interfaces/sched_interface.h" #include "srslte/interfaces/ue_interfaces.h" #include "srslte/srslog/srslog.h" +#include "srslte/system/sys_metrics_processor.h" namespace srsenb { @@ -98,6 +97,9 @@ struct general_args_t { bool alarms_log_enable; std::string alarms_filename; bool print_buffer_state; + bool tracing_enable; + std::size_t tracing_buffcapacity; + std::string tracing_filename; std::string eia_pref_list; std::string eea_pref_list; }; @@ -126,7 +128,7 @@ public: virtual ~enb(); - int init(const all_args_t& args_, srslte::logger* logger_); + int init(const all_args_t& args_); void stop(); @@ -145,7 +147,6 @@ private: int parse_args(const all_args_t& args_, rrc_cfg_t& rrc_cfg); - srslte::logger* logger = nullptr; srslog::sink& log_sink; srslog::basic_logger& enb_log; @@ -163,8 +164,6 @@ private: // System metrics processor. srslte::sys_metrics_processor sys_proc; - srslte::LOG_LEVEL_ENUM level(std::string l); - std::string get_build_mode(); std::string get_build_info(); std::string get_build_string(); diff --git a/srsenb/hdr/phy/nr/cc_worker.h b/srsenb/hdr/phy/nr/cc_worker.h index 74db1ae7b..c650c67f8 100644 --- a/srsenb/hdr/phy/nr/cc_worker.h +++ b/srsenb/hdr/phy/nr/cc_worker.h @@ -22,7 +22,6 @@ #ifndef SRSENB_NR_CC_WORKER_H #define SRSENB_NR_CC_WORKER_H -#include "srslte/common/log.h" #include "srslte/interfaces/gnb_interfaces.h" #include "srslte/phy/enb/enb_dl_nr.h" #include "srslte/srslog/srslog.h" diff --git a/srsenb/hdr/phy/phy.h b/srsenb/hdr/phy/phy.h index 3bff23aa0..3b52865b2 100644 --- a/srsenb/hdr/phy/phy.h +++ b/srsenb/hdr/phy/phy.h @@ -25,8 +25,6 @@ #include "lte/sf_worker.h" #include "phy_common.h" #include "srsenb/hdr/phy/enb_phy_base.h" -#include "srslte/common/log.h" -#include "srslte/common/log_filter.h" #include "srslte/common/trace.h" #include "srslte/interfaces/enb_metrics_interface.h" #include "srslte/interfaces/radio_interfaces.h" diff --git a/srsenb/hdr/phy/phy_common.h b/srsenb/hdr/phy/phy_common.h index f9c46c734..1fa6e8319 100644 --- a/srsenb/hdr/phy/phy_common.h +++ b/srsenb/hdr/phy/phy_common.h @@ -26,13 +26,14 @@ #include "srsenb/hdr/phy/phy_ue_db.h" #include "srslte/common/gen_mch_tables.h" #include "srslte/common/interfaces_common.h" -#include "srslte/common/log.h" +#include "srslte/common/standard_streams.h" #include "srslte/common/thread_pool.h" #include "srslte/common/threads.h" #include "srslte/interfaces/enb_metrics_interface.h" #include "srslte/interfaces/radio_interfaces.h" #include "srslte/phy/channel/channel.h" #include "srslte/radio/radio.h" + #include #include #include diff --git a/srsenb/hdr/phy/prach_worker.h b/srsenb/hdr/phy/prach_worker.h index 30977d1f8..791aabc5b 100644 --- a/srsenb/hdr/phy/prach_worker.h +++ b/srsenb/hdr/phy/prach_worker.h @@ -24,7 +24,6 @@ #include "srslte/common/block_queue.h" #include "srslte/common/buffer_pool.h" -#include "srslte/common/log.h" #include "srslte/common/threads.h" #include "srslte/interfaces/enb_phy_interfaces.h" #include "srslte/srslog/srslog.h" diff --git a/srsenb/hdr/phy/txrx.h b/srsenb/hdr/phy/txrx.h index 2c667b5b8..bbef4c693 100644 --- a/srsenb/hdr/phy/txrx.h +++ b/srsenb/hdr/phy/txrx.h @@ -26,7 +26,6 @@ #include "prach_worker.h" #include "srsenb/hdr/phy/lte/worker_pool.h" #include "srsenb/hdr/phy/nr/worker_pool.h" -#include "srslte/common/log.h" #include "srslte/config.h" #include "srslte/phy/channel/channel.h" #include "srslte/radio/radio.h" diff --git a/srsenb/hdr/phy/vnf_phy_nr.h b/srsenb/hdr/phy/vnf_phy_nr.h index 325f3c053..7edb571da 100644 --- a/srsenb/hdr/phy/vnf_phy_nr.h +++ b/srsenb/hdr/phy/vnf_phy_nr.h @@ -25,8 +25,6 @@ #include "srsenb/hdr/phy/enb_phy_base.h" #include "srsenb/hdr/phy/phy_common.h" #include "srslte/common/basic_vnf.h" -#include "srslte/common/log.h" -#include "srslte/common/log_filter.h" #include "srslte/interfaces/enb_metrics_interface.h" #include "srslte/interfaces/gnb_interfaces.h" #include "srslte/interfaces/radio_interfaces.h" @@ -71,4 +69,4 @@ private: } // namespace srsenb -#endif // SRSGNB_NR_VNF_PHY_H \ No newline at end of file +#endif // SRSGNB_NR_VNF_PHY_H diff --git a/srsenb/hdr/stack/enb_stack_lte.h b/srsenb/hdr/stack/enb_stack_lte.h index 3649a68ba..4a2785f0c 100644 --- a/srsenb/hdr/stack/enb_stack_lte.h +++ b/srsenb/hdr/stack/enb_stack_lte.h @@ -49,7 +49,7 @@ class enb_stack_lte final : public enb_stack_base, public srslte::thread { public: - enb_stack_lte(srslte::logger* logger_, srslog::sink& log_sink); + enb_stack_lte(srslog::sink& log_sink); ~enb_stack_lte() final; // eNB stack base interface @@ -154,24 +154,13 @@ private: srsenb::gtpu gtpu; srsenb::s1ap s1ap; - srslte::logger* logger = nullptr; - - // Radio and PHY log are in enb.cc - srslte::log_ref mac_log{"MAC"}; - srslte::log_ref rlc_log{"RLC"}; - srslte::log_ref pdcp_log{"PDCP"}; - srslte::log_ref rrc_log{"RRC"}; - srslte::log_ref s1ap_log{"S1AP"}; - srslte::log_ref gtpu_log{"GTPU"}; - srslte::log_ref stack_log{"STCK"}; - // RAT-specific interfaces phy_interface_stack_lte* phy = nullptr; // state bool started = false; - srslte::block_queue pending_stack_metrics; + srslte::dyn_blocking_queue pending_stack_metrics; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/gnb_stack_nr.h b/srsenb/hdr/stack/gnb_stack_nr.h index 6cccc98ce..e2db87572 100644 --- a/srsenb/hdr/stack/gnb_stack_nr.h +++ b/srsenb/hdr/stack/gnb_stack_nr.h @@ -35,8 +35,6 @@ #include "upper/s1ap.h" #include "upper/sdap.h" -#include "srslte/common/log_filter.h" - #include "enb_stack_base.h" #include "srsenb/hdr/enb.h" #include "srslte/interfaces/gnb_interfaces.h" @@ -90,6 +88,8 @@ private: srsenb::stack_args_t args = {}; phy_interface_stack_nr* phy = nullptr; + srslog::basic_logger& rlc_logger; + // task scheduling static const int STACK_MAIN_THREAD_PRIO = 4; srslte::task_scheduler task_sched; diff --git a/srsenb/hdr/stack/mac/mac.h b/srsenb/hdr/stack/mac/mac.h index 57e6c6030..2e400d389 100644 --- a/srsenb/hdr/stack/mac/mac.h +++ b/srsenb/hdr/stack/mac/mac.h @@ -24,7 +24,6 @@ #include "sched.h" #include "srsenb/hdr/stack/mac/schedulers/sched_time_rr.h" -#include "srslte/common/log.h" #include "srslte/common/mac_pcap.h" #include "srslte/common/mac_pcap_net.h" #include "srslte/common/task_scheduler.h" @@ -50,8 +49,7 @@ public: const cell_list_t& cells_, phy_interface_stack_lte* phy, rlc_interface_mac* rlc, - rrc_interface_mac* rrc, - srslte::log_ref log_h); + rrc_interface_mac* rrc); void stop(); void start_pcap(srslte::mac_pcap* pcap_); @@ -129,7 +127,6 @@ private: rlc_interface_mac* rlc_h = nullptr; rrc_interface_mac* rrc_h = nullptr; srslte::ext_task_sched_handle task_sched; - srslte::log_ref log_h; cell_list_t cells = {}; mac_args_t args = {}; @@ -149,8 +146,8 @@ private: std::map > ue_db, ues_to_rem; uint16_t last_rnti = 70; - srslte::block_queue > ue_pool; ///< Pool of pre-allocated UE objects - void prealloc_ue(uint32_t nof_ue); + srslte::static_blocking_queue, 32> ue_pool; ///< Pool of pre-allocated UE objects + void prealloc_ue(uint32_t nof_ue); uint8_t* assemble_rar(sched_interface::dl_sched_rar_grant_t* grants, uint32_t enb_cc_idx, diff --git a/srsenb/hdr/stack/mac/mac_nr.h b/srsenb/hdr/stack/mac/mac_nr.h index e6a0e3858..97d0b957c 100644 --- a/srsenb/hdr/stack/mac/mac_nr.h +++ b/srsenb/hdr/stack/mac/mac_nr.h @@ -23,7 +23,6 @@ #define SRSENB_MAC_NR_H #include "srslte/common/block_queue.h" -#include "srslte/common/logmap.h" #include "srslte/common/mac_pcap.h" #include "srslte/mac/mac_sch_pdu_nr.h" @@ -91,8 +90,8 @@ private: rrc_interface_mac_nr* rrc_h = nullptr; std::unique_ptr pcap = nullptr; - srslte::log_ref log_h; mac_nr_args_t args = {}; + srslog::basic_logger& logger; bool started = false; diff --git a/srsenb/hdr/stack/mac/sched.h b/srsenb/hdr/stack/mac/sched.h index b28efe6f8..08de8eba3 100644 --- a/srsenb/hdr/stack/mac/sched.h +++ b/srsenb/hdr/stack/mac/sched.h @@ -24,7 +24,6 @@ #include "sched_grid.h" #include "sched_ue.h" -#include "srslte/common/log.h" #include "srslte/interfaces/sched_interface.h" #include #include diff --git a/srsenb/hdr/stack/mac/sched_common.h b/srsenb/hdr/stack/mac/sched_common.h index f953d4424..eefab2a26 100644 --- a/srsenb/hdr/stack/mac/sched_common.h +++ b/srsenb/hdr/stack/mac/sched_common.h @@ -118,4 +118,13 @@ enum class alloc_type_t { DL_BC, DL_PCCH, DL_RAR, DL_DATA, UL_DATA }; } // namespace srsenb +namespace fmt { + +template <> +struct formatter : public formatter > {}; +template <> +struct formatter : public formatter > {}; + +} // namespace fmt + #endif // SRSLTE_SCHED_COMMON_H diff --git a/srsenb/hdr/stack/mac/sched_grid.h b/srsenb/hdr/stack/mac/sched_grid.h index f43506e01..a5c8c9348 100644 --- a/srsenb/hdr/stack/mac/sched_grid.h +++ b/srsenb/hdr/stack/mac/sched_grid.h @@ -26,7 +26,6 @@ #include "sched_phy_ch/sf_cch_allocator.h" #include "sched_ue.h" #include "srslte/adt/bounded_bitset.h" -#include "srslte/common/log.h" #include "srslte/srslog/srslog.h" #include #include @@ -113,7 +112,7 @@ public: dl_ctrl_alloc_t alloc_dl_ctrl(uint32_t aggr_lvl, alloc_type_t alloc_type); alloc_outcome_t alloc_dl_data(sched_ue* user, const rbgmask_t& user_mask, bool has_pusch_grant); bool reserve_dl_rbgs(uint32_t start_rbg, uint32_t end_rbg); - alloc_outcome_t alloc_ul_data(sched_ue* user, prb_interval alloc, bool needs_pdcch); + alloc_outcome_t alloc_ul_data(sched_ue* user, prb_interval alloc, bool needs_pdcch, bool strict = true); alloc_outcome_t reserve_ul_prbs(const prbmask_t& prbmask, bool strict); alloc_outcome_t reserve_ul_prbs(prb_interval alloc, bool strict); bool find_ul_alloc(uint32_t L, prb_interval* alloc) const; @@ -183,15 +182,15 @@ public: uint32_t pid; }; struct ul_alloc_t { - enum type_t { NEWTX, NOADAPT_RETX, ADAPT_RETX, MSG3, MSG3_RETX }; + enum type_t { NEWTX, NOADAPT_RETX, ADAPT_RETX }; + bool is_msg3 = false; size_t dci_idx; type_t type; uint16_t rnti; prb_interval alloc; int msg3_mcs = -1; bool is_retx() const { return type == NOADAPT_RETX or type == ADAPT_RETX; } - bool is_msg3() const { return type == MSG3; } - bool needs_pdcch() const { return type == NEWTX or type == ADAPT_RETX; } + bool needs_pdcch() const { return (type == NEWTX and not is_msg3) or type == ADAPT_RETX; } }; struct pending_msg3_t { uint16_t rnti = 0; @@ -221,7 +220,8 @@ public: // UL alloc methods alloc_outcome_t alloc_msg3(sched_ue* user, const sched_interface::dl_sched_rar_grant_t& rargrant); - alloc_outcome_t alloc_ul(sched_ue* user, prb_interval alloc, ul_alloc_t::type_t alloc_type, int msg3_mcs = -1); + alloc_outcome_t + alloc_ul(sched_ue* user, prb_interval alloc, ul_alloc_t::type_t alloc_type, bool is_msg3 = false, int msg3_mcs = -1); bool reserve_ul_prbs(const prbmask_t& ulmask, bool strict) { return tti_alloc.reserve_ul_prbs(ulmask, strict); } bool alloc_phich(sched_ue* user, sched_interface::ul_sched_res_t* ul_sf_result); @@ -237,10 +237,11 @@ public: tti_point get_tti_tx_ul() const { return to_tx_ul(tti_rx); } // getters - tti_point get_tti_rx() const { return tti_rx; } - bool is_dl_alloc(uint16_t rnti) const; - bool is_ul_alloc(uint16_t rnti) const; - uint32_t get_enb_cc_idx() const { return cc_cfg->enb_cc_idx; } + tti_point get_tti_rx() const { return tti_rx; } + bool is_dl_alloc(uint16_t rnti) const; + bool is_ul_alloc(uint16_t rnti) const; + uint32_t get_enb_cc_idx() const { return cc_cfg->enb_cc_idx; } + const sched_cell_params_t* get_cc_cfg() const { return cc_cfg; } private: ctrl_code_t alloc_dl_ctrl(uint32_t aggr_lvl, uint32_t tbs_bytes, uint16_t rnti); diff --git a/srsenb/hdr/stack/mac/sched_helpers.h b/srsenb/hdr/stack/mac/sched_helpers.h index c8b78df0a..bfb386a63 100644 --- a/srsenb/hdr/stack/mac/sched_helpers.h +++ b/srsenb/hdr/stack/mac/sched_helpers.h @@ -23,7 +23,6 @@ #define SRSLTE_SCHED_HELPERS_H #include "srsenb/hdr/stack/mac/sched_common.h" -#include "srslte/common/logmap.h" #include "srslte/interfaces/sched_interface.h" #include "srslte/srslog/srslog.h" @@ -65,7 +64,7 @@ inline uint32_t cell_nof_prb_to_rbg(uint32_t nof_prbs) case 100: return 25; default: - srslte::logmap::get("MAC")->error("Provided nof PRBs not valid"); + srslog::fetch_basic_logger("MAC").error("Provided nof PRBs not valid"); return 0; } } @@ -87,7 +86,7 @@ inline uint32_t cell_nof_rbg_to_prb(uint32_t nof_rbgs) case 25: return 100; default: - srslte::logmap::get("MAC")->error("Provided nof PRBs not valid"); + srslog::fetch_basic_logger("MAC").error("Provided nof PRBs not valid"); return 0; } } diff --git a/srsenb/hdr/stack/mac/sched_phy_ch/sf_cch_allocator.h b/srsenb/hdr/stack/mac/sched_phy_ch/sf_cch_allocator.h index 1936b177f..0cb226ebd 100644 --- a/srsenb/hdr/stack/mac/sched_phy_ch/sf_cch_allocator.h +++ b/srsenb/hdr/stack/mac/sched_phy_ch/sf_cch_allocator.h @@ -41,7 +41,7 @@ public: pdcch_mask_t total_mask; ///< Accumulation of all PDCCH masks for the current solution (tree route) prbmask_t total_pucch_mask; ///< Accumulation of all PUCCH masks for the current solution/tree route }; - using alloc_result_t = std::vector; + using alloc_result_t = srslte::bounded_vector; sf_cch_allocator() : logger(srslog::fetch_basic_logger("MAC")) {} @@ -83,8 +83,8 @@ private: // args size_t nof_cces; - const sched_cell_params_t* cc_cfg = nullptr; - srslte_pucch_cfg_t* pucch_cfg = nullptr; + const sched_cell_params_t* cc_cfg = nullptr; + srslte_pucch_cfg_t* pucch_cfg_temp = nullptr; uint32_t cfi; // state std::vector dci_alloc_tree; @@ -120,6 +120,9 @@ private: std::vector dci_record_list; ///< Keeps a record of all the PDCCH allocations done so far }; +// Helper methods +bool is_pucch_sr_collision(const srslte_pucch_cfg_t& ue_pucch_cfg, tti_point tti_tx_dl_ack, uint32_t n1_pucch); + } // namespace srsenb #endif // SRSLTE_PDCCH_SCHED_H diff --git a/srsenb/hdr/stack/mac/sched_ue.h b/srsenb/hdr/stack/mac/sched_ue.h index 0747bf967..3e392721e 100644 --- a/srsenb/hdr/stack/mac/sched_ue.h +++ b/srsenb/hdr/stack/mac/sched_ue.h @@ -23,7 +23,6 @@ #define SRSENB_SCHEDULER_UE_H #include "sched_common.h" -#include "srslte/common/log.h" #include "srslte/srslog/srslog.h" #include #include diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_harq.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_harq.h index c1e039f87..16ebd6c02 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_harq.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_harq.h @@ -23,7 +23,6 @@ #define SRSENB_SCHEDULER_HARQ_H #include "srslte/adt/bounded_bitset.h" -#include "srslte/common/log.h" #include "srslte/common/tti_point.h" #include "srslte/interfaces/sched_interface.h" #include "srslte/srslog/srslog.h" @@ -33,6 +32,7 @@ namespace srsenb { class harq_proc { public: + harq_proc(); void init(uint32_t id); void reset(uint32_t tb_idx); uint32_t get_id() const; @@ -54,6 +54,7 @@ protected: enum ack_t { NACK, ACK }; + srslog::basic_logger* logger; bool ack_state[SRSLTE_MAX_TB]; bool active[SRSLTE_MAX_TB]; std::array ndi = {}; diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h index 4885b034a..7c72b44c3 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h @@ -22,10 +22,10 @@ #ifndef SRSLTE_SCHED_LCH_H #define SRSLTE_SCHED_LCH_H -#include "srslte/common/logmap.h" #include "srslte/interfaces/sched_interface.h" #include "srslte/mac/pdu.h" #include "srslte/srslog/srslog.h" +#include namespace srsenb { @@ -64,7 +64,7 @@ public: int get_bsr_with_overhead(uint32_t lcid) const; int get_max_prio_lcid() const; - std::string get_bsr_text() const; + const std::array& get_bsr_state() const; // Control Element Command queue using ce_cmd = srslte::dl_sch_lcid; diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h index 98c0acac9..a7d17db0b 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h @@ -81,8 +81,6 @@ struct sched_ue_cell { int fixed_mcs_ul = 0, fixed_mcs_dl = 0; private: - void enter_idle_st(); - srslog::basic_logger& logger; const sched_interface::ue_cfg_t* ue_cfg = nullptr; diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/tpc.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/tpc.h index 14504eb20..8191ed393 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/tpc.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/tpc.h @@ -24,7 +24,6 @@ #include "srslte/adt/accumulators.h" #include "srslte/common/common.h" -#include "srslte/common/logmap.h" #include "srslte/srslog/srslog.h" namespace srsenb { diff --git a/srsenb/hdr/stack/mac/ue.h b/srsenb/hdr/stack/mac/ue.h index 435233be4..99d9cd8f5 100644 --- a/srsenb/hdr/stack/mac/ue.h +++ b/srsenb/hdr/stack/mac/ue.h @@ -25,13 +25,14 @@ #include "mac_metrics.h" #include "srslte/adt/circular_array.h" #include "srslte/common/block_queue.h" -#include "srslte/common/log.h" #include "srslte/common/mac_pcap.h" #include "srslte/common/mac_pcap_net.h" +#include "srslte/common/tti_point.h" #include "srslte/interfaces/sched_interface.h" #include "srslte/mac/pdu.h" #include "srslte/mac/pdu_queue.h" #include "srslte/srslog/srslog.h" + #include "ta.h" #include #include @@ -42,6 +43,34 @@ class rrc_interface_mac; class rlc_interface_mac; class phy_interface_stack_lte; +class cc_used_buffers_map +{ +public: + explicit cc_used_buffers_map(srslte::pdu_queue& shared_pdu_queue_); + + uint8_t* request_pdu(tti_point tti, uint32_t len); + + bool push_pdu(tti_point tti, uint32_t len); + + void clear_old_pdus(tti_point current_tti); + + bool try_deallocate_pdu(tti_point tti); + + void clear(); + + uint8_t*& operator[](tti_point tti); + + bool has_tti(tti_point tti) const; + +private: + void remove_pdu(tti_point tti); + + srslog::basic_logger* logger; + srslte::pdu_queue* shared_pdu_queue; + + srslte::circular_array, SRSLTE_FDD_NOF_HARQ * 2> pdu_map; +}; + class cc_buffer_handler { public: @@ -50,7 +79,7 @@ public: // List of Rx softbuffers for all HARQ processes of one carrier using cc_softbuffer_rx_list_t = std::vector; - cc_buffer_handler(); + explicit cc_buffer_handler(srslte::pdu_queue& shared_pdu_queue_); ~cc_buffer_handler(); void reset(); @@ -67,7 +96,7 @@ public: { return tx_payload_buffer[harq_pid][tb].get(); } - std::map& get_rx_used_buffers() { return rx_used_buffers; } + cc_used_buffers_map& get_rx_used_buffers() { return rx_used_buffers; } private: // args @@ -76,9 +105,9 @@ private: uint32_t nof_tx_harq_proc; // buffers - cc_softbuffer_tx_list_t softbuffer_tx_list; ///< List of softbuffer lists for Tx - cc_softbuffer_rx_list_t softbuffer_rx_list; ///< List of softbuffer lists for Rx - std::map rx_used_buffers; + cc_softbuffer_tx_list_t softbuffer_tx_list; ///< List of softbuffer lists for Tx + cc_softbuffer_rx_list_t softbuffer_rx_list; ///< List of softbuffer lists for Rx + cc_used_buffers_map rx_used_buffers; // One buffer per TB per HARQ process and per carrier is needed for each UE. std::array, SRSLTE_FDD_NOF_HARQ> tx_payload_buffer; @@ -93,7 +122,6 @@ public: rrc_interface_mac* rrc_, rlc_interface_mac* rlc, phy_interface_stack_lte* phy_, - srslte::log_ref log_, srslog::basic_logger& logger, uint32_t nof_cells_, uint32_t nof_rx_harq_proc = SRSLTE_FDD_NOF_HARQ, @@ -162,7 +190,7 @@ private: int nof_rx_harq_proc = 0; int nof_tx_harq_proc = 0; - std::vector cc_buffers; + srslte::bounded_vector cc_buffers; std::mutex rx_buffers_mutex; @@ -177,7 +205,6 @@ private: rlc_interface_mac* rlc = nullptr; rrc_interface_mac* rrc = nullptr; phy_interface_stack_lte* phy = nullptr; - srslte::log_ref log_h; srslog::basic_logger& logger; sched_interface* sched = nullptr; diff --git a/srsenb/hdr/stack/rrc/rrc.h b/srsenb/hdr/stack/rrc/rrc.h index 5a46ad861..e2ff615ff 100644 --- a/srsenb/hdr/stack/rrc/rrc.h +++ b/srsenb/hdr/stack/rrc/rrc.h @@ -26,18 +26,15 @@ #include "rrc_cell_cfg.h" #include "rrc_metrics.h" #include "srsenb/hdr/stack/upper/common_enb.h" -#include "srslte/adt/mem_pool.h" -#include "srslte/common/block_queue.h" +#include "srslte/adt/circular_buffer.h" #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/logmap.h" #include "srslte/common/stack_procedure.h" #include "srslte/common/task_scheduler.h" #include "srslte/common/timeout.h" #include "srslte/interfaces/enb_rrc_interfaces.h" #include "srslte/srslog/srslog.h" #include -#include namespace srsenb { @@ -199,8 +196,8 @@ private: const static uint32_t LCID_ACT_USER = 0xffff0004; const static uint32_t LCID_RTX_USER = 0xffff0005; - bool running = false; - srslte::block_queue rx_pdu_queue; + bool running = false; + srslte::dyn_blocking_queue rx_pdu_queue; asn1::rrc::mcch_msg_s mcch; bool enable_mbms = false; @@ -211,8 +208,6 @@ private: void rem_user_thread(uint16_t rnti); std::mutex paging_mutex; - - static srslte::big_obj_pool ue_pool; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h b/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h index b27c4ec97..9206e5d08 100644 --- a/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h +++ b/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h @@ -24,7 +24,6 @@ #include "srsenb/hdr/stack/rrc/rrc_config.h" #include "srslte/asn1/s1ap.h" -#include "srslte/common/logmap.h" #include "srslte/interfaces/enb_gtpu_interfaces.h" #include "srslte/interfaces/enb_interfaces.h" #include "srslte/interfaces/enb_rrc_interface_types.h" diff --git a/srsenb/hdr/stack/rrc/rrc_cell_cfg.h b/srsenb/hdr/stack/rrc/rrc_cell_cfg.h index 6f857cbfc..f3d31679b 100644 --- a/srsenb/hdr/stack/rrc/rrc_cell_cfg.h +++ b/srsenb/hdr/stack/rrc/rrc_cell_cfg.h @@ -23,7 +23,7 @@ #define SRSLTE_RRC_CELL_CFG_H #include "rrc_config.h" -#include "srslte/common/logmap.h" +#include "srslte/common/byte_buffer.h" #include "srslte/srslog/srslog.h" namespace srsenb { diff --git a/srsenb/hdr/stack/rrc/rrc_mobility.h b/srsenb/hdr/stack/rrc/rrc_mobility.h index 62670671f..ced1ff7e9 100644 --- a/srsenb/hdr/stack/rrc/rrc_mobility.h +++ b/srsenb/hdr/stack/rrc/rrc_mobility.h @@ -25,7 +25,6 @@ #include "rrc.h" #include "rrc_ue.h" #include "srslte/common/fsm.h" -#include "srslte/common/logmap.h" #include namespace srsenb { diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index 203100e25..41f3bf713 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -29,7 +29,6 @@ #include "srslte/common/block_queue.h" #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/logmap.h" #include "srslte/common/task_scheduler.h" #include "srslte/common/threads.h" #include "srslte/common/timeout.h" @@ -137,11 +136,11 @@ private: ngap_interface_rrc_nr* ngap = nullptr; // args - srslte::log_ref m_log; srslte::timer_handler* timers = nullptr; // derived - uint32_t slot_dur_ms = 0; + uint32_t slot_dur_ms = 0; + srslog::basic_logger& logger; // vars std::map > users; diff --git a/srsenb/hdr/stack/rrc/rrc_ue.h b/srsenb/hdr/stack/rrc/rrc_ue.h index 2a82e0366..b7ea6a455 100644 --- a/srsenb/hdr/stack/rrc/rrc_ue.h +++ b/srsenb/hdr/stack/rrc/rrc_ue.h @@ -24,6 +24,7 @@ #include "mac_controller.h" #include "rrc.h" +#include "srslte/adt/mem_pool.h" #include "srslte/interfaces/enb_phy_interfaces.h" #include "srslte/interfaces/pdcp_interface_types.h" @@ -128,6 +129,9 @@ public: void operator delete(void* ptr)noexcept; void operator delete[](void* ptr) = delete; + using ue_pool_t = srslte::background_allocator_obj_pool; + static ue_pool_t* get_ue_pool(); + private: // args srslte::timer_handler::unique_timer activity_timer; diff --git a/srsenb/hdr/stack/rrc/ue_rr_cfg.h b/srsenb/hdr/stack/rrc/ue_rr_cfg.h index ed0aa6173..f9a26a46c 100644 --- a/srsenb/hdr/stack/rrc/ue_rr_cfg.h +++ b/srsenb/hdr/stack/rrc/ue_rr_cfg.h @@ -44,7 +44,6 @@ #define SRSENB_UE_RR_CFG_H #include "srslte/asn1/rrc.h" -#include "srslte/common/logmap.h" #include "srslte/interfaces/rrc_interface_types.h" namespace srsenb { @@ -55,15 +54,15 @@ class bearer_cfg_handler; struct ue_var_cfg_t; /// Fill RadioResourceConfigDedicated with data known at the RRCSetup/Reestablishment stage -void fill_rr_cfg_ded_setup(asn1::rrc::rr_cfg_ded_s& rr_cfg, - const rrc_cfg_t& enb_cfg, - const ue_cell_ded_list& ue_cell_list); +void fill_rr_cfg_ded_setup(asn1::rrc::rr_cfg_ded_s& rr_cfg, + const rrc_cfg_t& enb_cfg, + const ue_cell_ded_list& ue_cell_list); /// Apply Reconf updates and update current state void apply_reconf_updates(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8, ue_var_cfg_t& current_ue_cfg, const rrc_cfg_t& enb_cfg, - const ue_cell_ded_list& ue_cell_list, + const ue_cell_ded_list& ue_cell_list, bearer_cfg_handler& bearers, const srslte::rrc_ue_capabilities_t& ue_caps, bool phy_cfg_updated); diff --git a/srsenb/hdr/stack/upper/gtpu.h b/srsenb/hdr/stack/upper/gtpu.h index b29e29a56..9d3ae3a43 100644 --- a/srsenb/hdr/stack/upper/gtpu.h +++ b/srsenb/hdr/stack/upper/gtpu.h @@ -21,10 +21,10 @@ #include #include +#include #include "common_enb.h" #include "srslte/common/buffer_pool.h" -#include "srslte/common/logmap.h" #include "srslte/common/threads.h" #include "srslte/interfaces/enb_gtpu_interfaces.h" #include "srslte/phy/common/phy_common.h" diff --git a/srsenb/hdr/stack/upper/pdcp.h b/srsenb/hdr/stack/upper/pdcp.h index 3635cdd8d..b5b93f5a6 100644 --- a/srsenb/hdr/stack/upper/pdcp.h +++ b/srsenb/hdr/stack/upper/pdcp.h @@ -47,8 +47,8 @@ public: // pdcp_interface_rlc void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) override; - void notify_delivery(uint16_t rnti, uint32_t lcid, const std::vector& pdcp_sn) override; - void notify_failure(uint16_t rnti, uint32_t lcid, const std::vector& pdcp_sn) override; + void notify_delivery(uint16_t rnti, uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sn) override; + void notify_failure(uint16_t rnti, uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sn) override; void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t sdu) {} // pdcp_interface_rrc diff --git a/srsenb/hdr/stack/upper/pdcp_nr.h b/srsenb/hdr/stack/upper/pdcp_nr.h index 523493fd9..ad16971b8 100644 --- a/srsenb/hdr/stack/upper/pdcp_nr.h +++ b/srsenb/hdr/stack/upper/pdcp_nr.h @@ -19,9 +19,6 @@ * */ -#include "srslte/common/log.h" -#include "srslte/common/log_filter.h" -#include "srslte/common/logger.h" #include "srslte/interfaces/gnb_interfaces.h" #include "srslte/interfaces/ue_gw_interfaces.h" #include "srslte/interfaces/ue_rlc_interfaces.h" @@ -51,8 +48,8 @@ public: // pdcp_interface_rlc_nr void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu); - void notify_delivery(uint16_t rnti, uint32_t lcid, const std::vector& tx_count); - void notify_failure(uint16_t rnti, uint32_t lcid, const std::vector& tx_count); + void notify_delivery(uint16_t rnti, uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sn); + void notify_failure(uint16_t rnti, uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sn); void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t sdu) {} // pdcp_interface_rrc_nr @@ -113,7 +110,6 @@ private: // args pdcp_nr_args_t m_args = {}; - srslte::log_ref m_log; rlc_interface_pdcp_nr* m_rlc = nullptr; rrc_interface_pdcp_nr* m_rrc = nullptr; sdap_interface_pdcp_nr* m_sdap = nullptr; @@ -121,6 +117,7 @@ private: std::map users; srslte::task_sched_handle task_sched; + srslog::basic_logger& logger; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/upper/rlc.h b/srsenb/hdr/stack/upper/rlc.h index 27b1e9c54..313711dc9 100644 --- a/srsenb/hdr/stack/upper/rlc.h +++ b/srsenb/hdr/stack/upper/rlc.h @@ -80,8 +80,8 @@ private: { public: void write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu); - void notify_delivery(uint32_t lcid, const std::vector& tx_count); - void notify_failure(uint32_t lcid, const std::vector& tx_count); + void notify_delivery(uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sn); + void notify_failure(uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sn); void write_pdu_bcch_bch(srslte::unique_byte_buffer_t sdu); void write_pdu_bcch_dlsch(srslte::unique_byte_buffer_t sdu); void write_pdu_pcch(srslte::unique_byte_buffer_t sdu); diff --git a/srsenb/hdr/stack/upper/rlc_nr.h b/srsenb/hdr/stack/upper/rlc_nr.h index 99fa0be1f..671d0826a 100644 --- a/srsenb/hdr/stack/upper/rlc_nr.h +++ b/srsenb/hdr/stack/upper/rlc_nr.h @@ -22,9 +22,6 @@ #ifndef SRSENB_RLC_NR_H #define SRSENB_RLC_NR_H -#include "srslte/common/log.h" -#include "srslte/common/log_filter.h" -#include "srslte/common/logger.h" #include "srslte/interfaces/gnb_interfaces.h" #include "srslte/upper/rlc.h" #include @@ -72,8 +69,8 @@ private: { public: void write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu); - void notify_delivery(uint32_t lcid, const std::vector& pdcp_sns); - void notify_failure(uint32_t lcid, const std::vector& pdcp_sns); + void notify_delivery(uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sns); + void notify_failure(uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sns); void write_pdu_bcch_bch(srslte::unique_byte_buffer_t sdu); void write_pdu_bcch_dlsch(srslte::unique_byte_buffer_t sdu); void write_pdu_pcch(srslte::unique_byte_buffer_t sdu); @@ -89,11 +86,11 @@ private: }; // args - srslte::log_ref m_log; srslte::timer_handler* timers = nullptr; mac_interface_rlc_nr* m_mac = nullptr; pdcp_interface_rlc_nr* m_pdcp = nullptr; rrc_interface_rlc_nr* m_rrc = nullptr; + srslog::basic_logger& logger; // state std::map users; diff --git a/srsenb/hdr/stack/upper/s1ap.h b/srsenb/hdr/stack/upper/s1ap.h index 41af0f977..b69cdc4f8 100644 --- a/srsenb/hdr/stack/upper/s1ap.h +++ b/srsenb/hdr/stack/upper/s1ap.h @@ -27,7 +27,6 @@ #include "common_enb.h" #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/logmap.h" #include "srslte/common/s1ap_pcap.h" #include "srslte/common/threads.h" #include "srslte/interfaces/enb_interfaces.h" diff --git a/srsenb/hdr/stack/upper/sdap.h b/srsenb/hdr/stack/upper/sdap.h index 8e4c89332..d4e974689 100644 --- a/srsenb/hdr/stack/upper/sdap.h +++ b/srsenb/hdr/stack/upper/sdap.h @@ -24,7 +24,6 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/logmap.h" #include "srslte/interfaces/gnb_interfaces.h" #include "srslte/interfaces/ue_gw_interfaces.h" diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index 0280e1c34..f33b5280d 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -20,13 +20,13 @@ */ #include "srsenb/hdr/enb.h" +#include "srsenb/hdr/phy/vnf_phy_nr.h" #include "srsenb/hdr/stack/enb_stack_lte.h" +#include "srsenb/hdr/stack/gnb_stack_nr.h" #include "srsenb/src/enb_cfg_parser.h" #include "srslte/build_info.h" #include "srslte/common/enb_events.h" #include "srslte/radio/radio_null.h" -#include "srsenb/hdr/phy/vnf_phy_nr.h" -#include "srsenb/hdr/stack/gnb_stack_nr.h" #include namespace srsenb { @@ -43,13 +43,11 @@ enb::~enb() stack.reset(); } -int enb::init(const all_args_t& args_, srslte::logger* logger_) +int enb::init(const all_args_t& args_) { int ret = SRSLTE_SUCCESS; - logger = logger_; // Init eNB log - srslte::logmap::set_default_logger(logger); enb_log.set_level(srslog::basic_levels::info); enb_log.info("%s", get_build_string().c_str()); @@ -63,7 +61,7 @@ int enb::init(const all_args_t& args_, srslte::logger* logger_) // Create layers if (args.stack.type == "lte") { - std::unique_ptr lte_stack(new enb_stack_lte(logger, log_sink)); + std::unique_ptr lte_stack(new enb_stack_lte(log_sink)); if (!lte_stack) { srslte::console("Error creating eNB stack.\n"); return SRSLTE_ERROR; @@ -209,7 +207,7 @@ bool enb::get_metrics(enb_metrics_t* m) phy->get_metrics(m->phy); stack->get_metrics(&m->stack); m->running = started; - m->sys = sys_proc.get_metrics(); + m->sys = sys_proc.get_metrics(); return true; } @@ -218,24 +216,6 @@ void enb::cmd_cell_gain(uint32_t cell_id, float gain) phy->cmd_cell_gain(cell_id, gain); } -srslte::LOG_LEVEL_ENUM enb::level(std::string l) -{ - std::transform(l.begin(), l.end(), l.begin(), ::toupper); - if ("NONE" == l) { - return srslte::LOG_LEVEL_NONE; - } else if ("ERROR" == l) { - return srslte::LOG_LEVEL_ERROR; - } else if ("WARNING" == l) { - return srslte::LOG_LEVEL_WARNING; - } else if ("INFO" == l) { - return srslte::LOG_LEVEL_INFO; - } else if ("DEBUG" == l) { - return srslte::LOG_LEVEL_DEBUG; - } else { - return srslte::LOG_LEVEL_NONE; - } -} - std::string enb::get_build_mode() { return std::string(srslte_get_build_mode()); diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index e6a731b91..2ced6a1c5 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -261,7 +261,7 @@ int mbsfn_sf_cfg_list_parser::parse(Setting& root) field_asn1_choice_number c( "subframeAllocation", "subframeAllocationNumFrames", &extract_sf_alloc, &(*mbsfn_list)[0].sf_alloc); - c.parse(root["mbsfnSubframeConfigList"]); + HANDLEPARSERCODE(c.parse(root["mbsfnSubframeConfigList"])); parser::field f("radioframeAllocationOffset", &(*mbsfn_list)[0].radioframe_alloc_offset); f.parse(root["mbsfnSubframeConfigList"]); @@ -269,7 +269,7 @@ int mbsfn_sf_cfg_list_parser::parse(Setting& root) (*mbsfn_list)[0].radioframe_alloc_period.value = mbsfn_sf_cfg_s::radioframe_alloc_period_opts::n1; field_asn1_enum_number e("radioframeAllocationPeriod", &(*mbsfn_list)[0].radioframe_alloc_period); - e.parse(root["mbsfnSubframeConfigList"]); + HANDLEPARSERCODE(e.parse(root["mbsfnSubframeConfigList"])); // TODO: Did you forget subframeAllocationNumFrames? @@ -406,11 +406,11 @@ int field_qci::parse(libconfig::Setting& root) field_asn1_enum_number discard_timer( "discard_timer", &qcicfg.pdcp_cfg.discard_timer, &qcicfg.pdcp_cfg.discard_timer_present); - discard_timer.parse(q["pdcp_config"]); + HANDLEPARSERCODE(discard_timer.parse(q["pdcp_config"])); field_asn1_enum_number pdcp_sn_size( "pdcp_sn_size", &qcicfg.pdcp_cfg.rlc_um.pdcp_sn_size, &qcicfg.pdcp_cfg.rlc_um_present); - pdcp_sn_size.parse(q["pdcp_config"]); + HANDLEPARSERCODE(pdcp_sn_size.parse(q["pdcp_config"])); qcicfg.pdcp_cfg.rlc_am_present = q["pdcp_config"].lookupValue("status_report_required", qcicfg.pdcp_cfg.rlc_am.status_report_required); @@ -443,6 +443,7 @@ int field_qci::parse(libconfig::Setting& root) field_asn1_enum_number sn_field_len("sn_field_length", &um_rlc->sn_field_len); if (sn_field_len.parse(q["rlc_config"]["ul_um"])) { ERROR("Error can't find sn_field_length in section ul_um"); + return -1; } } @@ -457,11 +458,13 @@ int field_qci::parse(libconfig::Setting& root) field_asn1_enum_number sn_field_len("sn_field_length", &um_rlc->sn_field_len); if (sn_field_len.parse(q["rlc_config"]["dl_um"])) { ERROR("Error can't find sn_field_length in section dl_um"); + return -1; } field_asn1_enum_number t_reordering("t_reordering", &um_rlc->t_reordering); if (t_reordering.parse(q["rlc_config"]["dl_um"])) { ERROR("Error can't find t_reordering in section dl_um"); + return -1; } } @@ -472,22 +475,26 @@ int field_qci::parse(libconfig::Setting& root) field_asn1_enum_number t_poll_retx("t_poll_retx", &am_rlc->t_poll_retx); if (t_poll_retx.parse(q["rlc_config"]["ul_am"])) { ERROR("Error can't find t_poll_retx in section ul_am"); + return -1; } field_asn1_enum_number poll_pdu("poll_pdu", &am_rlc->poll_pdu); if (poll_pdu.parse(q["rlc_config"]["ul_am"])) { ERROR("Error can't find poll_pdu in section ul_am"); + return -1; } field_asn1_enum_number poll_byte("poll_byte", &am_rlc->poll_byte); if (poll_byte.parse(q["rlc_config"]["ul_am"])) { ERROR("Error can't find poll_byte in section ul_am"); + return -1; } field_asn1_enum_number max_retx_thresh("max_retx_thresh", &am_rlc->max_retx_thres); if (max_retx_thresh.parse(q["rlc_config"]["ul_am"])) { ERROR("Error can't find max_retx_thresh in section ul_am"); + return -1; } } @@ -497,11 +504,13 @@ int field_qci::parse(libconfig::Setting& root) field_asn1_enum_number t_reordering("t_reordering", &am_rlc->t_reordering); if (t_reordering.parse(q["rlc_config"]["dl_am"])) { ERROR("Error can't find t_reordering in section dl_am"); + return -1; } field_asn1_enum_number t_status_prohibit("t_status_prohibit", &am_rlc->t_status_prohibit); if (t_status_prohibit.parse(q["rlc_config"]["dl_am"])) { ERROR("Error can't find t_status_prohibit in section dl_am"); + return -1; } } @@ -516,18 +525,21 @@ int field_qci::parse(libconfig::Setting& root) parser::field priority("priority", &lc_cfg->prio); if (priority.parse(q["logical_channel_config"])) { ERROR("Error can't find logical_channel_config in section priority"); + return -1; } field_asn1_enum_number prioritised_bit_rate( "prioritized_bit_rate", &lc_cfg->prioritised_bit_rate); if (prioritised_bit_rate.parse(q["logical_channel_config"])) { fprintf(stderr, "Error can't find prioritized_bit_rate in section logical_channel_config\n"); + return -1; } field_asn1_enum_number bucket_size_duration( "bucket_size_duration", &lc_cfg->bucket_size_dur); if (bucket_size_duration.parse(q["logical_channel_config"])) { ERROR("Error can't find bucket_size_duration in section logical_channel_config"); + return -1; } parser::field log_chan_group("log_chan_group", &lc_cfg->lc_ch_group); @@ -547,12 +559,14 @@ int parse_rr(all_args_t* args_, rrc_cfg_t* rrc_cfg_) if (args_->enb.transmission_mode < 1 || args_->enb.transmission_mode > 4) { ERROR("Invalid transmission mode (%d). Only indexes 1-4 are implemented.", args_->enb.transmission_mode); return SRSLTE_ERROR; - } else if (args_->enb.transmission_mode == 1 && args_->enb.nof_ports > 1) { + } + if (args_->enb.transmission_mode == 1 && args_->enb.nof_ports > 1) { ERROR("Invalid number of ports (%d) for transmission mode (%d). Only one antenna port is allowed.", args_->enb.nof_ports, args_->enb.transmission_mode); return SRSLTE_ERROR; - } else if (args_->enb.transmission_mode > 1 && args_->enb.nof_ports != 2) { + } + if (args_->enb.transmission_mode > 1 && args_->enb.nof_ports != 2) { ERROR("The selected number of ports (%d) are insufficient for the selected transmission mode (%d).", args_->enb.nof_ports, args_->enb.transmission_mode); @@ -746,7 +760,7 @@ static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root) } if (cellroot.exists("scell_list")) { - parse_scell_list(cell_cfg, cellroot); + HANDLEPARSERCODE(parse_scell_list(cell_cfg, cellroot)); } std::string type = "lte"; @@ -766,11 +780,13 @@ static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root) // Check RF port is not repeated if (it->rf_port == it2->rf_port) { ERROR("Repeated RF port for multiple cells"); + return -1; } // Check cell ID is not repeated if (it->cell_id == it2->cell_id) { ERROR("Repeated Cell identifier"); + return -1; } } } @@ -1126,7 +1142,7 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_ // Set sync queue capacity to 1 for ZMQ if (args_->rf.device_name == "zmq") { - srslte::logmap::get("ENB")->info("Using sync queue size of one for ZMQ based radio."); + srslog::fetch_basic_logger("ENB").info("Using sync queue size of one for ZMQ based radio."); args_->stack.sync_queue_size = 1; } else { // use default size diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index e09e35e6f..c785f2923 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -28,9 +28,8 @@ #include "srslte/common/common_helper.h" #include "srslte/common/config_file.h" #include "srslte/common/crash_handler.h" -#include "srslte/common/logger_srslog_wrapper.h" -#include "srslte/common/logmap.h" #include "srslte/common/signal_handler.h" +#include "srslte/srslog/event_trace.h" #include "srslte/srslog/srslog.h" #include @@ -216,6 +215,9 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("expert.report_json_filename", bpo::value(&args->general.report_json_filename)->default_value("/tmp/enb_report.json"), "Report JSON filename") ("expert.alarms_log_enable", bpo::value(&args->general.alarms_log_enable)->default_value(false), "Log alarms") ("expert.alarms_filename", bpo::value(&args->general.alarms_filename)->default_value("/tmp/enb_alarms.log"), "Alarms filename") + ("expert.tracing_enable", bpo::value(&args->general.tracing_enable)->default_value(false), "Events tracing") + ("expert.tracing_filename", bpo::value(&args->general.tracing_filename)->default_value("/tmp/enb_tracing.log"), "Tracing events filename") + ("expert.tracing_buffcapacity", bpo::value(&args->general.tracing_buffcapacity)->default_value(1000000), "Tracing buffer capcity") ("expert.rrc_inactivity_timer", bpo::value(&args->general.rrc_inactivity_timer)->default_value(30000), "Inactivity timer in ms.") ("expert.print_buffer_state", bpo::value(&args->general.print_buffer_state)->default_value(false), "Prints on the console the buffer state every 10 seconds") ("expert.eea_pref_list", bpo::value(&args->general.eea_pref_list)->default_value("EEA0, EEA2, EEA1"), "Ordered preference list for the selection of encryption algorithm (EEA) (default: EEA0, EEA2, EEA1).") @@ -503,18 +505,23 @@ int main(int argc, char* argv[]) ? srslog::fetch_stdout_sink() : srslog::fetch_file_sink(args.log.filename, fixup_log_file_maxsize(args.log.file_max_size))); - srslte::srslog_wrapper log_wrapper(srslog::fetch_log_channel("main_channel")); - // Alarms log channel creation. srslog::sink& alarm_sink = srslog::fetch_file_sink(args.general.alarms_filename); srslog::log_channel& alarms_channel = srslog::fetch_log_channel("alarms", alarm_sink, {"ALRM", '\0', false}); alarms_channel.set_enabled(args.general.alarms_log_enable); +#ifdef ENABLE_SRSLOG_EVENT_TRACE + if (args.general.tracing_enable) { + if (!srslog::event_trace_init(args.general.tracing_filename, args.general.tracing_buffcapacity)) { + return SRSLTE_ERROR; + } + } +#endif + // Start the log backend. srslog::init(); - srslte::logmap::set_default_logger(&log_wrapper); - srslte::logmap::get("COMMON")->set_level(srslte::LOG_LEVEL_INFO); + srslog::fetch_basic_logger("COMMON").set_level(srslog::basic_levels::info); srslte::log_args(argc, argv, "ENB"); srslte::check_scaling_governor(args.rf.device_name); @@ -532,7 +539,7 @@ int main(int argc, char* argv[]) // Create eNB unique_ptr enb{new srsenb::enb(srslog::get_default_sink())}; - if (enb->init(args, &log_wrapper) != SRSLTE_SUCCESS) { + if (enb->init(args) != SRSLTE_SUCCESS) { enb->stop(); return SRSLTE_ERROR; } diff --git a/srsenb/src/phy/lte/cc_worker.cc b/srsenb/src/phy/lte/cc_worker.cc index 2a9820d55..13485d6a3 100644 --- a/srsenb/src/phy/lte/cc_worker.cc +++ b/srsenb/src/phy/lte/cc_worker.cc @@ -19,7 +19,6 @@ * */ -#include "srslte/common/log.h" #include "srslte/common/threads.h" #include "srslte/srslte.h" diff --git a/srsenb/src/phy/lte/sf_worker.cc b/srsenb/src/phy/lte/sf_worker.cc index 9226c2704..6c5fe7c61 100644 --- a/srsenb/src/phy/lte/sf_worker.cc +++ b/srsenb/src/phy/lte/sf_worker.cc @@ -19,7 +19,6 @@ * */ -#include "srslte/common/log.h" #include "srslte/common/threads.h" #include "srslte/srslte.h" @@ -282,8 +281,8 @@ uint32_t sf_worker::get_metrics(std::vector& metrics) phy_metrics_t* m_ = &metrics_[r]; m->dl.mcs = SRSLTE_VEC_PMA(m->dl.mcs, m->dl.n_samples, m_->dl.mcs, m_->dl.n_samples); m->dl.n_samples += m_->dl.n_samples; - m->ul.n = SRSLTE_VEC_PMA(m->ul.n, m->ul.n_samples, m_->ul.n, m_->ul.n_samples); - m->ul.pusch_sinr = SRSLTE_VEC_PMA(m->ul.pusch_sinr, m->ul.n_samples, m_->ul.pusch_sinr, m_->ul.n_samples); + m->ul.n = SRSLTE_VEC_PMA(m->ul.n, m->ul.n_samples, m_->ul.n, m_->ul.n_samples); + m->ul.pusch_sinr = SRSLTE_VEC_PMA(m->ul.pusch_sinr, m->ul.n_samples, m_->ul.pusch_sinr, m_->ul.n_samples); m->ul.pucch_sinr = SRSLTE_VEC_PMA(m->ul.pucch_sinr, m->ul.n_samples_pucch, m_->ul.pucch_sinr, m_->ul.n_samples_pucch); m->ul.mcs = SRSLTE_VEC_PMA(m->ul.mcs, m->ul.n_samples, m_->ul.mcs, m_->ul.n_samples); diff --git a/srsenb/src/phy/phy.cc b/srsenb/src/phy/phy.cc index 4d7f25c38..7ebe0158a 100644 --- a/srsenb/src/phy/phy.cc +++ b/srsenb/src/phy/phy.cc @@ -28,7 +28,6 @@ #include #include "srsenb/hdr/phy/phy.h" -#include "srslte/common/log.h" #include "srslte/common/threads.h" #define Error(fmt, ...) \ diff --git a/srsenb/src/phy/txrx.cc b/srsenb/src/phy/txrx.cc index 4e98a1e28..5b04ec6ac 100644 --- a/srsenb/src/phy/txrx.cc +++ b/srsenb/src/phy/txrx.cc @@ -21,7 +21,6 @@ #include -#include "srslte/common/log.h" #include "srslte/common/threads.h" #include "srslte/srslte.h" diff --git a/srsenb/src/phy/vnf_phy_nr.cc b/srsenb/src/phy/vnf_phy_nr.cc index b5a5cfa07..5eb25cae8 100644 --- a/srsenb/src/phy/vnf_phy_nr.cc +++ b/srsenb/src/phy/vnf_phy_nr.cc @@ -19,19 +19,11 @@ * */ -#include -#include -#include #include -#include #include -#include #include "srsenb/hdr/phy/vnf_phy_nr.h" #include "srslte/common/basic_vnf_api.h" -#include "srslte/common/log.h" -#include "srslte/common/test_common.h" -#include "srslte/common/threads.h" using namespace std; @@ -81,4 +73,4 @@ int vnf_phy_nr::tx_request(const tx_request_t& request) return vnf->tx_request(request); } -} // namespace srsenb \ No newline at end of file +} // namespace srsenb diff --git a/srsenb/src/stack/enb_stack_lte.cc b/srsenb/src/stack/enb_stack_lte.cc index 097eaf30d..fe08eaa04 100644 --- a/srsenb/src/stack/enb_stack_lte.cc +++ b/srsenb/src/stack/enb_stack_lte.cc @@ -23,12 +23,13 @@ #include "srsenb/hdr/enb.h" #include "srslte/common/network_utils.h" #include "srslte/interfaces/enb_metrics_interface.h" +#include "srslte/srslog/event_trace.h" using namespace srslte; namespace srsenb { -enb_stack_lte::enb_stack_lte(srslte::logger* logger_, srslog::sink& log_sink) : +enb_stack_lte::enb_stack_lte(srslog::sink& log_sink) : thread("STACK"), mac_logger(srslog::fetch_basic_logger("MAC", log_sink)), rlc_logger(srslog::fetch_basic_logger("RLC", log_sink, false)), @@ -44,8 +45,8 @@ enb_stack_lte::enb_stack_lte(srslte::logger* logger_, srslog::sink& log_sink) : gtpu(gtpu_logger), s1ap(&task_sched, s1ap_logger), rrc(&task_sched), - logger(logger_), - mac_pcap() + mac_pcap(), + pending_stack_metrics(64) { get_background_workers().set_nof_workers(2); enb_task_queue = task_sched.make_task_queue(); @@ -80,37 +81,22 @@ int enb_stack_lte::init(const stack_args_t& args_, const rrc_cfg_t& rrc_cfg_) rrc_cfg = rrc_cfg_; // setup logging for each layer - srslte::logmap::register_log(std::unique_ptr{new log_filter{"MAC ", logger, true}}); - mac_log->set_level(args.log.mac_level); - mac_log->set_hex_limit(args.log.mac_hex_limit); mac_logger.set_level(srslog::str_to_basic_level(args.log.mac_level)); mac_logger.set_hex_dump_max_size(args.log.mac_hex_limit); // Init logs - rlc_log->set_level(args.log.rlc_level); rlc_logger.set_level(srslog::str_to_basic_level(args.log.rlc_level)); - pdcp_log->set_level(args.log.pdcp_level); pdcp_logger.set_level(srslog::str_to_basic_level(args.log.pdcp_level)); - rrc_log->set_level(args.log.rrc_level); rrc_logger.set_level(srslog::str_to_basic_level(args.log.rrc_level)); - gtpu_log->set_level(args.log.gtpu_level); gtpu_logger.set_level(srslog::str_to_basic_level(args.log.gtpu_level)); - s1ap_log->set_level(args.log.s1ap_level); s1ap_logger.set_level(srslog::str_to_basic_level(args.log.s1ap_level)); - stack_log->set_level(args.log.stack_level); stack_logger.set_level(srslog::str_to_basic_level(args.log.stack_level)); - rlc_log->set_hex_limit(args.log.rlc_hex_limit); rlc_logger.set_hex_dump_max_size(args.log.rlc_hex_limit); - pdcp_log->set_hex_limit(args.log.pdcp_hex_limit); pdcp_logger.set_hex_dump_max_size(args.log.pdcp_hex_limit); - rrc_log->set_hex_limit(args.log.rrc_hex_limit); rrc_logger.set_hex_dump_max_size(args.log.rrc_hex_limit); - gtpu_log->set_hex_limit(args.log.gtpu_hex_limit); gtpu_logger.set_hex_dump_max_size(args.log.gtpu_hex_limit); - s1ap_log->set_hex_limit(args.log.s1ap_hex_limit); s1ap_logger.set_hex_dump_max_size(args.log.s1ap_hex_limit); - stack_log->set_hex_limit(args.log.stack_hex_limit); stack_logger.set_hex_dump_max_size(args.log.stack_hex_limit); // Set up pcap and trace @@ -139,7 +125,7 @@ int enb_stack_lte::init(const stack_args_t& args_, const rrc_cfg_t& rrc_cfg_) sync_task_queue = task_sched.make_task_queue(args.sync_queue_size); // Init all layers - if (!mac.init(args.mac, rrc_cfg.cell_list, phy, &rlc, &rrc, mac_log)) { + if (!mac.init(args.mac, rrc_cfg.cell_list, phy, &rlc, &rrc)) { stack_logger.error("Couldn't initialize MAC"); return SRSLTE_ERROR; } @@ -174,6 +160,7 @@ void enb_stack_lte::tti_clock() void enb_stack_lte::tti_clock_impl() { + trace_complete_event("enb_stack_lte::tti_clock_impl", "total_time"); task_sched.tic(); rrc.tti_clock(); } @@ -227,12 +214,14 @@ bool enb_stack_lte::get_metrics(stack_metrics_t* metrics) } rrc.get_metrics(metrics.rrc); s1ap.get_metrics(metrics.s1ap); - pending_stack_metrics.push(metrics); + if (not pending_stack_metrics.try_push(metrics)) { + stack_logger.error("Unable to push metrics to queue"); + } }); if (ret.first) { // wait for result - *metrics = pending_stack_metrics.wait_pop(); + *metrics = pending_stack_metrics.pop_blocking(); return true; } return false; diff --git a/srsenb/src/stack/gnb_stack_nr.cc b/srsenb/src/stack/gnb_stack_nr.cc index 173562a1f..704a88fba 100644 --- a/srsenb/src/stack/gnb_stack_nr.cc +++ b/srsenb/src/stack/gnb_stack_nr.cc @@ -25,7 +25,7 @@ namespace srsenb { -gnb_stack_nr::gnb_stack_nr() : task_sched{512, 128}, thread("gNB") +gnb_stack_nr::gnb_stack_nr() : task_sched{512, 128}, thread("gNB"), rlc_logger(srslog::fetch_basic_logger("RLC")) { m_mac.reset(new mac_nr()); m_rlc.reset(new rlc_nr("RLC")); @@ -79,8 +79,8 @@ int gnb_stack_nr::init(const srsenb::stack_args_t& args_, const rrc_nr_cfg_t& rr mac_args.rnti = args.coreless.rnti; m_mac->init(mac_args, phy, this, m_rlc.get(), m_rrc.get()); - srslte::logmap::get("RLC")->set_level(args.log.rlc_level); - srslte::logmap::get("RLC")->set_hex_limit(args.log.rlc_hex_limit); + rlc_logger.set_level(srslog::str_to_basic_level(args.log.rlc_level)); + rlc_logger.set_hex_dump_max_size(args.log.rlc_hex_limit); m_rlc->init(m_pdcp.get(), m_rrc.get(), m_mac.get(), task_sched.get_timer_handler()); pdcp_nr_args_t pdcp_args = {}; diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index b01d8331f..edd309f74 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -23,12 +23,13 @@ #include #include "srsenb/hdr/stack/mac/mac.h" -#include "srslte/common/log.h" #include "srslte/common/rwlock_guard.h" +#include "srslte/common/standard_streams.h" #include "srslte/common/time_prof.h" #include "srslte/interfaces/enb_phy_interfaces.h" #include "srslte/interfaces/enb_rlc_interfaces.h" #include "srslte/interfaces/enb_rrc_interfaces.h" +#include "srslte/srslog/event_trace.h" // #define WRITE_SIB_PCAP using namespace asn1::rrc; @@ -51,16 +52,14 @@ bool mac::init(const mac_args_t& args_, const cell_list_t& cells_, phy_interface_stack_lte* phy, rlc_interface_mac* rlc, - rrc_interface_mac* rrc, - srslte::log_ref log_h_) + rrc_interface_mac* rrc) { started = false; - if (phy && rlc && log_h_) { + if (phy && rlc) { phy_h = phy; rlc_h = rlc; rrc_h = rrc; - log_h = log_h_; args = args_; cells = cells_; @@ -290,7 +289,6 @@ void mac::get_metrics(mac_metrics_t& metrics) int mac::ack_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) { logger.set_context(tti_rx); - log_h->step(tti_rx); srslte::rwlock_read_guard lock(rwlock); if (not check_ue_exists(rnti)) { @@ -312,7 +310,6 @@ int mac::ack_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t int mac::crc_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t nof_bytes, bool crc) { logger.set_context(tti_rx); - log_h->step(tti_rx); srslte::rwlock_read_guard lock(rwlock); if (not check_ue_exists(rnti)) { @@ -356,7 +353,6 @@ int mac::push_pdu(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t int mac::ri_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t ri_value) { logger.set_context(tti); - log_h->step(tti); srslte::rwlock_read_guard lock(rwlock); if (not check_ue_exists(rnti)) { @@ -372,7 +368,6 @@ int mac::ri_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t ri_v int mac::pmi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t pmi_value) { logger.set_context(tti); - log_h->step(tti); srslte::rwlock_read_guard lock(rwlock); if (not check_ue_exists(rnti)) { @@ -388,7 +383,6 @@ int mac::pmi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t pmi int mac::cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi_value) { logger.set_context(tti); - log_h->step(tti); srslte::rwlock_read_guard lock(rwlock); if (not check_ue_exists(rnti)) { @@ -404,7 +398,6 @@ int mac::cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi int mac::snr_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, float snr, ul_channel_t ch) { logger.set_context(tti_rx); - log_h->step(tti_rx); srslte::rwlock_read_guard lock(rwlock); if (not check_ue_exists(rnti)) { @@ -432,7 +425,6 @@ int mac::ta_info(uint32_t tti, uint16_t rnti, float ta_us) int mac::sr_detected(uint32_t tti, uint16_t rnti) { logger.set_context(tti); - log_h->step(tti); srslte::rwlock_read_guard lock(rwlock); if (not check_ue_exists(rnti)) { @@ -470,7 +462,7 @@ uint16_t mac::allocate_ue() logger.error("Ignoring RACH attempt. UE pool empty."); return SRSLTE_INVALID_RNTI; } - std::unique_ptr ue_ptr = ue_pool.wait_pop(); + std::unique_ptr ue_ptr = ue_pool.pop_blocking(); uint16_t rnti = ue_ptr->get_rnti(); // Set PCAP if available @@ -512,7 +504,6 @@ void mac::rach_detected(uint32_t tti, uint32_t enb_cc_idx, uint32_t preamble_idx { static srslte::mutexed_tprof rach_tprof("rach_tprof", "MAC", 1); logger.set_context(tti); - log_h->step(tti); auto rach_tprof_meas = rach_tprof.start(); uint16_t rnti = allocate_ue(); @@ -570,8 +561,11 @@ void mac::prealloc_ue(uint32_t nof_ue) { for (uint32_t i = 0; i < nof_ue; i++) { std::unique_ptr ptr = std::unique_ptr( - new ue(allocate_rnti(), args.nof_prb, &scheduler, rrc_h, rlc_h, phy_h, log_h, logger, cells.size())); - ue_pool.push(std::move(ptr)); + new ue(allocate_rnti(), args.nof_prb, &scheduler, rrc_h, rlc_h, phy_h, logger, cells.size())); + if (not ue_pool.try_push(std::move(ptr))) { + logger.info("Cannot preallocate more UEs as pool is full"); + return; + } } } @@ -581,8 +575,8 @@ int mac::get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res_list) return 0; } + trace_complete_event("mac::get_dl_sched", "total_time"); logger.set_context(TTI_SUB(tti_tx_dl, FDD_HARQ_DELAY_UL_MS)); - log_h->step(TTI_SUB(tti_tx_dl, FDD_HARQ_DELAY_UL_MS)); for (uint32_t enb_cc_idx = 0; enb_cc_idx < cell_config.size(); enb_cc_idx++) { // Run scheduler with current info @@ -783,7 +777,6 @@ int mac::get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res { dl_sched_t* dl_sched_res = &dl_sched_res_list[0]; logger.set_context(tti); - log_h->step(tti); srslte_ra_tb_t mcs = {}; srslte_ra_tb_t mcs_data = {}; mcs.mcs_idx = enum_to_number(this->sib13.mbsfn_area_info_list[0].mcch_cfg.sig_mcs); @@ -894,7 +887,6 @@ int mac::get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res_list) } logger.set_context(TTI_SUB(tti_tx_ul, FDD_HARQ_DELAY_UL_MS + FDD_HARQ_DELAY_DL_MS)); - log_h->step(TTI_SUB(tti_tx_ul, FDD_HARQ_DELAY_UL_MS + FDD_HARQ_DELAY_DL_MS)); // Execute UE FSMs (e.g. TA) for (auto& ue : ue_db) { @@ -998,8 +990,8 @@ void mac::write_mcch(const srslte::sib2_mbms_t* sib2_, sib13 = *sib13_; memcpy(mcch_payload_buffer, mcch_payload, mcch_payload_length * sizeof(uint8_t)); current_mcch_length = mcch_payload_length; - ue_db[SRSLTE_MRNTI] = std::unique_ptr{ - new ue(SRSLTE_MRNTI, args.nof_prb, &scheduler, rrc_h, rlc_h, phy_h, log_h, logger, cells.size())}; + ue_db[SRSLTE_MRNTI] = + std::unique_ptr{new ue(SRSLTE_MRNTI, args.nof_prb, &scheduler, rrc_h, rlc_h, phy_h, logger, cells.size())}; rrc_h->add_user(SRSLTE_MRNTI, {}); } diff --git a/srsenb/src/stack/mac/mac_nr.cc b/srsenb/src/stack/mac/mac_nr.cc index 9cccea54f..78c9b9b8f 100644 --- a/srsenb/src/stack/mac/mac_nr.cc +++ b/srsenb/src/stack/mac/mac_nr.cc @@ -29,7 +29,7 @@ namespace srsenb { -mac_nr::mac_nr() : log_h("MAC") +mac_nr::mac_nr() : logger(srslog::fetch_basic_logger("MAC")) { bcch_bch_payload = srslte::make_byte_buffer(); @@ -59,15 +59,15 @@ int mac_nr::init(const mac_nr_args_t& args_, rlc_h = rlc_; rrc_h = rrc_; - log_h->set_level(args.log_level); - log_h->set_hex_limit(args.log_hex_limit); + logger.set_level(srslog::str_to_basic_level(args.log_level)); + logger.set_hex_dump_max_size(args.log_hex_limit); if (args.pcap.enable) { pcap = std::unique_ptr(new srslte::mac_pcap()); pcap->open(args.pcap.filename); } - log_h->info("Started\n"); + logger.info("Started"); started = true; @@ -96,7 +96,7 @@ void mac_nr::get_dl_config(const uint32_t tti, if (tti % 80 == 0) { // try to read BCH PDU from RRC if (rrc_h->read_pdu_bcch_bch(tti, bcch_bch_payload) == SRSLTE_SUCCESS) { - log_h->info("Adding BCH in TTI=%d\n", tti); + logger.info("Adding BCH in TTI=%d", tti); tx_request.pdus[tx_request.nof_pdus].pbch.mib_present = true; tx_request.pdus[tx_request.nof_pdus].data[0] = bcch_bch_payload->msg; tx_request.pdus[tx_request.nof_pdus].length = bcch_bch_payload->N_bytes; @@ -107,7 +107,7 @@ void mac_nr::get_dl_config(const uint32_t tti, pcap->write_dl_bch(bcch_bch_payload->msg, bcch_bch_payload->N_bytes, 0xffff, 0, tti); } } else { - log_h->error("Couldn't read BCH payload from RRC\n"); + logger.error("Couldn't read BCH payload from RRC"); } } @@ -115,7 +115,7 @@ void mac_nr::get_dl_config(const uint32_t tti, for (auto& sib : bcch_dlsch_payload) { if (sib.payload->N_bytes > 0) { if (tti % (sib.periodicity * 10) == 0) { - log_h->info("Adding SIB %d in TTI=%d\n", sib.index, tti); + logger.info("Adding SIB %d in TTI=%d", sib.index, tti); tx_request.pdus[tx_request.nof_pdus].data[0] = sib.payload->msg; tx_request.pdus[tx_request.nof_pdus].length = sib.payload->N_bytes; @@ -143,18 +143,18 @@ void mac_nr::get_dl_config(const uint32_t tti, // Only create PDU if RLC has something to tx if (pdu_len > 0) { - log_h->info("Adding MAC PDU for RNTI=%d\n", args.rnti); + logger.info("Adding MAC PDU for RNTI=%d", args.rnti); ue_rlc_buffer->N_bytes = pdu_len; - log_h->info_hex(ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes, "Read %d B from RLC\n", ue_rlc_buffer->N_bytes); + logger.info(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 ue_tx_pdu.add_sdu(4, ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes); ue_tx_pdu.pack(); - log_h->debug_hex(ue_tx_buffer.at(buffer_index)->msg, - ue_tx_buffer.at(buffer_index)->N_bytes, - "Generated MAC PDU (%d B)\n", - ue_tx_buffer.at(buffer_index)->N_bytes); + logger.debug(ue_tx_buffer.at(buffer_index)->msg, + ue_tx_buffer.at(buffer_index)->N_bytes, + "Generated MAC PDU (%d B)", + ue_tx_buffer.at(buffer_index)->N_bytes); tx_request.pdus[tx_request.nof_pdus].data[0] = ue_tx_buffer.at(buffer_index)->msg; tx_request.pdus[tx_request.nof_pdus].length = ue_tx_buffer.at(buffer_index)->N_bytes; @@ -182,7 +182,7 @@ int mac_nr::sf_indication(const uint32_t tti) phy_interface_stack_nr::tx_request_t tx_request = {}; // step MAC TTI - log_h->step(tti); + logger.set_context(tti); get_dl_config(tti, config_request, tx_request); @@ -225,14 +225,14 @@ void mac_nr::process_pdus() int mac_nr::handle_pdu(srslte::unique_byte_buffer_t pdu) { - log_h->info_hex(pdu->msg, pdu->N_bytes, "Handling MAC PDU (%d B)\n", pdu->N_bytes); + logger.info(pdu->msg, pdu->N_bytes, "Handling MAC PDU (%d B)", pdu->N_bytes); ue_rx_pdu.init_rx(true); ue_rx_pdu.unpack(pdu->msg, pdu->N_bytes); for (uint32_t i = 0; i < ue_rx_pdu.get_num_subpdus(); ++i) { srslte::mac_sch_subpdu_nr subpdu = ue_rx_pdu.get_subpdu(i); - log_h->info("Handling subPDU %d/%d: lcid=%d, sdu_len=%d\n", + logger.info("Handling subPDU %d/%d: lcid=%d, sdu_len=%d", i, ue_rx_pdu.get_num_subpdus(), subpdu.get_lcid(), @@ -255,10 +255,10 @@ int mac_nr::cell_cfg(srsenb::sched_interface::cell_cfg_t* cell_cfg) sib.periodicity = cell_cfg->sibs->period_rf; sib.payload = srslte::make_byte_buffer(); if (rrc_h->read_pdu_bcch_dlsch(sib.index, sib.payload) != SRSLTE_SUCCESS) { - log_h->error("Couldn't read SIB %d from RRC\n", sib.index); + logger.error("Couldn't read SIB %d from RRC", sib.index); } - log_h->info("Including SIB %d into SI scheduling\n", sib.index); + logger.info("Including SIB %d into SI scheduling", sib.index); bcch_dlsch_payload.push_back(std::move(sib)); } } diff --git a/srsenb/src/stack/mac/sched.cc b/srsenb/src/stack/mac/sched.cc index 9fbb3b995..4e7baba96 100644 --- a/srsenb/src/stack/mac/sched.cc +++ b/srsenb/src/stack/mac/sched.cc @@ -25,7 +25,6 @@ #include "srsenb/hdr/stack/mac/sched.h" #include "srsenb/hdr/stack/mac/sched_carrier.h" #include "srsenb/hdr/stack/mac/sched_helpers.h" -#include "srslte/common/logmap.h" #include "srslte/srslog/srslog.h" #define Console(fmt, ...) srslte::console(fmt, ##__VA_ARGS__) diff --git a/srsenb/src/stack/mac/sched_carrier.cc b/srsenb/src/stack/mac/sched_carrier.cc index 57340da7f..9c7434431 100644 --- a/srsenb/src/stack/mac/sched_carrier.cc +++ b/srsenb/src/stack/mac/sched_carrier.cc @@ -23,7 +23,8 @@ #include "srsenb/hdr/stack/mac/sched_helpers.h" #include "srsenb/hdr/stack/mac/schedulers/sched_time_pf.h" #include "srsenb/hdr/stack/mac/schedulers/sched_time_rr.h" -#include "srslte/common/logmap.h" +#include "srslte/common/standard_streams.h" +#include "srslte/common/string_helpers.h" #include "srslte/interfaces/enb_rrc_interfaces.h" namespace srsenb { @@ -159,16 +160,14 @@ void ra_sched::dl_sched(sf_sched* tti_sched) rar.prach_tti + PRACH_RAR_OFFSET + cc_cfg->cfg.prach_rar_window}; if (not rar_window.contains(tti_tx_dl)) { if (tti_tx_dl >= rar_window.stop()) { - char error_msg[128]; - int len = snprintf(error_msg, - sizeof(error_msg), - "SCHED: Could not transmit RAR within the window (RA=%d, Window=%s, RAR=%d)", - rar.prach_tti.to_uint(), - rar_window.to_string().c_str(), - tti_tx_dl.to_uint()); - error_msg[len] = '\0'; - srslte::console("%s\n", error_msg); - logger.error("%s", error_msg); + fmt::memory_buffer str_buffer; + fmt::format_to(str_buffer, + "SCHED: Could not transmit RAR within the window (RA={}, Window={}, RAR={}", + rar.prach_tti, + rar_window, + tti_tx_dl); + srslte::console("%s\n", srslte::to_c_str(str_buffer)); + logger.error("%s", srslte::to_c_str(str_buffer)); // Remove from pending queue and get next one if window has passed already pending_rars.pop_front(); continue; diff --git a/srsenb/src/stack/mac/sched_grid.cc b/srsenb/src/stack/mac/sched_grid.cc index f5c59db96..35da3034e 100644 --- a/srsenb/src/stack/mac/sched_grid.cc +++ b/srsenb/src/stack/mac/sched_grid.cc @@ -21,7 +21,7 @@ #include "srsenb/hdr/stack/mac/sched_grid.h" #include "srsenb/hdr/stack/mac/sched_helpers.h" -#include "srslte/common/logmap.h" +#include "srslte/common/string_helpers.h" using srslte::tti_point; @@ -165,9 +165,11 @@ void sf_grid_t::new_tti(tti_point tti_rx_) prbmask_t prach_mask{cc_cfg->nof_prb()}; prach_mask.fill(cc_cfg->cfg.prach_freq_offset, cc_cfg->cfg.prach_freq_offset + 6); reserve_ul_prbs(prach_mask, false); // TODO: set to true once test sib.conf files are updated - logger.debug("SCHED: Allocated PRACH RBs for tti_tx_ul=%d. Mask: 0x%s", - to_tx_ul(tti_rx).to_uint(), - prach_mask.to_hex().c_str()); + if (logger.debug.enabled()) { + fmt::memory_buffer buffer; + fmt::format_to(buffer, "SCHED: Allocated PRACH RBs mask={:x} for tti_tx_ul={}", prach_mask, to_tx_ul(tti_rx)); + logger.debug("%s", srslte::to_c_str(buffer)); + } } // internal state @@ -238,7 +240,7 @@ alloc_outcome_t sf_grid_t::alloc_dl_data(sched_ue* user, const rbgmask_t& user_m return ret; } -alloc_outcome_t sf_grid_t::alloc_ul_data(sched_ue* user, prb_interval alloc, bool needs_pdcch) +alloc_outcome_t sf_grid_t::alloc_ul_data(sched_ue* user, prb_interval alloc, bool needs_pdcch, bool strict) { if (alloc.stop() > ul_mask.size()) { return alloc_outcome_t::ERROR; @@ -246,7 +248,7 @@ alloc_outcome_t sf_grid_t::alloc_ul_data(sched_ue* user, prb_interval alloc, boo prbmask_t newmask(ul_mask.size()); newmask.fill(alloc.start(), alloc.stop()); - if ((ul_mask & newmask).any()) { + if (strict and (ul_mask & newmask).any()) { return alloc_outcome_t::RB_COLLISION; } @@ -290,9 +292,9 @@ alloc_outcome_t sf_grid_t::reserve_ul_prbs(const prbmask_t& prbmask, bool strict { alloc_outcome_t ret = alloc_outcome_t::SUCCESS; if (strict and (ul_mask & prbmask).any()) { - logger.error("There was a collision in UL channel. current mask=0x%s, new alloc mask=0x%s", - ul_mask.to_hex().c_str(), - prbmask.to_hex().c_str()); + fmt::memory_buffer tmp_buffer; + fmt::format_to(tmp_buffer, "There was a collision in the UL. Current mask={:x}, new mask={:x}", ul_mask, prbmask); + logger.error("%s", srslte::to_c_str(tmp_buffer)); ret = alloc_outcome_t::ERROR; } ul_mask |= prbmask; @@ -509,7 +511,7 @@ std::pair sf_sched::alloc_rar(uint32_t aggr_lvl, cons break; } if (ret.first != alloc_outcome_t::SUCCESS) { - logger.info("SCHED: Failed to allocate RAR due to lack of RBs"); + logger.info("SCHED: RAR allocation postponed due to lack of RBs"); } return ret; } @@ -612,7 +614,8 @@ alloc_outcome_t sf_sched::alloc_dl_user(sched_ue* user, const rbgmask_t& user_ma return alloc_outcome_t::SUCCESS; } -alloc_outcome_t sf_sched::alloc_ul(sched_ue* user, prb_interval alloc, ul_alloc_t::type_t alloc_type, int msg3_mcs) +alloc_outcome_t +sf_sched::alloc_ul(sched_ue* user, prb_interval alloc, ul_alloc_t::type_t alloc_type, bool is_msg3, int msg3_mcs) { if (ul_data_allocs.size() >= sched_interface::MAX_DATA_LIST) { logger.warning("SCHED: Maximum number of UL allocations reached"); @@ -626,25 +629,21 @@ alloc_outcome_t sf_sched::alloc_ul(sched_ue* user, prb_interval alloc, ul_alloc_ } // Check if there is no collision with measGap - bool needs_pdcch = alloc_type == ul_alloc_t::ADAPT_RETX or alloc_type == ul_alloc_t::NEWTX; + bool needs_pdcch = alloc_type == ul_alloc_t::ADAPT_RETX or (alloc_type == ul_alloc_t::NEWTX and not is_msg3); if (not user->pusch_enabled(srslte::tti_point{get_tti_rx()}, cc_cfg->enb_cc_idx, needs_pdcch)) { return alloc_outcome_t::MEASGAP_COLLISION; } // Allocate RBGs and DCI space - alloc_outcome_t ret; - if (alloc_type != ul_alloc_t::MSG3 and alloc_type != ul_alloc_t::MSG3_RETX) { - ret = tti_alloc.alloc_ul_data(user, alloc, needs_pdcch); - } else { - // allow collisions between Msg3 and PUCCH for 6 PRBs - ret = tti_alloc.reserve_ul_prbs(alloc, cc_cfg->nof_prb() != 6); - } + bool allow_pucch_collision = cc_cfg->nof_prb() == 6 and is_msg3; + alloc_outcome_t ret = tti_alloc.alloc_ul_data(user, alloc, needs_pdcch, not allow_pucch_collision); if (ret != alloc_outcome_t::SUCCESS) { return ret; } ul_alloc_t ul_alloc = {}; ul_alloc.type = alloc_type; + ul_alloc.is_msg3 = is_msg3; ul_alloc.dci_idx = tti_alloc.get_pdcch_grid().nof_allocs() - 1; ul_alloc.rnti = user->get_rnti(); ul_alloc.alloc = alloc; @@ -662,15 +661,13 @@ alloc_outcome_t sf_sched::alloc_ul_user(sched_ue* user, prb_interval alloc) bool has_retx = h->has_pending_retx(); if (not has_retx) { alloc_type = ul_alloc_t::NEWTX; - } else if (h->is_msg3()) { - alloc_type = ul_alloc_t::MSG3_RETX; } else if (h->retx_requires_pdcch(tti_point{get_tti_tx_ul()}, alloc)) { alloc_type = ul_alloc_t::ADAPT_RETX; } else { alloc_type = ul_alloc_t::NOADAPT_RETX; } - return alloc_ul(user, alloc, alloc_type); + return alloc_ul(user, alloc, alloc_type, h->is_msg3()); } bool sf_sched::alloc_phich(sched_ue* user, sched_interface::ul_sched_res_t* ul_sf_result) @@ -744,8 +741,10 @@ void sf_sched::set_bc_sched_result(const sf_cch_allocator::alloc_result_t& dci_r } else { // Paging if (tbs <= 0) { + fmt::memory_buffer str_buffer; + fmt::format_to(str_buffer, "{}", bc_alloc.rbg_range); logger.warning("SCHED: Error Paging, rbgs=%s, dci=(%d,%d)", - bc_alloc.rbg_range.to_string().c_str(), + srslte::to_c_str(str_buffer), bc->dci.location.L, bc->dci.location.ncce); continue; @@ -755,8 +754,10 @@ void sf_sched::set_bc_sched_result(const sf_cch_allocator::alloc_result_t& dci_r bc->type = sched_interface::dl_sched_bc_t::PCCH; bc->tbs = (uint32_t)tbs; + fmt::memory_buffer str_buffer; + fmt::format_to(str_buffer, "{}", bc_alloc.rbg_range); logger.info("SCHED: PCH, rbgs=%s, dci=(%d,%d), tbs=%d, mcs=%d", - bc_alloc.rbg_range.to_string().c_str(), + srslte::to_c_str(str_buffer), bc->dci.location.L, bc->dci.location.ncce, tbs, @@ -780,9 +781,11 @@ void sf_sched::set_rar_sched_result(const sf_cch_allocator::alloc_result_t& dci_ prb_interval prb_range = prb_interval::rbgs_to_prbs(rar_alloc.alloc_data.rbg_range, cc_cfg->nof_prb()); int tbs = generate_format1a(prb_range, rar_alloc.alloc_data.req_bytes, 0, rar_alloc.alloc_data.rnti, &rar->dci); if (tbs <= 0) { + fmt::memory_buffer str_buffer; + fmt::format_to(str_buffer, "{}", rar_alloc.alloc_data.rbg_range); logger.warning("SCHED: Error RAR, ra_rnti_idx=%d, rbgs=%s, dci=(%d,%d)", rar_alloc.alloc_data.rnti, - rar_alloc.alloc_data.rbg_range.to_string().c_str(), + srslte::to_c_str(str_buffer), rar->dci.location.L, rar->dci.location.ncce); continue; @@ -794,13 +797,15 @@ void sf_sched::set_rar_sched_result(const sf_cch_allocator::alloc_result_t& dci_ // Print RAR allocation result for (uint32_t i = 0; i < rar->msg3_grant.size(); ++i) { - const auto& msg3_grant = rar->msg3_grant[i]; - uint16_t expected_rnti = msg3_grant.data.temp_crnti; + const auto& msg3_grant = rar->msg3_grant[i]; + uint16_t expected_rnti = msg3_grant.data.temp_crnti; + fmt::memory_buffer str_buffer; + fmt::format_to(str_buffer, "{}", rar_alloc.alloc_data.rbg_range); logger.info("SCHED: RAR, temp_crnti=0x%x, ra-rnti=%d, rbgs=%s, dci=(%d,%d), rar_grant_rba=%d, " "rar_grant_mcs=%d", expected_rnti, rar_alloc.alloc_data.rnti, - rar_alloc.alloc_data.rbg_range.to_string().c_str(), + srslte::to_c_str(str_buffer), rar->dci.location.L, rar->dci.location.ncce, msg3_grant.grant.rba, @@ -835,29 +840,35 @@ void sf_sched::set_dl_data_sched_result(const sf_cch_allocator::alloc_result_t& data_alloc.pid, data, get_tti_tx_dl(), cc_cfg->enb_cc_idx, tti_alloc.get_cfi(), data_alloc.user_mask); if (tbs <= 0) { - logger.warning("SCHED: DL %s failed rnti=0x%x, pid=%d, mask=%s, tbs=%d, buffer=%d", + fmt::memory_buffer str_buffer; + fmt::format_to(str_buffer, + "SCHED: DL {} failed rnti=0x{:x}, pid={}, mask={:x}, tbs={}, buffer={}", is_newtx ? "tx" : "retx", user->get_rnti(), data_alloc.pid, - data_alloc.user_mask.to_hex().c_str(), + data_alloc.user_mask, tbs, user->get_requested_dl_bytes(cc_cfg->enb_cc_idx).stop()); + logger.warning("%s", srslte::to_c_str(str_buffer)); continue; } // Print Resulting DL Allocation - logger.info("SCHED: DL %s rnti=0x%x, cc=%d, pid=%d, mask=0x%s, dci=(%d,%d), n_rtx=%d, tbs=%d, buffer=%d/%d", - !is_newtx ? "retx" : "tx", - user->get_rnti(), - cc_cfg->enb_cc_idx, - data_alloc.pid, - data_alloc.user_mask.to_hex().c_str(), - data->dci.location.L, - data->dci.location.ncce, - dl_harq.nof_retx(0) + dl_harq.nof_retx(1), - tbs, - data_before, - user->get_requested_dl_bytes(cc_cfg->enb_cc_idx).stop()); + fmt::memory_buffer str_buffer; + fmt::format_to(str_buffer, + "SCHED: DL {} rnti=0x{:x}, cc={}, pid={}, mask={:x}, dci=({}, {}), n_rtx={}, tbs={}, buffer={}/{}", + is_newtx ? "tx" : "retx", + user->get_rnti(), + cc_cfg->enb_cc_idx, + data_alloc.pid, + data_alloc.user_mask, + data->dci.location.L, + data->dci.location.ncce, + dl_harq.nof_retx(0) + dl_harq.nof_retx(1), + tbs, + data_before, + user->get_requested_dl_bytes(cc_cfg->enb_cc_idx).stop()); + logger.info("%s", srslte::to_c_str(str_buffer)); dl_result->nof_data_elems++; } @@ -986,34 +997,42 @@ void sf_sched::set_ul_sched_result(const sf_cch_allocator::alloc_result_t& dci_r uint32_t new_pending_bytes = user->get_pending_ul_new_data(get_tti_tx_ul(), cc_cfg->enb_cc_idx); // Allow TBS=0 in case of UCI-only PUSCH if (tbs < 0 || (tbs == 0 && pusch->dci.tb.mcs_idx != 29)) { - logger.warning("SCHED: Error %s %s rnti=0x%x, pid=%d, dci=(%d,%d), prb=%s, bsr=%d", - ul_alloc.type == ul_alloc_t::MSG3 ? "Msg3" : "UL", + fmt::memory_buffer str_buffer; + fmt::format_to(str_buffer, + "SCHED: Error {} {} rnti=0x{:x}, pid={}, dci=({},{}), prb={}, bsr={}", + ul_alloc.is_msg3 ? "Msg3" : "UL", ul_alloc.is_retx() ? "retx" : "tx", user->get_rnti(), h->get_id(), pusch->dci.location.L, pusch->dci.location.ncce, - ul_alloc.alloc.to_string().c_str(), + ul_alloc.alloc, new_pending_bytes); + logger.warning("%s", srslte::to_c_str(str_buffer)); continue; } // Print Resulting UL Allocation uint32_t old_pending_bytes = user->get_pending_ul_old_data(); - logger.info("SCHED: %s %s rnti=0x%x, cc=%d, pid=%d, dci=(%d,%d), prb=%s, n_rtx=%d, tbs=%d, bsr=%d (%d-%d)", - ul_alloc.is_msg3() ? "Msg3" : "UL", - ul_alloc.is_retx() ? "retx" : "tx", - user->get_rnti(), - cc_cfg->enb_cc_idx, - h->get_id(), - pusch->dci.location.L, - pusch->dci.location.ncce, - ul_alloc.alloc.to_string().c_str(), - h->nof_retx(0), - tbs, - new_pending_bytes, - total_data_before, - old_pending_bytes); + if (logger.info.enabled()) { + fmt::memory_buffer str_buffer; + fmt::format_to(str_buffer, + "SCHED: {} {} rnti=0x{:x}, cc={}, pid={}, dci=({},{}), prb={}, n_rtx={}, tbs={}, bsr={} ({}-{})", + ul_alloc.is_msg3 ? "Msg3" : "UL", + ul_alloc.is_retx() ? "retx" : "newtx", + user->get_rnti(), + cc_cfg->enb_cc_idx, + h->get_id(), + pusch->dci.location.L, + pusch->dci.location.ncce, + ul_alloc.alloc, + h->nof_retx(0), + tbs, + new_pending_bytes, + total_data_before, + old_pending_bytes); + logger.info("%s", srslte::to_c_str(str_buffer)); + } pusch->current_tx_nb = h->nof_retx(0); @@ -1026,9 +1045,11 @@ alloc_outcome_t sf_sched::alloc_msg3(sched_ue* user, const sched_interface::dl_s // Derive PRBs from allocated RAR grants prb_interval msg3_alloc = prb_interval::riv_to_prbs(rargrant.grant.rba, cc_cfg->nof_prb()); - alloc_outcome_t ret = alloc_ul(user, msg3_alloc, sf_sched::ul_alloc_t::MSG3, rargrant.grant.trunc_mcs); + alloc_outcome_t ret = alloc_ul(user, msg3_alloc, sf_sched::ul_alloc_t::NEWTX, true, rargrant.grant.trunc_mcs); if (not ret) { - logger.warning("SCHED: Could not allocate msg3 within %s", msg3_alloc.to_string().c_str()); + fmt::memory_buffer str_buffer; + fmt::format_to(str_buffer, "{}", msg3_alloc); + logger.warning("SCHED: Could not allocate msg3 within %s", srslte::to_c_str(str_buffer)); } return ret; } diff --git a/srsenb/src/stack/mac/sched_helpers.cc b/srsenb/src/stack/mac/sched_helpers.cc index 9c1ca20d9..6aae1de83 100644 --- a/srsenb/src/stack/mac/sched_helpers.cc +++ b/srsenb/src/stack/mac/sched_helpers.cc @@ -20,14 +20,16 @@ */ #include "srsenb/hdr/stack/mac/sched_helpers.h" +#include "srslte/common/standard_streams.h" #include "srslte/mac/pdu.h" #include "srslte/srslog/bundled/fmt/format.h" + #include -#define Debug(fmt, ...) srslog::fetch_basic_logger("MAC").debug(fmt, ##__VA_ARGS__) -#define Info(fmt, ...) srslog::fetch_basic_logger("MAC").info(fmt, ##__VA_ARGS__) -#define Warning(fmt, ...) srslog::fetch_basic_logger("MAC").warning(fmt, ##__VA_ARGS__) -#define Error(fmt, ...) srslog::fetch_basic_logger("MAC").error(fmt, ##__VA_ARGS__) +#define Debug(fmt, ...) get_mac_logger().debug(fmt, ##__VA_ARGS__) +#define Info(fmt, ...) get_mac_logger().info(fmt, ##__VA_ARGS__) +#define Warning(fmt, ...) get_mac_logger().warning(fmt, ##__VA_ARGS__) +#define Error(fmt, ...) get_mac_logger().error(fmt, ##__VA_ARGS__) namespace srsenb { @@ -35,6 +37,12 @@ using dl_sched_res_t = sched_interface::dl_sched_res_t; using dl_sched_data_t = sched_interface::dl_sched_data_t; using custom_mem_buffer = fmt::basic_memory_buffer; +srslog::basic_logger& get_mac_logger() +{ + static srslog::basic_logger& mac_logger = srslog::fetch_basic_logger("MAC"); + return mac_logger; +} + const char* to_string_short(srslte_dci_format_t dcifmt) { switch (dcifmt) { diff --git a/srsenb/src/stack/mac/sched_phy_ch/sched_dci.cc b/srsenb/src/stack/mac/sched_phy_ch/sched_dci.cc index e61c4d1eb..7c7250a93 100644 --- a/srsenb/src/stack/mac/sched_phy_ch/sched_dci.cc +++ b/srsenb/src/stack/mac/sched_phy_ch/sched_dci.cc @@ -29,7 +29,7 @@ namespace srsenb { /// Compute max TBS based on max coderate int coderate_to_tbs(float max_coderate, uint32_t nof_re) { - return floorf(nof_re * max_coderate - 24); + return static_cast(floorf(nof_re * max_coderate - 24)); } /// Compute {mcs, tbs_idx} based on {max_tbs, nof_prb} @@ -81,9 +81,9 @@ tbs_info compute_mcs_and_tbs(uint32_t nof_prb, assert((not is_ul or not use_tbs_index_alt) && "UL cannot use Alt CQI Table"); assert((is_ul or not ulqam64_enabled) && "DL cannot use UL-QAM64 enable flag"); - float max_coderate = srslte_cqi_to_coderate(std::min(cqi + 1u, 15u), use_tbs_index_alt); + float max_coderate = srslte_cqi_to_coderate(std::min(cqi + 1U, 15U), use_tbs_index_alt); uint32_t max_Qm = (is_ul) ? (ulqam64_enabled ? 6 : 4) : (use_tbs_index_alt ? 8 : 6); - max_coderate = std::min(max_coderate, 0.930f * max_Qm); + max_coderate = std::min(max_coderate, 0.93F * max_Qm); int mcs = 0; float prev_max_coderate = 0; @@ -113,12 +113,12 @@ tbs_info compute_mcs_and_tbs(uint32_t nof_prb, // update max coderate based on mcs srslte_mod_t mod = (is_ul) ? srslte_ra_ul_mod_from_mcs(mcs) : srslte_ra_dl_mod_from_mcs(mcs, use_tbs_index_alt); uint32_t Qm = srslte_mod_bits_x_symbol(mod); - max_coderate = std::min(0.930f * Qm, max_coderate); + max_coderate = std::min(0.93F * Qm, max_coderate); if (coderate <= max_coderate) { // solution was found tbs_info tb; - tb.tbs_bytes = tbs / 8u; + tb.tbs_bytes = tbs / 8; tb.mcs = mcs; return tb; } @@ -147,10 +147,11 @@ tbs_info compute_min_mcs_and_tbs_from_required_bytes(uint32_t nof_prb, } // get maximum MCS that leads to tbs < req_bytes (used as max_tbs argument) - int mcs_min = 0, tbs_idx_min = 0; + int mcs_min = 0; + int tbs_idx_min = 0; // Note: we subtract -1 to required data to get an exclusive lower bound for maximum MCS. This works ok because // req_bytes * 8 is always even - if (compute_mcs_from_max_tbs(nof_prb, req_bytes * 8u - 1, max_mcs, is_ul, use_tbs_index_alt, mcs_min, tbs_idx_min) != + if (compute_mcs_from_max_tbs(nof_prb, req_bytes * 8U - 1, max_mcs, is_ul, use_tbs_index_alt, mcs_min, tbs_idx_min) != SRSLTE_SUCCESS) { // Failed to compute maximum MCS that leads to TBS < req bytes. MCS=0 is likely a valid solution tbs_info tb2 = compute_mcs_and_tbs(nof_prb, nof_re, cqi, 0, is_ul, ulqam64_enabled, use_tbs_index_alt); diff --git a/srsenb/src/stack/mac/sched_phy_ch/sf_cch_allocator.cc b/srsenb/src/stack/mac/sched_phy_ch/sf_cch_allocator.cc index 4f0de3b81..0b9da52a6 100644 --- a/srsenb/src/stack/mac/sched_phy_ch/sf_cch_allocator.cc +++ b/srsenb/src/stack/mac/sched_phy_ch/sf_cch_allocator.cc @@ -168,8 +168,8 @@ std::string sf_cch_allocator::result_to_string(bool verbose) const sf_cch_allocator::alloc_tree_t::alloc_tree_t(uint32_t this_cfi, const sched_cell_params_t& cc_params, - srslte_pucch_cfg_t& pucch_cfg) : - cfi(this_cfi), cc_cfg(&cc_params), pucch_cfg(&pucch_cfg), nof_cces(cc_params.nof_cce_table[this_cfi - 1]) + srslte_pucch_cfg_t& pucch_cfg_common) : + cfi(this_cfi), cc_cfg(&cc_params), pucch_cfg_temp(&pucch_cfg_common), nof_cces(cc_params.nof_cce_table[this_cfi - 1]) { dci_alloc_tree.reserve(8); } @@ -181,10 +181,10 @@ void sf_cch_allocator::alloc_tree_t::reset() dci_alloc_tree.clear(); } -bool is_pucch_sr_collision(const srslte_pucch_cfg_t& pucch_cfg, tti_point tti_tx_dl, uint32_t n1_pucch) +bool is_pucch_sr_collision(const srslte_pucch_cfg_t& ue_pucch_cfg, tti_point tti_tx_dl_ack, uint32_t n1_pucch) { - if (pucch_cfg.sr_configured && srslte_ue_ul_sr_send_tti(&pucch_cfg, tti_tx_dl.to_uint())) { - return n1_pucch == pucch_cfg.n_pucch_sr; + if (ue_pucch_cfg.sr_configured && srslte_ue_ul_sr_send_tti(&ue_pucch_cfg, tti_tx_dl_ack.to_uint())) { + return n1_pucch == ue_pucch_cfg.n_pucch_sr; } return false; } @@ -218,14 +218,15 @@ bool sf_cch_allocator::alloc_tree_t::add_tree_node_leaves(int if (dci_record.alloc_type == alloc_type_t::DL_DATA and not dci_record.pusch_uci) { // The UE needs to allocate space in PUCCH for HARQ-ACK - pucch_cfg->n_pucch = ncce_pos + pucch_cfg->N_pucch_1; + pucch_cfg_temp->n_pucch = ncce_pos + pucch_cfg_temp->N_pucch_1; - if (is_pucch_sr_collision(*pucch_cfg, to_tx_dl_ack(tti_rx_), pucch_cfg->n_pucch)) { + if (is_pucch_sr_collision( + dci_record.user->get_ue_cfg().pucch_cfg, to_tx_dl_ack(tti_rx_), pucch_cfg_temp->n_pucch)) { // avoid collision of HARQ-ACK with own SR n(1)_pucch continue; } - pucch_prbidx = srslte_pucch_n_prb(&cc_cfg->cfg.cell, pucch_cfg, 0); + pucch_prbidx = srslte_pucch_n_prb(&cc_cfg->cfg.cell, pucch_cfg_temp, 0); if (not cc_cfg->sched_cfg->pucch_mux_enabled and parent_pucch_mask.test(pucch_prbidx)) { // PUCCH allocation would collide with other PUCCH/PUSCH grants. Try another CCE position continue; @@ -316,15 +317,15 @@ std::string sf_cch_allocator::alloc_tree_t::result_to_string(bool verbose) const pdcch_mask_t tot_mask; get_allocs(&vec, &tot_mask, i - prev_start); - fmt::format_to(strbuf, "[{}]: total mask=0x{}", count, tot_mask.to_hex().c_str()); + fmt::format_to(strbuf, "[{}]: total mask=0x{:x}", count, tot_mask); if (verbose) { fmt::format_to(strbuf, ", allocations:\n"); for (const auto& dci_alloc : vec) { fmt::format_to(strbuf, - " > rnti=0x{:0x}: 0x{} / 0x{}\n", + " > rnti=0x{:0x}: 0x{:x} / 0x{:x}\n", dci_alloc->rnti, - dci_alloc->current_mask.to_hex().c_str(), - dci_alloc->total_mask.to_hex().c_str()); + dci_alloc->current_mask, + dci_alloc->total_mask); } } else { fmt::format_to(strbuf, "\n"); diff --git a/srsenb/src/stack/mac/sched_ue.cc b/srsenb/src/stack/mac/sched_ue.cc index b326152a0..b18e8a208 100644 --- a/srsenb/src/stack/mac/sched_ue.cc +++ b/srsenb/src/stack/mac/sched_ue.cc @@ -24,8 +24,8 @@ #include "srsenb/hdr/stack/mac/sched.h" #include "srsenb/hdr/stack/mac/sched_helpers.h" #include "srsenb/hdr/stack/mac/sched_ue.h" -#include "srslte/common/log_helper.h" -#include "srslte/common/logmap.h" +#include "srslte/common/string_helpers.h" +#include "srslte/srslog/bundled/fmt/ranges.h" using srslte::tti_interval; @@ -951,10 +951,14 @@ uint32_t sched_ue::get_pending_ul_new_data(tti_point tti_tx_ul, int this_enb_cc_ pending_data = (pending_data > pending_ul_data) ? pending_data - pending_ul_data : 0; if (pending_data > 0) { - logger.debug("SCHED: pending_data=%d, in_harq_data=%d, bsr=%s", - pending_data, - pending_ul_data, - lch_handler.get_bsr_text().c_str()); + if (logger.debug.enabled()) { + fmt::memory_buffer str_buffer; + fmt::format_to(str_buffer, "{}", lch_handler.get_bsr_state()); + logger.debug("SCHED: pending_data=%d, in_harq_data=%d, bsr=%s", + pending_data, + pending_ul_data, + srslte::to_c_str(str_buffer)); + } } return pending_data; } diff --git a/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc index 425b3eecd..ed8557c89 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc @@ -36,6 +36,8 @@ namespace srsenb { * ******************************************************/ +harq_proc::harq_proc() : logger(&srslog::fetch_basic_logger("MAC")) {} + void harq_proc::init(uint32_t id_) { id = id_; @@ -85,19 +87,17 @@ tti_point harq_proc::get_tti() const int harq_proc::set_ack_common(uint32_t tb_idx, bool ack_) { if (is_empty(tb_idx)) { - srslog::fetch_basic_logger("MAC").warning("Received ACK for inactive harq"); + logger->warning("Received ACK for inactive harq"); return SRSLTE_ERROR; } ack_state[tb_idx] = ack_; - srslog::fetch_basic_logger("MAC").debug( - "ACK=%d received pid=%d, tb_idx=%d, n_rtx=%d, max_retx=%d", ack_, id, tb_idx, n_rtx[tb_idx], max_retx); + logger->debug("ACK=%d received pid=%d, tb_idx=%d, n_rtx=%d, max_retx=%d", ack_, id, tb_idx, n_rtx[tb_idx], max_retx); if (!ack_ && (n_rtx[tb_idx] + 1 >= max_retx)) { - srslog::fetch_basic_logger("MAC").info( - "SCHED: discarding TB=%d pid=%d, tti=%d, maximum number of retx exceeded (%d)", - tb_idx, - id, - tti.to_uint(), - max_retx); + logger->info("SCHED: discarding TB=%d pid=%d, tti=%d, maximum number of retx exceeded (%d)", + tb_idx, + id, + tti.to_uint(), + max_retx); active[tb_idx] = false; } else if (ack_) { active[tb_idx] = false; @@ -282,8 +282,14 @@ bool ul_harq_proc::has_pending_phich() const bool ul_harq_proc::pop_pending_phich() { + assert(pending_phich); bool ret = ack_state[0]; pending_phich = false; + if (is_empty(0)) { + // fully reset UL HARQ once PHICH is dispatched + is_msg3_ = false; + pending_data = 0; + } return ret; } @@ -292,6 +298,7 @@ void ul_harq_proc::reset_pending_data() reset_pending_data_common(); if (is_empty(0)) { pending_data = 0; + is_msg3_ = false; } } diff --git a/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc index 8d88c3399..908fa3a52 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc @@ -21,7 +21,8 @@ #include "srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h" #include "srsenb/hdr/stack/mac/sched_helpers.h" -#include "srslte/common/log_helper.h" +#include "srslte/common/string_helpers.h" +#include "srslte/srslog/bundled/fmt/ranges.h" namespace srsenb { @@ -119,7 +120,11 @@ void lch_ue_manager::ul_bsr(uint8_t lcg_id, uint32_t bsr) return; } lcg_bsr[lcg_id] = bsr; - logger.debug("SCHED: bsr=%d, lcg_id=%d, bsr=%s", bsr, lcg_id, get_bsr_text().c_str()); + if (logger.debug.enabled()) { + fmt::memory_buffer str_buffer; + fmt::format_to(str_buffer, "{}", get_bsr_state()); + logger.debug("SCHED: bsr=%d, lcg_id=%d, bsr=%s", bsr, lcg_id, srslte::to_c_str(str_buffer)); + } } void lch_ue_manager::ul_buffer_add(uint8_t lcid, uint32_t bytes) @@ -129,7 +134,12 @@ void lch_ue_manager::ul_buffer_add(uint8_t lcid, uint32_t bytes) return; } lcg_bsr[lch[lcid].cfg.group] += bytes; - logger.debug("SCHED: UL buffer update=%d, lcg_id=%d, bsr=%s", bytes, lch[lcid].cfg.group, get_bsr_text().c_str()); + if (logger.debug.enabled()) { + fmt::memory_buffer str_buffer; + fmt::format_to(str_buffer, "{}", get_bsr_state()); + logger.debug( + "SCHED: UL buffer update=%d, lcg_id=%d, bsr=%s", bytes, lch[lcid].cfg.group, srslte::to_c_str(str_buffer)); + } } void lch_ue_manager::dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t retx_queue) @@ -330,11 +340,9 @@ int lch_ue_manager::get_bsr_with_overhead(uint32_t lcg) const return get_ul_mac_sdu_size_with_overhead(get_bsr(lcg)); } -std::string lch_ue_manager::get_bsr_text() const +const std::array& lch_ue_manager::get_bsr_state() const { - std::stringstream ss; - ss << "{" << lcg_bsr[0] << ", " << lcg_bsr[1] << ", " << lcg_bsr[2] << ", " << lcg_bsr[3] << "}"; - return ss.str(); + return lcg_bsr; } uint32_t allocate_mac_sdus(sched_interface::dl_sched_data_t* data, diff --git a/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc index 6826f6228..3899c7104 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc @@ -39,14 +39,16 @@ sched_ue_cell::sched_ue_cell(uint16_t rnti_, const sched_cell_params_t& cell_cfg tpc_fsm(cell_cfg->nof_prb(), cell_cfg->cfg.target_ul_sinr, cell_cfg->cfg.enable_phr_handling), fixed_mcs_dl(cell_cfg_.sched_cfg->pdsch_mcs), fixed_mcs_ul(cell_cfg_.sched_cfg->pusch_mcs), - current_tti(current_tti_) + current_tti(current_tti_), + max_aggr_level(cell_cfg_.sched_cfg->max_aggr_level >= 0 ? cell_cfg_.sched_cfg->max_aggr_level : 3) { - max_aggr_level = cell_cfg->sched_cfg->max_aggr_level >= 0 ? cell_cfg->sched_cfg->max_aggr_level : 3; clear_feedback(); } void sched_ue_cell::set_ue_cfg(const sched_interface::ue_cfg_t& ue_cfg_) { + static const std::array max_64qam_mcs{20, 24, 28}; + cfg_tti = current_tti; ue_cfg = &ue_cfg_; int prev_ue_cc_idx = ue_cc_idx; @@ -61,14 +63,13 @@ void sched_ue_cell::set_ue_cfg(const sched_interface::ue_cfg_t& ue_cfg_) } // set max mcs - max_mcs_ul = cell_cfg->sched_cfg->pusch_max_mcs >= 0 ? cell_cfg->sched_cfg->pusch_max_mcs : 28u; + max_mcs_ul = cell_cfg->sched_cfg->pusch_max_mcs >= 0 ? cell_cfg->sched_cfg->pusch_max_mcs : 28U; if (cell_cfg->cfg.enable_64qam) { - const uint32_t max_64qam_mcs[] = {20, 24, 28}; - max_mcs_ul = std::min(max_mcs_ul, max_64qam_mcs[(size_t)ue_cfg->support_ul64qam]); + max_mcs_ul = std::min(max_mcs_ul, max_64qam_mcs[(size_t)ue_cfg->support_ul64qam]); } - max_mcs_dl = cell_cfg->sched_cfg->pdsch_max_mcs >= 0 ? std::min(cell_cfg->sched_cfg->pdsch_max_mcs, 28) : 28u; + max_mcs_dl = cell_cfg->sched_cfg->pdsch_max_mcs >= 0 ? std::min(cell_cfg->sched_cfg->pdsch_max_mcs, 28) : 28U; if (ue_cfg->use_tbs_index_alt) { - max_mcs_dl = std::min(max_mcs_dl, 27u); + max_mcs_dl = std::min(max_mcs_dl, 27U); } // If new cell configuration, clear Cell HARQs @@ -194,20 +195,18 @@ false_position_method(int x1, int x2, YType y0, const Callable& f, const ErrorDe YType y3_1 = f(x3 - 1); if (not is_error(y3_1) and y3_1 < y0) { return std::make_tuple(x3 - 1, y3_1, x3, y3); - } else { - x3--; - y3 = y3_1; } + x3--; + y3 = y3_1; } else if (x3 == x1) { y3 = y1; // check if in frontier YType y3_1 = f(x3 + 1); if (not is_error(y3_1) and y3_1 >= y0) { return std::make_tuple(x3, y3, x3 + 1, y3_1); - } else { - x3++; - y3 = y3_1; } + x3++; + y3 = y3_1; } else { y3 = f(x3); if (is_error(y3) or y3 == y0) { @@ -297,10 +296,10 @@ int get_required_prb_dl(const sched_ue_cell& cell, }; std::tuple ret = false_position_method( - 1u, cell.cell_cfg->nof_prb(), (int)req_bytes, compute_tbs_approx, [](int y) { return y == SRSLTE_ERROR; }); + 1U, cell.cell_cfg->nof_prb(), (int)req_bytes, compute_tbs_approx, [](int y) { return y == SRSLTE_ERROR; }); int upper_tbs = std::get<3>(ret); uint32_t upper_nprb = std::get<2>(ret); - return (upper_tbs < 0) ? 0 : ((upper_tbs < (int)req_bytes) ? -1 : upper_nprb); + return (upper_tbs < 0) ? 0 : ((upper_tbs < (int)req_bytes) ? -1 : static_cast(upper_nprb)); } uint32_t get_required_prb_ul(const sched_ue_cell& cell, uint32_t req_bytes) @@ -315,10 +314,10 @@ uint32_t get_required_prb_ul(const sched_ue_cell& cell, uint32_t req_bytes) }; // find nof prbs that lead to a tbs just above req_bytes - int target_tbs = req_bytes + 4; + int target_tbs = static_cast(req_bytes) + 4; uint32_t max_prbs = std::min(cell.tpc_fsm.max_ul_prbs(), cell.cell_cfg->nof_prb()); std::tuple ret = - false_position_method(1u, max_prbs, target_tbs, compute_tbs_approx, [](int y) { return y == SRSLTE_ERROR; }); + false_position_method(1U, max_prbs, target_tbs, compute_tbs_approx, [](int y) { return y == SRSLTE_ERROR; }); uint32_t req_prbs = std::get<2>(ret); while (!srslte_dft_precoding_valid_prb(req_prbs) && req_prbs < cell.cell_cfg->nof_prb()) { req_prbs++; diff --git a/srsenb/src/stack/mac/schedulers/sched_base.cc b/srsenb/src/stack/mac/schedulers/sched_base.cc index 5e45b0a23..ca5b9b9c6 100644 --- a/srsenb/src/stack/mac/schedulers/sched_base.cc +++ b/srsenb/src/stack/mac/schedulers/sched_base.cc @@ -234,11 +234,18 @@ const ul_harq_proc* get_ul_newtx_harq(sched_ue& user, sf_sched* tti_sched) alloc_outcome_t try_ul_retx_alloc(sf_sched& tti_sched, sched_ue& ue, const ul_harq_proc& h) { - // If can schedule the same mask, do it - prb_interval alloc = h.get_alloc(); - alloc_outcome_t ret = tti_sched.alloc_ul_user(&ue, alloc); - if (ret == alloc_outcome_t::SUCCESS or ret == alloc_outcome_t::DCI_COLLISION) { - return ret; + prb_interval alloc = h.get_alloc(); + if (tti_sched.get_cc_cfg()->nof_prb() == 6 and h.is_msg3()) { + // We allow collisions with PUCCH for special case of Msg3 and 6 PRBs + return tti_sched.alloc_ul_user(&ue, alloc); + } + + // If can schedule the same mask as in earlier tx, do it + if (not tti_sched.get_ul_mask().any(alloc.start(), alloc.stop())) { + alloc_outcome_t ret = tti_sched.alloc_ul_user(&ue, alloc); + if (ret == alloc_outcome_t::SUCCESS or ret == alloc_outcome_t::DCI_COLLISION) { + return ret; + } } // Avoid measGaps accounting for PDCCH diff --git a/srsenb/src/stack/mac/ue.cc b/srsenb/src/stack/mac/ue.cc index 8127e3073..3017490fc 100644 --- a/srsenb/src/stack/mac/ue.cc +++ b/srsenb/src/stack/mac/ue.cc @@ -25,13 +25,109 @@ #include #include "srsenb/hdr/stack/mac/ue.h" +#include "srslte/common/string_helpers.h" #include "srslte/interfaces/enb_phy_interfaces.h" #include "srslte/interfaces/enb_rlc_interfaces.h" #include "srslte/interfaces/enb_rrc_interfaces.h" namespace srsenb { -cc_buffer_handler::cc_buffer_handler() +cc_used_buffers_map::cc_used_buffers_map(srslte::pdu_queue& shared_pdu_queue_) : + pdu_map(), shared_pdu_queue(&shared_pdu_queue_), logger(&srslog::fetch_basic_logger("MAC")) +{} + +bool cc_used_buffers_map::push_pdu(tti_point tti, uint32_t len) +{ + if (not has_tti(tti)) { + return false; + } + auto& pdu_pair = pdu_map[tti.to_uint()]; + if (len > 0) { + shared_pdu_queue->push(pdu_pair.second, len); + } else { + shared_pdu_queue->deallocate(pdu_pair.second); + logger->error("Error pushing PDU: null length"); + } + // clear entry in map + pdu_pair.first = tti_point(); + pdu_pair.second = nullptr; + return len > 0; +} + +uint8_t* cc_used_buffers_map::request_pdu(tti_point tti, uint32_t len) +{ + if (pdu_map[tti.to_uint()].second != nullptr) { + logger->error("UE buffers: buffer for tti=%d already allocated", tti.to_uint()); + return nullptr; + } + + uint8_t* pdu = shared_pdu_queue->request(len); + if (pdu == nullptr) { + logger->error("UE buffers: Requesting buffer from pool"); + return nullptr; + } + + pdu_map[tti.to_uint()].first = tti; + pdu_map[tti.to_uint()].second = pdu; + return pdu; +} + +void cc_used_buffers_map::clear_old_pdus(tti_point current_tti) +{ + static const uint32_t old_tti_threshold = SRSLTE_FDD_NOF_HARQ + 4; + + tti_point max_tti{current_tti - old_tti_threshold}; + for (auto& pdu_pair : pdu_map) { + if (pdu_pair.second != nullptr and pdu_pair.first < max_tti) { + logger->warning("UE buffers: Removing old buffer tti=%d, interval=%d", + pdu_pair.first.to_uint(), + current_tti - pdu_pair.first); + remove_pdu(pdu_pair.first); + } + } +} + +void cc_used_buffers_map::remove_pdu(tti_point tti) +{ + auto& pdu_pair = pdu_map[tti.to_uint()]; + assert(pdu_pair.second != nullptr && "cannot remove inexistent PDU"); + // return pdus back to the queue + shared_pdu_queue->deallocate(pdu_pair.second); + // clear entry in map + pdu_pair.first = tti_point(); + pdu_pair.second = nullptr; +} + +bool cc_used_buffers_map::try_deallocate_pdu(tti_point tti) +{ + if (pdu_map[tti.to_uint()].second != nullptr) { + remove_pdu(tti); + return true; + } + return false; +} + +void cc_used_buffers_map::clear() +{ + for (auto& pdu : pdu_map) { + try_deallocate_pdu(pdu.first); + } +} + +uint8_t*& cc_used_buffers_map::operator[](tti_point tti) +{ + assert(has_tti(tti) && "Trying to access buffer that does not exist"); + return pdu_map[tti.to_uint()].second; +} + +bool cc_used_buffers_map::has_tti(tti_point tti) const +{ + return pdu_map[tti.to_uint()].first == tti and pdu_map[tti.to_uint()].second != nullptr; +} + +//////////////// + +cc_buffer_handler::cc_buffer_handler(srslte::pdu_queue& shared_pdu_queue_) : rx_used_buffers(shared_pdu_queue_) { for (auto& harq_buffers : tx_payload_buffer) { for (srslte::unique_byte_buffer_t& tb_buffer : harq_buffers) { @@ -105,8 +201,7 @@ ue::ue(uint16_t rnti_, rrc_interface_mac* rrc_, rlc_interface_mac* rlc_, phy_interface_stack_lte* phy_, - srslte::log_ref log_, - srslog::basic_logger& logger, + srslog::basic_logger& logger_, uint32_t nof_cells_, uint32_t nof_rx_harq_proc_, uint32_t nof_tx_harq_proc_) : @@ -116,17 +211,18 @@ ue::ue(uint16_t rnti_, rrc(rrc_), rlc(rlc_), phy(phy_), - log_h(log_), - logger(logger), - mac_msg_dl(20, logger), - mch_mac_msg_dl(10, logger), - mac_msg_ul(20, logger), - pdus(logger, 128), + logger(logger_), + mac_msg_dl(20, logger_), + mch_mac_msg_dl(10, logger_), + mac_msg_ul(20, logger_), + pdus(logger_), nof_rx_harq_proc(nof_rx_harq_proc_), nof_tx_harq_proc(nof_tx_harq_proc_), - ta_fsm(this), - cc_buffers(nof_cells_) + ta_fsm(this) { + for (size_t i = 0; i < nof_cells_; ++i) { + cc_buffers.emplace_back(pdus); + } pdus.init(this); // Allocate buffer for PCell @@ -135,14 +231,9 @@ ue::ue(uint16_t rnti_, ue::~ue() { - { - std::unique_lock lock(rx_buffers_mutex); - for (auto& cc : cc_buffers) { - for (auto& q : cc.get_rx_used_buffers()) { - pdus.deallocate(q.second); - } - cc.get_rx_used_buffers().clear(); - } + std::unique_lock lock(rx_buffers_mutex); + for (auto& cc : cc_buffers) { + cc.get_rx_used_buffers().clear(); } } @@ -173,7 +264,7 @@ srslte_softbuffer_rx_t* ue::get_rx_softbuffer(const uint32_t ue_cc_idx, const ui return nullptr; } - return &cc_buffers.at(ue_cc_idx).get_rx_softbuffer(tti % nof_rx_harq_proc); + return &cc_buffers[ue_cc_idx].get_rx_softbuffer(tti % nof_rx_harq_proc); } srslte_softbuffer_tx_t* @@ -192,17 +283,7 @@ uint8_t* ue::request_buffer(uint32_t tti, uint32_t ue_cc_idx, const uint32_t len std::unique_lock lock(rx_buffers_mutex); uint8_t* pdu = nullptr; if (len > 0) { - // Deallocate oldest buffer if we didn't deallocate it - if (!cc_buffers.at(ue_cc_idx).get_rx_used_buffers().count(tti)) { - pdu = pdus.request(len); - if (pdu) { - cc_buffers.at(ue_cc_idx).get_rx_used_buffers().emplace(tti, pdu); - } else { - logger.error("UE buffers: Requesting buffer from pool"); - } - } else { - logger.error("UE buffers: buffer for tti=%d already allocated", tti); - } + pdu = cc_buffers[ue_cc_idx].get_rx_used_buffers().request_pdu(tti_point(tti), len); } else { logger.error("UE buffers: Requesting buffer for zero bytes"); } @@ -215,20 +296,7 @@ void ue::clear_old_buffers(uint32_t tti) // remove old buffers for (auto& cc : cc_buffers) { - auto& rx_buffer_cc = cc.get_rx_used_buffers(); - for (auto it = rx_buffer_cc.begin(); it != rx_buffer_cc.end();) { - if (srslte_tti_interval(tti, it->first) > 20 && srslte_tti_interval(tti, it->first) < 500) { - logger.warning("UE buffers: Removing old buffer tti=%d, rnti=%d, now is %d, interval=%d", - it->first, - rnti, - tti, - srslte_tti_interval(tti, it->first)); - pdus.deallocate(it->second); - it = rx_buffer_cc.erase(it); - } else { - ++it; - } - } + cc.get_rx_used_buffers().clear_old_pdus(tti_point{tti}); } } @@ -264,7 +332,11 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srslte::pdu_queue::channe mac_msg_ul.init_rx(nof_bytes, true); mac_msg_ul.parse_packet(pdu); - logger.info("0x%x %s", rnti, mac_msg_ul.to_string().c_str()); + if (logger.info.enabled()) { + fmt::memory_buffer str_buffer; + mac_msg_ul.to_string(str_buffer); + logger.info("0x%x %s", rnti, srslte::to_c_str(str_buffer)); + } if (pcap) { pcap->write_ul_crnti(pdu, nof_bytes, rnti, true, last_tti, UL_CC_IDX); @@ -359,11 +431,7 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srslte::pdu_queue::channe void ue::deallocate_pdu(uint32_t tti, uint32_t ue_cc_idx) { std::unique_lock lock(rx_buffers_mutex); - - if (cc_buffers.at(ue_cc_idx).get_rx_used_buffers().count(tti)) { - pdus.deallocate(cc_buffers.at(ue_cc_idx).get_rx_used_buffers().at(tti)); - cc_buffers.at(ue_cc_idx).get_rx_used_buffers().erase(tti); - } else { + if (not cc_buffers[ue_cc_idx].get_rx_used_buffers().try_deallocate_pdu(tti_point(tti))) { logger.warning("UE buffers: Null RX PDU pointer in deallocate_pdu for rnti=0x%x pid=%d cc_idx=%d", rnti, tti % nof_rx_harq_proc, @@ -374,18 +442,9 @@ void ue::deallocate_pdu(uint32_t tti, uint32_t ue_cc_idx) void ue::push_pdu(uint32_t tti, uint32_t ue_cc_idx, uint32_t len) { std::unique_lock lock(rx_buffers_mutex); - if (cc_buffers.at(ue_cc_idx).get_rx_used_buffers().count(tti)) { - if (len > 0) { - pdus.push(cc_buffers.at(ue_cc_idx).get_rx_used_buffers().at(tti), len); - } else { - logger.error("Error pushing PDU: null length"); - } - cc_buffers.at(ue_cc_idx).get_rx_used_buffers().erase(tti); - } else { - logger.warning("UE buffers: Null RX PDU pointer in push_pdu for rnti=0x%x pid=%d cc_idx=%d", - rnti, - tti % nof_rx_harq_proc, - ue_cc_idx); + if (not cc_buffers[ue_cc_idx].get_rx_used_buffers().push_pdu(tti_point(tti), len)) { + logger.warning( + "UE buffers: Failed to push RX PDU for rnti=0x%x pid=%d cc_idx=%d", rnti, tti % nof_rx_harq_proc, ue_cc_idx); } } @@ -538,7 +597,11 @@ uint8_t* ue::generate_pdu(uint32_t ue_cc_idx, } } ret = mac_msg_dl.write_packet(logger); - logger.info("0x%x %s", rnti, mac_msg_dl.to_string().c_str()); + if (logger.info.enabled()) { + fmt::memory_buffer str_buffer; + mac_msg_dl.to_string(str_buffer); + logger.info("0x%x %s", rnti, srslte::to_c_str(str_buffer)); + } } else { logger.error( "Invalid parameters calling generate_pdu: cc_idx=%d, harq_pid=%d, tb_idx=%d", ue_cc_idx, harq_pid, tb_idx); diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index 8fc404a7c..c0e368518 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -26,6 +26,7 @@ #include "srslte/asn1/rrc_utils.h" #include "srslte/common/bcd_helpers.h" #include "srslte/common/int_helpers.h" +#include "srslte/common/standard_streams.h" #include "srslte/interfaces/enb_mac_interfaces.h" #include "srslte/interfaces/enb_pdcp_interfaces.h" #include "srslte/interfaces/enb_rlc_interfaces.h" @@ -39,10 +40,11 @@ using namespace asn1::rrc; namespace srsenb { -rrc::rrc(srslte::task_sched_handle task_sched_) : logger(srslog::fetch_basic_logger("RRC")), task_sched(task_sched_) +rrc::rrc(srslte::task_sched_handle task_sched_) : + logger(srslog::fetch_basic_logger("RRC")), task_sched(task_sched_), rx_pdu_queue(64) { pending_paging.clear(); - ue_pool.reserve(16); + rrc::ue::get_ue_pool()->allocate_batch_in_background(); } rrc::~rrc() {} @@ -98,7 +100,7 @@ void rrc::stop() if (running) { running = false; rrc_pdu p = {0, LCID_EXIT, nullptr}; - rx_pdu_queue.push(std::move(p)); + rx_pdu_queue.push_blocking(std::move(p)); } users.clear(); } @@ -136,13 +138,17 @@ uint8_t* rrc::read_pdu_bcch_dlsch(const uint8_t cc_idx, const uint32_t sib_index void rrc::set_activity_user(uint16_t rnti) { rrc_pdu p = {rnti, LCID_ACT_USER, nullptr}; - rx_pdu_queue.push(std::move(p)); + if (not rx_pdu_queue.try_push(std::move(p))) { + logger.error("Failed to push UE activity command to RRC queue"); + } } void rrc::rem_user_thread(uint16_t rnti) { rrc_pdu p = {rnti, LCID_REM_USER, nullptr}; - rx_pdu_queue.push(std::move(p)); + if (not rx_pdu_queue.try_push(std::move(p))) { + logger.error("Failed to push UE remove command to RRC queue"); + } } uint32_t rrc::get_nof_users() @@ -153,7 +159,9 @@ uint32_t rrc::get_nof_users() void rrc::max_retx_attempted(uint16_t rnti) { rrc_pdu p = {rnti, LCID_RTX_USER, nullptr}; - rx_pdu_queue.push(std::move(p)); + if (not rx_pdu_queue.try_push(std::move(p))) { + logger.error("Failed to push max Retx event to RRC queue"); + } } // This function is called from PRACH worker (can wait) @@ -250,7 +258,9 @@ void rrc::send_rrc_connection_reject(uint16_t rnti) void rrc::write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t pdu) { rrc_pdu p = {rnti, lcid, std::move(pdu)}; - rx_pdu_queue.push(std::move(p)); + if (not rx_pdu_queue.try_push(std::move(p))) { + logger.error("Failed to push Release command to RRC queue"); + } } /******************************************************************************* @@ -285,7 +295,9 @@ void rrc::write_dl_info(uint16_t rnti, srslte::unique_byte_buffer_t sdu) void rrc::release_complete(uint16_t rnti) { rrc_pdu p = {rnti, LCID_REL_USER, nullptr}; - rx_pdu_queue.push(std::move(p)); + if (not rx_pdu_queue.try_push(std::move(p))) { + logger.error("Failed to push Release command to RRC queue"); + } } bool rrc::setup_ue_ctxt(uint16_t rnti, const asn1::s1ap::init_context_setup_request_s& msg) @@ -972,7 +984,7 @@ void rrc::tti_clock() { // pop cmds from queue rrc_pdu p; - while (rx_pdu_queue.try_pop(&p)) { + while (rx_pdu_queue.try_pop(p)) { // print Rx PDU if (p.pdu != nullptr) { logger.info(p.pdu->msg, p.pdu->N_bytes, "Rx %s PDU", to_string((rb_id_t)p.lcid)); @@ -1016,7 +1028,4 @@ void rrc::tti_clock() } } -// definition of rrc static member -srslte::big_obj_pool rrc::ue_pool; - } // namespace srsenb diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index f996d6e32..beaa10815 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -29,11 +29,13 @@ #include "srslte/common/common.h" #include "srslte/common/enb_events.h" #include "srslte/common/int_helpers.h" +#include "srslte/common/standard_streams.h" #include "srslte/interfaces/enb_mac_interfaces.h" #include "srslte/interfaces/enb_pdcp_interfaces.h" #include "srslte/interfaces/enb_rlc_interfaces.h" #include "srslte/interfaces/enb_s1ap_interfaces.h" #include "srslte/rrc/rrc_cfg_utils.h" + #include #include #include @@ -73,6 +75,7 @@ uint16_t compute_mac_i(uint16_t crnti, srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo, const uint8_t* k_rrc_int) { + static srslog::basic_logger& logger = srslog::fetch_basic_logger("RRC"); // Compute shortMAC-I uint8_t varShortMAC_packed[16] = {}; uint8_t mac_key[4] = {}; @@ -89,8 +92,7 @@ uint16_t compute_mac_i(uint16_t crnti, } uint32_t N_bytes = bref.distance_bytes(); - srslte::logmap::get("RRC")->info( - "Encoded varShortMAC: cellId=0x%x, PCI=%d, rnti=0x%x (%d bytes)", cellid, pci, crnti, N_bytes); + logger.info("Encoded varShortMAC: cellId=0x%x, PCI=%d, rnti=0x%x (%d bytes)", cellid, pci, crnti, N_bytes); // Compute MAC-I switch (integ_algo) { diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index cf3b3f93b..c29c4700e 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -28,7 +28,7 @@ using namespace asn1::rrc_nr; namespace srsenb { -rrc_nr::rrc_nr(srslte::timer_handler* timers_) : m_log("RRC"), timers(timers_) {} +rrc_nr::rrc_nr(srslte::timer_handler* timers_) : logger(srslog::fetch_basic_logger("RRC")), timers(timers_) {} void rrc_nr::init(const rrc_nr_cfg_t& cfg_, phy_interface_stack_nr* phy_, @@ -49,8 +49,8 @@ void rrc_nr::init(const rrc_nr_cfg_t& cfg_, cfg = update_default_cfg(cfg_); // config logging - m_log->set_level(cfg.log_level); - m_log->set_hex_limit(cfg.log_hex_limit); + logger.set_level(srslog::str_to_basic_level(cfg.log_level)); + logger.set_hex_dump_max_size(cfg.log_hex_limit); // derived slot_dur_ms = 1; @@ -59,7 +59,7 @@ void rrc_nr::init(const rrc_nr_cfg_t& cfg_, config_mac(); // add dummy user - m_log->info("Creating dummy DRB for RNTI=%d on LCID=%d\n", cfg.coreless.rnti, cfg.coreless.drb_lcid); + logger.info("Creating dummy DRB for RNTI=%d on LCID=%d", cfg.coreless.rnti, cfg.coreless.drb_lcid); add_user(cfg.coreless.rnti); srslte::rlc_config_t rlc_cnfg = srslte::rlc_config_t::default_rlc_um_nr_config(6); rlc->add_bearer(cfg.coreless.rnti, cfg.coreless.drb_lcid, rlc_cnfg); @@ -73,7 +73,7 @@ void rrc_nr::init(const rrc_nr_cfg_t& cfg_, false}; pdcp->add_bearer(cfg.coreless.rnti, cfg.coreless.drb_lcid, pdcp_cnfg); - m_log->info("Started\n"); + logger.info("Started"); running = true; } @@ -92,23 +92,23 @@ void rrc_nr::log_rrc_message(const std::string& source, const srslte::byte_buffer_t* pdu, const T& msg) { - if (m_log->get_level() == srslte::LOG_LEVEL_INFO) { - m_log->info("%s - %s %s (%d B)\n", + if (logger.debug.enabled()) { + asn1::json_writer json_writer; + msg.to_json(json_writer); + logger.debug(pdu->msg, + pdu->N_bytes, + "%s - %s %s (%d B)", + source.c_str(), + dir == Tx ? "Tx" : "Rx", + msg.msg.c1().type().to_string().c_str(), + pdu->N_bytes); + logger.debug("Content:\n%s", json_writer.to_string().c_str()); + } else if (logger.info.enabled()) { + logger.info("%s - %s %s (%d B)", source.c_str(), dir == Tx ? "Tx" : "Rx", msg.msg.c1().type().to_string().c_str(), pdu->N_bytes); - } else if (m_log->get_level() >= srslte::LOG_LEVEL_DEBUG) { - asn1::json_writer json_writer; - msg.to_json(json_writer); - m_log->debug_hex(pdu->msg, - pdu->N_bytes, - "%s - %s %s (%d B)\n", - source.c_str(), - dir == Tx ? "Tx" : "Rx", - msg.msg.c1().type().to_string().c_str(), - pdu->N_bytes); - m_log->debug("Content:\n%s\n", json_writer.to_string().c_str()); } } @@ -179,9 +179,9 @@ void rrc_nr::add_user(uint16_t rnti) users.insert(std::make_pair(rnti, std::unique_ptr(new ue(this, rnti)))); rlc->add_user(rnti); pdcp->add_user(rnti); - m_log->info("Added new user rnti=0x%x\n", rnti); + logger.info("Added new user rnti=0x%x", rnti); } else { - m_log->error("Adding user rnti=0x%x (already exists)\n", rnti); + logger.error("Adding user rnti=0x%x (already exists)", rnti); } } @@ -198,7 +198,7 @@ void rrc_nr::config_mac() // PUCCH width sched_cfg.nrb_pucch = SRSLTE_MAX(cfg.sr_cfg.nof_prb, cfg.cqi_cfg.nof_prb); - m_log->info("Allocating %d PRBs for PUCCH\n", sched_cfg.nrb_pucch); + logger.info("Allocating %d PRBs for PUCCH", sched_cfg.nrb_pucch); // Copy Cell configuration sched_cfg.cell = cfg.cell; @@ -218,7 +218,7 @@ uint32_t rrc_nr::generate_sibs() asn1::bit_ref bref(mib_buf->msg, mib_buf->get_tailroom()); mib_msg.pack(bref); mib_buf->N_bytes = bref.distance_bytes(); - m_log->debug_hex(mib_buf->msg, mib_buf->N_bytes, "MIB payload (%d B)\n", mib_buf->N_bytes); + logger.debug(mib_buf->msg, mib_buf->N_bytes, "MIB payload (%d B)", mib_buf->N_bytes); mib_buffer = std::move(mib_buf); } @@ -278,12 +278,12 @@ int rrc_nr::read_pdu_bcch_bch(const uint32_t tti, srslte::unique_byte_buffer_t& int rrc_nr::read_pdu_bcch_dlsch(uint32_t sib_index, srslte::unique_byte_buffer_t& buffer) { if (sib_index >= sib_buffer.size()) { - m_log->error("SIB %d is not a configured SIB.\n", sib_index); + logger.error("SIB %d is not a configured SIB.", sib_index); return SRSLTE_ERROR; } if (buffer->get_tailroom() < sib_buffer[sib_index]->N_bytes) { - m_log->error("Not enough space to fit SIB %d into buffer (%d < %d)\n", + logger.error("Not enough space to fit SIB %d into buffer (%d < %d)", sib_index, buffer->get_tailroom(), sib_buffer[sib_index]->N_bytes); @@ -304,7 +304,7 @@ void rrc_nr::get_metrics(srsenb::rrc_metrics_t& m) void rrc_nr::handle_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t pdu) { if (pdu) { - m_log->info_hex(pdu->msg, pdu->N_bytes, "Rx %s PDU", srslte::to_string(static_cast(lcid))); + logger.info(pdu->msg, pdu->N_bytes, "Rx %s PDU", srslte::to_string(static_cast(lcid))); } if (users.count(rnti) == 1) { @@ -317,11 +317,11 @@ void rrc_nr::handle_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer // parse_ul_dcch(p.rnti, p.lcid, std::move(p.pdu)); break; default: - m_log->error("Rx PDU with invalid bearer id: %d", lcid); + logger.error("Rx PDU with invalid bearer id: %d", lcid); break; } } else { - m_log->warning("Discarding PDU for removed rnti=0x%x\n", rnti); + logger.warning("Discarding PDU for removed rnti=0x%x", rnti); } } @@ -378,11 +378,11 @@ void rrc_nr::ue::send_dl_ccch(dl_ccch_msg_s* dl_ccch_msg) // Allocate a new PDU buffer, pack the message and send to PDCP srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer(); if (pdu == nullptr) { - parent->m_log->error("Allocating pdu\n"); + parent->logger.error("Allocating pdu"); } asn1::bit_ref bref(pdu->msg, pdu->get_tailroom()); if (dl_ccch_msg->pack(bref) == asn1::SRSASN_ERROR_ENCODE_FAIL) { - parent->m_log->error("Failed to pack DL-CCCH message. Discarding msg.\n"); + parent->logger.error("Failed to pack DL-CCCH message. Discarding msg."); } pdu->N_bytes = bref.distance_bytes(); diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 84f013060..5663823ef 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -27,6 +27,7 @@ #include "srslte/asn1/rrc_utils.h" #include "srslte/common/enb_events.h" #include "srslte/common/int_helpers.h" +#include "srslte/common/standard_streams.h" #include "srslte/interfaces/enb_pdcp_interfaces.h" #include "srslte/interfaces/enb_rlc_interfaces.h" #include "srslte/interfaces/enb_s1ap_interfaces.h" @@ -71,18 +72,21 @@ int rrc::ue::init() return SRSLTE_SUCCESS; } +srslte::background_allocator_obj_pool* rrc::ue::get_ue_pool() +{ + // Note: batch allocation is going to be explicitly called in enb class construction. The pool object, therefore, + // will only be initialized if we instantiate an eNB + static rrc::ue::ue_pool_t ue_pool(true); + return &ue_pool; +} + void* rrc::ue::operator new(size_t sz) { - assert(sz == sizeof(ue)); - void* memchunk = rrc::ue_pool.allocate_node(sz); - if (ue_pool.capacity() <= 4) { - srslte::get_background_workers().push_task([]() { rrc::ue_pool.reserve(4); }); - } - return memchunk; + return rrc::ue::get_ue_pool()->allocate_node(sz); } void rrc::ue::operator delete(void* ptr)noexcept { - rrc::ue_pool.deallocate_node(ptr); + rrc::ue::get_ue_pool()->deallocate_node(ptr); } rrc_state_t rrc::ue::get_state() @@ -1094,9 +1098,11 @@ bool rrc::ue::send_dl_dcch(const dl_dcch_msg_s* dl_dcch_msg, srslte::unique_byte } pdu->N_bytes = (uint32_t)bref.distance_bytes(); - // send on SRB2 if user is fully registered (after RRC reconfig complete) - uint32_t lcid = - parent->rlc->has_bearer(rnti, RB_ID_SRB2) && state == RRC_STATE_REGISTERED ? RB_ID_SRB2 : RB_ID_SRB1; + uint32_t lcid = RB_ID_SRB1; + if (dl_dcch_msg->msg.c1().type() == dl_dcch_msg_type_c::c1_c_::types_opts::dl_info_transfer) { + // send messages with NAS on SRB2 if user is fully registered (after RRC reconfig complete) + lcid = parent->rlc->has_bearer(rnti, RB_ID_SRB2) && state == RRC_STATE_REGISTERED ? RB_ID_SRB2 : RB_ID_SRB1; + } char buf[32] = {}; sprintf(buf, "SRB%d - rnti=0x%x", lcid, rnti); diff --git a/srsenb/src/stack/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index 47c7c24b3..5cdc90386 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -21,8 +21,11 @@ #include "srslte/upper/gtpu.h" #include "srsenb/hdr/stack/upper/gtpu.h" #include "srslte/common/network_utils.h" +#include "srslte/common/standard_streams.h" +#include "srslte/common/string_helpers.h" #include "srslte/interfaces/enb_interfaces.h" #include "srslte/interfaces/enb_pdcp_interfaces.h" + #include #include #include @@ -162,12 +165,14 @@ uint32_t gtpu::add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t ue_teidin_db[rnti][lcid].push_back(teid_in); + fmt::memory_buffer str_buffer; + srslte::gtpu_ntoa(str_buffer, htonl(addr)); logger.info("New tunnel teid_in=0x%x, teid_out=0x%x, rnti=0x%x, lcid=%d, addr=%s", teid_in, teid_out, rnti, lcid, - srslte::gtpu_ntoa(htonl(addr)).c_str()); + srslte::to_c_str(str_buffer)); if (props != nullptr) { if (props->flush_before_teidin_present) { @@ -526,23 +531,29 @@ srslte::span gtpu::get_lcid_teids(uint16_t rnti, uint32_t lcid) void gtpu::log_message(tunnel& tun, bool is_rx, srslte::span pdu, int pdcp_sn) { - fmt::basic_memory_buffer strbuf; - struct iphdr* ip_pkt = (struct iphdr*)pdu.data(); + struct iphdr* ip_pkt = (struct iphdr*)pdu.data(); if (ip_pkt->version != 4 && ip_pkt->version != 6) { logger.error("%s SDU with invalid IP version %s SPGW", is_rx ? "Received" : "Sending", is_rx ? "from" : "to"); return; } + if (not logger.info.enabled()) { + return; + } - const char* dir = "Tx"; - fmt::memory_buffer strbuf2; + fmt::basic_memory_buffer strbuf; + const char* dir = "Tx"; + fmt::memory_buffer strbuf2, addrbuf; + srslte::gtpu_ntoa(addrbuf, htonl(tun.spgw_addr)); if (is_rx) { dir = "Rx"; - fmt::format_to(strbuf2, "{}:0x{:0x} > ", srslte::gtpu_ntoa(htonl(tun.spgw_addr)), tun.teid_in); + fmt::format_to(strbuf2, "{}:0x{:0x} > ", srslte::to_c_str(addrbuf), tun.teid_in); if (not tun.dl_enabled) { fmt::format_to(strbuf2, "DL (buffered), "); } else if (tun.fwd_teid_in_present) { tunnel& tx_tun = tunnels.at(tun.fwd_teid_in); - fmt::format_to(strbuf2, "{}:0x{:0x} (forwarded), ", srslte::gtpu_ntoa(htonl(tx_tun.spgw_addr)), tx_tun.teid_in); + addrbuf.clear(); + srslte::gtpu_ntoa(addrbuf, htonl(tx_tun.spgw_addr)); + fmt::format_to(strbuf2, "{}:0x{:0x} (forwarded), ", srslte::to_c_str(addrbuf), tx_tun.teid_in); } else { fmt::format_to(strbuf2, "DL, "); } @@ -552,7 +563,7 @@ void gtpu::log_message(tunnel& tun, bool is_rx, srslte::span pdu, int p } else { fmt::format_to(strbuf2, "UL "); } - fmt::format_to(strbuf2, "> {}:0x{:0x}, ", srslte::gtpu_ntoa(htonl(tun.spgw_addr)), tun.teid_in); + fmt::format_to(strbuf2, "> {}:0x{:0x}, ", srslte::to_c_str(addrbuf), tun.teid_in); } fmt::format_to(strbuf, "{} S1-U SDU, {}rnti=0x{:0x}, lcid={}, n_bytes={}, IPv{}", @@ -563,12 +574,16 @@ void gtpu::log_message(tunnel& tun, bool is_rx, srslte::span pdu, int p pdu.size(), (int)ip_pkt->version); if (ip_pkt->version == 4) { - fmt::format_to(strbuf, " {} > {}", srslte::gtpu_ntoa(ip_pkt->saddr), srslte::gtpu_ntoa(ip_pkt->daddr)); + addrbuf.clear(); + strbuf2.clear(); + srslte::gtpu_ntoa(addrbuf, ip_pkt->saddr); + srslte::gtpu_ntoa(strbuf2, ip_pkt->daddr); + fmt::format_to(strbuf, " {} > {}", srslte::to_c_str(addrbuf), srslte::to_c_str(strbuf2)); if (ntohs(ip_pkt->tot_len) != pdu.size()) { logger.error("IP Len and PDU N_bytes mismatch"); } } - logger.info(pdu.data(), pdu.size(), fmt::to_string(strbuf)); + logger.info(pdu.data(), pdu.size(), "%s", srslte::to_c_str(strbuf)); } /**************************************************************************** diff --git a/srsenb/src/stack/upper/pdcp.cc b/srsenb/src/stack/upper/pdcp.cc index 026ef5d9e..3116f6c18 100644 --- a/srsenb/src/stack/upper/pdcp.cc +++ b/srsenb/src/stack/upper/pdcp.cc @@ -152,14 +152,14 @@ void pdcp::send_status_report(uint16_t rnti) users[rnti].pdcp->send_status_report(); } -void pdcp::notify_delivery(uint16_t rnti, uint32_t lcid, const std::vector& pdcp_sns) +void pdcp::notify_delivery(uint16_t rnti, uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sns) { if (users.count(rnti)) { users[rnti].pdcp->notify_delivery(lcid, pdcp_sns); } } -void pdcp::notify_failure(uint16_t rnti, uint32_t lcid, const std::vector& pdcp_sns) +void pdcp::notify_failure(uint16_t rnti, uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sns) { if (users.count(rnti)) { users[rnti].pdcp->notify_failure(lcid, pdcp_sns); diff --git a/srsenb/src/stack/upper/pdcp_nr.cc b/srsenb/src/stack/upper/pdcp_nr.cc index 2d373f7fb..19bec02c9 100644 --- a/srsenb/src/stack/upper/pdcp_nr.cc +++ b/srsenb/src/stack/upper/pdcp_nr.cc @@ -24,7 +24,8 @@ namespace srsenb { -pdcp_nr::pdcp_nr(srslte::task_sched_handle task_sched_, const char* logname) : task_sched(task_sched_), m_log(logname) +pdcp_nr::pdcp_nr(srslte::task_sched_handle task_sched_, const char* logname) : + task_sched(task_sched_), logger(srslog::fetch_basic_logger(logname)) {} void pdcp_nr::init(const pdcp_nr_args_t& args_, @@ -37,8 +38,8 @@ void pdcp_nr::init(const pdcp_nr_args_t& args_, m_rrc = rrc_; m_sdap = sdap_; - m_log->set_level(m_args.log_level); - m_log->set_hex_limit(m_args.log_hex_limit); + logger.set_level(srslog::str_to_basic_level(m_args.log_level)); + logger.set_hex_dump_max_size(m_args.log_hex_limit); } void pdcp_nr::stop() @@ -104,25 +105,25 @@ void pdcp_nr::write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer if (users.count(rnti)) { users[rnti].pdcp->write_pdu(lcid, std::move(sdu)); } else { - m_log->error("Can't write PDU. RNTI=0x%X doesn't exist.\n", rnti); + logger.error("Can't write PDU. RNTI=0x%X doesn't exist.", rnti); } } -void pdcp_nr::notify_delivery(uint16_t rnti, uint32_t lcid, const std::vector& pdcp_sns) +void pdcp_nr::notify_delivery(uint16_t rnti, uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sns) { if (users.count(rnti)) { users[rnti].pdcp->notify_delivery(lcid, pdcp_sns); } else { - m_log->error("Can't notify Ack of PDU. RNTI=0x%X doesn't exist.\n", rnti); + logger.error("Can't notify Ack of PDU. RNTI=0x%X doesn't exist.", rnti); } } -void pdcp_nr::notify_failure(uint16_t rnti, uint32_t lcid, const std::vector& pdcp_sns) +void pdcp_nr::notify_failure(uint16_t rnti, uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sns) { if (users.count(rnti)) { users[rnti].pdcp->notify_failure(lcid, pdcp_sns); } else { - m_log->error("Can't notify Ack of PDU. RNTI=0x%X doesn't exist.\n", rnti); + logger.error("Can't notify Ack of PDU. RNTI=0x%X doesn't exist.", rnti); } } @@ -131,7 +132,7 @@ void pdcp_nr::write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer if (users.count(rnti)) { users[rnti].pdcp->write_sdu(lcid, std::move(sdu)); } else { - m_log->error("Can't write SDU. RNTI=0x%X doesn't exist.\n", rnti); + logger.error("Can't write SDU. RNTI=0x%X doesn't exist.", rnti); } } diff --git a/srsenb/src/stack/upper/rlc.cc b/srsenb/src/stack/upper/rlc.cc index 28be263fc..348232c86 100644 --- a/srsenb/src/stack/upper/rlc.cc +++ b/srsenb/src/stack/upper/rlc.cc @@ -278,12 +278,12 @@ void rlc::user_interface::write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t } } -void rlc::user_interface::notify_delivery(uint32_t lcid, const std::vector& pdcp_sns) +void rlc::user_interface::notify_delivery(uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sns) { pdcp->notify_delivery(rnti, lcid, pdcp_sns); } -void rlc::user_interface::notify_failure(uint32_t lcid, const std::vector& pdcp_sns) +void rlc::user_interface::notify_failure(uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sns) { pdcp->notify_failure(rnti, lcid, pdcp_sns); } diff --git a/srsenb/src/stack/upper/rlc_nr.cc b/srsenb/src/stack/upper/rlc_nr.cc index fd4ca0e38..841e9c040 100644 --- a/srsenb/src/stack/upper/rlc_nr.cc +++ b/srsenb/src/stack/upper/rlc_nr.cc @@ -24,7 +24,7 @@ namespace srsenb { -rlc_nr::rlc_nr(const char* logname) : m_log(logname) {} +rlc_nr::rlc_nr(const char* logname) : logger(srslog::fetch_basic_logger(logname)) {} void rlc_nr::init(pdcp_interface_rlc_nr* pdcp_, rrc_interface_rlc_nr* rrc_, @@ -53,7 +53,7 @@ void rlc_nr::add_user(uint16_t rnti) user_itf.m_pdcp = m_pdcp; user_itf.m_rrc = m_rrc; user_itf.parent = this; - user_itf.m_rlc.reset(new srslte::rlc(m_log->get_service_name().c_str())); + user_itf.m_rlc.reset(new srslte::rlc(logger.id().c_str())); users[rnti] = std::move(user_itf); users[rnti].m_rlc->init(&users[rnti], &users[rnti], timers, (int)srslte::rb_id_nr_t::NR_SRB0); } @@ -65,7 +65,7 @@ void rlc_nr::rem_user(uint16_t rnti) users[rnti].m_rlc->stop(); users.erase(rnti); } else { - m_log->error("Removing rnti=0x%x. Already removed\n", rnti); + logger.error("Removing rnti=0x%x. Already removed", rnti); } } @@ -76,7 +76,7 @@ void rlc_nr::clear_buffer(uint16_t rnti) for (int i = 0; i < SRSLTE_N_RADIO_BEARERS; i++) { m_mac->rlc_buffer_state(rnti, i, 0, 0); } - m_log->info("Cleared buffer rnti=0x%x\n", rnti); + logger.info("Cleared buffer rnti=0x%x", rnti); } } @@ -116,7 +116,7 @@ int rlc_nr::read_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t no // communicate buffer state every time a PDU is read uint32_t retx_queue = 0; - m_log->debug("Buffer state PDCP: rnti=0x%x, lcid=%d, tx_queue=%d\n", rnti, lcid, tx_queue); + logger.debug("Buffer state PDCP: rnti=0x%x, lcid=%d, tx_queue=%d", rnti, lcid, tx_queue); m_mac->rlc_buffer_state(rnti, lcid, tx_queue, retx_queue); } else { ret = SRSLTE_ERROR; @@ -133,7 +133,7 @@ void rlc_nr::write_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t // communicate buffer state every time a new PDU is written uint32_t tx_queue = users[rnti].m_rlc->get_buffer_state(lcid); uint32_t retx_queue = 0; - m_log->debug("Buffer state PDCP: rnti=0x%x, lcid=%d, tx_queue=%d\n", rnti, lcid, tx_queue); + logger.debug("Buffer state PDCP: rnti=0x%x, lcid=%d, tx_queue=%d", rnti, lcid, tx_queue); m_mac->rlc_buffer_state(rnti, lcid, tx_queue, retx_queue); } } @@ -161,7 +161,7 @@ void rlc_nr::write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_ uint32_t retx_queue = 0; m_mac->rlc_buffer_state(rnti, lcid, tx_queue, retx_queue); - m_log->info("Buffer state: rnti=0x%x, lcid=%d, tx_queue=%d\n", rnti, lcid, tx_queue); + logger.info("Buffer state: rnti=0x%x, lcid=%d, tx_queue=%d", rnti, lcid, tx_queue); } } @@ -216,12 +216,12 @@ std::string rlc_nr::user_interface::get_rb_name(uint32_t lcid) return srslte::to_string(static_cast(lcid)); } -void rlc_nr::user_interface::notify_delivery(uint32_t lcid, const std::vector& pdcp_sns) +void rlc_nr::user_interface::notify_delivery(uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sns) { m_pdcp->notify_delivery(rnti, lcid, pdcp_sns); } -void rlc_nr::user_interface::notify_failure(uint32_t lcid, const std::vector& pdcp_sns) +void rlc_nr::user_interface::notify_failure(uint32_t lcid, const srslte::pdcp_sn_vector_t& pdcp_sns) { m_pdcp->notify_failure(rnti, lcid, pdcp_sns); } diff --git a/srsenb/src/stack/upper/s1ap.cc b/srsenb/src/stack/upper/s1ap.cc index 35e77e057..4b5466db9 100644 --- a/srsenb/src/stack/upper/s1ap.cc +++ b/srsenb/src/stack/upper/s1ap.cc @@ -25,7 +25,7 @@ #include "srslte/common/bcd_helpers.h" #include "srslte/common/enb_events.h" #include "srslte/common/int_helpers.h" -#include "srslte/common/logmap.h" +#include "srslte/common/standard_streams.h" #include "srslte/interfaces/enb_rrc_interfaces.h" #include //for inet_ntop() @@ -1533,17 +1533,18 @@ s1ap::ue* s1ap::user_list::find_ue_mmeid(uint32_t mmeid) */ s1ap::ue* s1ap::user_list::add_user(std::unique_ptr user) { + static srslog::basic_logger& logger = srslog::fetch_basic_logger("S1AP"); // Check for ID repetitions if (find_ue_rnti(user->ctxt.rnti) != nullptr) { - srslte::logmap::get("S1AP")->error("The user to be added with rnti=0x%x already exists", user->ctxt.rnti); + logger.error("The user to be added with rnti=0x%x already exists", user->ctxt.rnti); return nullptr; } if (find_ue_enbid(user->ctxt.enb_ue_s1ap_id) != nullptr) { - srslte::logmap::get("S1AP")->error("The user to be added with enb id=%d already exists", user->ctxt.enb_ue_s1ap_id); + logger.error("The user to be added with enb id=%d already exists", user->ctxt.enb_ue_s1ap_id); return nullptr; } if (find_ue_mmeid(user->ctxt.mme_ue_s1ap_id) != nullptr) { - srslte::logmap::get("S1AP")->error("The user to be added with mme id=%d already exists", user->ctxt.mme_ue_s1ap_id); + logger.error("The user to be added with mme id=%d already exists", user->ctxt.mme_ue_s1ap_id); return nullptr; } auto p = users.insert(std::make_pair(user->ctxt.enb_ue_s1ap_id, std::move(user))); @@ -1552,9 +1553,10 @@ s1ap::ue* s1ap::user_list::add_user(std::unique_ptr user) void s1ap::user_list::erase(ue* ue_ptr) { - auto it = users.find(ue_ptr->ctxt.enb_ue_s1ap_id); + static srslog::basic_logger& logger = srslog::fetch_basic_logger("S1AP"); + auto it = users.find(ue_ptr->ctxt.enb_ue_s1ap_id); if (it == users.end()) { - srslte::logmap::get("S1AP")->error("User to be erased does not exist"); + logger.error("User to be erased does not exist"); return; } users.erase(it); diff --git a/srsenb/test/mac/sched_ca_test.cc b/srsenb/test/mac/sched_ca_test.cc index 2e0cf77cc..237026295 100644 --- a/srsenb/test/mac/sched_ca_test.cc +++ b/srsenb/test/mac/sched_ca_test.cc @@ -86,7 +86,7 @@ struct test_scell_activation_params { uint32_t pcell_idx = 0; }; -int test_scell_activation(test_scell_activation_params params) +int test_scell_activation(uint32_t sim_number, test_scell_activation_params params) { std::array prb_list{6, 15, 25, 50, 75, 100}; @@ -237,7 +237,8 @@ int test_scell_activation(test_scell_activation_params params) TESTASSERT(tot_dl_sched_data > 0); TESTASSERT(tot_ul_sched_data > 0); - srslog::fetch_basic_logger("TEST").info("[TESTER] Sim1 finished successfully"); + srslog::flush(); + printf("[TESTER] Sim%d finished successfully\n\n", sim_number); return SRSLTE_SUCCESS; } @@ -259,28 +260,27 @@ int main() } auto& mac_log = srslog::fetch_basic_logger("MAC"); - mac_log.set_level(srslog::basic_levels::info); + mac_log.set_level(srslog::basic_levels::debug); auto& test_log = srslog::fetch_basic_logger("TEST", *spy, false); - test_log.set_level(srslog::basic_levels::info); + test_log.set_level(srslog::basic_levels::debug); // Start the log backend. srslog::init(); sched_diagnostic_printer printer(*spy); - srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_INFO); printf("[TESTER] This is the chosen seed: %u\n", seed); uint32_t N_runs = 20; for (uint32_t n = 0; n < N_runs; ++n) { - printf("Sim run number: %u\n", n + 1); + printf("[TESTER] Sim run number: %u\n", n); test_scell_activation_params p = {}; p.pcell_idx = 0; - TESTASSERT(test_scell_activation(p) == SRSLTE_SUCCESS); + TESTASSERT(test_scell_activation(n * 2, p) == SRSLTE_SUCCESS); p = {}; p.pcell_idx = 1; - TESTASSERT(test_scell_activation(p) == SRSLTE_SUCCESS); + TESTASSERT(test_scell_activation(n * 2 + 1, p) == SRSLTE_SUCCESS); } srslog::flush(); diff --git a/srsenb/test/mac/sched_common_test_suite.cc b/srsenb/test/mac/sched_common_test_suite.cc index 57bb0f4ce..46614a0a6 100644 --- a/srsenb/test/mac/sched_common_test_suite.cc +++ b/srsenb/test/mac/sched_common_test_suite.cc @@ -35,13 +35,13 @@ int test_pusch_collisions(const sf_output_res_t& sf_out, uint32_t enb_cc_idx, co prbmask_t ul_allocs(nof_prb); auto try_ul_fill = [&](prb_interval alloc, const char* ch_str, bool strict = true) { - CONDERROR(alloc.stop() > nof_prb, "Allocated RBs %s out-of-bounds", alloc.to_string().c_str()); + CONDERROR(alloc.stop() > nof_prb, "Allocated RBs %s out-of-bounds", fmt::format("{}", alloc).c_str()); CONDERROR(alloc.empty(), "Allocations must have at least one PRB"); if (strict and ul_allocs.any(alloc.start(), alloc.stop())) { TESTERROR("Collision Detected of %s alloc=%s and cumulative_mask=0x%s", ch_str, - alloc.to_string().c_str(), - ul_allocs.to_hex().c_str()); + fmt::format("{}", alloc).c_str(), + fmt::format("{:x}", ul_allocs).c_str()); } ul_allocs.fill(alloc.start(), alloc.stop(), true); return SRSLTE_SUCCESS; @@ -73,8 +73,8 @@ int test_pusch_collisions(const sf_output_res_t& sf_out, uint32_t enb_cc_idx, co CONDERROR(expected_ul_mask != nullptr and *expected_ul_mask != ul_allocs, "The derived UL PRB mask %s does not match the expected one %s", - ul_allocs.to_string().c_str(), - expected_ul_mask->to_string().c_str()); + fmt::format("{}", ul_allocs).c_str(), + fmt::format("{}", *expected_ul_mask).c_str()); return SRSLTE_SUCCESS; } @@ -114,8 +114,8 @@ int test_pdsch_collisions(const sf_output_res_t& sf_out, uint32_t enb_cc_idx, co if ((dl_allocs & alloc_mask).any()) { TESTERROR("Detected collision in the DL %s allocation (%s intersects %s)", channel, - dl_allocs.to_string().c_str(), - alloc_mask.to_string().c_str()); + fmt::format("{}", dl_allocs).c_str(), + fmt::format("{}", alloc_mask).c_str()); } dl_allocs |= alloc_mask; return SRSLTE_SUCCESS; @@ -159,8 +159,8 @@ int test_pdsch_collisions(const sf_output_res_t& sf_out, uint32_t enb_cc_idx, co CONDERROR(expected_rbgmask != nullptr and *expected_rbgmask != rbgmask, "The derived DL RBG mask %s does not match the expected one %s", - rbgmask.to_string().c_str(), - expected_rbgmask->to_string().c_str()); + fmt::format("{}", rbgmask).c_str(), + fmt::format("{}", *expected_rbgmask).c_str()); return SRSLTE_SUCCESS; } @@ -255,8 +255,8 @@ int test_pdcch_collisions(const sf_output_res_t& sf_out, CONDERROR(expected_cce_mask != nullptr and *expected_cce_mask != used_cce, "The derived PDCCH mask %s does not match the expected one %s", - used_cce.to_string().c_str(), - expected_cce_mask->to_string().c_str()); + fmt::format("{}", used_cce).c_str(), + fmt::format("{}", *expected_cce_mask).c_str()); return SRSLTE_SUCCESS; } diff --git a/srsenb/test/mac/sched_test_rand.cc b/srsenb/test/mac/sched_test_rand.cc index 0374eda00..62a8cf5ec 100644 --- a/srsenb/test/mac/sched_test_rand.cc +++ b/srsenb/test/mac/sched_test_rand.cc @@ -28,7 +28,6 @@ #include #include -#include "srslte/common/log_filter.h" #include "srslte/interfaces/sched_interface.h" #include "srslte/phy/utils/debug.h" @@ -39,7 +38,7 @@ using srslte::tti_point; -uint32_t const seed = std::chrono::system_clock::now().time_since_epoch().count(); +uint32_t seed = std::chrono::system_clock::now().time_since_epoch().count(); struct ue_stats_t { uint32_t nof_dl_rbs = 0; @@ -160,8 +159,8 @@ int sched_tester::process_results() // UE dedicated tests TESTASSERT(run_ue_ded_tests_and_update_ctxt(sf_out) == SRSLTE_SUCCESS); - test_harqs(); - update_ue_stats(); + TESTASSERT(test_harqs() == SRSLTE_SUCCESS); + TESTASSERT(update_ue_stats() == SRSLTE_SUCCESS); return SRSLTE_SUCCESS; } @@ -244,7 +243,7 @@ int sched_tester::update_ue_stats() return SRSLTE_SUCCESS; } -void test_scheduler_rand(sched_sim_events sim) +int test_scheduler_rand(sched_sim_events sim) { // Create classes sched_tester tester; @@ -252,7 +251,8 @@ void test_scheduler_rand(sched_sim_events sim) tester.sim_cfg(std::move(sim.sim_args)); - tester.test_next_ttis(sim.tti_events); + TESTASSERT(tester.test_next_ttis(sim.tti_events) == SRSLTE_SUCCESS); + return SRSLTE_SUCCESS; } template @@ -294,6 +294,9 @@ sched_sim_events rand_sim_params(uint32_t nof_ttis) sim_gen.sim_args.default_ue_sim_cfg.ue_cfg.measgap_period = pick_random_uniform({0, 40, 80}); sim_gen.sim_args.default_ue_sim_cfg.ue_cfg.measgap_offset = std::uniform_int_distribution{ 0, sim_gen.sim_args.default_ue_sim_cfg.ue_cfg.measgap_period}(srsenb::get_rand_gen()); + sim_gen.sim_args.default_ue_sim_cfg.ue_cfg.pucch_cfg.n_pucch_sr = + std::uniform_int_distribution{0, 2047}(srsenb::get_rand_gen()); + sim_gen.sim_args.start_tti = 0; sim_gen.sim_args.sched_args.pdsch_mcs = boolean_dist() ? -1 : std::uniform_int_distribution<>{0, 24}(srsenb::get_rand_gen()); @@ -361,7 +364,7 @@ int main() for (uint32_t n = 0; n < N_runs; ++n) { printf("Sim run number: %u\n", n + 1); sched_sim_events sim = rand_sim_params(nof_ttis); - test_scheduler_rand(std::move(sim)); + TESTASSERT(test_scheduler_rand(std::move(sim)) == SRSLTE_SUCCESS); } return 0; diff --git a/srsenb/test/mac/sched_test_utils.h b/srsenb/test/mac/sched_test_utils.h index 0d5f306dc..fc4de650c 100644 --- a/srsenb/test/mac/sched_test_utils.h +++ b/srsenb/test/mac/sched_test_utils.h @@ -82,6 +82,10 @@ inline srsenb::sched_interface::ue_cfg_t generate_default_ue_cfg() ue_cfg.ue_bearers[srsenb::RB_ID_DRB1].direction = srsenb::sched_interface::ue_bearer_cfg_t::BOTH; ue_cfg.ue_bearers[srsenb::RB_ID_DRB1].group = 1; + ue_cfg.pucch_cfg.sr_configured = true; + ue_cfg.pucch_cfg.I_sr = 15; // periodicity of 20 msec + ue_cfg.pucch_cfg.n_pucch_sr = 0; + return ue_cfg; } @@ -126,11 +130,7 @@ inline srsenb::sched_interface::ue_cfg_t generate_setup_ue_cfg(const srsenb::sch inline srsenb::sched_interface::ue_cfg_t generate_reconf_ue_cfg(const srsenb::sched_interface::ue_cfg_t& final_cfg) { srsenb::sched_interface::ue_cfg_t cfg = generate_setup_ue_cfg(final_cfg); - - cfg.supported_cc_list.resize(1); - cfg.ue_bearers = {}; - cfg.ue_bearers[srsenb::RB_ID_SRB0] = final_cfg.ue_bearers[srsenb::RB_ID_SRB0]; - cfg.ue_bearers[srsenb::RB_ID_SRB1] = final_cfg.ue_bearers[srsenb::RB_ID_SRB1]; + cfg.ue_bearers[srsenb::RB_ID_SRB2] = final_cfg.ue_bearers[srsenb::RB_ID_SRB1]; return cfg; } diff --git a/srsenb/test/mac/sched_ue_ded_test_suite.cc b/srsenb/test/mac/sched_ue_ded_test_suite.cc index 3cbf70e56..cd8fdbc52 100644 --- a/srsenb/test/mac/sched_ue_ded_test_suite.cc +++ b/srsenb/test/mac/sched_ue_ded_test_suite.cc @@ -22,6 +22,7 @@ #include "sched_ue_ded_test_suite.h" #include "lib/include/srslte/mac/pdu.h" #include "srsenb/hdr/stack/mac/sched_helpers.h" +#include "srsenb/hdr/stack/mac/sched_phy_ch/sf_cch_allocator.h" #include "srslte/common/test_common.h" namespace srsenb { @@ -74,6 +75,7 @@ int test_pdsch_grant(const sim_enb_ctxt_t& enb_ctxt, const sim_ue_ctxt_t& ue_ctxt = *enb_ctxt.ue_db.at(pdsch.dci.rnti); const sched_interface::ue_cfg_t::cc_cfg_t* cc_cfg = ue_ctxt.get_cc_cfg(enb_cc_idx); const sched_interface::cell_cfg_t& cell_params = (*enb_ctxt.cell_params)[enb_cc_idx]; + bool has_pusch_grant = find_pusch_grant(pdsch.dci.rnti, sf_out.ul_cc_result[enb_cc_idx]) != nullptr; // TEST: Check if CC is configured and active CONDERROR(cc_cfg == nullptr or not cc_cfg->active, "PDSCH allocation for disabled or unavailable cc"); @@ -116,6 +118,12 @@ int test_pdsch_grant(const sim_enb_ctxt_t& enb_ctxt, CONDERROR(coderate > 0.930f * Qm, "Max coderate was exceeded"); } + // TEST: PUCCH-ACK will not collide with SR + CONDERROR(not has_pusch_grant and is_pucch_sr_collision(ue_ctxt.ue_cfg.pucch_cfg, + to_tx_dl_ack(sf_out.tti_rx), + pdsch.dci.location.ncce + cell_params.n1pucch_an), + "Collision detected between UE PUCCH-ACK and SR"); + return SRSLTE_SUCCESS; } @@ -200,11 +208,14 @@ int test_ul_sched_result(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& CONDERROR(nof_retx != 0, "Invalid rv index for new tx"); CONDERROR(pusch_ptr->current_tx_nb != 0, "UL HARQ retxs need to have been previously transmitted"); CONDERROR(not h_inactive, "New tx for already active UL HARQ"); + CONDERROR(not pusch_ptr->needs_pdcch and ue.msg3_tti_rx.is_valid() and sf_out.tti_rx > ue.msg3_tti_rx, + "In case of newtx, PDCCH allocation is required, unless it is Msg3"); } else { CONDERROR(pusch_ptr->current_tx_nb == 0, "UL retx has to have nof tx > 0"); if (not h.active) { - // the HARQ is being resumed - CONDERROR(not pusch_ptr->needs_pdcch, "Resumed UL HARQs need to be signalled in PDCCH"); + // the HARQ is being resumed. PDCCH must be active with the exception of Msg3 + CONDERROR(ue.msg4_tti_rx.is_valid() and not pusch_ptr->needs_pdcch, + "Resumed UL HARQs need to be signalled in PDCCH"); } else { if (pusch_ptr->needs_pdcch) { CONDERROR(pusch_ptr->dci.type2_alloc.riv == h.riv, "Adaptive retx must change riv"); diff --git a/srsenb/test/phy/enb_phy_test.cc b/srsenb/test/phy/enb_phy_test.cc index c227d74d1..34e60a045 100644 --- a/srsenb/test/phy/enb_phy_test.cc +++ b/srsenb/test/phy/enb_phy_test.cc @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/srsenb/test/upper/rrc_meascfg_test.cc b/srsenb/test/upper/rrc_meascfg_test.cc index cd4c6453c..476608b58 100644 --- a/srsenb/test/upper/rrc_meascfg_test.cc +++ b/srsenb/test/upper/rrc_meascfg_test.cc @@ -335,7 +335,6 @@ int test_minimize_meascfg_reordering() int main(int argc, char** argv) { - srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_INFO); auto& logger = srslog::fetch_basic_logger("RRC", false); logger.set_level(srslog::basic_levels::info); srslog::init(); diff --git a/srsenb/test/upper/test_helpers.cc b/srsenb/test/upper/test_helpers.cc index da3a7982f..54707867f 100644 --- a/srsenb/test/upper/test_helpers.cc +++ b/srsenb/test/upper/test_helpers.cc @@ -25,8 +25,8 @@ namespace argparse { -std::string repository_dir; -srslte::LOG_LEVEL_ENUM log_level; +std::string repository_dir; +srslog::basic_levels log_level; } // namespace argparse diff --git a/srsenb/test/upper/test_helpers.h b/srsenb/test/upper/test_helpers.h index 7d88e6f69..52333cd17 100644 --- a/srsenb/test/upper/test_helpers.h +++ b/srsenb/test/upper/test_helpers.h @@ -25,15 +25,14 @@ #include "srsenb/src/enb_cfg_parser.h" #include "srsenb/test/common/dummy_classes.h" #include "srslte/adt/span.h" -#include "srslte/common/log_filter.h" using namespace srsenb; using namespace asn1::rrc; namespace argparse { -extern std::string repository_dir; -extern srslte::LOG_LEVEL_ENUM log_level; +extern std::string repository_dir; +extern srslog::basic_levels log_level; inline void usage(char* prog) { @@ -51,7 +50,7 @@ inline void parse_args(int argc, char** argv) repository_dir = argv[optind]; break; case 'v': - log_level = srslte::LOG_LEVEL_DEBUG; + log_level = srslog::basic_levels::debug; break; default: usage(argv[0]); diff --git a/srsepc/hdr/hss/hss.h b/srsepc/hdr/hss/hss.h index 222d6410a..86a3f8de0 100644 --- a/srsepc/hdr/hss/hss.h +++ b/srsepc/hdr/hss/hss.h @@ -29,8 +29,7 @@ #define SRSEPC_HSS_H #include "srslte/common/buffer_pool.h" -#include "srslte/common/log.h" -#include "srslte/common/log_filter.h" +#include "srslte/common/standard_streams.h" #include "srslte/interfaces/epc_interfaces.h" #include "srslte/srslog/srslog.h" #include diff --git a/srsepc/hdr/mbms-gw/mbms-gw.h b/srsepc/hdr/mbms-gw/mbms-gw.h index 596ab84fb..a5aa12a25 100644 --- a/srsepc/hdr/mbms-gw/mbms-gw.h +++ b/srsepc/hdr/mbms-gw/mbms-gw.h @@ -30,8 +30,6 @@ #include "srslte/asn1/gtpc.h" #include "srslte/common/buffer_pool.h" -#include "srslte/common/log_filter.h" -#include "srslte/common/logmap.h" #include "srslte/common/threads.h" #include "srslte/srslog/srslog.h" #include "srslte/srslte.h" diff --git a/srsepc/hdr/mme/mme.h b/srsepc/hdr/mme/mme.h index 11a0f6de1..04ddcb5d7 100644 --- a/srsepc/hdr/mme/mme.h +++ b/srsepc/hdr/mme/mme.h @@ -30,8 +30,7 @@ #include "s1ap.h" #include "srslte/common/buffer_pool.h" -#include "srslte/common/log.h" -#include "srslte/common/log_filter.h" +#include "srslte/common/standard_streams.h" #include "srslte/common/threads.h" #include diff --git a/srsepc/hdr/mme/mme_gtpc.h b/srsepc/hdr/mme/mme_gtpc.h index a5261743d..4c5ecf480 100644 --- a/srsepc/hdr/mme/mme_gtpc.h +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -24,8 +24,6 @@ #include "nas.h" #include "srslte/asn1/gtpc.h" #include "srslte/common/buffer_pool.h" -#include "srslte/common/log.h" -#include "srslte/common/log_filter.h" #include #include diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index 5e1435b82..fcf3cacf4 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -33,8 +33,8 @@ #include "srslte/asn1/liblte_mme.h" #include "srslte/asn1/s1ap.h" #include "srslte/common/common.h" -#include "srslte/common/log.h" #include "srslte/common/s1ap_pcap.h" +#include "srslte/common/standard_streams.h" #include "srslte/interfaces/epc_interfaces.h" #include "srslte/srslog/srslog.h" #include diff --git a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h index 0ec144074..267b83228 100644 --- a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h @@ -26,7 +26,6 @@ #include "srslte/asn1/s1ap.h" #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/log_filter.h" namespace srsepc { diff --git a/srsepc/hdr/mme/s1ap_erab_mngmt_proc.h b/srsepc/hdr/mme/s1ap_erab_mngmt_proc.h index e74a85b4c..9b4c0c82c 100644 --- a/srsepc/hdr/mme/s1ap_erab_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_erab_mngmt_proc.h @@ -26,7 +26,6 @@ #include "srslte/asn1/s1ap.h" #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/log_filter.h" #include namespace srsepc { diff --git a/srsepc/hdr/mme/s1ap_mngmt_proc.h b/srsepc/hdr/mme/s1ap_mngmt_proc.h index f68338b4b..bd1ddb0e6 100644 --- a/srsepc/hdr/mme/s1ap_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_mngmt_proc.h @@ -24,7 +24,6 @@ #include "s1ap_common.h" #include "srslte/asn1/s1ap.h" #include "srslte/common/common.h" -#include "srslte/common/log_filter.h" #include "srslte/srslog/srslog.h" namespace srsepc { diff --git a/srsepc/hdr/mme/s1ap_paging.h b/srsepc/hdr/mme/s1ap_paging.h index f6a2e8dd2..5fb73f32a 100644 --- a/srsepc/hdr/mme/s1ap_paging.h +++ b/srsepc/hdr/mme/s1ap_paging.h @@ -24,7 +24,6 @@ #include "s1ap_common.h" #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/log_filter.h" #include "srslte/srslog/srslog.h" namespace srsepc { diff --git a/srsepc/hdr/spgw/gtpc.h b/srsepc/hdr/spgw/gtpc.h index a95356356..c3f248493 100644 --- a/srsepc/hdr/spgw/gtpc.h +++ b/srsepc/hdr/spgw/gtpc.h @@ -23,8 +23,10 @@ #include "srsepc/hdr/spgw/spgw.h" #include "srslte/asn1/gtpc.h" +#include "srslte/common/standard_streams.h" #include "srslte/interfaces/epc_interfaces.h" #include "srslte/srslog/srslog.h" + #include #include #include diff --git a/srsepc/hdr/spgw/gtpu.h b/srsepc/hdr/spgw/gtpu.h index 127039cf9..c693fbac7 100644 --- a/srsepc/hdr/spgw/gtpu.h +++ b/srsepc/hdr/spgw/gtpu.h @@ -25,7 +25,7 @@ #include "srsepc/hdr/spgw/spgw.h" #include "srslte/asn1/gtpc.h" #include "srslte/common/buffer_pool.h" -#include "srslte/common/logmap.h" +#include "srslte/common/standard_streams.h" #include "srslte/interfaces/epc_interfaces.h" #include "srslte/srslog/srslog.h" #include diff --git a/srsepc/hdr/spgw/spgw.h b/srsepc/hdr/spgw/spgw.h index e6e10d67f..3b84d561a 100644 --- a/srsepc/hdr/spgw/spgw.h +++ b/srsepc/hdr/spgw/spgw.h @@ -30,8 +30,6 @@ #include "srslte/asn1/gtpc.h" #include "srslte/common/buffer_pool.h" -#include "srslte/common/log_filter.h" -#include "srslte/common/logmap.h" #include "srslte/common/threads.h" #include "srslte/srslog/srslog.h" #include diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index e06c4d94c..9407e03c8 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -27,13 +27,11 @@ #include "srslte/common/common_helper.h" #include "srslte/common/config_file.h" #include "srslte/common/crash_handler.h" -#include "srslte/common/logger_srslog_wrapper.h" #include "srslte/common/signal_handler.h" #include "srslte/srslog/srslog.h" #include "srslte/srslte.h" #include #include -#include using namespace std; using namespace srsepc; @@ -338,24 +336,6 @@ void parse_args(all_args_t* args, int argc, char* argv[]) return; } -srslte::LOG_LEVEL_ENUM level(std::string l) -{ - std::transform(l.begin(), l.end(), l.begin(), ::toupper); - if ("NONE" == l) { - return srslte::LOG_LEVEL_NONE; - } else if ("ERROR" == l) { - return srslte::LOG_LEVEL_ERROR; - } else if ("WARNING" == l) { - return srslte::LOG_LEVEL_WARNING; - } else if ("INFO" == l) { - return srslte::LOG_LEVEL_INFO; - } else if ("DEBUG" == l) { - return srslte::LOG_LEVEL_DEBUG; - } else { - return srslte::LOG_LEVEL_NONE; - } -} - std::string get_build_mode() { return std::string(srslte_get_build_mode()); @@ -399,7 +379,6 @@ int main(int argc, char* argv[]) if (!chan) { return SRSLTE_ERROR; } - srslte::srslog_wrapper log_wrapper(*chan); srslog::set_default_sink(*log_sink); // Start the log backend. @@ -410,60 +389,32 @@ int main(int argc, char* argv[]) epc_logger.info("\n\n%s\n--- Software Radio Systems EPC log ---\n\n", get_build_string().c_str()); } - srslte::logmap::set_default_logger(&log_wrapper); srslte::log_args(argc, argv, "EPC"); - srslte::log_filter nas_log; - nas_log.init("NAS ", &log_wrapper); - nas_log.set_level(level(args.log_args.nas_level)); - nas_log.set_hex_limit(args.log_args.nas_hex_limit); - auto& nas_logger = srslog::fetch_basic_logger("NAS", false); + srslog::basic_logger& nas_logger = srslog::fetch_basic_logger("NAS", false); nas_logger.set_level(srslog::str_to_basic_level(args.log_args.nas_level)); nas_logger.set_hex_dump_max_size(args.log_args.nas_hex_limit); - srslte::log_filter s1ap_log; - s1ap_log.init("S1AP", &log_wrapper); - s1ap_log.set_level(level(args.log_args.s1ap_level)); - s1ap_log.set_hex_limit(args.log_args.s1ap_hex_limit); auto& s1ap_logger = srslog::fetch_basic_logger("S1AP", false); s1ap_logger.set_level(srslog::str_to_basic_level(args.log_args.s1ap_level)); s1ap_logger.set_hex_dump_max_size(args.log_args.s1ap_hex_limit); - srslte::log_filter mme_gtpc_log; - mme_gtpc_log.init("MME GTPC", &log_wrapper); - mme_gtpc_log.set_level(level(args.log_args.mme_gtpc_level)); - mme_gtpc_log.set_hex_limit(args.log_args.mme_gtpc_hex_limit); auto& mme_gtpc_logger = srslog::fetch_basic_logger("MME GTPC", false); mme_gtpc_logger.set_level(srslog::str_to_basic_level(args.log_args.mme_gtpc_level)); mme_gtpc_logger.set_hex_dump_max_size(args.log_args.mme_gtpc_hex_limit); - srslte::log_filter hss_log; - hss_log.init("HSS ", &log_wrapper); - hss_log.set_level(level(args.log_args.hss_level)); - hss_log.set_hex_limit(args.log_args.hss_hex_limit); auto& hss_logger = srslog::fetch_basic_logger("HSS", false); hss_logger.set_level(srslog::str_to_basic_level(args.log_args.hss_level)); hss_logger.set_hex_dump_max_size(args.log_args.hss_hex_limit); - srslte::log_filter spgw_gtpc_log; - spgw_gtpc_log.init("SPGW GTPC", &log_wrapper); - spgw_gtpc_log.set_level(level(args.log_args.spgw_gtpc_level)); - spgw_gtpc_log.set_hex_limit(args.log_args.spgw_gtpc_hex_limit); auto& spgw_gtpc_logger = srslog::fetch_basic_logger("SPGW GTPC", false); spgw_gtpc_logger.set_level(srslog::str_to_basic_level(args.log_args.spgw_gtpc_level)); spgw_gtpc_logger.set_hex_dump_max_size(args.log_args.spgw_gtpc_hex_limit); - srslte::log_ref gtpu_log{"GTPU"}; - gtpu_log->set_level(level(args.log_args.mme_gtpc_level)); - gtpu_log->set_hex_limit(args.log_args.mme_gtpc_hex_limit); auto& gtpu_logger = srslog::fetch_basic_logger("GTPU", false); gtpu_logger.set_level(srslog::str_to_basic_level(args.log_args.gtpu_level)); gtpu_logger.set_hex_dump_max_size(args.log_args.gtpu_hex_limit); - srslte::log_filter spgw_log; - spgw_log.init("SPGW", &log_wrapper); - spgw_log.set_level(level(args.log_args.spgw_level)); - spgw_log.set_hex_limit(args.log_args.spgw_hex_limit); auto& spgw_logger = srslog::fetch_basic_logger("SPGW", false); spgw_logger.set_level(srslog::str_to_basic_level(args.log_args.spgw_level)); spgw_logger.set_hex_dump_max_size(args.log_args.spgw_hex_limit); diff --git a/srsepc/src/mbms-gw/main.cc b/srsepc/src/mbms-gw/main.cc index ed60e07d4..6a28bae69 100644 --- a/srsepc/src/mbms-gw/main.cc +++ b/srsepc/src/mbms-gw/main.cc @@ -21,7 +21,6 @@ #include "srsepc/hdr/mbms-gw/mbms-gw.h" #include "srslte/common/config_file.h" -#include "srslte/common/logger_srslog_wrapper.h" #include "srslte/srslog/srslog.h" #include #include @@ -51,24 +50,6 @@ typedef struct { log_args_t log_args; } all_args_t; -srslte::LOG_LEVEL_ENUM level(std::string l) -{ - std::transform(l.begin(), l.end(), l.begin(), ::toupper); - if ("NONE" == l) { - return srslte::LOG_LEVEL_NONE; - } else if ("ERROR" == l) { - return srslte::LOG_LEVEL_ERROR; - } else if ("WARNING" == l) { - return srslte::LOG_LEVEL_WARNING; - } else if ("INFO" == l) { - return srslte::LOG_LEVEL_INFO; - } else if ("DEBUG" == l) { - return srslte::LOG_LEVEL_DEBUG; - } else { - return srslte::LOG_LEVEL_NONE; - } -} - /********************************************************************** * Program arguments processing ***********************************************************************/ @@ -203,7 +184,6 @@ int main(int argc, char* argv[]) if (!chan) { return SRSLTE_ERROR; } - srslte::srslog_wrapper log_wrapper(*chan); srslog::set_default_sink(*log_sink); // Start the log backend. @@ -214,11 +194,6 @@ int main(int argc, char* argv[]) mbms_gw_logger.info("\n--- Software Radio Systems MBMS log ---\n\n"); } - srslte::logmap::set_default_logger(&log_wrapper); - - srslte::log_ref mbms_gw_log{"MBMS"}; - mbms_gw_log->set_level(level(args.log_args.mbms_gw_level)); - mbms_gw_log->set_hex_limit(args.log_args.mbms_gw_hex_limit); auto& mbms_gw_logger = srslog::fetch_basic_logger("MBMS", false); mbms_gw_logger.set_level(srslog::str_to_basic_level(args.log_args.mbms_gw_level)); mbms_gw_logger.set_hex_dump_max_size(args.log_args.mbms_gw_hex_limit); diff --git a/srsepc/src/mbms-gw/mbms-gw.cc b/srsepc/src/mbms-gw/mbms-gw.cc index 7a15c80be..329a88f1f 100644 --- a/srsepc/src/mbms-gw/mbms-gw.cc +++ b/srsepc/src/mbms-gw/mbms-gw.cc @@ -20,6 +20,7 @@ */ #include "srsepc/hdr/mbms-gw/mbms-gw.h" +#include "srslte/common/standard_streams.h" #include "srslte/upper/gtpu.h" #include #include diff --git a/srsepc/src/spgw/gtpu.cc b/srsepc/src/spgw/gtpu.cc index defe8c5e1..fb37bea70 100644 --- a/srsepc/src/spgw/gtpu.cc +++ b/srsepc/src/spgw/gtpu.cc @@ -21,6 +21,7 @@ #include "srsepc/hdr/spgw/gtpu.h" #include "srsepc/hdr/mme/mme_gtpc.h" +#include "srslte/common/string_helpers.h" #include "srslte/upper/gtpu.h" #include #include @@ -215,8 +216,12 @@ void spgw::gtpu::handle_sgi_pdu(srslte::unique_byte_buffer_t msg) // Logging PDU info m_logger.debug("SGi PDU -- IP version %d, Total length %d", int(iph->version), ntohs(iph->tot_len)); - m_logger.debug("SGi PDU -- IP src addr %s", srslte::gtpu_ntoa(iph->saddr).c_str()); - m_logger.debug("SGi PDU -- IP dst addr %s", srslte::gtpu_ntoa(iph->daddr).c_str()); + fmt::memory_buffer buffer; + srslte::gtpu_ntoa(buffer, iph->saddr); + m_logger.debug("SGi PDU -- IP src addr %s", srslte::to_c_str(buffer)); + buffer.clear(); + srslte::gtpu_ntoa(buffer, iph->daddr); + m_logger.debug("SGi PDU -- IP dst addr %s", srslte::to_c_str(buffer)); // Find user and control tunnel gtpu_fteid_it = m_ip_to_usr_teid.find(iph->daddr); @@ -318,8 +323,12 @@ void spgw::gtpu::send_all_queued_packets(srslte::gtp_fteid_t bool spgw::gtpu::modify_gtpu_tunnel(in_addr_t ue_ipv4, srslte::gtpc_f_teid_ie dw_user_fteid, uint32_t up_ctrl_teid) { m_logger.info("Modifying GTP-U Tunnel."); - m_logger.info("UE IP %s", srslte::gtpu_ntoa(ue_ipv4).c_str()); - m_logger.info("Downlink eNB addr %s, U-TEID 0x%x", srslte::gtpu_ntoa(dw_user_fteid.ipv4).c_str(), dw_user_fteid.teid); + fmt::memory_buffer buffer; + srslte::gtpu_ntoa(buffer, ue_ipv4); + m_logger.info("UE IP %s", srslte::to_c_str(buffer)); + buffer.clear(); + srslte::gtpu_ntoa(buffer, dw_user_fteid.ipv4); + m_logger.info("Downlink eNB addr %s, U-TEID 0x%x", srslte::to_c_str(buffer), dw_user_fteid.teid); m_logger.info("Uplink C-TEID: 0x%x", up_ctrl_teid); m_ip_to_usr_teid[ue_ipv4] = dw_user_fteid; m_ip_to_ctr_teid[ue_ipv4] = up_ctrl_teid; diff --git a/srsue/hdr/phy/nr/cc_worker.h b/srsue/hdr/phy/nr/cc_worker.h index 10e997291..3b6ed7d60 100644 --- a/srsue/hdr/phy/nr/cc_worker.h +++ b/srsue/hdr/phy/nr/cc_worker.h @@ -22,7 +22,6 @@ #ifndef SRSLTE_NR_CC_WORKER_H #define SRSLTE_NR_CC_WORKER_H -#include "srslte/common/log.h" #include "srsue/hdr/phy/phy_common.h" #include "state.h" diff --git a/srsue/hdr/phy/nr/state.h b/srsue/hdr/phy/nr/state.h index c5185e446..35e0ad57c 100644 --- a/srsue/hdr/phy/nr/state.h +++ b/srsue/hdr/phy/nr/state.h @@ -82,9 +82,9 @@ public: carrier.max_mimo_layers = 1; // Hard-coded values, this should be set when the measurements take place - csi_measurements[0].K_csi_rs = 1; + csi_measurements[0].K_csi_rs = 1; csi_measurements[0].nof_ports = 1; - csi_measurements[1].K_csi_rs = 4; + csi_measurements[1].K_csi_rs = 4; csi_measurements[0].nof_ports = 1; } @@ -303,10 +303,10 @@ public: } // Configure SR fields in UCI data - uci_data.cfg.sr_resource_id = sr_resource_id[0]; - uci_data.cfg.o_sr = srslte_ra_ul_nr_nof_sr_bits(sr_count_all); - uci_data.cfg.sr_positive_present = sr_count_positive > 0; - uci_data.value.sr = sr_count_positive; + uci_data.cfg.pucch.sr_resource_id = sr_resource_id[0]; + uci_data.cfg.o_sr = srslte_ra_ul_nr_nof_sr_bits(sr_count_all); + uci_data.cfg.pucch.sr_positive_present = sr_count_positive > 0; + uci_data.value.sr = sr_count_positive; } void get_periodic_csi(const uint32_t& tti, srslte_uci_data_nr_t& uci_data) @@ -316,7 +316,7 @@ public: uci_data.cfg.nof_csi = n; } - uci_data.cfg.rnti = stack->get_ul_sched_rnti_nr(tti).id; + uci_data.cfg.pucch.rnti = stack->get_ul_sched_rnti_nr(tti).id; } }; } // namespace nr diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index ba7ecd6fc..2416b93e9 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -25,7 +25,6 @@ #include "phy_common.h" #include "phy_metrics.h" #include "srslte/common/block_queue.h" -#include "srslte/common/log_filter.h" #include "srslte/common/threads.h" #include "srslte/common/trace.h" #include "srslte/interfaces/phy_interface_types.h" diff --git a/srsue/hdr/phy/phy_common.h b/srsue/hdr/phy/phy_common.h index 62c3fe553..b037d720f 100644 --- a/srsue/hdr/phy/phy_common.h +++ b/srsue/hdr/phy/phy_common.h @@ -25,7 +25,6 @@ #include "phy_metrics.h" #include "srslte/adt/circular_array.h" #include "srslte/common/gen_mch_tables.h" -#include "srslte/common/log.h" #include "srslte/common/tti_sempahore.h" #include "srslte/interfaces/phy_interface_types.h" #include "srslte/interfaces/radio_interfaces.h" diff --git a/srsue/hdr/phy/prach.h b/srsue/hdr/phy/prach.h index ba97544cb..d328e32b3 100644 --- a/srsue/hdr/phy/prach.h +++ b/srsue/hdr/phy/prach.h @@ -22,7 +22,6 @@ #ifndef SRSUE_PRACH_H #define SRSUE_PRACH_H -#include "srslte/common/log.h" #include "srslte/interfaces/ue_phy_interfaces.h" #include "srslte/radio/radio.h" #include "srslte/srslog/srslog.h" diff --git a/srsue/hdr/phy/scell/intra_measure.h b/srsue/hdr/phy/scell/intra_measure.h index 2da5af70c..68b272f0b 100644 --- a/srsue/hdr/phy/scell/intra_measure.h +++ b/srsue/hdr/phy/scell/intra_measure.h @@ -21,7 +21,6 @@ #ifndef SRSUE_INTRA_MEASURE_H #define SRSUE_INTRA_MEASURE_H -#include #include #include #include diff --git a/srsue/hdr/phy/sync.h b/srsue/hdr/phy/sync.h index cf1f7e053..e3e578c60 100644 --- a/srsue/hdr/phy/sync.h +++ b/srsue/hdr/phy/sync.h @@ -33,7 +33,6 @@ #include "scell/scell_sync.h" #include "search.h" #include "sfn_sync.h" -#include "srslte/common/log.h" #include "srslte/common/thread_pool.h" #include "srslte/common/threads.h" #include "srslte/common/tti_sync_cv.h" diff --git a/srsue/hdr/phy/ue_lte_phy_base.h b/srsue/hdr/phy/ue_lte_phy_base.h index f037f85e6..0872d2747 100644 --- a/srsue/hdr/phy/ue_lte_phy_base.h +++ b/srsue/hdr/phy/ue_lte_phy_base.h @@ -27,7 +27,6 @@ #ifndef SRSUE_UE_LTE_PHY_BASE_H #define SRSUE_UE_LTE_PHY_BASE_H -#include "srslte/common/log_filter.h" #include "srslte/interfaces/radio_interfaces.h" #include "srsue/hdr/phy/ue_phy_base.h" diff --git a/srsue/hdr/phy/ue_nr_phy_base.h b/srsue/hdr/phy/ue_nr_phy_base.h index ba998e01e..9c6da4f40 100644 --- a/srsue/hdr/phy/ue_nr_phy_base.h +++ b/srsue/hdr/phy/ue_nr_phy_base.h @@ -27,7 +27,6 @@ #ifndef SRSUE_UE_NR_PHY_BASE_H #define SRSUE_UE_NR_PHY_BASE_H -#include "srslte/common/log_filter.h" #include "srslte/interfaces/radio_interfaces.h" #include "srslte/interfaces/ue_nr_interfaces.h" #include "srsue/hdr/phy/ue_phy_base.h" diff --git a/srsue/hdr/phy/ue_phy_base.h b/srsue/hdr/phy/ue_phy_base.h index 7397fe2e4..3bdd14ac5 100644 --- a/srsue/hdr/phy/ue_phy_base.h +++ b/srsue/hdr/phy/ue_phy_base.h @@ -27,7 +27,6 @@ #ifndef SRSUE_UE_PHY_BASE_H #define SRSUE_UE_PHY_BASE_H -#include "srslte/common/logger.h" #include "srslte/interfaces/ue_phy_interfaces.h" #include "srsue/hdr/phy/phy_metrics.h" diff --git a/srsue/hdr/phy/vnf_phy_nr.h b/srsue/hdr/phy/vnf_phy_nr.h index 4beab26b6..c7fc61636 100644 --- a/srsue/hdr/phy/vnf_phy_nr.h +++ b/srsue/hdr/phy/vnf_phy_nr.h @@ -24,8 +24,6 @@ #include "srsenb/hdr/phy/phy_common.h" #include "srslte/common/basic_vnf.h" -#include "srslte/common/log.h" -#include "srslte/common/log_filter.h" #include "srslte/interfaces/enb_metrics_interface.h" #include "srslte/interfaces/radio_interfaces.h" #include "srslte/interfaces/ue_interfaces.h" diff --git a/srsue/hdr/stack/mac/demux.h b/srsue/hdr/stack/mac/demux.h index 1bdc1c25a..74d49825d 100644 --- a/srsue/hdr/stack/mac/demux.h +++ b/srsue/hdr/stack/mac/demux.h @@ -22,7 +22,6 @@ #ifndef SRSUE_DEMUX_H #define SRSUE_DEMUX_H -#include "srslte/common/log.h" #include "srslte/common/timers.h" #include "srslte/interfaces/ue_mac_interfaces.h" #include "srslte/interfaces/ue_rlc_interfaces.h" diff --git a/srsue/hdr/stack/mac/dl_harq.h b/srsue/hdr/stack/mac/dl_harq.h index e23870476..87a1b3492 100644 --- a/srsue/hdr/stack/mac/dl_harq.h +++ b/srsue/hdr/stack/mac/dl_harq.h @@ -24,7 +24,6 @@ #include "demux.h" #include "dl_sps.h" -#include "srslte/common/log.h" #include "srslte/common/mac_pcap.h" #include "srslte/common/timers.h" diff --git a/srsue/hdr/stack/mac/dl_sps.h b/srsue/hdr/stack/mac/dl_sps.h index 45e2f8f65..78f3eda46 100644 --- a/srsue/hdr/stack/mac/dl_sps.h +++ b/srsue/hdr/stack/mac/dl_sps.h @@ -22,7 +22,6 @@ #ifndef SRSUE_DL_SPS_H #define SRSUE_DL_SPS_H -#include "srslte/common/log.h" #include "srslte/common/timers.h" /* Downlink Semi-Persistent schedulign (Section 5.10.1) */ diff --git a/srsue/hdr/stack/mac/mac.h b/srsue/hdr/stack/mac/mac.h index a47ceb498..2cdc909b9 100644 --- a/srsue/hdr/stack/mac/mac.h +++ b/srsue/hdr/stack/mac/mac.h @@ -30,7 +30,6 @@ #include "proc_phr.h" #include "proc_ra.h" #include "proc_sr.h" -#include "srslte/common/logmap.h" #include "srslte/common/mac_pcap.h" #include "srslte/common/threads.h" #include "srslte/common/timers.h" diff --git a/srsue/hdr/stack/mac/mux.h b/srsue/hdr/stack/mac/mux.h index e30e5b9ab..f959471fb 100644 --- a/srsue/hdr/stack/mac/mux.h +++ b/srsue/hdr/stack/mac/mux.h @@ -29,7 +29,6 @@ #include "proc_bsr.h" #include "proc_phr.h" #include "srslte/common/common.h" -#include "srslte/common/log.h" #include "srslte/interfaces/mac_interface_types.h" #include "srslte/mac/pdu.h" #include "srslte/srslog/srslog.h" diff --git a/srsue/hdr/stack/mac/proc_bsr.h b/srsue/hdr/stack/mac/proc_bsr.h index 4f5076e6c..9f2f0055f 100644 --- a/srsue/hdr/stack/mac/proc_bsr.h +++ b/srsue/hdr/stack/mac/proc_bsr.h @@ -26,7 +26,6 @@ #include #include "proc_sr.h" -#include "srslte/common/logmap.h" #include "srslte/common/task_scheduler.h" #include "srslte/srslog/srslog.h" diff --git a/srsue/hdr/stack/mac/proc_phr.h b/srsue/hdr/stack/mac/proc_phr.h index fae65e989..8cce71d75 100644 --- a/srsue/hdr/stack/mac/proc_phr.h +++ b/srsue/hdr/stack/mac/proc_phr.h @@ -22,7 +22,6 @@ #ifndef SRSUE_PROC_PHR_H #define SRSUE_PROC_PHR_H -#include "srslte/common/logmap.h" #include "srslte/common/task_scheduler.h" #include "srslte/interfaces/ue_mac_interfaces.h" #include "srslte/srslog/srslog.h" diff --git a/srsue/hdr/stack/mac/proc_ra.h b/srsue/hdr/stack/mac/proc_ra.h index 5360dc032..bb03e1aa7 100644 --- a/srsue/hdr/stack/mac/proc_ra.h +++ b/srsue/hdr/stack/mac/proc_ra.h @@ -28,7 +28,6 @@ #include "demux.h" #include "mux.h" -#include "srslte/common/log.h" #include "srslte/common/mac_pcap.h" #include "srslte/common/timers.h" #include "srslte/mac/pdu.h" diff --git a/srsue/hdr/stack/mac/proc_sr.h b/srsue/hdr/stack/mac/proc_sr.h index 77c424f08..48556e7f5 100644 --- a/srsue/hdr/stack/mac/proc_sr.h +++ b/srsue/hdr/stack/mac/proc_sr.h @@ -22,7 +22,6 @@ #ifndef SRSUE_PROC_SR_H #define SRSUE_PROC_SR_H -#include "srslte/common/logmap.h" #include "srslte/interfaces/ue_mac_interfaces.h" #include "srslte/srslog/srslog.h" #include diff --git a/srsue/hdr/stack/mac/ul_harq.h b/srsue/hdr/stack/mac/ul_harq.h index 274e5b010..a752c390b 100644 --- a/srsue/hdr/stack/mac/ul_harq.h +++ b/srsue/hdr/stack/mac/ul_harq.h @@ -25,7 +25,6 @@ #include "mux.h" #include "proc_ra.h" #include "srslte/common/interfaces_common.h" -#include "srslte/common/log.h" #include "srslte/common/mac_pcap.h" #include "srslte/common/timers.h" #include "ul_sps.h" diff --git a/srsue/hdr/stack/mac/ul_sps.h b/srsue/hdr/stack/mac/ul_sps.h index 17945c845..00cf35915 100644 --- a/srsue/hdr/stack/mac/ul_sps.h +++ b/srsue/hdr/stack/mac/ul_sps.h @@ -22,7 +22,6 @@ #ifndef SRSUE_UL_SPS_H #define SRSUE_UL_SPS_H -#include "srslte/common/log.h" #include "srslte/common/timers.h" /* Uplink Semi-Persistent schedulign (Section 5.10.2) */ diff --git a/srsue/hdr/stack/rrc/phy_controller.h b/srsue/hdr/stack/rrc/phy_controller.h index cc9c5f1ca..a553dc36d 100644 --- a/srsue/hdr/stack/rrc/phy_controller.h +++ b/srsue/hdr/stack/rrc/phy_controller.h @@ -24,7 +24,6 @@ #include "srslte/adt/observer.h" #include "srslte/common/fsm.h" -#include "srslte/common/logmap.h" #include "srslte/common/task_scheduler.h" #include "srslte/interfaces/ue_phy_interfaces.h" #include "srslte/interfaces/ue_rrc_interfaces.h" diff --git a/srsue/hdr/stack/rrc/rrc.h b/srsue/hdr/stack/rrc/rrc.h index c0cf70439..6c5a371e6 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -30,7 +30,6 @@ #include "srslte/common/block_queue.h" #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/logmap.h" #include "srslte/common/security.h" #include "srslte/common/stack_procedure.h" #include "srslte/interfaces/ue_interfaces.h" diff --git a/srsue/hdr/stack/rrc/rrc_meas.h b/srsue/hdr/stack/rrc/rrc_meas.h index 191dd7044..5634b3fa5 100644 --- a/srsue/hdr/stack/rrc/rrc_meas.h +++ b/srsue/hdr/stack/rrc/rrc_meas.h @@ -24,7 +24,6 @@ #include "srslte/asn1/rrc.h" #include "srslte/asn1/rrc_utils.h" #include "srslte/common/common.h" -#include "srslte/common/log.h" #include "srslte/interfaces/ue_interfaces.h" #include "srsue/hdr/stack/rrc/rrc.h" diff --git a/srsue/hdr/stack/rrc/rrc_nr.h b/srsue/hdr/stack/rrc/rrc_nr.h index 7cb253e4e..04244566b 100644 --- a/srsue/hdr/stack/rrc/rrc_nr.h +++ b/srsue/hdr/stack/rrc/rrc_nr.h @@ -26,7 +26,6 @@ #include "srslte/asn1/rrc_nr_utils.h" #include "srslte/common/block_queue.h" #include "srslte/common/buffer_pool.h" -#include "srslte/common/logmap.h" #include "srslte/common/stack_procedure.h" #include "srslte/common/task_scheduler.h" #include "srslte/interfaces/nr_common_interface_types.h" @@ -142,6 +141,7 @@ private: uint16_t lcid; }; + srslog::basic_logger& logger; bool running = false; srslte::block_queue cmd_q; @@ -154,8 +154,6 @@ private: usim_interface_rrc_nr* usim = nullptr; stack_interface_rrc* stack = nullptr; - srslte::log_ref log_h; - uint32_t fake_measurement_carrier_freq_r15; srslte::timer_handler::unique_timer fake_measurement_timer; diff --git a/srsue/hdr/stack/rrc/rrc_procedures.h b/srsue/hdr/stack/rrc/rrc_procedures.h index 4afd37416..8c6dc30fc 100644 --- a/srsue/hdr/stack/rrc/rrc_procedures.h +++ b/srsue/hdr/stack/rrc/rrc_procedures.h @@ -20,7 +20,6 @@ */ #include "phy_controller.h" -#include "srslte/common/log.h" #include "srslte/interfaces/ue_nas_interfaces.h" #include "srslte/srslog/srslog.h" #include "srsue/hdr/stack/rrc/rrc.h" diff --git a/srsue/hdr/stack/ue_stack_base.h b/srsue/hdr/stack/ue_stack_base.h index 9a42f8100..dc966071f 100644 --- a/srsue/hdr/stack/ue_stack_base.h +++ b/srsue/hdr/stack/ue_stack_base.h @@ -22,7 +22,6 @@ #ifndef SRSUE_UE_STACK_BASE_H #define SRSUE_UE_STACK_BASE_H -#include "srslte/common/logger.h" #include "srsue/hdr/stack/upper/nas_config.h" #include "srsue/hdr/ue_metrics_interface.h" diff --git a/srsue/hdr/stack/ue_stack_lte.h b/srsue/hdr/stack/ue_stack_lte.h index 00dc3e408..bc779ee5b 100644 --- a/srsue/hdr/stack/ue_stack_lte.h +++ b/srsue/hdr/stack/ue_stack_lte.h @@ -41,7 +41,6 @@ #include "upper/usim.h" #include "srslte/common/buffer_pool.h" -#include "srslte/common/log_filter.h" #include "srslte/common/multiqueue.h" #include "srslte/common/string_helpers.h" #include "srslte/common/task_scheduler.h" diff --git a/srsue/hdr/stack/ue_stack_nr.h b/srsue/hdr/stack/ue_stack_nr.h index fd2c4f025..2e53f9a52 100644 --- a/srsue/hdr/stack/ue_stack_nr.h +++ b/srsue/hdr/stack/ue_stack_nr.h @@ -36,7 +36,6 @@ #include "upper/usim.h" #include "srslte/common/buffer_pool.h" -#include "srslte/common/log_filter.h" #include "srslte/common/mac_pcap.h" #include "srslte/common/multiqueue.h" #include "srslte/common/thread_pool.h" @@ -59,7 +58,7 @@ class ue_stack_nr final : public ue_stack_base, public srslte::thread { public: - ue_stack_nr(srslte::logger* logger_); + ue_stack_nr(); ~ue_stack_nr(); std::string get_type() final; @@ -120,9 +119,9 @@ private: srslte::task_multiqueue::queue_handle sync_task_queue, ue_task_queue, gw_task_queue; // UE stack logging - srslte::logger* logger = nullptr; - srslte::log_ref rlc_log; - srslte::log_ref pdcp_log; + srslog::basic_logger& mac_logger; + srslog::basic_logger& rlc_logger; + srslog::basic_logger& pdcp_logger; // stack components std::unique_ptr mac; diff --git a/srsue/hdr/stack/upper/gw.h b/srsue/hdr/stack/upper/gw.h index 47edc8547..721bf536f 100644 --- a/srsue/hdr/stack/upper/gw.h +++ b/srsue/hdr/stack/upper/gw.h @@ -26,8 +26,6 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" #include "srslte/common/interfaces_common.h" -#include "srslte/common/log.h" -#include "srslte/common/log_filter.h" #include "srslte/common/threads.h" #include "srslte/interfaces/ue_gw_interfaces.h" #include "srslte/srslog/srslog.h" diff --git a/srsue/hdr/stack/upper/nas.h b/srsue/hdr/stack/upper/nas.h index fd235ae1e..a6c9b6712 100644 --- a/srsue/hdr/stack/upper/nas.h +++ b/srsue/hdr/stack/upper/nas.h @@ -25,7 +25,6 @@ #include "srslte/asn1/liblte_mme.h" #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/logmap.h" #include "srslte/common/nas_pcap.h" #include "srslte/common/security.h" #include "srslte/common/stack_procedure.h" diff --git a/srsue/hdr/stack/upper/nas_emm_state.h b/srsue/hdr/stack/upper/nas_emm_state.h index 63689287e..d44631d0b 100644 --- a/srsue/hdr/stack/upper/nas_emm_state.h +++ b/srsue/hdr/stack/upper/nas_emm_state.h @@ -22,7 +22,6 @@ #ifndef SRSUE_NAS_EMM_STATE_H #define SRSUE_NAS_EMM_STATE_H -#include "srslte/common/logmap.h" #include "srslte/srslog/srslog.h" #include #include diff --git a/srsue/hdr/stack/upper/pcsc_usim.h b/srsue/hdr/stack/upper/pcsc_usim.h index 8a4afa967..b08110dde 100644 --- a/srsue/hdr/stack/upper/pcsc_usim.h +++ b/srsue/hdr/stack/upper/pcsc_usim.h @@ -23,7 +23,6 @@ #define SRSUE_PCSC_USIM_H #include "srslte/common/common.h" -#include "srslte/common/log.h" #include "srslte/common/security.h" #include "srsue/hdr/stack/upper/usim.h" #include diff --git a/srsue/hdr/stack/upper/tft_packet_filter.h b/srsue/hdr/stack/upper/tft_packet_filter.h index 29dd672cb..80b342bf8 100644 --- a/srsue/hdr/stack/upper/tft_packet_filter.h +++ b/srsue/hdr/stack/upper/tft_packet_filter.h @@ -24,8 +24,6 @@ #include "srslte/asn1/liblte_mme.h" #include "srslte/common/buffer_pool.h" -#include "srslte/common/log.h" -#include "srslte/common/log_filter.h" #include "srslte/srslog/srslog.h" #include diff --git a/srsue/hdr/stack/upper/usim.h b/srsue/hdr/stack/upper/usim.h index 7fccdb879..ca377e522 100644 --- a/srsue/hdr/stack/upper/usim.h +++ b/srsue/hdr/stack/upper/usim.h @@ -23,7 +23,6 @@ #define SRSUE_USIM_H #include "srslte/common/common.h" -#include "srslte/common/log.h" #include "srslte/common/security.h" #include "usim_base.h" #include diff --git a/srsue/hdr/stack/upper/usim_base.h b/srsue/hdr/stack/upper/usim_base.h index f8a64ba89..ba86408d7 100644 --- a/srsue/hdr/stack/upper/usim_base.h +++ b/srsue/hdr/stack/upper/usim_base.h @@ -23,7 +23,6 @@ #define SRSUE_USIM_BASE_H #include "srslte/common/common.h" -#include "srslte/common/log.h" #include "srslte/common/security.h" #include "srslte/interfaces/ue_usim_interfaces.h" #include "srslte/srslog/srslog.h" diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index 90d9a3758..1e16dfd7b 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -34,7 +34,6 @@ #include "phy/ue_phy_base.h" #include "srslte/common/buffer_pool.h" -#include "srslte/common/log_filter.h" #include "srslte/radio/radio.h" #include "srslte/srslog/srslog.h" #include "srslte/system/sys_metrics_processor.h" @@ -71,6 +70,9 @@ typedef struct { bool metrics_csv_append; int metrics_csv_flush_period_sec; std::string metrics_csv_filename; + bool tracing_enable; + std::string tracing_filename; + std::size_t tracing_buffcapacity; } general_args_t; typedef struct { @@ -96,7 +98,7 @@ public: ue(); ~ue(); - int init(const all_args_t& args_, srslte::logger* logger_); + int init(const all_args_t& args_); void stop(); bool switch_on(); bool switch_off(); @@ -115,7 +117,6 @@ private: std::unique_ptr gw_inst; // Generic logger members - srslte::logger* old_logger = nullptr; srslog::basic_logger& logger; // System metrics processor. diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 34b16c7a3..e74a0aab5 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -22,10 +22,9 @@ #include "srslte/common/common_helper.h" #include "srslte/common/config_file.h" #include "srslte/common/crash_handler.h" -#include "srslte/common/logger_srslog_wrapper.h" -#include "srslte/common/logmap.h" #include "srslte/common/metrics_hub.h" #include "srslte/common/signal_handler.h" +#include "srslte/srslog/event_trace.h" #include "srslte/srslog/srslog.h" #include "srslte/srslte.h" #include "srslte/version.h" @@ -428,6 +427,18 @@ static int parse_args(all_args_t* args, int argc, char* argv[]) bpo::value(&args->general.metrics_csv_flush_period_sec)->default_value(-1), "Periodicity in s to flush CSV file to disk (-1 for auto)") + ("general.tracing_enable", + bpo::value(&args->general.tracing_enable)->default_value(false), + "Events tracing") + + ("general.tracing_filename", + bpo::value(&args->general.tracing_filename)->default_value("/tmp/ue_tracing.log"), + "Tracing events filename") + + ("general.tracing_buffcapacity", + bpo::value(&args->general.tracing_buffcapacity)->default_value(1000000), + "Tracing buffer capcity") + ("stack.have_tti_time_stats", bpo::value(&args->stack.have_tti_time_stats)->default_value(true), "Calculate TTI execution statistics") @@ -648,20 +659,26 @@ int main(int argc, char* argv[]) if (!chan) { return SRSLTE_ERROR; } - srslte::srslog_wrapper log_wrapper(*chan); srslog::set_default_sink(*log_sink); +#ifdef ENABLE_SRSLOG_EVENT_TRACE + if (args.general.tracing_enable) { + if (!srslog::event_trace_init(args.general.tracing_filename, args.general.tracing_buffcapacity)) { + return SRSLTE_ERROR; + } + } +#endif + // Start the log backend. srslog::init(); - srslte::logmap::set_default_logger(&log_wrapper); srslte::log_args(argc, argv, "UE"); srslte::check_scaling_governor(args.rf.device_name); - // Create UE instance + // Create UE instance. srsue::ue ue; - if (ue.init(args, &log_wrapper)) { + if (ue.init(args)) { ue.stop(); return SRSLTE_SUCCESS; } diff --git a/srsue/src/phy/lte/cc_worker.cc b/srsue/src/phy/lte/cc_worker.cc index 843c2075a..4e4953254 100644 --- a/srsue/src/phy/lte/cc_worker.cc +++ b/srsue/src/phy/lte/cc_worker.cc @@ -21,6 +21,7 @@ #include "srslte/srslte.h" +#include "srslte/common/standard_streams.h" #include "srsue/hdr/phy/lte/cc_worker.h" #define Error(fmt, ...) \ @@ -328,7 +329,12 @@ bool cc_worker::work_dl_mbsfn(srslte_mbsfn_cfg_t mbsfn_cfg) return false; } - decode_pdcch_ul(); + // Look for DL and UL dci(s) if the serving cell is active and it is NOT a secondary serving cell without + // cross-carrier scheduling is enabled + if (phy->cell_state.is_active(cc_idx, sf_cfg_dl.tti) and (cc_idx != 0 or not ue_dl_cfg.cfg.dci.cif_present)) { + decode_pdcch_dl(); + decode_pdcch_ul(); + } if (mbsfn_cfg.enable) { srslte_configure_pmch(&pmch_cfg, &cell, &mbsfn_cfg); diff --git a/srsue/src/phy/lte/sf_worker.cc b/srsue/src/phy/lte/sf_worker.cc index c052caec8..4ed8c1413 100644 --- a/srsue/src/phy/lte/sf_worker.cc +++ b/srsue/src/phy/lte/sf_worker.cc @@ -21,6 +21,7 @@ #include "srslte/srslte.h" +#include "srslte/common/standard_streams.h" #include "srsue/hdr/phy/lte/sf_worker.h" #include @@ -188,7 +189,8 @@ void sf_worker::work_imp() ZERO_OBJECT(mbsfn_cfg); if (carrier_idx == 0 && phy->is_mbsfn_sf(&mbsfn_cfg, tti)) { - cc_workers[0]->work_dl_mbsfn(mbsfn_cfg); // Don't do chest_ok in mbsfn since it trigger measurements + rx_signal_ok = + cc_workers[0]->work_dl_mbsfn(mbsfn_cfg); // Don't do chest_ok in mbsfn since it trigger measurements } else { if (phy->cell_state.is_configured(carrier_idx)) { rx_signal_ok = cc_workers[carrier_idx]->work_dl_regular(); diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index 35b7cdc98..f04a0bebc 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -20,6 +20,7 @@ */ #include "srsue/hdr/phy/nr/cc_worker.h" +#include "srslte/common/buffer_pool.h" #include "srslte/srslte.h" namespace srsue { @@ -297,8 +298,11 @@ bool cc_worker::work_ul() // Assignning MAC provided values to PUSCH config structs pusch_cfg.grant.tb[0].softbuffer.tx = ul_action.tb.softbuffer; + srslte_pusch_data_nr_t data = {}; + data.payload = ul_action.tb.payload->msg; + // Encode PUSCH transmission - if (srslte_ue_ul_nr_encode_pusch(&ue_ul, &ul_slot_cfg, &pusch_cfg, ul_action.tb.payload->msg) < SRSLTE_SUCCESS) { + if (srslte_ue_ul_nr_encode_pusch(&ue_ul, &ul_slot_cfg, &pusch_cfg, &data) < SRSLTE_SUCCESS) { ERROR("Encoding PUSCH"); return false; } diff --git a/srsue/src/phy/nr/sf_worker.cc b/srsue/src/phy/nr/sf_worker.cc index c3e242e09..f69aac632 100644 --- a/srsue/src/phy/nr/sf_worker.cc +++ b/srsue/src/phy/nr/sf_worker.cc @@ -20,6 +20,7 @@ */ #include "srsue/hdr/phy/nr/sf_worker.h" +#include "srslte/common/standard_streams.h" #ifdef ENABLE_GUI #include "srsgui/srsgui.h" diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index ccc4b62bf..f066f3c48 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -19,16 +19,10 @@ * */ -#include -#include -#include #include -#include #include -#include -#include "srslte/common/log.h" -#include "srslte/common/threads.h" +#include "srslte/common/standard_streams.h" #include "srslte/srslte.h" #include "srsue/hdr/phy/phy.h" diff --git a/srsue/src/phy/prach.cc b/srsue/src/phy/prach.cc index c2992a174..be663fe1d 100644 --- a/srsue/src/phy/prach.cc +++ b/srsue/src/phy/prach.cc @@ -20,7 +20,7 @@ */ #include "srsue/hdr/phy/prach.h" -#include "srslte/common/log.h" +#include "srslte/common/standard_streams.h" #include "srslte/interfaces/phy_interface_types.h" #include "srslte/srslte.h" diff --git a/srsue/src/phy/search.cc b/srsue/src/phy/search.cc index bff861a1d..66a7d45bc 100644 --- a/srsue/src/phy/search.cc +++ b/srsue/src/phy/search.cc @@ -20,6 +20,7 @@ */ #include "srsue/hdr/phy/search.h" +#include "srslte/common/standard_streams.h" #define Error(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ diff --git a/srsue/src/phy/sync.cc b/srsue/src/phy/sync.cc index eb0891748..ed1613024 100644 --- a/srsue/src/phy/sync.cc +++ b/srsue/src/phy/sync.cc @@ -20,10 +20,11 @@ */ #include "srsue/hdr/phy/sync.h" -#include "srslte/common/log.h" +#include "srslte/common/standard_streams.h" #include "srslte/phy/channel/channel.h" #include "srslte/srslte.h" #include "srsue/hdr/phy/lte/sf_worker.h" + #include #include diff --git a/srsue/src/phy/vnf_phy_nr.cc b/srsue/src/phy/vnf_phy_nr.cc index 652c0b70b..cecba41bf 100644 --- a/srsue/src/phy/vnf_phy_nr.cc +++ b/srsue/src/phy/vnf_phy_nr.cc @@ -28,7 +28,6 @@ #include #include "srslte/common/basic_vnf_api.h" -#include "srslte/common/log.h" #include "srslte/common/test_common.h" #include "srslte/common/threads.h" #include "srsue/hdr/phy/vnf_phy_nr.h" diff --git a/srsue/src/stack/mac/demux.cc b/srsue/src/stack/mac/demux.cc index 112f2d69f..28beed284 100644 --- a/srsue/src/stack/mac/demux.cc +++ b/srsue/src/stack/mac/demux.cc @@ -19,14 +19,16 @@ * */ +#include "srsue/hdr/stack/mac/demux.h" +#include "srslte/common/standard_streams.h" +#include "srslte/common/string_helpers.h" +#include "srslte/interfaces/ue_phy_interfaces.h" + #define Error(fmt, ...) logger.error(fmt, ##__VA_ARGS__) #define Warning(fmt, ...) logger.warning(fmt, ##__VA_ARGS__) #define Info(fmt, ...) logger.info(fmt, ##__VA_ARGS__) #define Debug(fmt, ...) logger.debug(fmt, ##__VA_ARGS__) -#include "srsue/hdr/stack/mac/demux.h" -#include "srslte/interfaces/ue_phy_interfaces.h" - namespace srsue { demux::demux(srslog::basic_logger& logger) : @@ -162,7 +164,11 @@ void demux::process_pdu(uint8_t* mac_pdu, uint32_t nof_bytes, srslte::pdu_queue: // Unpack DLSCH MAC PDU mac_msg.init_rx(nof_bytes); mac_msg.parse_packet(mac_pdu); - Info("%s", mac_msg.to_string().c_str()); + { + fmt::memory_buffer buffer; + mac_msg.to_string(buffer); + Info("%s", srslte::to_c_str(buffer)); + } process_sch_pdu(&mac_msg); pdus.deallocate(mac_pdu); break; diff --git a/srsue/src/stack/mac/dl_harq.cc b/srsue/src/stack/mac/dl_harq.cc index 09fb5b876..4e011806c 100644 --- a/srsue/src/stack/mac/dl_harq.cc +++ b/srsue/src/stack/mac/dl_harq.cc @@ -25,7 +25,6 @@ #define Debug(fmt, ...) logger.debug(fmt, ##__VA_ARGS__) #include "srsue/hdr/stack/mac/dl_harq.h" -#include "srslte/common/log.h" #include "srslte/common/mac_pcap.h" #include "srslte/common/timers.h" diff --git a/srsue/src/stack/mac/mac.cc b/srsue/src/stack/mac/mac.cc index f2b056643..77f068406 100644 --- a/srsue/src/stack/mac/mac.cc +++ b/srsue/src/stack/mac/mac.cc @@ -27,7 +27,6 @@ #include #include -#include "srslte/common/log.h" #include "srslte/common/pcap.h" #include "srslte/interfaces/ue_phy_interfaces.h" #include "srsue/hdr/stack/mac/mac.h" diff --git a/srsue/src/stack/mac/mux.cc b/srsue/src/stack/mac/mux.cc index 98d7212a7..93eec7977 100644 --- a/srsue/src/stack/mac/mux.cc +++ b/srsue/src/stack/mac/mux.cc @@ -25,6 +25,7 @@ #define Debug(fmt, ...) logger.debug(fmt, ##__VA_ARGS__) #include "srsue/hdr/stack/mac/mux.h" +#include "srslte/common/string_helpers.h" #include "srsue/hdr/stack/mac/mac.h" #include @@ -294,8 +295,10 @@ uint8_t* mux::pdu_get(srslte::byte_buffer_t* payload, uint32_t pdu_sz) bsr_procedure->update_bsr_tti_end(&bsr); // Generate MAC PDU and save to buffer - uint8_t* ret = pdu_msg.write_packet(logger); - Info("%s", pdu_msg.to_string().c_str()); + uint8_t* ret = pdu_msg.write_packet(logger); + fmt::memory_buffer buffer; + pdu_msg.to_string(buffer); + Info("%s", srslte::to_c_str(buffer)); Debug("Assembled MAC PDU msg size %d/%d bytes", pdu_msg.get_pdu_len() - pdu_msg.rem_size(), pdu_sz); return ret; diff --git a/srsue/src/stack/mac/proc_ra.cc b/srsue/src/stack/mac/proc_ra.cc index 329c52d0d..f6763038c 100644 --- a/srsue/src/stack/mac/proc_ra.cc +++ b/srsue/src/stack/mac/proc_ra.cc @@ -20,6 +20,7 @@ */ #include "srsue/hdr/stack/mac/proc_ra.h" +#include "srslte/common/standard_streams.h" #include "srslte/interfaces/ue_phy_interfaces.h" #include "srslte/interfaces/ue_rrc_interfaces.h" #include "srsue/hdr/stack/mac/mux.h" diff --git a/srsue/src/stack/mac/proc_sr.cc b/srsue/src/stack/mac/proc_sr.cc index 7f617908d..62c8dfd12 100644 --- a/srsue/src/stack/mac/proc_sr.cc +++ b/srsue/src/stack/mac/proc_sr.cc @@ -25,6 +25,7 @@ #define Debug(fmt, ...) logger.debug(fmt, ##__VA_ARGS__) #include "srsue/hdr/stack/mac/proc_sr.h" +#include "srslte/common/standard_streams.h" #include "srslte/interfaces/ue_phy_interfaces.h" #include "srslte/interfaces/ue_rrc_interfaces.h" #include "srsue/hdr/stack/mac/proc_ra.h" diff --git a/srsue/src/stack/mac/ul_harq.cc b/srsue/src/stack/mac/ul_harq.cc index 556271a8a..f5ba3e207 100644 --- a/srsue/src/stack/mac/ul_harq.cc +++ b/srsue/src/stack/mac/ul_harq.cc @@ -26,7 +26,6 @@ #include "srsue/hdr/stack/mac/ul_harq.h" #include "srslte/common/interfaces_common.h" -#include "srslte/common/log.h" #include "srslte/common/mac_pcap.h" #include "srslte/common/timers.h" diff --git a/srsue/src/stack/mac_nr/proc_ra_nr.cc b/srsue/src/stack/mac_nr/proc_ra_nr.cc index cc0f96f26..828119a4a 100644 --- a/srsue/src/stack/mac_nr/proc_ra_nr.cc +++ b/srsue/src/stack/mac_nr/proc_ra_nr.cc @@ -20,6 +20,7 @@ */ #include "srsue/hdr/stack/mac_nr/proc_ra_nr.h" +#include "srslte/common/standard_streams.h" #include "srslte/mac/mac_rar_pdu_nr.h" #include "srsue/hdr/stack/mac_nr/mac_nr.h" @@ -190,7 +191,7 @@ void proc_ra_nr::ra_response_reception(const mac_interface_phy_nr::mac_nr_grant_ logger.warning("Error unpacking RAR PDU (%d)", i); return; } - logger.info(pdu.to_string()); + logger.info("%s", pdu.to_string()); for (auto& subpdu : pdu.get_subpdus()) { if (subpdu.has_rapid() && subpdu.get_rapid() == preamble_index) { diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index c12b43420..355063fd7 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -23,6 +23,7 @@ #include "srslte/asn1/rrc.h" #include "srslte/common/bcd_helpers.h" #include "srslte/common/security.h" +#include "srslte/common/standard_streams.h" #include "srslte/interfaces/ue_gw_interfaces.h" #include "srslte/interfaces/ue_nas_interfaces.h" #include "srslte/interfaces/ue_pdcp_interfaces.h" @@ -31,6 +32,7 @@ #include "srsue/hdr/stack/rrc/phy_controller.h" #include "srsue/hdr/stack/rrc/rrc_meas.h" #include "srsue/hdr/stack/rrc/rrc_procedures.h" + #include #include #include // for printing uint64_t diff --git a/srsue/src/stack/rrc/rrc_nr.cc b/srsue/src/stack/rrc/rrc_nr.cc index ffb2a735c..636940324 100644 --- a/srsue/src/stack/rrc/rrc_nr.cc +++ b/srsue/src/stack/rrc/rrc_nr.cc @@ -21,14 +21,15 @@ #include "srsue/hdr/stack/rrc/rrc_nr.h" #include "srslte/common/security.h" +#include "srslte/common/standard_streams.h" #include "srslte/interfaces/ue_pdcp_interfaces.h" #include "srslte/interfaces/ue_rlc_interfaces.h" #include "srsue/hdr/stack/upper/usim.h" -#define Error(fmt, ...) rrc_ptr->log_h->error("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) -#define Warning(fmt, ...) rrc_ptr->log_h->warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) -#define Info(fmt, ...) rrc_ptr->log_h->info("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) -#define Debug(fmt, ...) rrc_ptr->log_h->debug("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define Error(fmt, ...) rrc_ptr->logger.error("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define Warning(fmt, ...) rrc_ptr->logger.warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define Info(fmt, ...) rrc_ptr->logger.info("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define Debug(fmt, ...) rrc_ptr->logger.debug("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) using namespace asn1::rrc_nr; using namespace asn1; @@ -37,7 +38,9 @@ namespace srsue { const char* rrc_nr::rrc_nr_state_text[] = {"IDLE", "CONNECTED", "CONNECTED-INACTIVE"}; -rrc_nr::rrc_nr(srslte::task_sched_handle task_sched_) : log_h("RRC"), task_sched(task_sched_), conn_recfg_proc(this) {} +rrc_nr::rrc_nr(srslte::task_sched_handle task_sched_) : + logger(srslog::fetch_basic_logger("RRC")), task_sched(task_sched_), conn_recfg_proc(this) +{} rrc_nr::~rrc_nr() = default; @@ -74,7 +77,7 @@ void rrc_nr::stop() void rrc_nr::init_core_less() { - log_h->info("Creating dummy DRB on LCID=%d", args.coreless.drb_lcid); + logger.info("Creating dummy DRB on LCID=%d", args.coreless.drb_lcid); srslte::rlc_config_t rlc_cnfg = srslte::rlc_config_t::default_rlc_um_nr_config(6); rlc->add_bearer(args.coreless.drb_lcid, rlc_cnfg); @@ -95,9 +98,9 @@ void rrc_nr::get_metrics(rrc_nr_metrics_t& m) {} // Timeout callback interface void rrc_nr::timer_expired(uint32_t timeout_id) { - log_h->debug("[NR] Handling Timer Expired"); + logger.debug("[NR] Handling Timer Expired"); if (timeout_id == fake_measurement_timer.id()) { - log_h->debug("[NR] Triggered Fake Measurement"); + logger.debug("[NR] Triggered Fake Measurement"); phy_meas_nr_t fake_meas = {}; std::vector phy_meas_nr; @@ -124,19 +127,19 @@ void rrc_nr::log_rrc_message(const std::string& source, const T& msg, const std::string& msg_type) { - if (log_h->get_level() == srslte::LOG_LEVEL_INFO) { - log_h->info("%s - %s %s (%d B)", source.c_str(), (dir == Rx) ? "Rx" : "Tx", msg_type.c_str(), pdu->N_bytes); - } else if (log_h->get_level() >= srslte::LOG_LEVEL_DEBUG) { + if (logger.debug.enabled()) { asn1::json_writer json_writer; msg.to_json(json_writer); - log_h->debug_hex(pdu->msg, - pdu->N_bytes, - "%s - %s %s (%d B)", - source.c_str(), - (dir == Rx) ? "Rx" : "Tx", - msg_type.c_str(), - pdu->N_bytes); - log_h->debug_long("Content:\n%s", json_writer.to_string().c_str()); + logger.debug(pdu->msg, + pdu->N_bytes, + "%s - %s %s (%d B)", + source.c_str(), + (dir == Rx) ? "Rx" : "Tx", + msg_type.c_str(), + pdu->N_bytes); + logger.debug("Content:\n%s", json_writer.to_string().c_str()); + } else if (logger.info.enabled()) { + logger.info("%s - %s %s (%d B)", source.c_str(), (dir == Rx) ? "Rx" : "Tx", msg_type.c_str(), pdu->N_bytes); } } @@ -147,29 +150,29 @@ void rrc_nr::log_rrc_message(const std::string& source, const T& msg, const std::string& msg_type) { - if (log_h->get_level() == srslte::LOG_LEVEL_INFO) { - log_h->info("%s - %s %s (%d B)", source.c_str(), (dir == Rx) ? "Rx" : "Tx", msg_type.c_str(), oct.size()); - } else if (log_h->get_level() >= srslte::LOG_LEVEL_DEBUG) { + if (logger.debug.enabled()) { asn1::json_writer json_writer; msg.to_json(json_writer); - log_h->debug_hex(oct.data(), - oct.size(), - "%s - %s %s (%d B)", - source.c_str(), - (dir == Rx) ? "Rx" : "Tx", - msg_type.c_str(), - oct.size()); - log_h->debug_long("Content:\n%s", json_writer.to_string().c_str()); + logger.debug(oct.data(), + oct.size(), + "%s - %s %s (%d B)", + source.c_str(), + (dir == Rx) ? "Rx" : "Tx", + msg_type.c_str(), + oct.size()); + logger.debug("Content:\n%s", json_writer.to_string().c_str()); + } else if (logger.info.enabled()) { + logger.info("%s - %s %s (%d B)", source.c_str(), (dir == Rx) ? "Rx" : "Tx", msg_type.c_str(), oct.size()); } } bool rrc_nr::add_lcid_rb(uint32_t lcid, rb_type_t rb_type, uint32_t rbid) { if (lcid_rb.find(lcid) != lcid_rb.end()) { - log_h->error("Couldn't add RB to LCID. RB %d does exist.", rbid); + logger.error("Couldn't add RB to LCID. RB %d does exist.", rbid); return false; } else { - log_h->info("Adding lcid %d and radio bearer ID %d with type %s ", lcid, rbid, (rb_type == Srb) ? "SRB" : "DRB"); + logger.info("Adding lcid %d and radio bearer ID %d with type %s ", lcid, rbid, (rb_type == Srb) ? "SRB" : "DRB"); lcid_rb[lcid].rb_id = rbid; lcid_rb[lcid].rb_type = rb_type; } @@ -183,7 +186,7 @@ uint32_t rrc_nr::get_lcid_for_rbid(uint32_t rb_id) return rb.first; } } - log_h->error("Couldn't find LCID for rb LCID. RB %d does exist.", rb_id); + logger.error("Couldn't find LCID for rb LCID. RB %d does exist.", rb_id); return 0; } @@ -320,7 +323,7 @@ void rrc_nr::get_eutra_nr_capabilities(srslte::byte_buffer_t* eutra_nr_caps_pdu) } #endif - log_h->debug_hex( + logger.debug( eutra_nr_caps_pdu->msg, eutra_nr_caps_pdu->N_bytes, "EUTRA-NR capabilities (%u B)", eutra_nr_caps_pdu->N_bytes); return; @@ -337,7 +340,7 @@ bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15, // sanity check only for now if (nr_secondary_cell_group_cfg_r15_present == false || sk_counter_r15_present == false || nr_radio_bearer_cfg1_r15_present == false) { - log_h->error("RRC NR Reconfiguration failed sanity check failed"); + logger.error("RRC NR Reconfiguration failed sanity check failed"); return false; } @@ -350,7 +353,7 @@ bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15, err = rrc_recfg.unpack(bref); if (err != asn1::SRSASN_SUCCESS) { - log_h->error("Could not unpack NR reconfiguration message."); + logger.error("Could not unpack NR reconfiguration message."); return false; } @@ -364,7 +367,7 @@ bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15, err = cell_group_cfg.unpack(bref0); if (err != asn1::SRSASN_SUCCESS) { - log_h->error("Could not unpack cell group message message."); + logger.error("Could not unpack cell group message message."); return false; } @@ -374,7 +377,7 @@ bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15, cell_group_cfg, "Secondary Cell Group Config"); } else { - log_h->error("Reconfiguration does not contain Secondary Cell Group Config"); + logger.error("Reconfiguration does not contain Secondary Cell Group Config"); return false; } } @@ -383,7 +386,7 @@ bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15, err = radio_bearer_cfg.unpack(bref1); if (err != asn1::SRSASN_SUCCESS) { - log_h->error("Could not unpack radio bearer config."); + logger.error("Could not unpack radio bearer config."); return false; } @@ -394,7 +397,7 @@ bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15, sk_counter_r15_present, sk_counter_r15, radio_bearer_cfg)) { - log_h->error("Unable to launch NR RRC configuration procedure"); + logger.error("Unable to launch NR RRC configuration procedure"); return false; } else { callback_list.add_proc(conn_recfg_proc); @@ -440,7 +443,7 @@ void rrc_nr::get_nr_capabilities(srslte::byte_buffer_t* nr_caps_pdu) } #endif - log_h->debug_hex(nr_caps_pdu->msg, nr_caps_pdu->N_bytes, "NR capabilities (%u B)", nr_caps_pdu->N_bytes); + logger.debug(nr_caps_pdu->msg, nr_caps_pdu->N_bytes, "NR capabilities (%u B)", nr_caps_pdu->N_bytes); return; }; @@ -448,13 +451,13 @@ void rrc_nr::phy_meas_stop() { // possbile race condition for fake_measurement timer, which might be set at the same moment as stopped => fix with // phy integration - log_h->debug("[NR] Stopping fake measurements"); + logger.debug("[NR] Stopping fake measurements"); fake_measurement_timer.stop(); } void rrc_nr::phy_set_cells_to_meas(uint32_t carrier_freq_r15) { - log_h->debug("[NR] Measuring phy cell %d ", carrier_freq_r15); + logger.debug("[NR] Measuring phy cell %d ", carrier_freq_r15); // Start timer for fake measurements auto timer_expire_func = [this](uint32_t tid) { timer_expired(tid); }; fake_measurement_carrier_freq_r15 = carrier_freq_r15; @@ -464,7 +467,7 @@ void rrc_nr::phy_set_cells_to_meas(uint32_t carrier_freq_r15) void rrc_nr::configure_sk_counter(uint16_t sk_counter) { - log_h->info("[NR] Configure new SK counter %d. Update Key for secondary gnb", sk_counter); + logger.info("[NR] Configure new SK counter %d. Update Key for secondary gnb", sk_counter); usim->generate_nr_context(sk_counter, &sec_cfg); } bool rrc_nr::is_config_pending() @@ -492,7 +495,7 @@ bool rrc_nr::apply_rlc_add_mod(const rlc_bearer_cfg_s& rlc_bearer_cfg) add_lcid_rb(lc_ch_id, Srb, srb_id); } } else { - log_h->warning("In RLC bearer cfg does not contain served radio bearer"); + logger.warning("In RLC bearer cfg does not contain served radio bearer"); return false; } @@ -503,13 +506,13 @@ bool rrc_nr::apply_rlc_add_mod(const rlc_bearer_cfg_s& rlc_bearer_cfg) rlc_bearer_cfg.rlc_cfg.um_bi_dir().ul_um_rlc.sn_field_len_present && rlc_bearer_cfg.rlc_cfg.um_bi_dir().dl_um_rlc.sn_field_len != rlc_bearer_cfg.rlc_cfg.um_bi_dir().ul_um_rlc.sn_field_len) { - log_h->warning("NR RLC sequence number length is not the same in uplink and downlink"); + logger.warning("NR RLC sequence number length is not the same in uplink and downlink"); } } else { - log_h->warning("NR RLC type is not unacknowledged mode bidirectional"); + logger.warning("NR RLC type is not unacknowledged mode bidirectional"); } } else { - log_h->warning("In RLC bearer cfg does not contain rlc cfg"); + logger.warning("In RLC bearer cfg does not contain rlc cfg"); return false; } @@ -529,20 +532,20 @@ bool rrc_nr::apply_mac_cell_group(const mac_cell_group_cfg_s& mac_cell_group_cfg sr_cfg_t sr_cfg; if (mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list_present) { if (mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list.size() > 1) { - log_h->warning("Only handling 1 scheduling request index to add"); + logger.warning("Only handling 1 scheduling request index to add"); sr_cfg.dsr_transmax = mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list[1].sr_trans_max; mac->set_config(sr_cfg); } } if (mac_cell_group_cfg.sched_request_cfg.sched_request_to_release_list_present) { - log_h->warning("Not handling sched request to release list"); + logger.warning("Not handling sched request to release list"); } } if (mac_cell_group_cfg.sched_request_cfg_present) if (mac_cell_group_cfg.bsr_cfg_present) { - log_h->debug("Handling MAC BSR config"); + logger.debug("Handling MAC BSR config"); srslte::bsr_cfg_t bsr_cfg; bsr_cfg.periodic_timer = mac_cell_group_cfg.bsr_cfg.periodic_bsr_timer.to_number(); bsr_cfg.retx_timer = mac_cell_group_cfg.bsr_cfg.retx_bsr_timer.to_number(); @@ -550,15 +553,15 @@ bool rrc_nr::apply_mac_cell_group(const mac_cell_group_cfg_s& mac_cell_group_cfg } if (mac_cell_group_cfg.tag_cfg_present) { - log_h->warning("Not handling tag cfg in MAC cell group config"); + logger.warning("Not handling tag cfg in MAC cell group config"); } if (mac_cell_group_cfg.phr_cfg_present) { - log_h->warning("Not handling phr cfg in MAC cell group config"); + logger.warning("Not handling phr cfg in MAC cell group config"); } if (mac_cell_group_cfg.skip_ul_tx_dynamic) { - log_h->warning("Not handling phr cfg in skip_ul_tx_dynamic cell group config"); + logger.warning("Not handling phr cfg in skip_ul_tx_dynamic cell group config"); } return true; } @@ -596,7 +599,7 @@ bool rrc_nr::apply_cell_group_cfg(const cell_group_cfg_s& cell_group_cfg) apply_mac_cell_group(cell_group_cfg.mac_cell_group_cfg); } if (cell_group_cfg.phys_cell_group_cfg_present) { - log_h->warning("Not handling physical cell group config"); + logger.warning("Not handling physical cell group config"); } if (cell_group_cfg.sp_cell_cfg_present) { apply_sp_cell_cfg(cell_group_cfg.sp_cell_cfg); @@ -607,7 +610,7 @@ bool rrc_nr::apply_cell_group_cfg(const cell_group_cfg_s& cell_group_cfg) bool rrc_nr::apply_drb_add_mod(const drb_to_add_mod_s& drb_cfg) { if (!drb_cfg.pdcp_cfg_present) { - log_h->error("Cannot add DRB - incomplete configuration"); + logger.error("Cannot add DRB - incomplete configuration"); return false; } @@ -615,17 +618,17 @@ bool rrc_nr::apply_drb_add_mod(const drb_to_add_mod_s& drb_cfg) // Setup PDCP if (!(drb_cfg.pdcp_cfg.drb_present == true)) { - log_h->error("PDCP config does not contain DRB config"); + logger.error("PDCP config does not contain DRB config"); return false; } if (!(drb_cfg.cn_assoc_present == true)) { - log_h->error("DRB config does not contain an associated cn"); + logger.error("DRB config does not contain an associated cn"); return false; } if (!(drb_cfg.cn_assoc.type() == drb_to_add_mod_s::cn_assoc_c_::types_opts::eps_bearer_id)) { - log_h->error("CN associtaion type not supported %s ", drb_cfg.cn_assoc.type().to_string().c_str()); + logger.error("CN associtaion type not supported %s ", drb_cfg.cn_assoc.type().to_string().c_str()); return false; } uint32_t eps_bearer_id = drb_cfg.cn_assoc.eps_bearer_id(); @@ -633,7 +636,7 @@ bool rrc_nr::apply_drb_add_mod(const drb_to_add_mod_s& drb_cfg) if (drb_cfg.pdcp_cfg.drb.pdcp_sn_size_dl_present && drb_cfg.pdcp_cfg.drb.pdcp_sn_size_ul_present && (drb_cfg.pdcp_cfg.drb.pdcp_sn_size_ul.to_number() != drb_cfg.pdcp_cfg.drb.pdcp_sn_size_dl.to_number())) { - log_h->warning("PDCP SN size in UL and DL are not the same. make_drb_pdcp_config_t will use the DL SN size %d ", + logger.warning("PDCP SN size in UL and DL are not the same. make_drb_pdcp_config_t will use the DL SN size %d ", drb_cfg.pdcp_cfg.drb.pdcp_sn_size_dl.to_number()); } @@ -648,7 +651,7 @@ bool rrc_nr::apply_security_cfg(const security_cfg_s& security_cfg) // TODO derive correct keys if (security_cfg.key_to_use_present) { if (security_cfg.key_to_use.value != security_cfg_s::key_to_use_opts::options::secondary) { - log_h->warning("Only secondary key supported yet"); + logger.warning("Only secondary key supported yet"); } } @@ -667,7 +670,7 @@ bool rrc_nr::apply_security_cfg(const security_cfg_s& security_cfg) sec_cfg.cipher_algo = CIPHERING_ALGORITHM_ID_128_EEA3; break; default: - log_h->warning("Unsupported algorithm"); + logger.warning("Unsupported algorithm"); break; } @@ -686,7 +689,7 @@ bool rrc_nr::apply_security_cfg(const security_cfg_s& security_cfg) sec_cfg.integ_algo = INTEGRITY_ALGORITHM_ID_128_EIA3; break; default: - log_h->warning("Unsupported algorithm"); + logger.warning("Unsupported algorithm"); break; } } diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index aecd9080a..a081e8d5f 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -966,12 +966,10 @@ srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::init(const asn1::rrc:: if (rrc_ptr->reestablishment_successful) { // Reestablish PDCP and RLC for SRB2 and all DRB // TODO: Which is the maximum LCID? - rrc_ptr->reestablishment_successful = false; for (int i = 2; i < SRSLTE_N_RADIO_BEARERS; i++) { if (rrc_ptr->rlc->has_bearer(i)) { rrc_ptr->rlc->reestablish(i); rrc_ptr->pdcp->reestablish(i); - rrc_ptr->pdcp->send_status_report(i); } } } @@ -983,6 +981,16 @@ srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::init(const asn1::rrc:: } } + if (rrc_ptr->reestablishment_successful) { + // Send status report if necessary. + rrc_ptr->reestablishment_successful = false; + for (int i = 2; i < SRSLTE_N_RADIO_BEARERS; i++) { + if (rrc_ptr->rlc->has_bearer(i)) { + rrc_ptr->pdcp->send_status_report(i); + } + } + } + // Apply Scell RR configurations (call is non-blocking). Make a copy since can be changed inside // apply_scell_config() Note that apply_scell_config() calls set_scell() and set_config() which run in the // background. @@ -1333,9 +1341,9 @@ proc_outcome_t rrc::connection_reest_proc::init(asn1::rrc::reest_cause_e cause) reest_cellid = rrc_ptr->meas_cells.find_cell(reest_source_freq, reest_source_pci)->get_cell_id(); Info("Starting... cause: \"%s\", UE context: {C-RNTI=0x%x, PCI=%d, CELL ID=%d}", - reest_cause == asn1::rrc::reest_cause_opts::recfg_fail - ? "Reconfiguration failure" - : cause == asn1::rrc::reest_cause_opts::ho_fail ? "Handover failure" : "Other failure", + reest_cause == asn1::rrc::reest_cause_opts::recfg_fail ? "Reconfiguration failure" + : cause == asn1::rrc::reest_cause_opts::ho_fail ? "Handover failure" + : "Other failure", reest_rnti, reest_source_pci, reest_cellid); diff --git a/srsue/src/stack/ue_stack_lte.cc b/srsue/src/stack/ue_stack_lte.cc index 7242a3a15..9c300ea83 100644 --- a/srsue/src/stack/ue_stack_lte.cc +++ b/srsue/src/stack/ue_stack_lte.cc @@ -20,8 +20,9 @@ */ #include "srsue/hdr/stack/ue_stack_lte.h" -#include "srslte/common/logmap.h" +#include "srslte/common/standard_streams.h" #include "srslte/interfaces/ue_phy_interfaces.h" +#include "srslte/srslog/event_trace.h" #include #include @@ -410,6 +411,9 @@ void ue_stack_lte::run_tti_impl(uint32_t tti, uint32_t tti_jump) if (args.have_tti_time_stats) { tti_tprof.start(); } + + trace_complete_event("ue_stack_lte::run_tti_impl", "total time"); + current_tti = tti_point{tti}; // perform tasks for the received TTI range diff --git a/srsue/src/stack/ue_stack_nr.cc b/srsue/src/stack/ue_stack_nr.cc index e7cad87d8..bb81953f6 100644 --- a/srsue/src/stack/ue_stack_nr.cc +++ b/srsue/src/stack/ue_stack_nr.cc @@ -26,8 +26,12 @@ using namespace srslte; namespace srsue { -ue_stack_nr::ue_stack_nr(srslte::logger* logger_) : - logger(logger_), thread("STACK"), task_sched(64, 64), rlc_log("RLC"), pdcp_log("PDCP") +ue_stack_nr::ue_stack_nr() : + thread("STACK"), + task_sched(64, 64), + mac_logger(srslog::fetch_basic_logger("MAC")), + rlc_logger(srslog::fetch_basic_logger("RLC", false)), + pdcp_logger(srslog::fetch_basic_logger("PDCP", false)) { get_background_workers().set_nof_workers(2); mac.reset(new mac_nr(&task_sched)); @@ -64,15 +68,12 @@ int ue_stack_nr::init(const stack_args_t& args_) { args = args_; - srslte::logmap::register_log(std::unique_ptr{new srslte::log_filter{"MAC", logger, true}}); - - srslte::log_ref mac_log{"MAC"}; - mac_log->set_level(args.log.mac_level); - mac_log->set_hex_limit(args.log.mac_hex_limit); - rlc_log->set_level(args.log.rlc_level); - rlc_log->set_hex_limit(args.log.rlc_hex_limit); - pdcp_log->set_level(args.log.pdcp_level); - pdcp_log->set_hex_limit(args.log.pdcp_hex_limit); + mac_logger.set_level(srslog::str_to_basic_level(args.log.mac_level)); + mac_logger.set_hex_dump_max_size(args.log.mac_hex_limit); + rlc_logger.set_level(srslog::str_to_basic_level(args.log.rlc_level)); + rlc_logger.set_hex_dump_max_size(args.log.rlc_hex_limit); + pdcp_logger.set_level(srslog::str_to_basic_level(args.log.pdcp_level)); + pdcp_logger.set_hex_dump_max_size(args.log.pdcp_hex_limit); mac_nr_args_t mac_args = {}; mac->init(mac_args, phy, rlc.get()); @@ -165,7 +166,7 @@ void ue_stack_nr::write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu) std::pair ret = gw_task_queue.try_push(std::bind( [this, lcid](srslte::unique_byte_buffer_t& sdu) { pdcp->write_sdu(lcid, std::move(sdu)); }, std::move(sdu))); if (not ret.first) { - pdcp_log->warning("GW SDU with lcid=%d was discarded.", lcid); + pdcp_logger.warning("GW SDU with lcid=%d was discarded.", lcid); } } } diff --git a/srsue/src/stack/upper/gw.cc b/srsue/src/stack/upper/gw.cc index 445408936..8c5751b1a 100644 --- a/srsue/src/stack/upper/gw.cc +++ b/srsue/src/stack/upper/gw.cc @@ -20,6 +20,7 @@ */ #include "srsue/hdr/stack/upper/gw.h" +#include "srslte/common/standard_streams.h" #include "srslte/interfaces/ue_pdcp_interfaces.h" #include "srslte/upper/ipv6.h" diff --git a/srsue/src/stack/upper/nas.cc b/srsue/src/stack/upper/nas.cc index 9f28c6492..83e3efe01 100644 --- a/srsue/src/stack/upper/nas.cc +++ b/srsue/src/stack/upper/nas.cc @@ -28,7 +28,7 @@ #include #include "srslte/asn1/liblte_mme.h" -#include "srslte/common/logmap.h" +#include "srslte/common/standard_streams.h" #include "srslte/interfaces/ue_gw_interfaces.h" #include "srslte/interfaces/ue_rrc_interfaces.h" #include "srslte/interfaces/ue_usim_interfaces.h" diff --git a/srsue/src/stack/upper/nas_idle_procedures.cc b/srsue/src/stack/upper/nas_idle_procedures.cc index 92a774ccb..1df15d4d7 100644 --- a/srsue/src/stack/upper/nas_idle_procedures.cc +++ b/srsue/src/stack/upper/nas_idle_procedures.cc @@ -20,6 +20,7 @@ */ #include "srsue/hdr/stack/upper/nas_idle_procedures.h" +#include "srslte/common/standard_streams.h" #include "srslte/interfaces/ue_rrc_interfaces.h" using namespace srslte; diff --git a/srsue/src/stack/upper/pcsc_usim.cc b/srsue/src/stack/upper/pcsc_usim.cc index b1accd356..1115df4ab 100644 --- a/srsue/src/stack/upper/pcsc_usim.cc +++ b/srsue/src/stack/upper/pcsc_usim.cc @@ -22,6 +22,7 @@ #include #include "srslte/common/bcd_helpers.h" +#include "srslte/common/standard_streams.h" #include "srsue/hdr/stack/upper/pcsc_usim.h" #include "string.h" diff --git a/srsue/src/stack/upper/tft_packet_filter.cc b/srsue/src/stack/upper/tft_packet_filter.cc index 605688176..ec8c8ccf6 100644 --- a/srsue/src/stack/upper/tft_packet_filter.cc +++ b/srsue/src/stack/upper/tft_packet_filter.cc @@ -21,6 +21,11 @@ #include "srsue/hdr/stack/upper/tft_packet_filter.h" #include "srslte/upper/ipv6.h" + +extern "C" { +#include "srslte/config.h" +} + #include #include #include diff --git a/srsue/src/stack/upper/usim.cc b/srsue/src/stack/upper/usim.cc index 867397ba2..8d8a2b1c1 100644 --- a/srsue/src/stack/upper/usim.cc +++ b/srsue/src/stack/upper/usim.cc @@ -21,6 +21,7 @@ #include "srsue/hdr/stack/upper/usim.h" #include "srslte/common/bcd_helpers.h" +#include "srslte/common/standard_streams.h" #include using namespace srslte; diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index d67b90fb4..3ed1d3d9d 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -38,7 +38,7 @@ using namespace srslte; namespace srsue { -ue::ue() : old_logger(nullptr), logger(srslog::fetch_basic_logger("UE", false)) +ue::ue() : logger(srslog::fetch_basic_logger("UE", false)) { // print build info std::cout << std::endl << get_build_string() << std::endl << std::endl; @@ -49,10 +49,9 @@ ue::~ue() stack.reset(); } -int ue::init(const all_args_t& args_, srslte::logger* logger_) +int ue::init(const all_args_t& args_) { - int ret = SRSLTE_SUCCESS; - old_logger = logger_; + int ret = SRSLTE_SUCCESS; // Init UE log logger.set_level(srslog::basic_levels::info); @@ -130,7 +129,7 @@ int ue::init(const all_args_t& args_, srslte::logger* logger_) radio = std::move(lte_radio); } else if (args.stack.type == "nr") { logger.info("Initializing NR stack"); - std::unique_ptr nr_stack(new srsue::ue_stack_nr(old_logger)); + std::unique_ptr nr_stack(new srsue::ue_stack_nr()); std::unique_ptr nr_radio(new srslte::radio_null); std::unique_ptr nr_phy(new srsue::vnf_phy_nr); std::unique_ptr gw_ptr(new gw()); diff --git a/srsue/test/mac_nr/proc_ra_nr_test.cc b/srsue/test/mac_nr/proc_ra_nr_test.cc index 5f60ef5a2..054256266 100644 --- a/srsue/test/mac_nr/proc_ra_nr_test.cc +++ b/srsue/test/mac_nr/proc_ra_nr_test.cc @@ -18,8 +18,8 @@ * and at http://www.gnu.org/licenses/. * */ +#include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/log_filter.h" #include "srslte/common/test_common.h" #include "srsue/hdr/stack/mac_nr/proc_ra_nr.h" diff --git a/srsue/test/phy/ue_phy_test.cc b/srsue/test/phy/ue_phy_test.cc index 8f5f51d8b..2db196bc9 100644 --- a/srsue/test/phy/ue_phy_test.cc +++ b/srsue/test/phy/ue_phy_test.cc @@ -19,7 +19,6 @@ * */ -#include #include #include #include diff --git a/srsue/test/ttcn3/hdr/ttcn3_port_handler.h b/srsue/test/ttcn3/hdr/ttcn3_port_handler.h index fd17dc235..28bdff8b1 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_port_handler.h +++ b/srsue/test/ttcn3/hdr/ttcn3_port_handler.h @@ -28,7 +28,7 @@ #define SRSUE_TTCN3_PORT_HANDLER_H #include "srslte/common/epoll_helper.h" -#include "srslte/common/log.h" +#include "srslte/common/standard_streams.h" #include "srslte/srslog/srslog.h" #include "ttcn3_common.h" #include diff --git a/srsue/test/ttcn3/hdr/ttcn3_ue.h b/srsue/test/ttcn3/hdr/ttcn3_ue.h index 0c13fc85d..c7fe4c88d 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_ue.h +++ b/srsue/test/ttcn3/hdr/ttcn3_ue.h @@ -23,6 +23,7 @@ #define SRSUE_TTCN3_UE_H #include "lte_ttcn3_phy.h" +#include "srslte/common/standard_streams.h" #include "srsue/hdr/stack/ue_stack_lte.h" #include diff --git a/srsue/test/ttcn3/hdr/ttcn3_ut_interface.h b/srsue/test/ttcn3/hdr/ttcn3_ut_interface.h index ec852b825..89950c7cc 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_ut_interface.h +++ b/srsue/test/ttcn3/hdr/ttcn3_ut_interface.h @@ -24,7 +24,6 @@ #include "rapidjson/document.h" #include "rapidjson/prettywriter.h" -#include "srslte/common/log.h" #include "srslte/common/netsource_handler.h" #include "ttcn3_interfaces.h" diff --git a/srsue/test/ttcn3/src/ttcn3_dut.cc b/srsue/test/ttcn3/src/ttcn3_dut.cc index 426a9f954..3bfa9f188 100644 --- a/srsue/test/ttcn3/src/ttcn3_dut.cc +++ b/srsue/test/ttcn3/src/ttcn3_dut.cc @@ -20,7 +20,6 @@ */ #include "srslte/build_info.h" -#include "srslte/common/logmap.h" #include "srslte/srslog/srslog.h" #include "srsue/hdr/ue.h" #include "swappable_sink.h" diff --git a/srsue/test/ttcn3/src/ttcn3_syssim.cc b/srsue/test/ttcn3/src/ttcn3_syssim.cc index e493f55ff..2842263d9 100644 --- a/srsue/test/ttcn3/src/ttcn3_syssim.cc +++ b/srsue/test/ttcn3/src/ttcn3_syssim.cc @@ -21,7 +21,6 @@ #include "srsue/test/ttcn3/hdr/ttcn3_syssim.h" #include "dut_utils.h" -#include "srslte/common/logger_srslog_wrapper.h" #include "srslte/mac/pdu_queue.h" #include "srslte/srslog/srslog.h" #include "srslte/test/ue_test_interfaces.h" @@ -57,7 +56,7 @@ ttcn3_syssim::ttcn3_syssim(ttcn3_ue* ue_) : drb(drb_logger), mac_msg_ul(20, ss_mac_logger), mac_msg_dl(20, ss_mac_logger), - pdus(logger, 128), + pdus(logger), ue(ue_), signal_handler(&running), timer_handler(create_tti_timer(), [&](uint64_t res) { new_tti_indication(res); }) diff --git a/srsue/test/upper/gw_test.cc b/srsue/test/upper/gw_test.cc index 6c58b5f73..904b8b5b6 100644 --- a/srsue/test/upper/gw_test.cc +++ b/srsue/test/upper/gw_test.cc @@ -19,7 +19,6 @@ * */ -#include "srslte/common/logger_srslog_wrapper.h" #include "srslte/common/test_common.h" #include "srslte/interfaces/ue_pdcp_interfaces.h" #include "srslte/srslog/srslog.h" diff --git a/srsue/test/upper/nas_test.cc b/srsue/test/upper/nas_test.cc index c93e545f5..21aead075 100644 --- a/srsue/test/upper/nas_test.cc +++ b/srsue/test/upper/nas_test.cc @@ -20,8 +20,6 @@ */ #include "srslte/common/bcd_helpers.h" -#include "srslte/common/logger_srslog_wrapper.h" -#include "srslte/common/logmap.h" #include "srslte/common/test_common.h" #include "srslte/interfaces/ue_pdcp_interfaces.h" #include "srslte/srslog/srslog.h" diff --git a/srsue/test/upper/rrc_meas_test.cc b/srsue/test/upper/rrc_meas_test.cc index baf72a605..7b73683a4 100644 --- a/srsue/test/upper/rrc_meas_test.cc +++ b/srsue/test/upper/rrc_meas_test.cc @@ -21,7 +21,6 @@ #include "srslte/asn1/rrc/meascfg.h" #include "srslte/common/buffer_pool.h" -#include "srslte/common/log_filter.h" #include "srslte/common/test_common.h" #include "srslte/test/ue_test_interfaces.h" #include "srslte/upper/pdcp.h" @@ -1226,7 +1225,6 @@ int meas_obj_inter_rat_nr_test() TESTASSERT(rrctest.send_meas_cfg(rrc_conn_recfg)); TESTASSERT(rrctest.phytest.meas_nof_freqs() == 0); - rrctest.add_neighbour_cell(2, 300, 2.0); rrctest.set_serving_cell(2, 300); rrctest.add_neighbour_cell_nr(500, 631680, -60.0); diff --git a/srsue/test/upper/rrc_reconfig_test.cc b/srsue/test/upper/rrc_reconfig_test.cc index 022121967..2b6740983 100644 --- a/srsue/test/upper/rrc_reconfig_test.cc +++ b/srsue/test/upper/rrc_reconfig_test.cc @@ -21,7 +21,6 @@ #include "srslte/asn1/liblte_mme.h" #include "srslte/asn1/rrc/dl_dcch_msg.h" -#include "srslte/common/log_filter.h" #include "srslte/srslog/srslog.h" #include #include diff --git a/srsue/test/upper/tft_test.cc b/srsue/test/upper/tft_test.cc index c607bdba4..1a17bc88b 100644 --- a/srsue/test/upper/tft_test.cc +++ b/srsue/test/upper/tft_test.cc @@ -20,13 +20,11 @@ */ #include "srslte/asn1/liblte_mme.h" -#include "srslte/common/log_filter.h" +#include "srslte/common/buffer_pool.h" +#include "srslte/common/int_helpers.h" +#include "srslte/srslte.h" #include "srsue/hdr/stack/upper/tft_packet_filter.h" #include -#include -#include -#include -#include #define TESTASSERT(cond) \ { \ diff --git a/srsue/test/upper/ue_rrc_nr_test.cc b/srsue/test/upper/ue_rrc_nr_test.cc index 1b83ad39e..211961b87 100644 --- a/srsue/test/upper/ue_rrc_nr_test.cc +++ b/srsue/test/upper/ue_rrc_nr_test.cc @@ -26,9 +26,9 @@ using namespace srsue; int rrc_nr_cap_request_test() { - srslte::log_ref rrc_log("RRC"); - rrc_log->set_level(srslte::LOG_LEVEL_DEBUG); - rrc_log->set_hex_limit(-1); + srslog::basic_logger& logger = srslog::fetch_basic_logger("RRC"); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(-1); srslte::task_scheduler task_sched{512, 100}; srslte::task_sched_handle task_sched_handle(&task_sched); rrc_nr rrc_nr(task_sched_handle); diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index 69ae83a71..9b329182d 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -377,11 +377,20 @@ enable = false # # metrics_csv_filename: File path to use for CSV metrics. # +# tracing_enable: Write source code tracing information to a file. +# +# tracing_filename: File path to use for tracing information. +# +# tracing_buffcapacity: Maximum capacity in bytes the tracing framework can store. +# # have_tti_time_stats: Calculate TTI execution statistics using system clock # ##################################################################### [general] -#metrics_csv_enable = false -#metrics_period_secs = 1 +#metrics_csv_enable = false +#metrics_period_secs = 1 #metrics_csv_filename = /tmp/ue_metrics.csv -#have_tti_time_stats = true +#have_tti_time_stats = true +#tracing_enable = true +#tracing_filename = /tmp/ue_tracing.log +#tracing_buffcapacity = 1000000