From 822e26b63f1c8196ea2df667604c13cf35bfbfd2 Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 5 Mar 2021 21:55:18 +0000 Subject: [PATCH 01/65] implemented circular buffer-based queue --- lib/include/srslte/adt/circular_buffer.h | 329 ++++++++++++++++++ lib/test/adt/CMakeLists.txt | 4 + lib/test/adt/circular_buffer_test.cc | 125 +++++++ lib/test/common/CMakeLists.txt | 2 +- .../{queue_test.cc => multiqueue_test.cc} | 0 5 files changed, 459 insertions(+), 1 deletion(-) create mode 100644 lib/include/srslte/adt/circular_buffer.h create mode 100644 lib/test/adt/circular_buffer_test.cc rename lib/test/common/{queue_test.cc => multiqueue_test.cc} (100%) diff --git a/lib/include/srslte/adt/circular_buffer.h b/lib/include/srslte/adt/circular_buffer.h new file mode 100644 index 000000000..8c455bf55 --- /dev/null +++ b/lib/include/srslte/adt/circular_buffer.h @@ -0,0 +1,329 @@ +/** + * + * \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(); +} + +template +class base_circular_buffer +{ + using T = typename Container::value_type; + +public: + using value_type = T; + using difference_type = ptrdiff_t; + + 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 + base_circular_buffer(Args&&... args) : buffer(std::forward(args)...) + {} + + void push(T&& t) + { + assert(not full()); + size_t wpos = (rpos + count) % max_size(); + buffer[wpos] = std::move(t); + count++; + } + 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()); } + +private: + Container buffer; + size_t rpos = 0; + size_t count = 0; +}; + +template +class base_block_queue +{ + using T = typename CircBuffer::value_type; + +public: + template + base_block_queue(Args&&... args) : circ_buffer(std::forward(args)...) + {} + ~base_block_queue() { stop(); } + + 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(const T& t) { return push_(t, true); } + srslte::error_type push(T&& t) { return push_(std::move(t), true); } + bool try_pop(T& obj) { return pop_(obj, false); } + T pop() + { + T obj{}; + pop_(obj, true); + return obj; + } + 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(); + } + size_t empty() const + { + std::lock_guard lock(mutex); + return circ_buffer.empty(); + } + 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; + } + +private: + bool active = true; + uint8_t nof_waiting = 0; + mutable std::mutex mutex; + std::condition_variable cvar_empty, cvar_full; + CircBuffer circ_buffer; + + 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; + } + } + 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); + } + } + circ_buffer.push(t); + lock.unlock(); + cvar_empty.notify_one(); + return {}; + } + + bool pop_(T& obj, bool block) + { + std::unique_lock lock(mutex); + if (not active) { + return false; + } + if (circ_buffer.empty()) { + if (not block) { + return false; + } + nof_waiting++; + while (circ_buffer.empty() and active) { + cvar_empty.wait(lock); + } + nof_waiting--; + if (not active) { + return false; + } + } + obj = std::move(circ_buffer.top()); + circ_buffer.pop(); + lock.unlock(); + cvar_full.notify_one(); + return true; + } +}; + +} // namespace detail + +template +class static_circular_buffer : public detail::base_circular_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::buffer.resize(size); + } +}; + +template +class static_block_queue : public detail::base_block_queue > +{}; + +template +class dyn_block_queue : public detail::base_block_queue > +{ + using base_t = detail::base_block_queue >; + +public: + dyn_block_queue() = default; + explicit dyn_block_queue(size_t size) : base_t(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/test/adt/CMakeLists.txt b/lib/test/adt/CMakeLists.txt index 357572300..0ccf53d06 100644 --- a/lib/test/adt/CMakeLists.txt +++ b/lib/test/adt/CMakeLists.txt @@ -41,3 +41,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/circular_buffer_test.cc b/lib/test/adt/circular_buffer_test.cc new file mode 100644 index 000000000..5464f1be5 --- /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_block_queue queue(100); + + std::thread t([&queue]() { + int count = 0; + while (true) { + int val = queue.pop(); + if (queue.is_stopped()) { + break; + } + assert(val == count); + count++; + } + }); + + for (int i = 0; i < 10000; ++i) { + queue.push(i); + } + + queue.stop(); + t.join(); + return SRSLTE_SUCCESS; +} + +int test_queue_block_api_2() +{ + std::thread t; + + { + dyn_block_queue queue(100); + + t = std::thread([&queue]() { + int count = 0; + while (queue.push(count++)) { + } + }); + + for (int i = 0; i < 10000; ++i) { + TESTASSERT(queue.pop() == 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/common/CMakeLists.txt b/lib/test/common/CMakeLists.txt index 3c43defb3..69a5ba96d 100644 --- a/lib/test/common/CMakeLists.txt +++ b/lib/test/common/CMakeLists.txt @@ -51,7 +51,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) 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 From 0ba93d274f4ff5824f8585d83694d6d437c9c842 Mon Sep 17 00:00:00 2001 From: Francisco Date: Sat, 6 Mar 2021 13:52:37 +0000 Subject: [PATCH 02/65] converted byte_buffer_queue to use new circular buffer-based queue to avoid mallocs --- lib/include/srslte/adt/circular_buffer.h | 84 ++++++++++++++++---- lib/include/srslte/upper/byte_buffer_queue.h | 51 ++++++------ lib/test/adt/circular_buffer_test.cc | 8 +- 3 files changed, 98 insertions(+), 45 deletions(-) diff --git a/lib/include/srslte/adt/circular_buffer.h b/lib/include/srslte/adt/circular_buffer.h index 8c455bf55..4b16f3898 100644 --- a/lib/include/srslte/adt/circular_buffer.h +++ b/lib/include/srslte/adt/circular_buffer.h @@ -128,20 +128,35 @@ public: 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; }; -template +struct noop_operator { + template + void operator()(const T&) + { + // noop + } +}; + +template class base_block_queue { using T = typename CircBuffer::value_type; public: template - base_block_queue(Args&&... args) : circ_buffer(std::forward(args)...) + base_block_queue(PushingFunc push_func_, PoppingFunc pop_func_, Args&&... args) : + circ_buffer(std::forward(args)...), push_func(push_func_), pop_func(pop_func_) {} ~base_block_queue() { stop(); } @@ -165,10 +180,10 @@ public: 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(const T& t) { return push_(t, true); } - srslte::error_type push(T&& t) { return push_(std::move(t), true); } + 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() + T pop_blocking() { T obj{}; pop_(obj, true); @@ -187,11 +202,16 @@ public: std::lock_guard lock(mutex); return circ_buffer.size(); } - size_t empty() const + 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); @@ -202,12 +222,24 @@ public: 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; + } -private: +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; bool push_(const T& t, bool block_mode) @@ -229,6 +261,7 @@ private: return false; } } + push_func(t); circ_buffer.push(t); lock.unlock(); cvar_empty.notify_one(); @@ -253,7 +286,8 @@ private: return std::move(t); } } - circ_buffer.push(t); + push_func(t); + circ_buffer.push(std::move(t)); lock.unlock(); cvar_empty.notify_one(); return {}; @@ -279,6 +313,7 @@ private: } } obj = std::move(circ_buffer.top()); + pop_func(obj); circ_buffer.pop(); lock.unlock(); cvar_full.notify_one(); @@ -305,22 +340,37 @@ public: { // Note: dynamic resizes not supported. assert(base_t::empty()); - base_t::buffer.resize(size); + base_t::set_size(size); } }; -template -class static_block_queue : public detail::base_block_queue > -{}; - -template -class dyn_block_queue : public detail::base_block_queue > +template +class static_block_queue + : public detail::base_block_queue, PushingCallback, PoppingCallback> { - using base_t = detail::base_block_queue >; + using base_t = detail::base_block_queue, PushingCallback, PoppingCallback>; + +public: + explicit static_block_queue(PushingCallback push_callback = {}, PoppingCallback pop_callback = {}) : + base_t(push_callback, pop_callback) + {} +}; + +template +class dyn_block_queue : public detail::base_block_queue, PushingCallback, PoppingCallback> +{ + using base_t = detail::base_block_queue, PushingCallback, PoppingCallback>; public: dyn_block_queue() = default; - explicit dyn_block_queue(size_t size) : base_t(size) {} + explicit dyn_block_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); } }; diff --git a/lib/include/srslte/upper/byte_buffer_queue.h b/lib/include/srslte/upper/byte_buffer_queue.h index 4013afe91..db8b050ed 100644 --- a/lib/include/srslte/upper/byte_buffer_queue.h +++ b/lib/include/srslte/upper/byte_buffer_queue.h @@ -21,51 +21,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) @@ -76,8 +68,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_block_queue queue; + uint32_t unread_bytes = 0; }; } // namespace srslte diff --git a/lib/test/adt/circular_buffer_test.cc b/lib/test/adt/circular_buffer_test.cc index 5464f1be5..cc7b4d3c7 100644 --- a/lib/test/adt/circular_buffer_test.cc +++ b/lib/test/adt/circular_buffer_test.cc @@ -71,7 +71,7 @@ int test_queue_block_api() std::thread t([&queue]() { int count = 0; while (true) { - int val = queue.pop(); + int val = queue.pop_blocking(); if (queue.is_stopped()) { break; } @@ -81,7 +81,7 @@ int test_queue_block_api() }); for (int i = 0; i < 10000; ++i) { - queue.push(i); + queue.push_blocking(i); } queue.stop(); @@ -98,12 +98,12 @@ int test_queue_block_api_2() t = std::thread([&queue]() { int count = 0; - while (queue.push(count++)) { + while (queue.push_blocking(count++)) { } }); for (int i = 0; i < 10000; ++i) { - TESTASSERT(queue.pop() == i); + TESTASSERT(queue.pop_blocking() == i); } // queue dtor called From 28ef5833a227ca06fd2a985a2f63740f8c97eeaf Mon Sep 17 00:00:00 2001 From: Francisco Date: Sat, 6 Mar 2021 14:33:03 +0000 Subject: [PATCH 03/65] fix compilation issue for centos7 --- lib/include/srslte/adt/circular_buffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/include/srslte/adt/circular_buffer.h b/lib/include/srslte/adt/circular_buffer.h index 4b16f3898..fa29655f4 100644 --- a/lib/include/srslte/adt/circular_buffer.h +++ b/lib/include/srslte/adt/circular_buffer.h @@ -46,7 +46,7 @@ class base_circular_buffer public: using value_type = T; - using difference_type = ptrdiff_t; + using difference_type = typename Container::difference_type; struct iterator { iterator(base_circular_buffer& parent_, size_t i) : parent(&parent_), idx(i) {} From d1236fd62f78b555cf61690d96a983fae1dbe09d Mon Sep 17 00:00:00 2001 From: Francisco Date: Mon, 8 Mar 2021 09:50:39 +0000 Subject: [PATCH 04/65] stack,optimization - replaced previous block_queue design for new bounded queue in several places in the enb --- lib/include/srslte/common/mac_pcap_base.h | 12 +++++----- lib/include/srslte/mac/pdu_queue.h | 7 +++--- lib/include/srslte/upper/rlc_common.h | 10 ++++----- lib/src/common/mac_pcap.cc | 2 +- lib/src/common/mac_pcap_base.cc | 8 +++---- lib/src/common/mac_pcap_net.cc | 2 +- lib/src/mac/pdu_queue.cc | 6 ++--- lib/test/upper/rlc_stress_test.cc | 3 ++- srsenb/hdr/stack/enb_stack_lte.h | 2 +- srsenb/hdr/stack/mac/mac.h | 4 ++-- srsenb/hdr/stack/rrc/rrc.h | 7 +++--- srsenb/src/stack/enb_stack_lte.cc | 9 +++++--- srsenb/src/stack/mac/mac.cc | 7 ++++-- srsenb/src/stack/rrc/rrc.cc | 27 ++++++++++++++++------- 14 files changed, 62 insertions(+), 44 deletions(-) diff --git a/lib/include/srslte/common/mac_pcap_base.h b/lib/include/srslte/common/mac_pcap_base.h index 67fd706b0..35eb3b748 100644 --- a/lib/include/srslte/common/mac_pcap_base.h +++ b/lib/include/srslte/common/mac_pcap_base.h @@ -13,7 +13,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" @@ -93,11 +93,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_block_queue queue; + uint16_t ue_id = 0; private: void pack_and_queue(uint8_t* payload, diff --git a/lib/include/srslte/mac/pdu_queue.h b/lib/include/srslte/mac/pdu_queue.h index 1e3ceca47..5b968f239 100644 --- a/lib/include/srslte/mac/pdu_queue.h +++ b/lib/include/srslte/mac/pdu_queue.h @@ -13,6 +13,7 @@ #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" @@ -34,7 +35,7 @@ public: }; pdu_queue(srslog::basic_logger& logger, uint32_t pool_size = DEFAULT_POOL_SIZE) : - pool(pool_size), callback(NULL), logger(logger) + pool(pool_size), callback(NULL), logger(logger), pdu_q(pool_size) {} void init(process_callback* callback); @@ -60,8 +61,8 @@ private: } pdu_t; - block_queue pdu_q; - buffer_pool pool; + dyn_block_queue pdu_q; + buffer_pool pool; process_callback* callback; srslog::basic_logger& logger; diff --git a/lib/include/srslte/upper/rlc_common.h b/lib/include/srslte/upper/rlc_common.h index 54eca35f3..1b33ac886 100644 --- a/lib/include/srslte/upper/rlc_common.h +++ b/lib/include/srslte/upper/rlc_common.h @@ -13,7 +13,7 @@ #ifndef SRSLTE_RLC_COMMON_H #define SRSLTE_RLC_COMMON_H -#include "srslte/common/block_queue.h" +#include "srslte/adt/circular_buffer.h" #include "srslte/common/logmap.h" #include "srslte/interfaces/rlc_interface_types.h" #include "srslte/upper/rlc_metrics.h" @@ -219,13 +219,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; @@ -303,8 +303,8 @@ private: uint32_t nof_bytes; } pdu_t; - block_queue rx_pdu_resume_queue; - block_queue tx_sdu_resume_queue{256}; + static_block_queue rx_pdu_resume_queue; + static_block_queue tx_sdu_resume_queue; }; } // namespace srslte diff --git a/lib/src/common/mac_pcap.cc b/lib/src/common/mac_pcap.cc index 650542ab9..01d96e8d6 100644 --- a/lib/src/common/mac_pcap.cc +++ b/lib/src/common/mac_pcap.cc @@ -58,7 +58,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 979cfaab8..2cd2483e4 100644 --- a/lib/src/common/mac_pcap_base.cc +++ b/lib/src/common/mac_pcap_base.cc @@ -37,7 +37,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); @@ -47,7 +47,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); } } @@ -84,7 +84,7 @@ 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)); + queue.push_blocking(std::move(pdu)); } else { logger.info("Dropping PDU in PCAP. No buffer available or not enough space (pdu_len=%d).", payload_len); } @@ -119,7 +119,7 @@ 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)); + queue.push_blocking(std::move(pdu)); } 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 3b098be7b..08352e25d 100644 --- a/lib/src/common/mac_pcap_net.cc +++ b/lib/src/common/mac_pcap_net.cc @@ -71,7 +71,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/mac/pdu_queue.cc b/lib/src/mac/pdu_queue.cc index 089852669..77b790cb2 100644 --- a/lib/src/mac/pdu_queue.cc +++ b/lib/src/mac/pdu_queue.cc @@ -58,7 +58,7 @@ 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); + pdu_q.push_blocking(pdu); } else { logger.warning("Error pushing pdu: ptr is empty"); } @@ -69,7 +69,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); } @@ -86,7 +86,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/test/upper/rlc_stress_test.cc b/lib/test/upper/rlc_stress_test.cc index 3e6d39765..4313f327e 100644 --- a/lib/test/upper/rlc_stress_test.cc +++ b/lib/test/upper/rlc_stress_test.cc @@ -10,6 +10,7 @@ * */ +#include "srslte/common/block_queue.h" #include "srslte/common/crash_handler.h" #include "srslte/common/log_filter.h" #include "srslte/common/rlc_pcap.h" @@ -459,7 +460,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/srsenb/hdr/stack/enb_stack_lte.h b/srsenb/hdr/stack/enb_stack_lte.h index 93c1a6650..a67a67eb2 100644 --- a/srsenb/hdr/stack/enb_stack_lte.h +++ b/srsenb/hdr/stack/enb_stack_lte.h @@ -162,7 +162,7 @@ private: // state bool started = false; - srslte::block_queue pending_stack_metrics; + srslte::dyn_block_queue pending_stack_metrics; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/mac/mac.h b/srsenb/hdr/stack/mac/mac.h index e6c2ee4a2..8782d7705 100644 --- a/srsenb/hdr/stack/mac/mac.h +++ b/srsenb/hdr/stack/mac/mac.h @@ -140,8 +140,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_block_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/rrc/rrc.h b/srsenb/hdr/stack/rrc/rrc.h index 75328750b..3cd429ef7 100644 --- a/srsenb/hdr/stack/rrc/rrc.h +++ b/srsenb/hdr/stack/rrc/rrc.h @@ -17,8 +17,8 @@ #include "rrc_cell_cfg.h" #include "rrc_metrics.h" #include "srsenb/hdr/stack/upper/common_enb.h" +#include "srslte/adt/circular_buffer.h" #include "srslte/adt/mem_pool.h" -#include "srslte/common/block_queue.h" #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" #include "srslte/common/logmap.h" @@ -28,7 +28,6 @@ #include "srslte/interfaces/enb_rrc_interfaces.h" #include "srslte/srslog/srslog.h" #include -#include namespace srsenb { @@ -190,8 +189,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_block_queue rx_pdu_queue; asn1::rrc::mcch_msg_s mcch; bool enable_mbms = false; diff --git a/srsenb/src/stack/enb_stack_lte.cc b/srsenb/src/stack/enb_stack_lte.cc index 237e2d1df..3acaa65af 100644 --- a/srsenb/src/stack/enb_stack_lte.cc +++ b/srsenb/src/stack/enb_stack_lte.cc @@ -36,7 +36,8 @@ enb_stack_lte::enb_stack_lte(srslte::logger* logger_, srslog::sink& log_sink) : 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(); @@ -218,12 +219,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/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index f7482950b..fc55aab1e 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -461,7 +461,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 @@ -562,7 +562,10 @@ 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)); + if (not ue_pool.try_push(std::move(ptr))) { + logger.info("Cannot preallocate more UEs as pool is full"); + return; + } } } diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index 938618813..37233748a 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -30,7 +30,8 @@ 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); @@ -89,7 +90,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(); } @@ -127,13 +128,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() @@ -144,7 +149,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) @@ -241,7 +248,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"); + } } /******************************************************************************* @@ -276,7 +285,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) @@ -963,7 +974,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)); From f0ed1e06a826c58650c14947c07a5fe042487c3a Mon Sep 17 00:00:00 2001 From: Francisco Date: Mon, 8 Mar 2021 11:37:12 +0000 Subject: [PATCH 05/65] documentation,bugfix - added documentation to new blocking queues, changed class names, and removed blocking pushes from the critical path --- lib/include/srslte/adt/circular_buffer.h | 90 +++++++++++++++++--- lib/include/srslte/common/mac_pcap_base.h | 10 +-- lib/include/srslte/mac/pdu_queue.h | 4 +- lib/include/srslte/upper/byte_buffer_queue.h | 4 +- lib/include/srslte/upper/rlc_common.h | 4 +- lib/src/common/mac_pcap_base.cc | 8 +- lib/test/adt/circular_buffer_test.cc | 4 +- srsenb/hdr/stack/enb_stack_lte.h | 2 +- srsenb/hdr/stack/mac/mac.h | 4 +- srsenb/hdr/stack/rrc/rrc.h | 4 +- 10 files changed, 102 insertions(+), 32 deletions(-) diff --git a/lib/include/srslte/adt/circular_buffer.h b/lib/include/srslte/adt/circular_buffer.h index fa29655f4..7c4076a15 100644 --- a/lib/include/srslte/adt/circular_buffer.h +++ b/lib/include/srslte/adt/circular_buffer.h @@ -39,6 +39,14 @@ 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 { @@ -85,9 +93,16 @@ public: }; template - base_circular_buffer(Args&&... args) : buffer(std::forward(args)...) + 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()); @@ -95,6 +110,13 @@ public: 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()); @@ -148,17 +170,26 @@ struct noop_operator { } }; +/** + * 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_block_queue +class base_blocking_queue { using T = typename CircBuffer::value_type; public: template - base_block_queue(PushingFunc push_func_, PoppingFunc pop_func_, Args&&... args) : + base_blocking_queue(PushingFunc push_func_, PoppingFunc pop_func_, Args&&... args) : circ_buffer(std::forward(args)...), push_func(push_func_), pop_func(pop_func_) {} - ~base_block_queue() { stop(); } + ~base_blocking_queue() { stop(); } void stop() { @@ -323,10 +354,24 @@ protected: } // 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 > { @@ -344,31 +389,52 @@ public: } }; +/** + * 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_block_queue - : public detail::base_block_queue, PushingCallback, PoppingCallback> +class static_blocking_queue + : public detail::base_blocking_queue, PushingCallback, PoppingCallback> { - using base_t = detail::base_block_queue, PushingCallback, PoppingCallback>; + using base_t = detail::base_blocking_queue, PushingCallback, PoppingCallback>; public: - explicit static_block_queue(PushingCallback push_callback = {}, PoppingCallback pop_callback = {}) : + 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_block_queue : public detail::base_block_queue, PushingCallback, PoppingCallback> +class dyn_blocking_queue : public detail::base_blocking_queue, PushingCallback, PoppingCallback> { - using base_t = detail::base_block_queue, PushingCallback, PoppingCallback>; + using base_t = detail::base_blocking_queue, PushingCallback, PoppingCallback>; public: - dyn_block_queue() = default; - explicit dyn_block_queue(size_t size, PushingCallback push_callback = {}, PoppingCallback pop_callback = {}) : + 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); } diff --git a/lib/include/srslte/common/mac_pcap_base.h b/lib/include/srslte/common/mac_pcap_base.h index 35eb3b748..fb321d7df 100644 --- a/lib/include/srslte/common/mac_pcap_base.h +++ b/lib/include/srslte/common/mac_pcap_base.h @@ -93,11 +93,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; - static_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/mac/pdu_queue.h b/lib/include/srslte/mac/pdu_queue.h index 5b968f239..9a26ae1e5 100644 --- a/lib/include/srslte/mac/pdu_queue.h +++ b/lib/include/srslte/mac/pdu_queue.h @@ -61,8 +61,8 @@ private: } pdu_t; - dyn_block_queue pdu_q; - buffer_pool pool; + dyn_blocking_queue pdu_q; + buffer_pool pool; process_callback* callback; srslog::basic_logger& logger; diff --git a/lib/include/srslte/upper/byte_buffer_queue.h b/lib/include/srslte/upper/byte_buffer_queue.h index db8b050ed..f061f2c31 100644 --- a/lib/include/srslte/upper/byte_buffer_queue.h +++ b/lib/include/srslte/upper/byte_buffer_queue.h @@ -79,8 +79,8 @@ private: uint32_t* unread_bytes; }; - dyn_block_queue queue; - uint32_t unread_bytes = 0; + dyn_blocking_queue queue; + uint32_t unread_bytes = 0; }; } // namespace srslte diff --git a/lib/include/srslte/upper/rlc_common.h b/lib/include/srslte/upper/rlc_common.h index 1b33ac886..ab32faa53 100644 --- a/lib/include/srslte/upper/rlc_common.h +++ b/lib/include/srslte/upper/rlc_common.h @@ -303,8 +303,8 @@ private: uint32_t nof_bytes; } pdu_t; - static_block_queue rx_pdu_resume_queue; - static_block_queue tx_sdu_resume_queue; + static_blocking_queue rx_pdu_resume_queue; + static_blocking_queue tx_sdu_resume_queue; }; } // namespace srslte diff --git a/lib/src/common/mac_pcap_base.cc b/lib/src/common/mac_pcap_base.cc index 2cd2483e4..f89705e8d 100644 --- a/lib/src/common/mac_pcap_base.cc +++ b/lib/src/common/mac_pcap_base.cc @@ -84,7 +84,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_blocking(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); } @@ -119,7 +121,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_blocking(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/test/adt/circular_buffer_test.cc b/lib/test/adt/circular_buffer_test.cc index cc7b4d3c7..a2a7e1387 100644 --- a/lib/test/adt/circular_buffer_test.cc +++ b/lib/test/adt/circular_buffer_test.cc @@ -66,7 +66,7 @@ int test_static_circular_buffer() int test_queue_block_api() { - dyn_block_queue queue(100); + dyn_blocking_queue queue(100); std::thread t([&queue]() { int count = 0; @@ -94,7 +94,7 @@ int test_queue_block_api_2() std::thread t; { - dyn_block_queue queue(100); + dyn_blocking_queue queue(100); t = std::thread([&queue]() { int count = 0; diff --git a/srsenb/hdr/stack/enb_stack_lte.h b/srsenb/hdr/stack/enb_stack_lte.h index a67a67eb2..f0ca26a6b 100644 --- a/srsenb/hdr/stack/enb_stack_lte.h +++ b/srsenb/hdr/stack/enb_stack_lte.h @@ -162,7 +162,7 @@ private: // state bool started = false; - srslte::dyn_block_queue pending_stack_metrics; + srslte::dyn_blocking_queue pending_stack_metrics; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/mac/mac.h b/srsenb/hdr/stack/mac/mac.h index 8782d7705..82d9060c7 100644 --- a/srsenb/hdr/stack/mac/mac.h +++ b/srsenb/hdr/stack/mac/mac.h @@ -140,8 +140,8 @@ private: std::map > ue_db, ues_to_rem; uint16_t last_rnti = 70; - srslte::static_block_queue, 32> 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/rrc/rrc.h b/srsenb/hdr/stack/rrc/rrc.h index 3cd429ef7..b9c93c39c 100644 --- a/srsenb/hdr/stack/rrc/rrc.h +++ b/srsenb/hdr/stack/rrc/rrc.h @@ -189,8 +189,8 @@ private: const static uint32_t LCID_ACT_USER = 0xffff0004; const static uint32_t LCID_RTX_USER = 0xffff0005; - bool running = false; - srslte::dyn_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; From 0b6293c6769873bbc2e9be3039a6fa7c8b878e3b Mon Sep 17 00:00:00 2001 From: Francisco Date: Mon, 8 Mar 2021 12:35:47 +0000 Subject: [PATCH 06/65] adt lib additions - add the ability to perform timedwait for popping from a blocking queue --- lib/include/srslte/adt/circular_buffer.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/include/srslte/adt/circular_buffer.h b/lib/include/srslte/adt/circular_buffer.h index 7c4076a15..e6df1cd47 100644 --- a/lib/include/srslte/adt/circular_buffer.h +++ b/lib/include/srslte/adt/circular_buffer.h @@ -189,7 +189,6 @@ public: base_blocking_queue(PushingFunc push_func_, PoppingFunc pop_func_, Args&&... args) : circ_buffer(std::forward(args)...), push_func(push_func_), pop_func(pop_func_) {} - ~base_blocking_queue() { stop(); } void stop() { @@ -220,6 +219,7 @@ public: pop_(obj, true); return obj; } + bool pop_wait_for(T& obj, const std::chrono::microseconds& duration) { return pop_(obj, true, &duration); } void clear() { std::lock_guard lock(mutex); @@ -273,6 +273,8 @@ protected: PoppingFunc pop_func; CircBuffer circ_buffer; + ~base_blocking_queue() { stop(); } + bool push_(const T& t, bool block_mode) { std::unique_lock lock(mutex); @@ -324,7 +326,7 @@ protected: return {}; } - bool pop_(T& obj, bool block) + bool pop_(T& obj, bool block, const std::chrono::microseconds* duration = nullptr) { std::unique_lock lock(mutex); if (not active) { @@ -335,11 +337,14 @@ protected: return false; } nof_waiting++; - while (circ_buffer.empty() and active) { - cvar_empty.wait(lock); + if (duration == nullptr) { + cvar_empty.wait(lock, [this]() { return not circ_buffer.empty() or not active; }); + } else { + cvar_empty.wait_for(lock, *duration, [this]() { return not circ_buffer.empty() or not active; }); } nof_waiting--; - if (not active) { + if (circ_buffer.empty()) { + // either queue got deactivated or there was a timeout return false; } } From ace87645681873c490fc3b20e0755e8404517da7 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 8 Mar 2021 13:59:02 +0100 Subject: [PATCH 07/65] rlc_am_lte: add missing unlock when building status PDU fails --- lib/src/upper/rlc_am_lte.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/upper/rlc_am_lte.cc b/lib/src/upper/rlc_am_lte.cc index df19a4873..2a2e6a7fd 100644 --- a/lib/src/upper/rlc_am_lte.cc +++ b/lib/src/upper/rlc_am_lte.cc @@ -1823,6 +1823,7 @@ int rlc_am_lte::rlc_am_lte_rx::get_status_pdu(rlc_status_pdu_t* status, const ui rlc_am_packed_length(status), max_pdu_size, status->N_nack); + pthread_mutex_unlock(&mutex); return 0; } break; From 7b588eafecbd546b531108d33a8896c9d9a4c43d Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 2 Mar 2021 10:57:25 +0100 Subject: [PATCH 08/65] Minor aesthet change --- lib/src/phy/phch/pusch_nr.c | 4 ++-- lib/src/phy/phch/sch_nr.c | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/src/phy/phch/pusch_nr.c b/lib/src/phy/phch/pusch_nr.c index a463b7148..a88056b26 100644 --- a/lib/src/phy/phch/pusch_nr.c +++ b/lib/src/phy/phch/pusch_nr.c @@ -440,7 +440,7 @@ static inline int pusch_nr_encode_codeword(srslte_pusch_nr_t* q, // 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"); + ERROR("Error in SCH encoding"); return SRSLTE_ERROR; } @@ -585,7 +585,7 @@ static inline int pusch_nr_decode_codeword(srslte_pusch_nr_t* q, // 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"); + ERROR("Error in SCH decoding"); return SRSLTE_ERROR; } diff --git a/lib/src/phy/phch/sch_nr.c b/lib/src/phy/phch/sch_nr.c index 3caa632d8..cc3d8cb97 100644 --- a/lib/src/phy/phch/sch_nr.c +++ b/lib/src/phy/phch/sch_nr.c @@ -216,21 +216,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); From f4e9d00ea8440eb973f26959029a8bc034c758f4 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 2 Mar 2021 19:43:49 +0100 Subject: [PATCH 09/65] Initial HARQ-ACK multiplex in PUSCH --- lib/include/srslte/phy/phch/phch_cfg_nr.h | 9 +- lib/include/srslte/phy/phch/pucch_nr.h | 22 ++- lib/include/srslte/phy/phch/pusch_nr.h | 32 ++-- lib/include/srslte/phy/phch/sch_nr.h | 47 +++--- lib/include/srslte/phy/phch/uci_cfg_nr.h | 14 +- lib/include/srslte/phy/phch/uci_nr.h | 33 +++- lib/include/srslte/phy/ue/ue_ul_nr.h | 8 +- lib/src/phy/phch/pucch_nr.c | 73 +++++---- lib/src/phy/phch/pusch_nr.c | 46 ++++-- lib/src/phy/phch/sch_nr.c | 63 ++++---- lib/src/phy/phch/test/pucch_nr_test.c | 26 ++-- lib/src/phy/phch/test/pusch_nr_test.c | 96 +++++++----- lib/src/phy/phch/uci_nr.c | 177 ++++++++++++++++++---- lib/src/phy/ue/ue_ul_nr.c | 22 +-- srsue/src/phy/nr/cc_worker.cc | 5 +- 15 files changed, 449 insertions(+), 224 deletions(-) diff --git a/lib/include/srslte/phy/phch/phch_cfg_nr.h b/lib/include/srslte/phy/phch/phch_cfg_nr.h index 27011170b..79a74069f 100644 --- a/lib/include/srslte/phy/phch/phch_cfg_nr.h +++ b/lib/include/srslte/phy/phch/phch_cfg_nr.h @@ -23,6 +23,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 @@ -201,8 +202,12 @@ 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; } 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 2c8584386..cdaf5ed57 100644 --- a/lib/include/srslte/phy/phch/pucch_nr.h +++ b/lib/include/srslte/phy/phch/pucch_nr.h @@ -42,6 +42,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; @@ -55,10 +56,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 @@ -104,7 +114,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 @@ -113,7 +122,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, @@ -123,7 +131,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 @@ -133,7 +140,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, @@ -156,7 +162,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 @@ -166,7 +171,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, @@ -177,7 +181,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 @@ -188,7 +191,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, @@ -200,7 +202,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 @@ -210,7 +211,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, @@ -221,7 +221,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 @@ -232,7 +231,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 00ed9299e..74d32b586 100644 --- a/lib/include/srslte/phy/phch/pusch_nr.h +++ b/lib/include/srslte/phy/phch/pusch_nr.h @@ -20,6 +20,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" /** @@ -27,6 +28,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; @@ -40,6 +42,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 @@ -47,15 +50,26 @@ typedef struct SRSLTE_API { srslte_evm_buffer_t* evm_buffer; bool meas_time_en; uint32_t meas_time_us; + uint8_t* uci_ack; + uint8_t* uci_csi; } 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); @@ -66,11 +80,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/sch_nr.h b/lib/include/srslte/phy/phch/sch_nr.h index ce3cebbf3..1772ea9ad 100644 --- a/lib/include/srslte/phy/phch/sch_nr.h +++ b/lib/include/srslte/phy/phch/sch_nr.h @@ -69,27 +69,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 @@ -110,10 +107,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_cfg(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 34c1729a2..1408e0897 100644 --- a/lib/include/srslte/phy/phch/uci_cfg_nr.h +++ b/lib/include/srslte/phy/phch/uci_cfg_nr.h @@ -29,23 +29,12 @@ */ #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 - */ -#define SRSLTE_UCI_NR_MAX_SR_BITS 10 - /** * @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_CSI1_BITS 10 -/** - * @brief Maximum number of Channel State Information part 2 (CSI2) bits that can be carried in Uplink Control - * Information (UCI) message - */ -#define SRSLTE_UCI_NR_MAX_CSI2_BITS 10 - /** * @brief Uplink Control Information (UCI) message configuration */ @@ -57,7 +46,8 @@ typedef struct SRSLTE_API { uint32_t nof_csi; ///< Number of CSI reports /// PUSCH only parameters - srslte_mod_t modulation; ///< Modulation + bool without_ul_sch; ///< Set to true if no UL-SCH data is scheduled + bool has_csi_part2; ///< Set to true if the CSI reports have part 2 /// PUCCH only parameters uint16_t rnti; ///< RNTI diff --git a/lib/include/srslte/phy/phch/uci_nr.h b/lib/include/srslte/phy/phch/uci_nr.h index 114c95aeb..c98b7a82b 100644 --- a/lib/include/srslte/phy/phch/uci_nr.h +++ b/lib/include/srslte/phy/phch/uci_nr.h @@ -13,13 +13,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 @@ -33,6 +34,7 @@ typedef struct { } srslte_uci_nr_args_t; typedef struct { + srslte_carrier_nr_t carrier; srslte_polar_rm_t rm_tx; srslte_polar_rm_t rm_rx; srslte_polar_encoder_t encoder; @@ -70,6 +72,14 @@ SRSLTE_API uint32_t srslte_uci_nr_crc_len(uint32_t A); */ SRSLTE_API int srslte_uci_nr_init(srslte_uci_nr_t* q, const srslte_uci_nr_args_t* args); +/** + * @brief Sets NR carrier + * @param[in,out] q NR-UCI object + * @param carrier Provides carrier configuration + * @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise + */ +SRSLTE_API int srslte_uci_nr_set_carrier(srslte_uci_nr_t* q, const srslte_carrier_nr_t* carrier); + /** * @brief Deallocates NR-UCI encoder/decoder object * @param[in,out] q NR-UCI object @@ -114,6 +124,27 @@ SRSLTE_API int srslte_uci_nr_decode_pucch(srslte_uci_nr_t* q, int8_t* llr, srslte_uci_value_nr_t* value); +/** + * @brief Calculates the total number of encoded bits for HARQ-ACK + * @param[in,out] q NR-UCI object + * @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_E_uci_ack(srslte_uci_nr_t* q, const srslte_sch_cfg_nr_t* cfg); + +/** + * @brief Encodes HARQ-ACK bits for PUSCH transmission + * @param[in,out] q NR-UCI object + * @param[in] cfg PUSCH transmission 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_sch_cfg_nr_t* cfg, + const srslte_uci_value_nr_t* value, + uint8_t* o_ack); + /** * @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 25c57d987..d87f35556 100644 --- a/lib/include/srslte/phy/ue/ue_ul_nr.h +++ b/lib/include/srslte/phy/ue/ue_ul_nr.h @@ -54,10 +54,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/src/phy/phch/pucch_nr.c b/lib/src/phy/phch/pucch_nr.c index 6b2a2e57b..92e4b9d51 100644 --- a/lib/src/phy/phch/pucch_nr.c +++ b/lib/src/phy/phch/pucch_nr.c @@ -174,6 +174,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) { @@ -201,14 +212,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; } @@ -219,7 +229,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; } @@ -228,8 +238,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; } @@ -241,7 +251,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); @@ -251,7 +261,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, @@ -259,7 +268,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; } @@ -270,7 +279,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; } @@ -281,8 +290,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; } @@ -295,7 +304,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; @@ -360,7 +369,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, @@ -368,7 +376,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; } @@ -393,7 +401,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; } @@ -404,11 +412,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; } @@ -439,7 +447,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, @@ -450,6 +457,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; @@ -466,7 +478,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; } @@ -477,8 +489,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]; @@ -486,8 +498,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; } @@ -630,7 +642,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, @@ -639,8 +650,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; } @@ -653,7 +664,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"); @@ -667,7 +678,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, @@ -677,8 +687,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; } @@ -686,7 +696,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 a88056b26..858f3124c 100644 --- a/lib/src/phy/phch/pusch_nr.c +++ b/lib/src/phy/phch/pusch_nr.c @@ -28,6 +28,11 @@ 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; + } + return SRSLTE_SUCCESS; } @@ -59,7 +64,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; } @@ -415,11 +420,20 @@ 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) +// int pusch_nr_mux_uci(srslte_pusch_nr_t* q) { +// uint8_t *g_ul_sch; // coded bits for UL-SCH +// uint8_t *g_ack; // coded bits for HARQ-ACK +// uint8_t *g_csi_p1; // coded bits for CSI part 1 +// uint8_t *g_csi_p2; // coded bits for CSI part 2 +// +//} + +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) { @@ -464,11 +478,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) { @@ -486,12 +500,20 @@ int srslte_pusch_nr_encode(srslte_pusch_nr_t* q, return SRSLTE_ERROR; } + // Encode HARQ-ACK bits + int E_uci_ack = srslte_uci_nr_encode_pusch_ack(&q->uci, cfg, &data[0].uci, q->uci_ack); + if (E_uci_ack < SRSLTE_SUCCESS) { + ERROR("Error encoding HARQ-ACK bits"); + 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; } diff --git a/lib/src/phy/phch/sch_nr.c b/lib/src/phy/phch/sch_nr.c index cc3d8cb97..794cc855f 100644 --- a/lib/src/phy/phch/sch_nr.c +++ b/lib/src/phy/phch/sch_nr.c @@ -65,10 +65,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_cfg(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; @@ -111,10 +111,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)); @@ -128,22 +128,13 @@ 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); @@ -380,19 +371,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_cfg(&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; } @@ -406,16 +401,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); @@ -470,11 +465,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); } } @@ -518,25 +513,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_cfg(&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; } @@ -586,7 +585,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; @@ -650,7 +649,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/pucch_nr_test.c b/lib/src/phy/phch/test/pucch_nr_test.c index c3d026f10..bbabd4712 100644 --- a/lib/src/phy/phch/test/pucch_nr_test.c +++ b/lib/src/phy/phch/test/pucch_nr_test.c @@ -53,15 +53,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); @@ -115,8 +114,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) == @@ -137,7 +136,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 @@ -202,8 +201,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) == @@ -226,10 +224,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); @@ -311,6 +308,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 8edbed4dc..581b3752f 100644 --- a/lib/src/phy/phch/test/pusch_nr_test.c +++ b/lib/src/phy/phch/test/pusch_nr_test.c @@ -27,11 +27,13 @@ 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 srslte_sch_grant_nr_t pusch_grant = {}; +static uint16_t rnti = 0x1234; +static uint32_t nof_ack_bits = 0; +static uint32_t nof_csi_bits = 0; void usage(char* prog) { @@ -41,13 +43,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); @@ -61,6 +65,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; @@ -75,16 +85,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; @@ -126,14 +135,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 = {}; @@ -198,18 +205,39 @@ int main(int argc, char** argv) 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); + data_tx[tb].payload[i] = (uint8_t)srslte_random_uniform_int_dist(rand_gen, 0, UINT8_MAX); } pusch_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[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; + for (uint32_t i = 0; i < nof_csi_bits; i++) { + csi_report[i] = (uint8_t)srslte_random_uniform_int_dist(rand_gen, 0, 1); + } + } + if (srslte_pusch_nr_encode(&pusch_tx, &pusch_cfg, &pusch_grant, data_tx, sf_symbols) < SRSLTE_SUCCESS) { ERROR("Error encoding"); goto clean_exit; @@ -225,13 +253,13 @@ int main(int argc, char** argv) } chest.nof_re = pusch_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_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; } @@ -256,21 +284,21 @@ int main(int argc, char** argv) goto clean_exit; } - if (!pusch_res[0].crc) { + if (!data_rx[0].crc) { ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pusch_grant.tb[0].tbs); goto clean_exit; } - if (memcmp(data_tx[0], data_rx[0], pusch_grant.tb[0].tbs / 8) != 0) { + if (memcmp(data_tx[0].payload, data_rx[0].payload, 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); 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_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_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); + printf("n_prb=%d; mcs=%d; TBS=%d; EVM=%f; PASSED!\n", n_prb, mcs, pusch_grant.tb[0].tbs, data_rx[0].evm); } } @@ -282,11 +310,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 3aac61c30..1a5c778b7 100644 --- a/lib/src/phy/phch/uci_nr.c +++ b/lib/src/phy/phch/uci_nr.c @@ -11,13 +11,14 @@ */ #include "srslte/phy/phch/uci_nr.h" +#include "srslte/phy/ch_estimation/dmrs_sch.h" #include "srslte/phy/fec/block/block.h" #include "srslte/phy/fec/polar/polar_chanalloc.h" #include "srslte/phy/phch/csi.h" +#include "srslte/phy/phch/sch_nr.h" #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__) @@ -118,6 +119,17 @@ int srslte_uci_nr_init(srslte_uci_nr_t* q, const srslte_uci_nr_args_t* args) return SRSLTE_SUCCESS; } +int srslte_uci_nr_set_carrier(srslte_uci_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_uci_nr_free(srslte_uci_nr_t* q) { if (q == NULL) { @@ -207,7 +219,7 @@ 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); @@ -226,7 +238,7 @@ 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); @@ -246,12 +258,13 @@ static int uci_nr_unpacking(const srslte_uci_cfg_nr_t* cfg, uint8_t* sequence, s return SRSLTE_ERROR; } -static int uci_nr_encode_1bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, uint8_t* o, uint32_t E) +static int +uci_nr_encode_1bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, srslte_mod_t modulation, 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; - switch (cfg->modulation) { + switch (modulation) { case SRSLTE_MOD_BPSK: while (i < E) { o[i++] = c0; @@ -304,14 +317,15 @@ static int uci_nr_encode_1bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg return E; } -static int uci_nr_encode_2bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, uint8_t* o, uint32_t E) +static int +uci_nr_encode_2bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, srslte_mod_t modulation, 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; - switch (cfg->modulation) { + switch (modulation) { case SRSLTE_MOD_BPSK: case SRSLTE_MOD_QPSK: while (i < E) { @@ -629,31 +643,21 @@ 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, + srslte_mod_t mod, + 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); + return uci_nr_encode_1bit(q, uci_cfg, mod, o, E_uci); } // 5.3.3.2 Encoding of 2-bit information if (A == 2) { - return uci_nr_encode_2bit(q, uci_cfg, o, E_uci); + return uci_nr_encode_2bit(q, uci_cfg, mod, o, E_uci); } // 5.3.3.3 Encoding of other small block lengths @@ -704,7 +708,7 @@ static int uci_nr_decode(srslte_uci_nr_t* q, } // Unpack bits - if (uci_nr_unpacking(uci_cfg, q->bit_sequence, uci_value) < SRSLTE_SUCCESS) { + if (uci_nr_unpack_pucch(uci_cfg, q->bit_sequence, uci_value) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } @@ -770,7 +774,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, SRSLTE_MOD_NITEMS, A, o, E_uci); } int srslte_uci_nr_decode_pucch(srslte_uci_nr_t* q, @@ -823,3 +834,115 @@ uint32_t srslte_uci_nr_info(const srslte_uci_data_nr_t* uci_data, char* str, uin return len; } + +static int uci_nr_Q_ack_prime(srslte_uci_nr_t* q, const srslte_sch_cfg_nr_t* sch_cfg, uint32_t A) +{ + // Get UL-SCH TB information + srslte_sch_nr_tb_info_t tb_info = {}; + if (srslte_sch_nr_fill_cfg(&q->carrier, &sch_cfg->sch_cfg, &sch_cfg->grant.tb[0], &tb_info) < SRSLTE_SUCCESS) { + return SRSLTE_ERROR; + } + + // 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(&sch_cfg->dmrs, &sch_cfg->grant, dmrs_l); + if (n < SRSLTE_SUCCESS) { + return SRSLTE_ERROR; + } + nof_dmrs_l = (uint32_t)n; + + uint32_t O_ack = A; // Number of HARQ-ACK bits + uint32_t L_ack = srslte_uci_nr_crc_len(A); // Number of CRC bits + float beta_pusch_offset = sch_cfg->beta_harq_ack_offset; // Beta offset given by higher layers + uint32_t C_ulsch = tb_info.C; // number of code blocks for UL-SCH of the PUSCH + float alpha = sch_cfg->scaling; // Higher layer parameter scaling + float R = (float)sch_cfg->grant.tb[0].R; // code rate of the PUSCH + float Qm = srslte_mod_bits_x_symbol(sch_cfg->grant.tb[0].mod); // modulation order of the PUSCH + + uint32_t K_sum = 0; + for (uint32_t i = 0; i < SRSLTE_MIN(C_ulsch, SRSLTE_SCH_NR_MAX_NOF_CB_LDPC); i++) { + K_sum += tb_info.mask[i] ? 0 : tb_info.Kr; + } + + uint32_t dmrs_l_idx = 0; + uint32_t M_uci_sum = 0; + uint32_t M_uci_l0_sum = 0; + for (uint32_t l = sch_cfg->grant.S; l < sch_cfg->grant.S + sch_cfg->grant.L; l++) { + uint32_t M_ptrs_sc = 0; // Not implemented yet + uint32_t M_pusch_sc = sch_cfg->grant.nof_prb * SRSLTE_NRE; + uint32_t M_uci_sc = M_pusch_sc - M_ptrs_sc; + + // If the OFDM symbol contains DMRS, no UCI is mapped + if (l == dmrs_l[dmrs_l_idx] && dmrs_l_idx < nof_dmrs_l) { + M_uci_sc = 0; + dmrs_l_idx++; + } + + // Add subcarriers that can contain UCI RE + M_uci_sum += M_uci_sc; + + // Start adding after the first DMRS symbol + if (dmrs_l_idx > 0) { + M_uci_l0_sum += M_uci_sc; + } + } + + if (sch_cfg->uci.without_ul_sch) { + return (int)SRSLTE_MIN(ceilf(((O_ack + L_ack) * beta_pusch_offset) / (Qm * R)), alpha * M_uci_l0_sum); + } + return (int)SRSLTE_MIN(ceilf(((O_ack + L_ack) * beta_pusch_offset * M_uci_sum) / (float)K_sum), alpha * M_uci_l0_sum); +} + +int srslte_uci_nr_pusch_E_uci_ack(srslte_uci_nr_t* q, const srslte_sch_cfg_nr_t* cfg) +{ + int A = cfg->uci.o_ack; + + // Check inputs + if (q == NULL || cfg == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + if (cfg->uci.without_ul_sch && cfg->uci.nof_csi > 1 && !cfg->uci.has_csi_part2 && cfg->uci.o_ack < 2) { + A = 2; + } + + int Q_ack_prime = uci_nr_Q_ack_prime(q, cfg, A); + if (Q_ack_prime < SRSLTE_SUCCESS) { + return Q_ack_prime; + } + + return (int)(Q_ack_prime * cfg->grant.nof_layers * srslte_mod_bits_x_symbol(cfg->grant.tb[0].mod)); +} + +int srslte_uci_nr_encode_pusch_ack(srslte_uci_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_uci_value_nr_t* value, + uint8_t* o) +{ + int A = cfg->uci.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 + if (cfg->uci.without_ul_sch && cfg->uci.nof_csi > 1 && !cfg->uci.has_csi_part2 && cfg->uci.o_ack < 2) { + A = 2; + q->bit_sequence[0] = (cfg->uci.o_ack == 0) ? 0 : value->ack[0]; + q->bit_sequence[1] = 0; + } else { + srslte_vec_u8_copy(q->bit_sequence, value->ack, cfg->uci.o_ack); + } + + // Compute total of encoded bits according to 6.3.2.4 Rate matching + int E_uci = srslte_uci_nr_pusch_E_uci_ack(q, cfg); + if (E_uci < SRSLTE_SUCCESS) { + ERROR("Error calculating number of encoded bits"); + return SRSLTE_ERROR; + } + + return uci_nr_encode(q, &cfg->uci, cfg->grant.tb[0].mod, A, o, E_uci); +} \ No newline at end of file diff --git a/lib/src/phy/ue/ue_ul_nr.c b/lib/src/phy/ue/ue_ul_nr.c index b44252551..43496a887 100644 --- a/lib/src/phy/ue/ue_ul_nr.c +++ b/lib/src/phy/ue/ue_ul_nr.c @@ -82,6 +82,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; @@ -90,16 +95,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; } @@ -158,7 +160,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, @@ -192,7 +194,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/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index 4f5ba9236..3cd314902 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -288,8 +288,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; } From 9dffad87f215534524d4cb1d3b72dacea7949573 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 3 Mar 2021 19:54:55 +0100 Subject: [PATCH 10/65] Initial UCI bits multiplexing in PUSCH --- lib/include/srslte/phy/phch/csi.h | 8 + lib/include/srslte/phy/phch/csi_cfg.h | 1 + lib/include/srslte/phy/phch/phch_cfg_nr.h | 1 + lib/include/srslte/phy/phch/pusch_nr.h | 13 +- lib/include/srslte/phy/phch/ra_ul_nr.h | 2 +- lib/include/srslte/phy/phch/sch_nr.h | 8 +- lib/include/srslte/phy/phch/uci_cfg_nr.h | 49 ++- lib/include/srslte/phy/phch/uci_nr.h | 18 +- lib/src/phy/phch/csi.c | 14 + lib/src/phy/phch/pdsch_nr.c | 2 +- lib/src/phy/phch/pucch_nr.c | 2 +- lib/src/phy/phch/pusch_nr.c | 425 +++++++++++++++++++++- lib/src/phy/phch/ra_ul_nr.c | 18 +- lib/src/phy/phch/sch_nr.c | 12 +- lib/src/phy/phch/test/pusch_nr_test.c | 72 ++-- lib/src/phy/phch/uci_nr.c | 145 +++----- lib/src/phy/ue/ue_dl_nr.c | 4 +- srsue/hdr/phy/nr/state.h | 14 +- 18 files changed, 617 insertions(+), 191 deletions(-) diff --git a/lib/include/srslte/phy/phch/csi.h b/lib/include/srslte/phy/phch/csi.h index 240097a8c..3f971eec7 100644 --- a/lib/include/srslte/phy/phch/csi.h +++ b/lib/include/srslte/phy/phch/csi.h @@ -37,6 +37,14 @@ SRSLTE_API int srslte_csi_generate_reports(const srslte_csi_hl_cfg_t* cfg, */ SRSLTE_API int srslte_csi_nof_bits(const srslte_csi_report_cfg_t* report_list, uint32_t nof_reports); +/** + * @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 transmission * @param report_list Provides the CSI report list diff --git a/lib/include/srslte/phy/phch/csi_cfg.h b/lib/include/srslte/phy/phch/csi_cfg.h index 48a33699b..f6c578525 100644 --- a/lib/include/srslte/phy/phch/csi_cfg.h +++ b/lib/include/srslte/phy/phch/csi_cfg.h @@ -130,6 +130,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 79a74069f..f694eb80f 100644 --- a/lib/include/srslte/phy/phch/phch_cfg_nr.h +++ b/lib/include/srslte/phy/phch/phch_cfg_nr.h @@ -208,6 +208,7 @@ typedef struct SRSLTE_API { 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/pusch_nr.h b/lib/include/srslte/phy/phch/pusch_nr.h index 74d32b586..629e6464d 100644 --- a/lib/include/srslte/phy/phch/pusch_nr.h +++ b/lib/include/srslte/phy/phch/pusch_nr.h @@ -50,8 +50,17 @@ typedef struct SRSLTE_API { srslte_evm_buffer_t* evm_buffer; bool meas_time_en; uint32_t meas_time_us; - uint8_t* uci_ack; - uint8_t* uci_csi; + 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 + 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 } srslte_pusch_nr_t; /** diff --git a/lib/include/srslte/phy/phch/ra_ul_nr.h b/lib/include/srslte/phy/phch/ra_ul_nr.h index 6b4ec57da..346ca91ed 100644 --- a/lib/include/srslte/phy/phch/ra_ul_nr.h +++ b/lib/include/srslte/phy/phch/ra_ul_nr.h @@ -52,7 +52,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 1772ea9ad..649e4de9f 100644 --- a/lib/include/srslte/phy/phch/sch_nr.h +++ b/lib/include/srslte/phy/phch/sch_nr.h @@ -107,10 +107,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(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); +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 1408e0897..95f2e856c 100644 --- a/lib/include/srslte/phy/phch/uci_cfg_nr.h +++ b/lib/include/srslte/phy/phch/uci_cfg_nr.h @@ -14,7 +14,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 @@ -35,6 +35,37 @@ */ #define SRSLTE_UCI_NR_MAX_CSI1_BITS 10 +/** + * @brief Uplink Control Information bits configuration for PUCCH transmission + */ +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 Uplink Control Information bits configuration for PUSCH transmission + */ +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_pusch_sc_acc[SRSLTE_NSYMB_PER_SLOT_NR]; ///< Number of potential RE for PUSCH before the symbol + 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_csi_part1_offset; + uint32_t nof_re; +} srslte_uci_nr_pusch_cfg_t; + /** * @brief Uplink Control Information (UCI) message configuration */ @@ -44,18 +75,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 - bool without_ul_sch; ///< Set to true if no UL-SCH data is scheduled - bool has_csi_part2; ///< Set to true if the CSI reports have part 2 - - /// 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 c98b7a82b..f3f93d796 100644 --- a/lib/include/srslte/phy/phch/uci_nr.h +++ b/lib/include/srslte/phy/phch/uci_nr.h @@ -125,23 +125,33 @@ SRSLTE_API int srslte_uci_nr_decode_pucch(srslte_uci_nr_t* q, srslte_uci_value_nr_t* value); /** - * @brief Calculates the total number of encoded bits for HARQ-ACK + * @brief Calculates total number of resource elements for HARQ-ACK multiplexing in PUSCH + * @remark Implementation according to TS 38.312 clause 6.3.2.4.1.1 for UCI encoded by polar code + * @remark Implementation according to TS 38.312 clause 6.3.2.4.2.1 for UCI encoded by channel codig of small lengths + * @param cfg UCI NR PUSCH configuration + * @param O_ack Number of ACK + * @return The number of resource elements for HARQ-ACK in a PUSCH transmission + */ +SRSLTE_API int srslte_uci_nr_pusch_ack_nof_re(const srslte_uci_nr_pusch_cfg_t* cfg, uint32_t O_ack); + +/** + * @brief Calculates total number of ebncoded bits for HARQ-ACK multiplexing in PUSCH * @param[in,out] q NR-UCI object * @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_E_uci_ack(srslte_uci_nr_t* q, const srslte_sch_cfg_nr_t* cfg); +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 PUSCH transmission configuration + * @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_sch_cfg_nr_t* cfg, + const srslte_uci_cfg_nr_t* cfg, const srslte_uci_value_nr_t* value, uint8_t* o_ack); diff --git a/lib/src/phy/phch/csi.c b/lib/src/phy/phch/csi.c index 7b426da71..d6c7813e9 100644 --- a/lib/src/phy/phch/csi.c +++ b/lib/src/phy/phch/csi.c @@ -172,6 +172,20 @@ int srslte_csi_nof_bits(const srslte_csi_report_cfg_t* report_list, uint32_t nof 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, diff --git a/lib/src/phy/phch/pdsch_nr.c b/lib/src/phy/phch/pdsch_nr.c index 8ad4b2499..b7ee4dc0d 100644 --- a/lib/src/phy/phch/pdsch_nr.c +++ b/lib/src/phy/phch/pdsch_nr.c @@ -194,7 +194,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 92e4b9d51..30950cc96 100644 --- a/lib/src/phy/phch/pucch_nr.c +++ b/lib/src/phy/phch/pucch_nr.c @@ -538,7 +538,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 diff --git a/lib/src/phy/phch/pusch_nr.c b/lib/src/phy/phch/pusch_nr.c index 858f3124c..130fd8fc2 100644 --- a/lib/src/phy/phch/pusch_nr.c +++ b/lib/src/phy/phch/pusch_nr.c @@ -33,6 +33,24 @@ int pusch_nr_init_common(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* arg return SRSLTE_ERROR; } + q->g_ulsch = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_LEN_RE_NR); + q->g_ack = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_LEN_RE_NR); + q->g_csi1 = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_LEN_RE_NR); + q->g_csi2 = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_LEN_RE_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_LEN_RE_NR); + q->pos_ack = srslte_vec_u32_malloc(SRSLTE_SLOT_MAX_LEN_RE_NR); + q->pos_csi1 = srslte_vec_u32_malloc(SRSLTE_SLOT_MAX_LEN_RE_NR); + q->pos_csi2 = srslte_vec_u32_malloc(SRSLTE_SLOT_MAX_LEN_RE_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; } @@ -151,6 +169,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]); @@ -176,6 +220,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); } /** @@ -420,13 +466,302 @@ pusch_nr_cinit(const srslte_carrier_nr_t* carrier, const srslte_sch_cfg_nr_t* cf return cinit; } -// int pusch_nr_mux_uci(srslte_pusch_nr_t* q) { -// uint8_t *g_ul_sch; // coded bits for UL-SCH -// uint8_t *g_ack; // coded bits for HARQ-ACK -// uint8_t *g_csi_p1; // coded bits for CSI part 1 -// uint8_t *g_csi_p2; // coded bits for CSI part 2 -// -//} +static inline int +pusch_nr_fill_uci_cfg(srslte_pusch_nr_t* q, const srslte_sch_cfg_nr_t* cfg, srslte_uci_cfg_nr_t* uci_cfg) +{ + // Initially, copy all fields + *uci_cfg = cfg->uci; + + // Reset UCI PUSCH configuration + SRSLTE_MEM_ZERO(&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 + 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]) { + 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 + int n_prb_dmrs = srslte_dmrs_sch_get_N_prb(&cfg->dmrs, &cfg->grant); + if (n_prb_dmrs < SRSLTE_SUCCESS) { + ERROR("Error calculating number of DMRS per PRB"); + return SRSLTE_ERROR; + } + + // Accumulative Resource Element shall start in zero + uci_cfg->pusch.M_pusch_sc_acc[0] = 0; + + // 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) || l == dmrs_l[dmrs_l_idx]) { + uci_cfg->pusch.M_pusch_sc[l] = 0; + uci_cfg->pusch.M_pusch_sc_acc[l + 1] = uci_cfg->pusch.M_pusch_sc_acc[l] + uci_cfg->pusch.M_pusch_sc[l]; + uci_cfg->pusch.M_uci_sc[l] = 0; + continue; + } + + // OFDM symbol carries DMRS + if (l == dmrs_l[dmrs_l_idx]) { + // Calculate PUSCH RE candidates + uci_cfg->pusch.M_pusch_sc[l] = cfg->grant.nof_prb * (SRSLTE_NRE - n_prb_dmrs); + uci_cfg->pusch.M_pusch_sc_acc[l + 1] = uci_cfg->pusch.M_pusch_sc_acc[l] + uci_cfg->pusch.M_pusch_sc[l]; + + // The Number of RE candidates for UCI are 0 + 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 + uci_cfg->pusch.M_pusch_sc[l] = cfg->grant.nof_prb * SRSLTE_NRE; + + // Calculate the number of UCI candidates + uci_cfg->pusch.M_uci_sc[l] = 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 + uci_cfg->pusch.K_sum += (sch_tb_info.mask[i]) ? sch_tb_info.Kr : 0; + } + + // Set other PUSCH parameters + uci_cfg->pusch.modulation = cfg->grant.tb[0].mod; + uci_cfg->pusch.nof_layers = cfg->grant.nof_layers; + uci_cfg->pusch.R = (float)cfg->grant.tb[0].R; + uci_cfg->pusch.alpha = cfg->scaling; + uci_cfg->pusch.beta_harq_ack_offset = cfg->beta_harq_ack_offset; + uci_cfg->pusch.beta_csi_part1_offset = cfg->beta_csi_part1_offset; + uci_cfg->pusch.nof_re = cfg->grant.tb[0].nof_re; + + return SRSLTE_SUCCESS; +} + +#define CEIL(NUM, DEN) (((NUM) + ((DEN)-1)) / (DEN)) + +// 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) +{ + // 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 2 or less HARQ-ACK bits, use reserve + uint32_t G_ack_rvd = 0; + if (cfg->o_ack <= 2) { + G_ack_rvd = G_ack; + 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 && m_ack_count < G_ack_rvd) { + if (cfg->o_ack <= 2) { + 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 = CEIL(G_ack_rvd - m_ack_count, Nl * Qm); + } + M_uci_rvd = ack_m_re_count; + } else { + 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_rvd - m_ack_count); + ack_m_re_count = M_ulsch_sc; + } + 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 = 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 = 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] * Qm * Nl; i++) { + 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++; + } + ack_m_re_count--; + } else if (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++; + } + csi1_m_re_count--; + csi1_i++; + } else if (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++; + } + 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++; + } + ulsch_m_re_count--; + csi1_i++; + csi2_i++; + } + + // Set reserved bits + if (i % ack_d == 0 && m_ack_count < G_ack_rvd) { + for (uint32_t j = 0; j < Nl * Qm; j++) { + pos_ack[m_ack_count++] = m_all_count++; + } + ack_m_re_count--; + } + } + + // Checks that all RE are allocated as planned + 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); + } + } + + if (G_ack_rvd != 0 && G_ack_rvd != m_ack_count) { + 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); + } + 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); + } + + return SRSLTE_SUCCESS; +} static inline int pusch_nr_encode_codeword(srslte_pusch_nr_t* q, const srslte_sch_cfg_nr_t* cfg, @@ -453,7 +788,7 @@ static inline int pusch_nr_encode_codeword(srslte_pusch_nr_t* q, } // Encode SCH - if (srslte_ulsch_nr_encode(&q->sch, &cfg->sch_cfg, tb, data, q->b[tb->cw_idx]) < SRSLTE_SUCCESS) { + 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; } @@ -463,6 +798,30 @@ static inline int pusch_nr_encode_codeword(srslte_pusch_nr_t* q, srslte_vec_fprint_b(stdout, q->b[tb->cw_idx], tb->nof_bits); } + // Multiplex UL-SCH + for (uint32_t i = 0; i < tb->nof_bits; i++) { + q->b[tb->cw_idx][q->pos_ulsch[i]] = q->g_ulsch[i]; + } + if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) { + DEBUG("UL-SCH bit positions:"); + srslte_vec_fprint_i(stdout, (int*)q->pos_ulsch, tb->nof_bits); + } + + // Multiplex CSI part 1 + for (uint32_t i = 0; i < q->G_csi1; i++) { + q->b[tb->cw_idx][q->pos_csi1[i]] = q->g_csi1[i]; + } + + // Multiplex CSI part 2 + for (uint32_t i = 0; i < q->G_csi2; i++) { + q->b[tb->cw_idx][q->pos_csi2[i]] = q->g_csi2[i]; + } + + // Multiplex HARQ-ACK + for (uint32_t i = 0; i < q->G_ack; i++) { + q->b[tb->cw_idx][q->pos_ack[i]] = q->g_ack[i]; + } + // 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); @@ -500,12 +859,26 @@ int srslte_pusch_nr_encode(srslte_pusch_nr_t* q, return SRSLTE_ERROR; } + // Fill UCI configuration for PUSCH configuration + srslte_uci_cfg_nr_t uci_cfg = {}; + if (pusch_nr_fill_uci_cfg(q, cfg, &uci_cfg) < SRSLTE_SUCCESS) { + ERROR("Error filling UCI configuration for PUSCH"); + return SRSLTE_ERROR; + } + // Encode HARQ-ACK bits - int E_uci_ack = srslte_uci_nr_encode_pusch_ack(&q->uci, cfg, &data[0].uci, q->uci_ack); + int E_uci_ack = srslte_uci_nr_encode_pusch_ack(&q->uci, &uci_cfg, &data[0].uci, q->g_ack); if (E_uci_ack < SRSLTE_SUCCESS) { ERROR("Error encoding HARQ-ACK bits"); return SRSLTE_ERROR; } + q->G_ack = E_uci_ack; + + // Generate PUSCH UCI/UL-SCH multiplexing + if (pusch_nr_gen_mux_uci(q, &uci_cfg) < SRSLTE_SUCCESS) { + ERROR("Error generating PUSCH mux tables"); + return SRSLTE_ERROR; + } // 7.3.1.1 and 7.3.1.2 uint32_t nof_cw = 0; @@ -592,21 +965,26 @@ 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 + // Demultiplex UL-SCH, change sign + int8_t* g_ulsch_llr = (int8_t*)q->g_ulsch; for (uint32_t i = 0; i < tb->nof_bits; i++) { - llr[i] = -llr[i]; + g_ulsch_llr[i] = -llr[q->pos_ulsch[i]]; + } + if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) { + DEBUG("UL-SCH bit positions:"); + srslte_vec_fprint_i(stdout, (int*)q->pos_ulsch, tb->nof_bits); } // Descrambling - srslte_sequence_apply_c(llr, llr, tb->nof_bits, pusch_nr_cinit(&q->carrier, cfg, rnti, tb->cw_idx)); + srslte_sequence_apply_c(g_ulsch_llr, g_ulsch_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, g_ulsch_llr, tb->nof_bits); } // Decode SCH - if (srslte_ulsch_nr_decode(&q->sch, &cfg->sch_cfg, tb, llr, res->payload, &res->crc) < SRSLTE_SUCCESS) { + if (srslte_ulsch_nr_decode(&q->sch, &cfg->sch_cfg, tb, g_ulsch_llr, res->payload, &res->crc) < SRSLTE_SUCCESS) { ERROR("Error in SCH decoding"); return SRSLTE_ERROR; } @@ -631,6 +1009,25 @@ 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 + srslte_uci_cfg_nr_t uci_cfg = {}; + if (pusch_nr_fill_uci_cfg(q, cfg, &uci_cfg) < SRSLTE_SUCCESS) { + ERROR("Error filling UCI configuration for PUSCH"); + return SRSLTE_ERROR; + } + + // Generate PUSCH UCI/UL-SCH multiplexing + if (pusch_nr_gen_mux_uci(q, &uci_cfg) < SRSLTE_SUCCESS) { + ERROR("Error generating PUSCH mux tables"); + 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_ul_nr.c b/lib/src/phy/phch/ra_ul_nr.c index 8663245f3..e78ca4d2e 100644 --- a/lib/src/phy/phch/ra_ul_nr.c +++ b/lib/src/phy/phch/ra_ul_nr.c @@ -42,7 +42,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}; @@ -141,7 +141,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 { @@ -154,7 +154,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); } @@ -168,7 +168,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"); @@ -461,9 +461,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; @@ -486,7 +486,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 @@ -502,10 +502,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 794cc855f..becba1cd5 100644 --- a/lib/src/phy/phch/sch_nr.c +++ b/lib/src/phy/phch/sch_nr.c @@ -65,10 +65,10 @@ uint32_t sch_nr_n_prb_lbrm(uint32_t nof_prb) return 273; } -int srslte_sch_nr_fill_cfg(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) +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; @@ -372,7 +372,7 @@ static inline int sch_nr_encode(srslte_sch_nr_t* q, uint8_t* output_ptr = e_bits; srslte_sch_nr_tb_info_t cfg = {}; - if (srslte_sch_nr_fill_cfg(&q->carrier, sch_cfg, tb, &cfg) < SRSLTE_SUCCESS) { + if (srslte_sch_nr_fill_tb_info(&q->carrier, sch_cfg, tb, &cfg) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } @@ -514,7 +514,7 @@ int sch_nr_decode(srslte_sch_nr_t* q, int8_t* input_ptr = e_bits; srslte_sch_nr_tb_info_t cfg = {}; - if (srslte_sch_nr_fill_cfg(&q->carrier, sch_cfg, tb, &cfg) < SRSLTE_SUCCESS) { + if (srslte_sch_nr_fill_tb_info(&q->carrier, sch_cfg, tb, &cfg) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } diff --git a/lib/src/phy/phch/test/pusch_nr_test.c b/lib/src/phy/phch/test/pusch_nr_test.c index 581b3752f..a123612f1 100644 --- a/lib/src/phy/phch/test/pusch_nr_test.c +++ b/lib/src/phy/phch/test/pusch_nr_test.c @@ -27,13 +27,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 nof_ack_bits = 0; -static uint32_t nof_csi_bits = 0; +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) { @@ -159,20 +158,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; @@ -188,6 +187,10 @@ int main(int argc, char** argv) mcs_end = SRSLTE_MIN(mcs + 1, mcs_end); } + pusch_cfg.scaling = 0.650f; + pusch_cfg.beta_harq_ack_offset = 5.000f; + pusch_cfg.beta_csi_part1_offset = 5.000f; + if (srslte_chest_dl_res_init(&chest, carrier.nof_prb) < SRSLTE_SUCCESS) { ERROR("Initiating chest"); goto clean_exit; @@ -196,11 +199,11 @@ 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_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; } @@ -212,10 +215,10 @@ int main(int argc, char** argv) continue; } - for (uint32_t i = 0; i < pusch_grant.tb[tb].tbs; i++) { + 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_grant.tb[tb].softbuffer.tx = &softbuffer_tx; + pusch_cfg.grant.tb[tb].softbuffer.tx = &softbuffer_tx; } // Generate HARQ ACK bits @@ -238,22 +241,23 @@ int main(int argc, char** argv) } } - 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, data_rx) < 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; } @@ -264,18 +268,18 @@ int main(int argc, char** argv) } 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); @@ -285,20 +289,20 @@ int main(int argc, char** argv) } if (!data_rx[0].crc) { - ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pusch_grant.tb[0].tbs); + 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].payload, data_rx[0].payload, 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); + 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].payload, 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_tx[0].payload, 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, data_rx[0].evm); + 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); } } diff --git a/lib/src/phy/phch/uci_nr.c b/lib/src/phy/phch/uci_nr.c index 1a5c778b7..1e4ce8dc2 100644 --- a/lib/src/phy/phch/uci_nr.c +++ b/lib/src/phy/phch/uci_nr.c @@ -11,11 +11,9 @@ */ #include "srslte/phy/phch/uci_nr.h" -#include "srslte/phy/ch_estimation/dmrs_sch.h" #include "srslte/phy/fec/block/block.h" #include "srslte/phy/fec/polar/polar_chanalloc.h" #include "srslte/phy/phch/csi.h" -#include "srslte/phy/phch/sch_nr.h" #include "srslte/phy/phch/uci_cfg.h" #include "srslte/phy/utils/bit.h" #include "srslte/phy/utils/vector.h" @@ -258,13 +256,12 @@ static int uci_nr_unpack_pucch(const srslte_uci_cfg_nr_t* cfg, uint8_t* sequence return SRSLTE_ERROR; } -static int -uci_nr_encode_1bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, srslte_mod_t modulation, uint8_t* o, uint32_t E) +static int uci_nr_encode_1bit(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; - switch (modulation) { + switch (cfg->pusch.modulation) { case SRSLTE_MOD_BPSK: while (i < E) { o[i++] = c0; @@ -317,15 +314,14 @@ uci_nr_encode_1bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, srslte_mo return E; } -static int -uci_nr_encode_2bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, srslte_mod_t modulation, uint8_t* o, uint32_t E) +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; - switch (modulation) { + switch (cfg->pusch.modulation) { case SRSLTE_MOD_BPSK: case SRSLTE_MOD_QPSK: while (i < E) { @@ -643,21 +639,16 @@ 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, - srslte_mod_t mod, - uint32_t A, - 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) { // 5.3.3.1 Encoding of 1-bit information if (A == 1) { - return uci_nr_encode_1bit(q, uci_cfg, mod, o, E_uci); + return uci_nr_encode_1bit(q, uci_cfg, o, E_uci); } // 5.3.3.2 Encoding of 2-bit information if (A == 2) { - return uci_nr_encode_2bit(q, uci_cfg, mod, o, E_uci); + return uci_nr_encode_2bit(q, uci_cfg, o, E_uci); } // 5.3.3.3 Encoding of other small block lengths @@ -781,7 +772,7 @@ int srslte_uci_nr_encode_pucch(srslte_uci_nr_t* q, return SRSLTE_ERROR; } - return uci_nr_encode(q, uci_cfg, SRSLTE_MOD_NITEMS, A, o, E_uci); + return uci_nr_encode(q, uci_cfg, A, o, E_uci); } int srslte_uci_nr_decode_pucch(srslte_uci_nr_t* q, @@ -816,7 +807,7 @@ uint32_t srslte_uci_nr_info(const srslte_uci_data_nr_t* uci_data, char* str, uin { 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]; @@ -835,92 +826,59 @@ uint32_t srslte_uci_nr_info(const srslte_uci_data_nr_t* uci_data, char* str, uin return len; } -static int uci_nr_Q_ack_prime(srslte_uci_nr_t* q, const srslte_sch_cfg_nr_t* sch_cfg, uint32_t A) +int srslte_uci_nr_pusch_ack_nof_re(const srslte_uci_nr_pusch_cfg_t* cfg, uint32_t O_ack) { - // Get UL-SCH TB information - srslte_sch_nr_tb_info_t tb_info = {}; - if (srslte_sch_nr_fill_cfg(&q->carrier, &sch_cfg->sch_cfg, &sch_cfg->grant.tb[0], &tb_info) < SRSLTE_SUCCESS) { - return SRSLTE_ERROR; - } - - // 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(&sch_cfg->dmrs, &sch_cfg->grant, dmrs_l); - if (n < SRSLTE_SUCCESS) { - return SRSLTE_ERROR; - } - nof_dmrs_l = (uint32_t)n; - - uint32_t O_ack = A; // Number of HARQ-ACK bits - uint32_t L_ack = srslte_uci_nr_crc_len(A); // Number of CRC bits - float beta_pusch_offset = sch_cfg->beta_harq_ack_offset; // Beta offset given by higher layers - uint32_t C_ulsch = tb_info.C; // number of code blocks for UL-SCH of the PUSCH - float alpha = sch_cfg->scaling; // Higher layer parameter scaling - float R = (float)sch_cfg->grant.tb[0].R; // code rate of the PUSCH - float Qm = srslte_mod_bits_x_symbol(sch_cfg->grant.tb[0].mod); // modulation order of the PUSCH - - uint32_t K_sum = 0; - for (uint32_t i = 0; i < SRSLTE_MIN(C_ulsch, SRSLTE_SCH_NR_MAX_NOF_CB_LDPC); i++) { - K_sum += tb_info.mask[i] ? 0 : tb_info.Kr; - } - - uint32_t dmrs_l_idx = 0; - uint32_t M_uci_sum = 0; - uint32_t M_uci_l0_sum = 0; - for (uint32_t l = sch_cfg->grant.S; l < sch_cfg->grant.S + sch_cfg->grant.L; l++) { - uint32_t M_ptrs_sc = 0; // Not implemented yet - uint32_t M_pusch_sc = sch_cfg->grant.nof_prb * SRSLTE_NRE; - uint32_t M_uci_sc = M_pusch_sc - M_ptrs_sc; - - // If the OFDM symbol contains DMRS, no UCI is mapped - if (l == dmrs_l[dmrs_l_idx] && dmrs_l_idx < nof_dmrs_l) { - M_uci_sc = 0; - dmrs_l_idx++; - } - - // Add subcarriers that can contain UCI RE - M_uci_sum += M_uci_sc; - - // Start adding after the first DMRS symbol - if (dmrs_l_idx > 0) { - M_uci_l0_sum += M_uci_sc; - } - } - - if (sch_cfg->uci.without_ul_sch) { - return (int)SRSLTE_MIN(ceilf(((O_ack + L_ack) * beta_pusch_offset) / (Qm * R)), alpha * M_uci_l0_sum); - } - return (int)SRSLTE_MIN(ceilf(((O_ack + L_ack) * beta_pusch_offset * M_uci_sum) / (float)K_sum), alpha * M_uci_l0_sum); -} - -int srslte_uci_nr_pusch_E_uci_ack(srslte_uci_nr_t* q, const srslte_sch_cfg_nr_t* cfg) -{ - int A = cfg->uci.o_ack; - - // Check inputs - if (q == NULL || cfg == NULL) { + if (cfg == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } - if (cfg->uci.without_ul_sch && cfg->uci.nof_csi > 1 && !cfg->uci.has_csi_part2 && cfg->uci.o_ack < 2) { - A = 2; + 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]; + } } - int Q_ack_prime = uci_nr_Q_ack_prime(q, cfg, A); + 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; + } + + int Q_ack_prime = srslte_uci_nr_pusch_ack_nof_re(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->grant.nof_layers * srslte_mod_bits_x_symbol(cfg->grant.tb[0].mod)); + 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_sch_cfg_nr_t* cfg, + const srslte_uci_cfg_nr_t* cfg, const srslte_uci_value_nr_t* value, uint8_t* o) { - int A = cfg->uci.o_ack; + int A = cfg->o_ack; // Check inputs if (q == NULL || cfg == NULL || value == NULL || o == NULL) { @@ -929,20 +887,21 @@ int srslte_uci_nr_encode_pusch_ack(srslte_uci_nr_t* q, // 6.3.2.1 UCI bit sequence generation // 6.3.2.1.1 HARQ-ACK - if (cfg->uci.without_ul_sch && cfg->uci.nof_csi > 1 && !cfg->uci.has_csi_part2 && cfg->uci.o_ack < 2) { + 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; - q->bit_sequence[0] = (cfg->uci.o_ack == 0) ? 0 : value->ack[0]; + q->bit_sequence[0] = (cfg->o_ack == 0) ? 0 : value->ack[0]; q->bit_sequence[1] = 0; } else { - srslte_vec_u8_copy(q->bit_sequence, value->ack, cfg->uci.o_ack); + 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_E_uci_ack(q, cfg); + 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->uci, cfg->grant.tb[0].mod, A, o, E_uci); + return uci_nr_encode(q, cfg, A, o, E_uci); } \ 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 6367d5be3..dd253931b 100644 --- a/lib/src/phy/ue/ue_dl_nr.c +++ b/lib/src/phy/ue/ue_dl_nr.c @@ -574,8 +574,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/srsue/hdr/phy/nr/state.h b/srsue/hdr/phy/nr/state.h index 7db19bee2..ff379c16d 100644 --- a/srsue/hdr/phy/nr/state.h +++ b/srsue/hdr/phy/nr/state.h @@ -73,9 +73,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; } @@ -294,10 +294,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) @@ -307,7 +307,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 From dc2542901adaf363db41ea505d81d263fceb0c82 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 4 Mar 2021 12:12:16 +0100 Subject: [PATCH 11/65] Verified HARQ-ACK in PUSCH --- .../srslte/phy/ch_estimation/dmrs_sch.h | 6 + lib/include/srslte/phy/phch/pusch_nr.h | 2 + lib/include/srslte/phy/phch/uci_cfg_nr.h | 15 +- lib/include/srslte/phy/phch/uci_nr.h | 13 + lib/include/srslte/phy/utils/vector.h | 3 + lib/src/phy/ch_estimation/dmrs_sch.c | 3 +- lib/src/phy/fec/cbsegm.c | 9 +- lib/src/phy/phch/pusch_nr.c | 234 +++++++++++------- lib/src/phy/phch/ra_nr.c | 17 +- lib/src/phy/phch/sch_nr.c | 3 +- lib/src/phy/phch/test/CMakeLists.txt | 2 + lib/src/phy/phch/test/pusch_nr_test.c | 29 ++- lib/src/phy/phch/uci_nr.c | 76 ++++-- 13 files changed, 270 insertions(+), 142 deletions(-) diff --git a/lib/include/srslte/phy/ch_estimation/dmrs_sch.h b/lib/include/srslte/phy/ch_estimation/dmrs_sch.h index 6b7829a9b..3db0fc834 100644 --- a/lib/include/srslte/phy/ch_estimation/dmrs_sch.h +++ b/lib/include/srslte/phy/ch_estimation/dmrs_sch.h @@ -20,6 +20,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/phch/pusch_nr.h b/lib/include/srslte/phy/phch/pusch_nr.h index 629e6464d..6f37ee646 100644 --- a/lib/include/srslte/phy/phch/pusch_nr.h +++ b/lib/include/srslte/phy/phch/pusch_nr.h @@ -50,6 +50,7 @@ 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 @@ -61,6 +62,7 @@ typedef struct SRSLTE_API { 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; /** diff --git a/lib/include/srslte/phy/phch/uci_cfg_nr.h b/lib/include/srslte/phy/phch/uci_cfg_nr.h index 95f2e856c..453ba6457 100644 --- a/lib/include/srslte/phy/phch/uci_cfg_nr.h +++ b/lib/include/srslte/phy/phch/uci_cfg_nr.h @@ -53,14 +53,13 @@ typedef struct { 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_pusch_sc_acc[SRSLTE_NSYMB_PER_SLOT_NR]; ///< Number of potential RE for PUSCH before the symbol - 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 + 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_csi_part1_offset; uint32_t nof_re; diff --git a/lib/include/srslte/phy/phch/uci_nr.h b/lib/include/srslte/phy/phch/uci_nr.h index f3f93d796..523d5b8b1 100644 --- a/lib/include/srslte/phy/phch/uci_nr.h +++ b/lib/include/srslte/phy/phch/uci_nr.h @@ -155,6 +155,19 @@ SRSLTE_API int srslte_uci_nr_encode_pusch_ack(srslte_uci_nr_t* q, 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 the total number of UCI bits * @param uci_cfg UCI configuration diff --git a/lib/include/srslte/phy/utils/vector.h b/lib/include/srslte/phy/utils/vector.h index a2a4a9c92..bf5276b09 100644 --- a/lib/include/srslte/phy/utils/vector.h +++ b/lib/include/srslte/phy/utils/vector.h @@ -40,6 +40,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/src/phy/ch_estimation/dmrs_sch.c b/lib/src/phy/ch_estimation/dmrs_sch.c index 1415739cb..4cdc35ba0 100644 --- a/lib/src/phy/ch_estimation/dmrs_sch.c +++ b/lib/src/phy/ch_estimation/dmrs_sch.c @@ -430,8 +430,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 39029aacd..71740f5c0 100644 --- a/lib/src/phy/fec/cbsegm.c +++ b/lib/src/phy/fec/cbsegm.c @@ -14,6 +14,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 /** @@ -31,8 +32,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 @@ -46,7 +45,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); } } @@ -151,12 +150,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/phch/pusch_nr.c b/lib/src/phy/phch/pusch_nr.c index 130fd8fc2..e74e1e07b 100644 --- a/lib/src/phy/phch/pusch_nr.c +++ b/lib/src/phy/phch/pusch_nr.c @@ -206,6 +206,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]) { @@ -466,14 +467,13 @@ pusch_nr_cinit(const srslte_carrier_nr_t* carrier, const srslte_sch_cfg_nr_t* cf return cinit; } -static inline int -pusch_nr_fill_uci_cfg(srslte_pusch_nr_t* q, const srslte_sch_cfg_nr_t* cfg, srslte_uci_cfg_nr_t* uci_cfg) +static inline int pusch_nr_fill_uci_cfg(srslte_pusch_nr_t* q, const srslte_sch_cfg_nr_t* cfg) { // Initially, copy all fields - *uci_cfg = cfg->uci; + q->uci_cfg = cfg->uci; // Reset UCI PUSCH configuration - SRSLTE_MEM_ZERO(&uci_cfg->pusch, srslte_uci_nr_pusch_cfg_t, 1); + SRSLTE_MEM_ZERO(&q->uci_cfg.pusch, srslte_uci_nr_pusch_cfg_t, 1); // Get DMRS symbol indexes uint32_t nof_dmrs_l = 0; @@ -490,7 +490,7 @@ pusch_nr_fill_uci_cfg(srslte_pusch_nr_t* q, const srslte_sch_cfg_nr_t* cfg, srsl // Check if it is not carrying DMRS... if (l != dmrs_l[dmrs_l_idx]) { // Set value and stop iterating - uci_cfg->pusch.l0 = l; + q->uci_cfg.pusch.l0 = l; break; } @@ -505,7 +505,7 @@ pusch_nr_fill_uci_cfg(srslte_pusch_nr_t* q, const srslte_sch_cfg_nr_t* cfg, srsl 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]) { - uci_cfg->pusch.l1 = l; + q->uci_cfg.pusch.l1 = l; break; } @@ -516,33 +516,24 @@ pusch_nr_fill_uci_cfg(srslte_pusch_nr_t* q, const srslte_sch_cfg_nr_t* cfg, srsl } // Number of DMRS per PRB - int n_prb_dmrs = srslte_dmrs_sch_get_N_prb(&cfg->dmrs, &cfg->grant); - if (n_prb_dmrs < SRSLTE_SUCCESS) { - ERROR("Error calculating number of DMRS per PRB"); - return SRSLTE_ERROR; - } - - // Accumulative Resource Element shall start in zero - uci_cfg->pusch.M_pusch_sc_acc[0] = 0; + 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) || l == dmrs_l[dmrs_l_idx]) { - uci_cfg->pusch.M_pusch_sc[l] = 0; - uci_cfg->pusch.M_pusch_sc_acc[l + 1] = uci_cfg->pusch.M_pusch_sc_acc[l] + uci_cfg->pusch.M_pusch_sc[l]; - uci_cfg->pusch.M_uci_sc[l] = 0; + 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 - uci_cfg->pusch.M_pusch_sc[l] = cfg->grant.nof_prb * (SRSLTE_NRE - n_prb_dmrs); - uci_cfg->pusch.M_pusch_sc_acc[l + 1] = uci_cfg->pusch.M_pusch_sc_acc[l] + uci_cfg->pusch.M_pusch_sc[l]; + 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 - uci_cfg->pusch.M_uci_sc[l] = 0; + q->uci_cfg.pusch.M_uci_sc[l] = 0; // Advance DMRS symbol index dmrs_l_idx++; @@ -555,10 +546,10 @@ pusch_nr_fill_uci_cfg(srslte_pusch_nr_t* q, const srslte_sch_cfg_nr_t* cfg, srsl uint32_t M_ptrs_sc = 0; // Not implemented yet // Number of RE given by the grant - uci_cfg->pusch.M_pusch_sc[l] = cfg->grant.nof_prb * SRSLTE_NRE; + q->uci_cfg.pusch.M_pusch_sc[l] = cfg->grant.nof_prb * SRSLTE_NRE; // Calculate the number of UCI candidates - uci_cfg->pusch.M_uci_sc[l] = uci_cfg->pusch.M_pusch_sc[l] - M_ptrs_sc; + q->uci_cfg.pusch.M_uci_sc[l] = q->uci_cfg.pusch.M_pusch_sc[l] - M_ptrs_sc; } // Generate SCH Transport block information @@ -571,23 +562,21 @@ pusch_nr_fill_uci_cfg(srslte_pusch_nr_t* q, const srslte_sch_cfg_nr_t* cfg, srsl // Calculate the sum of codeblock sizes for (uint32_t i = 0; i < sch_tb_info.C; i++) { // Accumulate codeblock size if mask is enabled - uci_cfg->pusch.K_sum += (sch_tb_info.mask[i]) ? sch_tb_info.Kr : 0; + q->uci_cfg.pusch.K_sum += (sch_tb_info.mask[i]) ? sch_tb_info.Kr : 0; } // Set other PUSCH parameters - uci_cfg->pusch.modulation = cfg->grant.tb[0].mod; - uci_cfg->pusch.nof_layers = cfg->grant.nof_layers; - uci_cfg->pusch.R = (float)cfg->grant.tb[0].R; - uci_cfg->pusch.alpha = cfg->scaling; - uci_cfg->pusch.beta_harq_ack_offset = cfg->beta_harq_ack_offset; - uci_cfg->pusch.beta_csi_part1_offset = cfg->beta_csi_part1_offset; - uci_cfg->pusch.nof_re = cfg->grant.tb[0].nof_re; + 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_csi_part1_offset = cfg->beta_csi_part1_offset; + q->uci_cfg.pusch.nof_re = cfg->grant.tb[0].nof_re; return SRSLTE_SUCCESS; } -#define CEIL(NUM, DEN) (((NUM) + ((DEN)-1)) / (DEN)) - // 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) { @@ -646,21 +635,21 @@ static int pusch_nr_gen_mux_uci(srslte_pusch_nr_t* q, const srslte_uci_cfg_nr_t* // Compute HARQ-ACK bits multiplexing uint32_t ack_d = 0; uint32_t ack_m_re_count = 0; - if (l >= l1 && m_ack_count < G_ack_rvd) { - if (cfg->o_ack <= 2) { + 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 = CEIL(G_ack_rvd - m_ack_count, Nl * Qm); + ack_m_re_count = SRSLTE_CEIL(G_ack_rvd - m_ack_count, Nl * Qm); } M_uci_rvd = ack_m_re_count; - } else { + } 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_rvd - m_ack_count); - ack_m_re_count = M_ulsch_sc; + 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; } @@ -674,7 +663,7 @@ static int pusch_nr_gen_mux_uci(srslte_pusch_nr_t* q, const srslte_uci_cfg_nr_t* 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 = CEIL(G_csi1 - m_csi1_count, Nl * Qm); + csi1_m_re_count = SRSLTE_CEIL(G_csi1 - m_csi1_count, Nl * Qm); } M_uci_sc -= csi1_m_re_count; } @@ -687,7 +676,7 @@ static int pusch_nr_gen_mux_uci(srslte_pusch_nr_t* q, const srslte_uci_cfg_nr_t* 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 = CEIL(G_csi2 - m_csi2_count, Nl * Qm); + csi2_m_re_count = SRSLTE_CEIL(G_csi2 - m_csi2_count, Nl * Qm); } M_uci_sc -= csi2_m_re_count; } @@ -695,7 +684,7 @@ static int pusch_nr_gen_mux_uci(srslte_pusch_nr_t* q, const srslte_uci_cfg_nr_t* // 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] * Qm * Nl; i++) { + for (uint32_t i = 0, csi1_i = 0, csi2_i = 0; i < cfg->pusch.M_pusch_sc[l]; i++) { 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++; @@ -724,7 +713,7 @@ static int pusch_nr_gen_mux_uci(srslte_pusch_nr_t* q, const srslte_uci_cfg_nr_t* } // Set reserved bits - if (i % ack_d == 0 && m_ack_count < G_ack_rvd) { + if (ack_m_re_count != 0 && i % ack_d == 0 && m_ack_count < G_ack_rvd) { for (uint32_t j = 0; j < Nl * Qm; j++) { pos_ack[m_ack_count++] = m_all_count++; } @@ -732,7 +721,7 @@ static int pusch_nr_gen_mux_uci(srslte_pusch_nr_t* q, const srslte_uci_cfg_nr_t* } } - // Checks that all RE are allocated as planned + // Assert that all RE have been allocated if (ack_m_re_count != 0) { ERROR("ack_m_re_count=%d", ack_m_re_count); } @@ -747,6 +736,10 @@ static int pusch_nr_gen_mux_uci(srslte_pusch_nr_t* q, const srslte_uci_cfg_nr_t* } } + // 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) { ERROR("Not matched %d!=%d", G_ack_rvd, m_ack_count); } @@ -760,6 +753,26 @@ static int pusch_nr_gen_mux_uci(srslte_pusch_nr_t* q, const srslte_uci_cfg_nr_t* 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) { + 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; } @@ -787,25 +800,32 @@ 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 = E_uci_ack; + q->G_csi1 = 0; + 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->g_ulsch) < SRSLTE_SUCCESS) { ERROR("Error in SCH encoding"); return SRSLTE_ERROR; } - 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); - } - // Multiplex UL-SCH - for (uint32_t i = 0; i < tb->nof_bits; i++) { + for (uint32_t i = 0; i < q->G_ulsch; i++) { q->b[tb->cw_idx][q->pos_ulsch[i]] = q->g_ulsch[i]; } - if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) { - DEBUG("UL-SCH bit positions:"); - srslte_vec_fprint_i(stdout, (int*)q->pos_ulsch, tb->nof_bits); - } // Multiplex CSI part 1 for (uint32_t i = 0; i < q->G_csi1; i++) { @@ -822,6 +842,11 @@ static inline int pusch_nr_encode_codeword(srslte_pusch_nr_t* q, q->b[tb->cw_idx][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); + } + // 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); @@ -860,26 +885,11 @@ int srslte_pusch_nr_encode(srslte_pusch_nr_t* q, } // Fill UCI configuration for PUSCH configuration - srslte_uci_cfg_nr_t uci_cfg = {}; - if (pusch_nr_fill_uci_cfg(q, cfg, &uci_cfg) < SRSLTE_SUCCESS) { + if (pusch_nr_fill_uci_cfg(q, cfg) < SRSLTE_SUCCESS) { ERROR("Error filling UCI configuration for PUSCH"); return SRSLTE_ERROR; } - // Encode HARQ-ACK bits - int E_uci_ack = srslte_uci_nr_encode_pusch_ack(&q->uci, &uci_cfg, &data[0].uci, q->g_ack); - if (E_uci_ack < SRSLTE_SUCCESS) { - ERROR("Error encoding HARQ-ACK bits"); - return SRSLTE_ERROR; - } - q->G_ack = E_uci_ack; - - // Generate PUSCH UCI/UL-SCH multiplexing - if (pusch_nr_gen_mux_uci(q, &uci_cfg) < SRSLTE_SUCCESS) { - ERROR("Error generating PUSCH mux tables"); - 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++) { @@ -954,6 +964,22 @@ 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 UCI 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; + q->G_csi1 = 0; + 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)) { @@ -965,28 +991,55 @@ 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); } - // Demultiplex UL-SCH, change sign - int8_t* g_ulsch_llr = (int8_t*)q->g_ulsch; - for (uint32_t i = 0; i < tb->nof_bits; i++) { - g_ulsch_llr[i] = -llr[q->pos_ulsch[i]]; - } - if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) { - DEBUG("UL-SCH bit positions:"); - srslte_vec_fprint_i(stdout, (int*)q->pos_ulsch, tb->nof_bits); - } - // Descrambling - srslte_sequence_apply_c(g_ulsch_llr, g_ulsch_llr, tb->nof_bits, pusch_nr_cinit(&q->carrier, cfg, rnti, tb->cw_idx)); + 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_bs(stdout, g_ulsch_llr, 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, g_ulsch_llr, res->payload, &res->crc) < SRSLTE_SUCCESS) { - ERROR("Error in SCH decoding"); - return SRSLTE_ERROR; + // 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 Ul-SCH + if (q->G_ulsch != 0) { + if (srslte_ulsch_nr_decode(&q->sch, &cfg->sch_cfg, tb, g_ulsch, res->payload, &res->crc) < SRSLTE_SUCCESS) { + ERROR("Error in SCH decoding"); + return SRSLTE_ERROR; + } + } + + // 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; + } } return SRSLTE_SUCCESS; @@ -1016,18 +1069,11 @@ int srslte_pusch_nr_decode(srslte_pusch_nr_t* q, } // Fill UCI configuration for PUSCH configuration - srslte_uci_cfg_nr_t uci_cfg = {}; - if (pusch_nr_fill_uci_cfg(q, cfg, &uci_cfg) < SRSLTE_SUCCESS) { + if (pusch_nr_fill_uci_cfg(q, cfg) < SRSLTE_SUCCESS) { ERROR("Error filling UCI configuration for PUSCH"); return SRSLTE_ERROR; } - // Generate PUSCH UCI/UL-SCH multiplexing - if (pusch_nr_gen_mux_uci(q, &uci_cfg) < SRSLTE_SUCCESS) { - ERROR("Error generating PUSCH mux tables"); - 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 d340fae32..399c881da 100644 --- a/lib/src/phy/phch/ra_nr.c +++ b/lib/src/phy/phch/ra_nr.c @@ -310,16 +310,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++) { @@ -335,19 +332,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/sch_nr.c b/lib/src/phy/phch/sch_nr.c index becba1cd5..174f76e1d 100644 --- a/lib/src/phy/phch/sch_nr.c +++ b/lib/src/phy/phch/sch_nr.c @@ -131,7 +131,6 @@ int srslte_sch_nr_fill_tb_info(const srslte_carrier_nr_t* carrier, 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_tb_info_t* cfg, uint32_t j) @@ -144,7 +143,7 @@ static inline uint32_t sch_nr_get_E(const srslte_sch_nr_tb_info_t* cfg, uint32_t 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) diff --git a/lib/src/phy/phch/test/CMakeLists.txt b/lib/src/phy/phch/test/CMakeLists.txt index ae8febb8f..869d33aef 100644 --- a/lib/src/phy/phch/test/CMakeLists.txt +++ b/lib/src/phy/phch/test/CMakeLists.txt @@ -631,6 +631,8 @@ 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_ack_4_test pusch_nr_test -p 50 -m 20 -A 4) +add_nr_test(pusch_nr_ack_20_test pusch_nr_test -p 50 -m 20 -A 20) 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/pusch_nr_test.c b/lib/src/phy/phch/test/pusch_nr_test.c index a123612f1..acedcdd50 100644 --- a/lib/src/phy/phch/test/pusch_nr_test.c +++ b/lib/src/phy/phch/test/pusch_nr_test.c @@ -187,9 +187,9 @@ int main(int argc, char** argv) mcs_end = SRSLTE_MIN(mcs + 1, mcs_end); } - pusch_cfg.scaling = 0.650f; - pusch_cfg.beta_harq_ack_offset = 5.000f; - pusch_cfg.beta_csi_part1_offset = 5.000f; + pusch_cfg.scaling = 0.5f; + pusch_cfg.beta_harq_ack_offset = 1.500f; + pusch_cfg.beta_csi_part1_offset = 1.500f; if (srslte_chest_dl_res_init(&chest, carrier.nof_prb) < SRSLTE_SUCCESS) { ERROR("Initiating chest"); @@ -201,6 +201,7 @@ int main(int argc, char** argv) for (uint32_t n = 0; n < SRSLTE_MAX_PRB_NR; n++) { pusch_cfg.grant.prb_idx[n] = (n < n_prb); } + pusch_cfg.grant.nof_prb = n_prb; 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) { @@ -288,11 +289,13 @@ int main(int argc, char** argv) goto clean_exit; } + // 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; } + // 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: "); @@ -302,6 +305,26 @@ int main(int argc, char** argv) goto clean_exit; } + // 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; + } + } + 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); } } diff --git a/lib/src/phy/phch/uci_nr.c b/lib/src/phy/phch/uci_nr.c index 1e4ce8dc2..5dd7b3100 100644 --- a/lib/src/phy/phch/uci_nr.c +++ b/lib/src/phy/phch/uci_nr.c @@ -467,8 +467,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) { @@ -487,7 +485,7 @@ 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; @@ -570,7 +568,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; @@ -664,13 +662,10 @@ static int uci_nr_encode(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* uci_cfg, return SRSLTE_ERROR; } -static int uci_nr_decode(srslte_uci_nr_t* q, - const srslte_uci_cfg_nr_t* uci_cfg, - int8_t* llr, - uint32_t E_uci, - srslte_uci_value_nr_t* uci_value) +static int +uci_nr_decode(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* uci_cfg, int8_t* llr, uint32_t E_uci, 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; } @@ -687,22 +682,17 @@ static int uci_nr_decode(srslte_uci_nr_t* q, } else if (A == 2) { ERROR("Not implemented"); } 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_unpack_pucch(uci_cfg, q->bit_sequence, uci_value) < SRSLTE_SUCCESS) { - return SRSLTE_ERROR; - } - return SRSLTE_SUCCESS; } @@ -788,10 +778,22 @@ 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); + if (uci_nr_decode(q, uci_cfg, llr, 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) @@ -904,4 +906,42 @@ int srslte_uci_nr_encode_pusch_ack(srslte_uci_nr_t* q, } 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, 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; } \ No newline at end of file From 97435b085ee8dcd7cb44be1c07d28429f6595a11 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 4 Mar 2021 18:57:18 +0100 Subject: [PATCH 12/65] Added CSI part1 and 1/2 bit HARQ-ACK multiplexing on PUSCH --- lib/include/srslte/phy/phch/csi.h | 19 +- lib/include/srslte/phy/phch/uci_cfg_nr.h | 5 +- lib/include/srslte/phy/phch/uci_nr.h | 58 +++- lib/src/phy/fec/polar/polar_code.c | 2 +- lib/src/phy/phch/csi.c | 93 +++++- lib/src/phy/phch/pusch_nr.c | 110 ++++-- lib/src/phy/phch/ra_ul_nr.c | 2 +- lib/src/phy/phch/test/CMakeLists.txt | 13 +- lib/src/phy/phch/test/pusch_nr_test.c | 25 +- lib/src/phy/phch/uci_nr.c | 405 ++++++++++++++++++----- 10 files changed, 595 insertions(+), 137 deletions(-) diff --git a/lib/include/srslte/phy/phch/csi.h b/lib/include/srslte/phy/phch/csi.h index 3f971eec7..30f2c773b 100644 --- a/lib/include/srslte/phy/phch/csi.h +++ b/lib/include/srslte/phy/phch/csi.h @@ -35,7 +35,7 @@ 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 Checks if the report list contains part 2 CSI report @@ -46,7 +46,7 @@ SRSLTE_API int srslte_csi_nof_bits(const srslte_csi_report_cfg_t* report_list, u 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 transmission + * @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 @@ -59,6 +59,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/uci_cfg_nr.h b/lib/include/srslte/phy/phch/uci_cfg_nr.h index 453ba6457..a61b3377e 100644 --- a/lib/include/srslte/phy/phch/uci_cfg_nr.h +++ b/lib/include/srslte/phy/phch/uci_cfg_nr.h @@ -33,7 +33,7 @@ * @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_CSI1_BITS 10 +#define SRSLTE_UCI_NR_MAX_CSI1_BITS 360 /** * @brief Uplink Control Information bits configuration for PUCCH transmission @@ -61,8 +61,9 @@ typedef struct { float R; ///< Code rate of the PUSCH float alpha; ///< Higher layer parameter scaling float beta_harq_ack_offset; - float beta_csi_part1_offset; + float beta_csi1_offset; uint32_t nof_re; + bool csi_part2_present; } srslte_uci_nr_pusch_cfg_t; /** diff --git a/lib/include/srslte/phy/phch/uci_nr.h b/lib/include/srslte/phy/phch/uci_nr.h index 523d5b8b1..31b2385ef 100644 --- a/lib/include/srslte/phy/phch/uci_nr.h +++ b/lib/include/srslte/phy/phch/uci_nr.h @@ -31,6 +31,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 { @@ -42,11 +43,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; /** @@ -125,18 +127,7 @@ SRSLTE_API int srslte_uci_nr_decode_pucch(srslte_uci_nr_t* q, srslte_uci_value_nr_t* value); /** - * @brief Calculates total number of resource elements for HARQ-ACK multiplexing in PUSCH - * @remark Implementation according to TS 38.312 clause 6.3.2.4.1.1 for UCI encoded by polar code - * @remark Implementation according to TS 38.312 clause 6.3.2.4.2.1 for UCI encoded by channel codig of small lengths - * @param cfg UCI NR PUSCH configuration - * @param O_ack Number of ACK - * @return The number of resource elements for HARQ-ACK in a PUSCH transmission - */ -SRSLTE_API int srslte_uci_nr_pusch_ack_nof_re(const srslte_uci_nr_pusch_cfg_t* cfg, uint32_t O_ack); - -/** - * @brief Calculates total number of ebncoded bits for HARQ-ACK multiplexing in PUSCH - * @param[in,out] q NR-UCI object + * @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 */ @@ -168,6 +159,39 @@ SRSLTE_API int srslte_uci_nr_decode_pusch_ack(srslte_uci_nr_t* q, 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/src/phy/fec/polar/polar_code.c b/lib/src/phy/fec/polar/polar_code.c index c4ece0928..f13e09381 100644 --- a/lib/src/phy/fec/polar/polar_code.c +++ b/lib/src/phy/fec/polar/polar_code.c @@ -123,7 +123,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 d6c7813e9..1d5519d89 100644 --- a/lib/src/phy/phch/csi.c +++ b/lib/src/phy/phch/csi.c @@ -12,6 +12,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 @@ -82,9 +83,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; @@ -101,6 +102,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], @@ -152,7 +193,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; @@ -166,6 +207,8 @@ 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); } } @@ -198,7 +241,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; @@ -208,6 +251,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, @@ -229,6 +308,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/pusch_nr.c b/lib/src/phy/phch/pusch_nr.c index e74e1e07b..89c2c0a30 100644 --- a/lib/src/phy/phch/pusch_nr.c +++ b/lib/src/phy/phch/pusch_nr.c @@ -14,7 +14,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) { @@ -33,19 +35,19 @@ int pusch_nr_init_common(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* arg return SRSLTE_ERROR; } - q->g_ulsch = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_LEN_RE_NR); - q->g_ack = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_LEN_RE_NR); - q->g_csi1 = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_LEN_RE_NR); - q->g_csi2 = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_LEN_RE_NR); + 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_LEN_RE_NR); - q->pos_ack = srslte_vec_u32_malloc(SRSLTE_SLOT_MAX_LEN_RE_NR); - q->pos_csi1 = srslte_vec_u32_malloc(SRSLTE_SLOT_MAX_LEN_RE_NR); - q->pos_csi2 = srslte_vec_u32_malloc(SRSLTE_SLOT_MAX_LEN_RE_NR); + 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; @@ -566,13 +568,13 @@ static inline int pusch_nr_fill_uci_cfg(srslte_pusch_nr_t* q, const srslte_sch_c } // 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_csi_part1_offset = cfg->beta_csi_part1_offset; - q->uci_cfg.pusch.nof_re = cfg->grant.tb[0].nof_re; + 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; } @@ -685,27 +687,33 @@ static int pusch_nr_gen_mux_uci(srslte_pusch_nr_t* q, const srslte_uci_cfg_nr_t* 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++; + pos_ack[m_ack_count++] = m_all_count + j; } ack_m_re_count--; - } else if (csi1_m_re_count != 0 && csi1_i % csi1_d == 0 && m_csi1_count < G_csi1) { + } 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++; + pos_csi1[m_csi1_count++] = m_all_count + j; } csi1_m_re_count--; csi1_i++; } else if (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++; + 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++; + pos_ulsch[m_ulsch_count++] = m_all_count + j; } ulsch_m_re_count--; csi1_i++; @@ -713,12 +721,15 @@ static int pusch_nr_gen_mux_uci(srslte_pusch_nr_t* q, const srslte_uci_cfg_nr_t* } // Set reserved bits - if (ack_m_re_count != 0 && i % ack_d == 0 && m_ack_count < G_ack_rvd) { + if (reserved) { for (uint32_t j = 0; j < Nl * Qm; j++) { - pos_ack[m_ack_count++] = m_all_count++; + pos_ack[m_ack_count++] = m_all_count + j; } ack_m_re_count--; } + + // Increment all bit counter + m_all_count += Nl * Qm; } // Assert that all RE have been allocated @@ -806,8 +817,18 @@ static inline int pusch_nr_encode_codeword(srslte_pusch_nr_t* q, ERROR("Error encoding HARQ-ACK bits"); return SRSLTE_ERROR; } - q->G_ack = E_uci_ack; - q->G_csi1 = 0; + 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 @@ -851,6 +872,20 @@ static inline int pusch_nr_encode_codeword(srslte_pusch_nr_t* q, 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); + // 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); @@ -964,14 +999,24 @@ 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 UCI bits + // 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; - q->G_csi1 = 0; + 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 @@ -1042,6 +1087,17 @@ static inline int pusch_nr_decode_codeword(srslte_pusch_nr_t* q, } } + // 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 + return SRSLTE_SUCCESS; } diff --git a/lib/src/phy/phch/ra_ul_nr.c b/lib/src/phy/phch/ra_ul_nr.c index e78ca4d2e..55366fc28 100644 --- a/lib/src/phy/phch/ra_ul_nr.c +++ b/lib/src/phy/phch/ra_ul_nr.c @@ -373,7 +373,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); diff --git a/lib/src/phy/phch/test/CMakeLists.txt b/lib/src/phy/phch/test/CMakeLists.txt index 869d33aef..39dd38552 100644 --- a/lib/src/phy/phch/test/CMakeLists.txt +++ b/lib/src/phy/phch/test/CMakeLists.txt @@ -631,8 +631,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_ack_4_test pusch_nr_test -p 50 -m 20 -A 4) -add_nr_test(pusch_nr_ack_20_test pusch_nr_test -p 50 -m 20 -A 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/pusch_nr_test.c b/lib/src/phy/phch/test/pusch_nr_test.c index acedcdd50..8fa57630f 100644 --- a/lib/src/phy/phch/test/pusch_nr_test.c +++ b/lib/src/phy/phch/test/pusch_nr_test.c @@ -188,8 +188,8 @@ int main(int argc, char** argv) } pusch_cfg.scaling = 0.5f; - pusch_cfg.beta_harq_ack_offset = 1.500f; - pusch_cfg.beta_csi_part1_offset = 1.500f; + 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"); @@ -231,15 +231,18 @@ int main(int argc, char** argv) } // Generate CSI report bits - uint8_t csi_report[SRSLTE_UCI_NR_MAX_CSI1_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; + data_tx->uci.csi[0].none = csi_report_tx; for (uint32_t i = 0; i < nof_csi_bits; i++) { - csi_report[i] = (uint8_t)srslte_random_uniform_int_dist(rand_gen, 0, 1); + csi_report_tx[i] = (uint8_t)srslte_random_uniform_int_dist(rand_gen, 0, 1); } + + data_rx->uci.csi[0].none = csi_report_rx; } if (srslte_pusch_nr_encode(&pusch_tx, &pusch_cfg, &pusch_cfg.grant, data_tx, sf_symbols) < SRSLTE_SUCCESS) { @@ -325,6 +328,18 @@ int main(int argc, char** argv) } } + // 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); } } diff --git a/lib/src/phy/phch/uci_nr.c b/lib/src/phy/phch/uci_nr.c index 5dd7b3100..451c5b30d 100644 --- a/lib/src/phy/phch/uci_nr.c +++ b/lib/src/phy/phch/uci_nr.c @@ -26,6 +26,7 @@ #define UCI_NR_POLAR_RM_IBIL 0 #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) { @@ -113,6 +114,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; } @@ -200,7 +206,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) { @@ -219,7 +225,7 @@ static int uci_nr_A(const srslte_uci_cfg_nr_t* cfg) 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) { @@ -238,7 +244,7 @@ static int uci_nr_pack_pucch(const srslte_uci_cfg_nr_t* cfg, const srslte_uci_va 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) { @@ -270,39 +276,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: @@ -311,15 +317,67 @@ 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->pusch.modulation) { case SRSLTE_MOD_BPSK: @@ -334,38 +392,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: @@ -373,28 +431,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: @@ -403,9 +461,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; o="); + 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) { @@ -439,6 +556,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; } @@ -491,6 +609,7 @@ uci_nr_encode_11_1706_bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, ui 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; } @@ -662,25 +781,26 @@ static int uci_nr_encode(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* uci_cfg, return SRSLTE_ERROR; } -static int -uci_nr_decode(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* uci_cfg, int8_t* llr, uint32_t E_uci, bool* valid) +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, + bool* valid) { 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, valid) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; @@ -782,7 +902,14 @@ int srslte_uci_nr_decode_pucch(srslte_uci_nr_t* q, return SRSLTE_ERROR; } - if (uci_nr_decode(q, uci_cfg, llr, E_uci, &value->valid) < SRSLTE_SUCCESS) { + // 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; } @@ -802,7 +929,7 @@ 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) @@ -828,7 +955,7 @@ uint32_t srslte_uci_nr_info(const srslte_uci_data_nr_t* uci_data, char* str, uin return len; } -int srslte_uci_nr_pusch_ack_nof_re(const srslte_uci_nr_pusch_cfg_t* cfg, uint32_t O_ack) +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; @@ -866,7 +993,7 @@ int srslte_uci_nr_pusch_ack_nof_bits(const srslte_uci_nr_pusch_cfg_t* cfg, uint3 return SRSLTE_ERROR_INVALID_INPUTS; } - int Q_ack_prime = srslte_uci_nr_pusch_ack_nof_re(cfg, O_ack); + 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; @@ -935,7 +1062,7 @@ int srslte_uci_nr_decode_pusch_ack(srslte_uci_nr_t* q, } // Decode - if (uci_nr_decode(q, cfg, llr, E_uci, &value->valid) < SRSLTE_SUCCESS) { + if (uci_nr_decode(q, cfg, llr, A, E_uci, &value->valid) < SRSLTE_SUCCESS) { ERROR("Error decoding UCI"); return SRSLTE_ERROR; } @@ -943,5 +1070,133 @@ int srslte_uci_nr_decode_pusch_ack(srslte_uci_nr_t* q, // 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 + + uint32_t Q_prime_ack = 0; + int n = uci_nr_pusch_Q_prime_ack(cfg, SRSLTE_MAX(2, O_ack)); + if (n < SRSLTE_ERROR) { + ERROR("Calculating Q_prime_ack"); + return SRSLTE_ERROR; + } + + 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) { + 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_l0_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_l0_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; + } + + // 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 From 289fff9c223250080b2c1a17c61ddfa346e9dc3d Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 4 Mar 2021 19:14:19 +0100 Subject: [PATCH 13/65] Removed carrier set in UCI NR module --- lib/include/srslte/phy/phch/uci_nr.h | 9 --------- lib/src/phy/phch/uci_nr.c | 11 ----------- 2 files changed, 20 deletions(-) diff --git a/lib/include/srslte/phy/phch/uci_nr.h b/lib/include/srslte/phy/phch/uci_nr.h index 31b2385ef..913d769f0 100644 --- a/lib/include/srslte/phy/phch/uci_nr.h +++ b/lib/include/srslte/phy/phch/uci_nr.h @@ -35,7 +35,6 @@ typedef struct { } srslte_uci_nr_args_t; typedef struct { - srslte_carrier_nr_t carrier; srslte_polar_rm_t rm_tx; srslte_polar_rm_t rm_rx; srslte_polar_encoder_t encoder; @@ -74,14 +73,6 @@ SRSLTE_API uint32_t srslte_uci_nr_crc_len(uint32_t A); */ SRSLTE_API int srslte_uci_nr_init(srslte_uci_nr_t* q, const srslte_uci_nr_args_t* args); -/** - * @brief Sets NR carrier - * @param[in,out] q NR-UCI object - * @param carrier Provides carrier configuration - * @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise - */ -SRSLTE_API int srslte_uci_nr_set_carrier(srslte_uci_nr_t* q, const srslte_carrier_nr_t* carrier); - /** * @brief Deallocates NR-UCI encoder/decoder object * @param[in,out] q NR-UCI object diff --git a/lib/src/phy/phch/uci_nr.c b/lib/src/phy/phch/uci_nr.c index 451c5b30d..f1c025a14 100644 --- a/lib/src/phy/phch/uci_nr.c +++ b/lib/src/phy/phch/uci_nr.c @@ -123,17 +123,6 @@ int srslte_uci_nr_init(srslte_uci_nr_t* q, const srslte_uci_nr_args_t* args) return SRSLTE_SUCCESS; } -int srslte_uci_nr_set_carrier(srslte_uci_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_uci_nr_free(srslte_uci_nr_t* q) { if (q == NULL) { From 2b9bd1173e0a2c6b6308543e19fd6d2fa8574301 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 8 Mar 2021 11:48:02 +0100 Subject: [PATCH 14/65] More NR-PUSCH UCI bit multiplexing --- lib/include/srslte/phy/phch/pusch_nr.h | 1 + lib/src/phy/phch/pusch_nr.c | 182 +++++++++++++++---------- lib/src/phy/phch/uci_nr.c | 21 ++- 3 files changed, 130 insertions(+), 74 deletions(-) diff --git a/lib/include/srslte/phy/phch/pusch_nr.h b/lib/include/srslte/phy/phch/pusch_nr.h index 6f37ee646..2db7268e4 100644 --- a/lib/include/srslte/phy/phch/pusch_nr.h +++ b/lib/include/srslte/phy/phch/pusch_nr.h @@ -59,6 +59,7 @@ typedef struct SRSLTE_API { 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 diff --git a/lib/src/phy/phch/pusch_nr.c b/lib/src/phy/phch/pusch_nr.c index 89c2c0a30..89b5159cd 100644 --- a/lib/src/phy/phch/pusch_nr.c +++ b/lib/src/phy/phch/pusch_nr.c @@ -471,6 +471,11 @@ pusch_nr_cinit(const srslte_carrier_nr_t* carrier, const srslte_sch_cfg_nr_t* cf 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; @@ -582,6 +587,15 @@ static inline int pusch_nr_fill_uci_cfg(srslte_pusch_nr_t* q, const srslte_sch_c // 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) { + q->G_ulsch = 0; + 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 @@ -602,11 +616,15 @@ static int pusch_nr_gen_mux_uci(srslte_pusch_nr_t* q, const srslte_uci_cfg_nr_t* uint32_t Nl = cfg->pusch.nof_layers; uint32_t Qm = srslte_mod_bits_x_symbol(cfg->pusch.modulation); - // If 2 or less HARQ-ACK bits, use reserve + // 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) { - G_ack_rvd = G_ack; - G_ack = 0; + // 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 @@ -704,7 +722,7 @@ static int pusch_nr_gen_mux_uci(srslte_pusch_nr_t* q, const srslte_uci_cfg_nr_t* } csi1_m_re_count--; csi1_i++; - } else if (csi2_m_re_count != 0 && csi2_i % csi2_d == 0 && m_csi2_count < G_csi2) { + } 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; } @@ -716,14 +734,20 @@ static int pusch_nr_gen_mux_uci(srslte_pusch_nr_t* q, const srslte_uci_cfg_nr_t* pos_ulsch[m_ulsch_count++] = m_all_count + j; } ulsch_m_re_count--; - csi1_i++; - csi2_i++; + if (!reserved) { + csi1_i++; + csi2_i++; + } } - // Set reserved bits + // Set reserved bits only if there are ACK bits if (reserved) { - for (uint32_t j = 0; j < Nl * Qm; j++) { - pos_ack[m_ack_count++] = m_all_count + j; + 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--; } @@ -751,12 +775,13 @@ static int pusch_nr_gen_mux_uci(srslte_pusch_nr_t* q, const srslte_uci_cfg_nr_t* q->G_ulsch = m_ulsch_count; // Assert Number of bits - if (G_ack_rvd != 0 && G_ack_rvd != m_ack_count) { + 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); } @@ -770,7 +795,7 @@ static int pusch_nr_gen_mux_uci(srslte_pusch_nr_t* q, const srslte_uci_cfg_nr_t* DEBUG("UL-SCH bit positions:"); srslte_vec_fprint_i(stdout, (int*)pos_ulsch, m_ulsch_count); } - if (m_ack_count != 0) { + 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); } @@ -843,34 +868,41 @@ static inline int pusch_nr_encode_codeword(srslte_pusch_nr_t* q, return SRSLTE_ERROR; } - // Multiplex UL-SCH - for (uint32_t i = 0; i < q->G_ulsch; i++) { - q->b[tb->cw_idx][q->pos_ulsch[i]] = q->g_ulsch[i]; - } + // 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 CSI part 1 - for (uint32_t i = 0; i < q->G_csi1; i++) { - q->b[tb->cw_idx][q->pos_csi1[i]] = q->g_csi1[i]; - } + // 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 2 - for (uint32_t i = 0; i < q->G_csi2; i++) { - q->b[tb->cw_idx][q->pos_csi2[i]] = q->g_csi2[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 HARQ-ACK - for (uint32_t i = 0; i < q->G_ack; i++) { - q->b[tb->cw_idx][q->pos_ack[i]] = q->g_ack[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) { @@ -1044,60 +1076,70 @@ static inline int pusch_nr_decode_codeword(srslte_pusch_nr_t* q, srslte_vec_fprint_bs(stdout, llr, tb->nof_bits); } - // 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 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 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 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]]; + // 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 (q->G_ulsch != 0) { - if (srslte_ulsch_nr_decode(&q->sch, &cfg->sch_cfg, tb, g_ulsch, res->payload, &res->crc) < SRSLTE_SUCCESS) { + 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; } } - // 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 - return SRSLTE_SUCCESS; } diff --git a/lib/src/phy/phch/uci_nr.c b/lib/src/phy/phch/uci_nr.c index f1c025a14..bed5e35e6 100644 --- a/lib/src/phy/phch/uci_nr.c +++ b/lib/src/phy/phch/uci_nr.c @@ -451,7 +451,7 @@ static int uci_nr_encode_2bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg } if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) { - UCI_NR_INFO_TX("Two bit encoded NR-UCI; o="); + UCI_NR_INFO_TX("Two bit encoded NR-UCI; E=%d; o=", E); srslte_vec_fprint_b(stdout, o, E); } @@ -982,6 +982,11 @@ int srslte_uci_nr_pusch_ack_nof_bits(const srslte_uci_nr_pusch_cfg_t* cfg, uint3 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"); @@ -1006,10 +1011,13 @@ int srslte_uci_nr_encode_pusch_ack(srslte_uci_nr_t* q, // 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; - q->bit_sequence[0] = (cfg->o_ack == 0) ? 0 : value->ack[0]; + 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); } @@ -1142,6 +1150,11 @@ int srslte_uci_nr_encode_pusch_csi1(srslte_uci_nr_t* q, 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) { From 05f4d6af717640215b772b0f613ddf998de63319 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 8 Mar 2021 16:28:05 +0100 Subject: [PATCH 15/65] Fix and validated UCI multiplex in NR-PUSCH --- lib/src/phy/phch/uci_nr.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/src/phy/phch/uci_nr.c b/lib/src/phy/phch/uci_nr.c index bed5e35e6..199d8572a 100644 --- a/lib/src/phy/phch/uci_nr.c +++ b/lib/src/phy/phch/uci_nr.c @@ -23,7 +23,7 @@ #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 @@ -640,12 +640,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); } } @@ -1079,20 +1084,15 @@ static int uci_nr_pusch_Q_prime_csi1(const srslte_uci_nr_pusch_cfg_t* cfg, uint3 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 - uint32_t Q_prime_ack = 0; - int n = uci_nr_pusch_Q_prime_ack(cfg, SRSLTE_MAX(2, O_ack)); - if (n < SRSLTE_ERROR) { + 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; - 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)) { @@ -1103,12 +1103,12 @@ static int uci_nr_pusch_Q_prime_csi1(const srslte_uci_nr_pusch_cfg_t* cfg, uint3 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_l0_sum - Q_prime_ack); + 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_l0_sum) - Q_prime_ack); + ceilf(cfg->alpha * M_uci_sum) - Q_prime_ack); } int srslte_uci_nr_pusch_csi1_nof_bits(const srslte_uci_cfg_nr_t* cfg) From a03c78a7771330a4f9770812af8bed6f125dfa98 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 8 Mar 2021 16:50:47 +0100 Subject: [PATCH 16/65] Fix NR-PUSCH defect --- lib/src/phy/phch/pusch_nr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/src/phy/phch/pusch_nr.c b/lib/src/phy/phch/pusch_nr.c index 89b5159cd..519c3b20c 100644 --- a/lib/src/phy/phch/pusch_nr.c +++ b/lib/src/phy/phch/pusch_nr.c @@ -592,7 +592,6 @@ static int pusch_nr_gen_mux_uci(srslte_pusch_nr_t* q, const srslte_uci_cfg_nr_t* // Check if UCI multiplexing is NOT required if (!q->uci_mux) { - q->G_ulsch = 0; return SRSLTE_SUCCESS; } @@ -1133,7 +1132,7 @@ static inline int pusch_nr_decode_codeword(srslte_pusch_nr_t* q, } // Decode Ul-SCH - if (q->G_ulsch != 0) { + 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; From d77b6e1d9c9939fd97cde663808174a2231d1ca2 Mon Sep 17 00:00:00 2001 From: Francisco Date: Mon, 8 Mar 2021 22:36:32 +0000 Subject: [PATCH 17/65] sched,optimization,refactor - use of custom formatter that avoids mallocs for getting bitmasks strings in hex and binary formats --- lib/include/srslte/adt/bounded_bitset.h | 74 ++++++++++++++----- lib/include/srslte/adt/bounded_vector.h | 1 + lib/test/adt/bounded_bitset_test.cc | 37 +++++++++- .../stack/mac/sched_phy_ch/sf_cch_allocator.h | 2 +- srsenb/src/stack/mac/sched_grid.cc | 23 ++++-- srsenb/src/stack/mac/sched_helpers.cc | 14 +++- .../mac/sched_phy_ch/sf_cch_allocator.cc | 8 +- srsenb/test/mac/sched_common_test_suite.cc | 18 ++--- 8 files changed, 130 insertions(+), 47 deletions(-) diff --git a/lib/include/srslte/adt/bounded_bitset.h b/lib/include/srslte/adt/bounded_bitset.h index 7b05889d1..f691c0819 100644 --- a/lib/include/srslte/adt/bounded_bitset.h +++ b/lib/include/srslte/adt/bounded_bitset.h @@ -14,6 +14,7 @@ #define SRSLTE_DYN_BITSET_H #include "adt_utils.h" +#include "srslte/srslog/bundled/fmt/format.h" #include #include #include @@ -219,24 +220,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 @@ -248,19 +250,21 @@ 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: @@ -318,7 +322,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; @@ -348,4 +352,34 @@ inline bounded_bitset fliplr(const bounded_bitset& oth } // namespace srslte +/// Custom formatter for bounded_bitset +template +struct fmt::formatter > { + enum { hexadecimal, binary } mode = binary; + + template + auto parse(ParseContext& ctx) -> decltype(ctx.begin()) + { + auto it = ctx.begin(); + while (*it != '\0' 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()); + } +}; + #endif // SRSLTE_DYN_BITSET_H diff --git a/lib/include/srslte/adt/bounded_vector.h b/lib/include/srslte/adt/bounded_vector.h index 2b4e102c8..c1cf124b9 100644 --- a/lib/include/srslte/adt/bounded_vector.h +++ b/lib/include/srslte/adt/bounded_vector.h @@ -27,6 +27,7 @@ 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> diff --git a/lib/test/adt/bounded_bitset_test.cc b/lib/test/adt/bounded_bitset_test.cc index c4eee3b9c..1eaf2970b 100644 --- a/lib/test/adt/bounded_bitset_test.cc +++ b/lib/test/adt/bounded_bitset_test.cc @@ -95,7 +95,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); @@ -104,11 +104,46 @@ 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 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); + printf("Success\n"); 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 47da9e7d9..ca5ba2674 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 @@ -32,7 +32,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")) {} diff --git a/srsenb/src/stack/mac/sched_grid.cc b/srsenb/src/stack/mac/sched_grid.cc index 63e140d16..a7be1f2ee 100644 --- a/srsenb/src/stack/mac/sched_grid.cc +++ b/srsenb/src/stack/mac/sched_grid.cc @@ -156,9 +156,9 @@ 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()); + fmt::memory_buffer buffer; + prach_mask.to_hex(buffer); + logger.debug("SCHED: Allocated PRACH RBs for tti_tx_ul=%d. Mask: 0x%s", to_tx_ul(tti_rx).to_uint(), buffer.data()); } // internal state @@ -281,9 +281,12 @@ 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()) { + fmt::memory_buffer ulmask_buffer, prbmask_buffer; + ul_mask.to_hex(ulmask_buffer); + prbmask.to_hex(prbmask_buffer); 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()); + ulmask_buffer.data(), + prbmask_buffer.data()); ret = alloc_outcome_t::ERROR; } ul_mask |= prbmask; @@ -826,23 +829,27 @@ 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) { + fmt::memory_buffer buffer; + data_alloc.user_mask.to_hex(buffer); logger.warning("SCHED: DL %s failed rnti=0x%x, pid=%d, mask=%s, tbs=%d, buffer=%d", is_newtx ? "tx" : "retx", user->get_rnti(), data_alloc.pid, - data_alloc.user_mask.to_hex().c_str(), + buffer.data(), tbs, user->get_requested_dl_bytes(cc_cfg->enb_cc_idx).stop()); 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", + fmt::memory_buffer buffer; + data_alloc.user_mask.to_hex(buffer); + logger.info("SCHED: DL %s rnti=0x%x, cc=%d, pid=%d, mask=%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(), + buffer.data(), data->dci.location.L, data->dci.location.ncce, dl_harq.nof_retx(0) + dl_harq.nof_retx(1), diff --git a/srsenb/src/stack/mac/sched_helpers.cc b/srsenb/src/stack/mac/sched_helpers.cc index 1794dcb57..46531973d 100644 --- a/srsenb/src/stack/mac/sched_helpers.cc +++ b/srsenb/src/stack/mac/sched_helpers.cc @@ -15,10 +15,10 @@ #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 { @@ -26,6 +26,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/sf_cch_allocator.cc b/srsenb/src/stack/mac/sched_phy_ch/sf_cch_allocator.cc index 045f0beee..5934f3c31 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 @@ -307,15 +307,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/test/mac/sched_common_test_suite.cc b/srsenb/test/mac/sched_common_test_suite.cc index 288b2e5b8..2d9f2b787 100644 --- a/srsenb/test/mac/sched_common_test_suite.cc +++ b/srsenb/test/mac/sched_common_test_suite.cc @@ -32,7 +32,7 @@ int test_pusch_collisions(const sf_output_res_t& sf_out, uint32_t enb_cc_idx, co 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("{:x}", ul_allocs).c_str()); } ul_allocs.fill(alloc.start(), alloc.stop(), true); return SRSLTE_SUCCESS; @@ -64,8 +64,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; } @@ -105,8 +105,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; @@ -150,8 +150,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; } @@ -246,8 +246,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; } From 1ffc4cef868a8c075628df5027c2c83befdaea96 Mon Sep 17 00:00:00 2001 From: Francisco Date: Mon, 8 Mar 2021 22:54:32 +0000 Subject: [PATCH 18/65] rlc am,optimization - change helper log methods to avoid mallocs --- lib/include/srslte/upper/rlc_am_lte.h | 28 ++++----- lib/src/upper/rlc_am_lte.cc | 86 ++++++++++++++------------- lib/test/upper/rlc_am_test.cc | 46 +++++++------- 3 files changed, 82 insertions(+), 78 deletions(-) diff --git a/lib/include/srslte/upper/rlc_am_lte.h b/lib/include/srslte/upper/rlc_am_lte.h index 5bf0bc00f..da1b066bb 100644 --- a/lib/include/srslte/upper/rlc_am_lte.h +++ b/lib/include/srslte/upper/rlc_am_lte.h @@ -345,8 +345,8 @@ private: // Tx windows rlc_ringbuffer_t tx_window; - pdu_retx_queue retx_queue; - std::vector notify_info_vec; + pdu_retx_queue retx_queue; + std::vector notify_info_vec; // Mutexes pthread_mutex_t mutex; @@ -462,18 +462,18 @@ void rlc_am_read_status_pdu(uint8_t* payload, uint32_t nof_bytes, rlc_status_pdu void rlc_am_write_status_pdu(rlc_status_pdu_t* status, byte_buffer_t* pdu); int rlc_am_write_status_pdu(rlc_status_pdu_t* status, uint8_t* payload); -uint32_t rlc_am_packed_length(rlc_amd_pdu_header_t* header); -uint32_t rlc_am_packed_length(rlc_status_pdu_t* status); -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); -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); -bool rlc_am_not_start_aligned(const uint8_t fi); +uint32_t rlc_am_packed_length(rlc_amd_pdu_header_t* header); +uint32_t rlc_am_packed_length(rlc_status_pdu_t* status); +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); +fmt::memory_buffer rlc_am_status_pdu_to_string(rlc_status_pdu_t* status); +fmt::memory_buffer rlc_amd_pdu_header_to_string(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); +bool rlc_am_not_start_aligned(const uint8_t fi); } // namespace srslte diff --git a/lib/src/upper/rlc_am_lte.cc b/lib/src/upper/rlc_am_lte.cc index 2a2e6a7fd..1d1fdb6f6 100644 --- a/lib/src/upper/rlc_am_lte.cc +++ b/lib/src/upper/rlc_am_lte.cc @@ -562,9 +562,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()); + logger.debug("%s", rlc_am_status_pdu_to_string(&tx_status).data()); 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()); + logger.info("%s Tx status PDU - %s", RB_NAME, rlc_am_status_pdu_to_string(&tx_status).data()); parent->rx.reset_status(); @@ -652,7 +652,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()); + logger.debug("%s", rlc_amd_pdu_header_to_string(new_header).data()); debug_state(); return (ptr - payload) + tx_window[retx.sn].buf->N_bytes; @@ -1026,7 +1026,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt 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()); + logger.debug("%s", rlc_amd_pdu_header_to_string(header).data()); debug_state(); return total_len; @@ -1045,7 +1045,7 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no 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()); + logger.info("%s Rx Status PDU: %s", RB_NAME, rlc_am_status_pdu_to_string(&status).data()); // 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 @@ -1074,10 +1074,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 @@ -1350,7 +1350,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()); + logger.debug("%s", rlc_amd_pdu_header_to_string(header).data()); // sanity check for segments not exceeding PDU length if (header.N_li > 0) { @@ -1384,7 +1384,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"); @@ -1476,7 +1476,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()); + logger.debug("%s", rlc_amd_pdu_header_to_string(header).data()); // Check inside rx window if (!inside_rx_window(header.sn)) { @@ -1941,8 +1941,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) { @@ -1954,7 +1954,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; @@ -2335,23 +2338,22 @@ 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) +fmt::memory_buffer 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; + fmt::memory_buffer buffer; + fmt::format_to(buffer, "ACK_SN = {}, N_nack = {}", status->ack_sn, status->N_nack); if (status->N_nack > 0) { - ss << ", NACK_SN = "; - for (uint32_t i = 0; i < status->N_nack; i++) { + fmt::format_to(buffer, ", 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 - << "]"; + fmt::format_to( + buffer, "[{} {}:{}]", status->nacks[i].nack_sn, status->nacks[i].so_start, status->nacks[i].so_end); } else { - ss << "[" << status->nacks[i].nack_sn << "]"; + fmt::format_to(buffer, "[{}]", status->nacks[i].nack_sn); } } } - return ss.str(); + return buffer; } std::string rlc_am_undelivered_sdu_info_to_string(const std::map& info_queue) @@ -2376,26 +2378,28 @@ 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, "]"); + return buffer; } bool rlc_am_start_aligned(const uint8_t fi) diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index bc617c268..2c3d20a55 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -2455,7 +2455,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}; @@ -2496,7 +2496,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(); @@ -2560,7 +2560,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(); @@ -2576,7 +2576,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 @@ -2622,7 +2622,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(); @@ -2637,20 +2637,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) @@ -2665,7 +2665,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; @@ -2712,7 +2712,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(); @@ -2727,7 +2727,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 @@ -2788,7 +2788,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(); @@ -2803,7 +2803,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 @@ -2824,7 +2824,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}; @@ -2867,7 +2867,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(); @@ -2882,7 +2882,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 @@ -2970,7 +2970,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(); @@ -2986,14 +2986,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}; @@ -3002,7 +3002,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}; @@ -3011,7 +3011,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}; @@ -3021,7 +3021,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}; @@ -3071,7 +3071,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; } From 5a1bf28fe192582a697cb33f55db2993c7873476 Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 9 Mar 2021 01:03:12 +0000 Subject: [PATCH 19/65] optimization - minimization of number of std::string allocations for logging --- lib/include/srslte/mac/pdu.h | 31 +++++----- lib/include/srslte/upper/gtpu.h | 6 +- lib/src/mac/pdu.cc | 58 +++++++++---------- lib/src/upper/gtpu.cc | 7 ++- lib/test/mac/pdu_test.cc | 29 +++++++--- .../hdr/stack/mac/sched_ue_ctrl/sched_harq.h | 2 + .../src/stack/mac/sched_ue_ctrl/sched_harq.cc | 18 +++--- srsenb/src/stack/mac/ue.cc | 8 ++- srsenb/src/stack/upper/gtpu.cc | 32 ++++++---- srsepc/src/spgw/gtpu.cc | 16 +++-- srsue/src/stack/mac/demux.cc | 6 +- srsue/src/stack/mac/mux.cc | 6 +- 12 files changed, 129 insertions(+), 90 deletions(-) diff --git a/lib/include/srslte/mac/pdu.h b/lib/include/srslte/mac/pdu.h index d90fb16c7..a40d3edf1 100644 --- a/lib/include/srslte/mac/pdu.h +++ b/lib/include/srslte/mac/pdu.h @@ -133,13 +133,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() << " "; + subheaders[i].to_string(buffer); + fmt::format_to(buffer, " "); } - return ss.str(); } /* Resets the Read/Write position and remaining PDU length */ @@ -289,11 +288,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; @@ -357,8 +356,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); @@ -396,7 +395,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 @@ -433,8 +432,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]; @@ -453,8 +452,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/upper/gtpu.h b/lib/include/srslte/upper/gtpu.h index 324893c35..502984e51 100644 --- a/lib/include/srslte/upper/gtpu.h +++ b/lib/include/srslte/upper/gtpu.h @@ -70,9 +70,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/src/mac/pdu.cc b/lib/src/mac/pdu.cc index 82e4f000c..71ae9470f 100644 --- a/lib/src/mac/pdu.cc +++ b/lib/src/mac/pdu.cc @@ -199,11 +199,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) @@ -897,19 +896,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: @@ -918,18 +916,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 @@ -938,20 +936,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; @@ -960,16 +958,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) @@ -1000,11 +997,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) @@ -1065,20 +1062,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/upper/gtpu.cc b/lib/src/upper/gtpu.cc index 3f7bfbd4a..2b22923ea 100644 --- a/lib/src/upper/gtpu.cc +++ b/lib/src/upper/gtpu.cc @@ -178,7 +178,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 = {}; @@ -186,9 +186,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/test/mac/pdu_test.cc b/lib/test/mac/pdu_test.cc index 1c21b5afd..2cdd536da 100644 --- a/lib/test/mac/pdu_test.cc +++ b/lib/test/mac/pdu_test.cc @@ -54,7 +54,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); @@ -72,7 +74,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()); @@ -101,7 +105,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; } @@ -500,8 +506,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", str_buffer.data()); // log mac_logger.info(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):", buffer.N_bytes); @@ -530,7 +537,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", str_buffer.data()); TESTASSERT(memcmp(buffer.msg, tv2, buffer.N_bytes) == 0); @@ -583,7 +592,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", str_buffer.data()); TESTASSERT(memcmp(buffer.msg, tv3, buffer.N_bytes) == 0); @@ -999,7 +1010,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/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_harq.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_harq.h index c2147410f..6ecfb50f4 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_harq.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_harq.h @@ -24,6 +24,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; @@ -45,6 +46,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/src/stack/mac/sched_ue_ctrl/sched_harq.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc index 5ced31492..cde622989 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc @@ -27,6 +27,8 @@ namespace srsenb { * ******************************************************/ +harq_proc::harq_proc() : logger(&srslog::fetch_basic_logger("MAC")) {} + void harq_proc::init(uint32_t id_) { id = id_; @@ -76,19 +78,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; diff --git a/srsenb/src/stack/mac/ue.cc b/srsenb/src/stack/mac/ue.cc index 8ae03fa68..09bbedc8f 100644 --- a/srsenb/src/stack/mac/ue.cc +++ b/srsenb/src/stack/mac/ue.cc @@ -255,7 +255,9 @@ 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()); + fmt::memory_buffer buffer; + mac_msg_ul.to_string(buffer); + logger.info("0x%x %s", rnti, buffer.data()); if (pcap) { pcap->write_ul_crnti(pdu, nof_bytes, rnti, true, last_tti, UL_CC_IDX); @@ -529,7 +531,9 @@ 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()); + fmt::memory_buffer str_buffer; + mac_msg_dl.to_string(str_buffer); + logger.info("0x%x %s", rnti, str_buffer.data()); } 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/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index e90778662..e6fe14b8b 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -153,12 +153,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 buffer; + srslte::gtpu_ntoa(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()); + buffer.data()); if (props != nullptr) { if (props->flush_before_teidin_present) { @@ -517,23 +519,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} > ", addrbuf.data(), 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), ", addrbuf.data(), tx_tun.teid_in); } else { fmt::format_to(strbuf2, "DL, "); } @@ -543,7 +551,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}, ", addrbuf.data(), tun.teid_in); } fmt::format_to(strbuf, "{} S1-U SDU, {}rnti=0x{:0x}, lcid={}, n_bytes={}, IPv{}", @@ -554,12 +562,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, " {} > {}", addrbuf.data(), strbuf2.data()); 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", strbuf.data()); } /**************************************************************************** diff --git a/srsepc/src/spgw/gtpu.cc b/srsepc/src/spgw/gtpu.cc index cf749272c..5a2366f5e 100644 --- a/srsepc/src/spgw/gtpu.cc +++ b/srsepc/src/spgw/gtpu.cc @@ -206,8 +206,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", buffer.data()); + buffer.clear(); + srslte::gtpu_ntoa(buffer, iph->daddr); + m_logger.debug("SGi PDU -- IP dst addr %s", buffer.data()); // Find user and control tunnel gtpu_fteid_it = m_ip_to_usr_teid.find(iph->daddr); @@ -309,8 +313,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", buffer.data()); + buffer.clear(); + srslte::gtpu_ntoa(buffer, dw_user_fteid.ipv4); + m_logger.info("Downlink eNB addr %s, U-TEID 0x%x", buffer.data(), 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/src/stack/mac/demux.cc b/srsue/src/stack/mac/demux.cc index 546508f1a..995a487f7 100644 --- a/srsue/src/stack/mac/demux.cc +++ b/srsue/src/stack/mac/demux.cc @@ -153,7 +153,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", buffer.data()); + } process_sch_pdu(&mac_msg); pdus.deallocate(mac_pdu); break; diff --git a/srsue/src/stack/mac/mux.cc b/srsue/src/stack/mac/mux.cc index 0c7aa06ad..3e8d0f592 100644 --- a/srsue/src/stack/mac/mux.cc +++ b/srsue/src/stack/mac/mux.cc @@ -285,8 +285,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", buffer.data()); Debug("Assembled MAC PDU msg size %d/%d bytes", pdu_msg.get_pdu_len() - pdu_msg.rem_size(), pdu_sz); return ret; From 0f9d73012f193db2ccd937d4e8244ce220828206 Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 9 Mar 2021 01:25:26 +0000 Subject: [PATCH 20/65] use srslte::move_callback instead of std::function in timers to avoid allocations --- lib/include/srslte/adt/move_callback.h | 2 +- lib/include/srslte/common/timers.h | 26 +++++++++++++--------- lib/include/srslte/upper/pdcp_entity_lte.h | 8 +++---- lib/src/upper/pdcp_entity_lte.cc | 10 ++++----- 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/lib/include/srslte/adt/move_callback.h b/lib/include/srslte/adt/move_callback.h index f7335af83..a1b2f920c 100644 --- a/lib/include/srslte/adt/move_callback.h +++ b/lib/include/srslte/adt/move_callback.h @@ -172,7 +172,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/timers.h b/lib/include/srslte/common/timers.h index 4daf016fb..883604a37 100644 --- a/lib/include/srslte/common/timers.h +++ b/lib/include/srslte/common/timers.h @@ -20,6 +20,7 @@ #ifndef SRSLTE_TIMERS_H #define SRSLTE_TIMERS_H +#include "srslte/adt/move_callback.h" #include "srslte/phy/utils/debug.h" #include #include @@ -45,11 +46,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_) {} @@ -79,7 +80,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_); @@ -113,7 +114,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 } @@ -121,7 +122,7 @@ class timer_handler { if (is_running()) { running = false; - if (callback) { + if (not callback.is_empty()) { callback(id()); } } @@ -164,7 +165,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_); } @@ -270,8 +274,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/upper/pdcp_entity_lte.h b/lib/include/srslte/upper/pdcp_entity_lte.h index bf982b7d6..13a017430 100644 --- a/lib/include/srslte/upper/pdcp_entity_lte.h +++ b/lib/include/srslte/upper/pdcp_entity_lte.h @@ -48,10 +48,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) { diff --git a/lib/src/upper/pdcp_entity_lte.cc b/lib/src/upper/pdcp_entity_lte.cc index b3dbefd00..c42740e2e 100644 --- a/lib/src/upper/pdcp_entity_lte.cc +++ b/lib/src/upper/pdcp_entity_lte.cc @@ -782,10 +782,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"); @@ -824,7 +824,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 From 4c1067bcf68b848041e0fcc41d512ef35a0fa0af Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 9 Mar 2021 11:29:40 +0000 Subject: [PATCH 21/65] bitset - fix compilation issue for centos7 --- lib/include/srslte/adt/bounded_bitset.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/include/srslte/adt/bounded_bitset.h b/lib/include/srslte/adt/bounded_bitset.h index f691c0819..bef2fa36f 100644 --- a/lib/include/srslte/adt/bounded_bitset.h +++ b/lib/include/srslte/adt/bounded_bitset.h @@ -352,9 +352,10 @@ inline bounded_bitset fliplr(const bounded_bitset& oth } // namespace srslte +namespace fmt { /// Custom formatter for bounded_bitset template -struct fmt::formatter > { +struct formatter > { enum { hexadecimal, binary } mode = binary; template @@ -381,5 +382,6 @@ struct fmt::formatter > { return s.template to_string(ctx.out()); } }; +} // namespace fmt #endif // SRSLTE_DYN_BITSET_H From f72cd4151cebed22cb5ae97ad0d2ceee80a4e6a3 Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 9 Mar 2021 13:31:41 +0000 Subject: [PATCH 22/65] rlc am,bugfix - fixed formatting of RLC AM header and status pdu --- lib/include/srslte/common/string_helpers.h | 7 +++++ lib/include/srslte/mac/pdu.h | 2 +- lib/include/srslte/upper/rlc_am_lte.h | 28 ++++++++++-------- lib/src/upper/rlc_am_lte.cc | 34 +++++++++++++++------- 4 files changed, 47 insertions(+), 24 deletions(-) diff --git a/lib/include/srslte/common/string_helpers.h b/lib/include/srslte/common/string_helpers.h index 0303bbde8..d51ff26fd 100644 --- a/lib/include/srslte/common/string_helpers.h +++ b/lib/include/srslte/common/string_helpers.h @@ -111,6 +111,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) +{ + fmt::format_to(mem_buffer, "{}", '\0'); + return mem_buffer.data(); +} + } // namespace srslte #endif // SRSLTE_STRING_HELPERS_H diff --git a/lib/include/srslte/mac/pdu.h b/lib/include/srslte/mac/pdu.h index a40d3edf1..28a3147a4 100644 --- a/lib/include/srslte/mac/pdu.h +++ b/lib/include/srslte/mac/pdu.h @@ -136,8 +136,8 @@ public: void to_string(fmt::memory_buffer& buffer) { for (int i = 0; i < nof_subheaders; i++) { - subheaders[i].to_string(buffer); fmt::format_to(buffer, " "); + subheaders[i].to_string(buffer); } } diff --git a/lib/include/srslte/upper/rlc_am_lte.h b/lib/include/srslte/upper/rlc_am_lte.h index da1b066bb..95d76c6e9 100644 --- a/lib/include/srslte/upper/rlc_am_lte.h +++ b/lib/include/srslte/upper/rlc_am_lte.h @@ -462,18 +462,22 @@ void rlc_am_read_status_pdu(uint8_t* payload, uint32_t nof_bytes, rlc_status_pdu void rlc_am_write_status_pdu(rlc_status_pdu_t* status, byte_buffer_t* pdu); int rlc_am_write_status_pdu(rlc_status_pdu_t* status, uint8_t* payload); -uint32_t rlc_am_packed_length(rlc_amd_pdu_header_t* header); -uint32_t rlc_am_packed_length(rlc_status_pdu_t* status); -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); -fmt::memory_buffer rlc_am_status_pdu_to_string(rlc_status_pdu_t* status); -fmt::memory_buffer rlc_amd_pdu_header_to_string(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); -bool rlc_am_not_start_aligned(const uint8_t fi); +uint32_t rlc_am_packed_length(rlc_amd_pdu_header_t* header); +uint32_t rlc_am_packed_length(rlc_status_pdu_t* status); +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); +template +void log_rlc_am_status_pdu_to_string(srslog::log_channel& log_ch, + rlc_status_pdu_t* status, + const char* fmt = "%s", + Args&&... args); +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); +bool rlc_am_not_start_aligned(const uint8_t fi); } // namespace srslte diff --git a/lib/src/upper/rlc_am_lte.cc b/lib/src/upper/rlc_am_lte.cc index 1d1fdb6f6..6cf4e7093 100644 --- a/lib/src/upper/rlc_am_lte.cc +++ b/lib/src/upper/rlc_am_lte.cc @@ -11,6 +11,7 @@ */ #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" @@ -562,9 +563,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).data()); + log_rlc_am_status_pdu_to_string(logger.debug, &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).data()); + log_rlc_am_status_pdu_to_string(logger.info, &tx_status, "%s Tx status PDU - %s", RB_NAME); parent->rx.reset_status(); @@ -652,7 +653,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).data()); + log_rlc_amd_pdu_header_to_string(logger.debug, new_header); debug_state(); return (ptr - payload) + tx_window[retx.sn].buf->N_bytes; @@ -1026,7 +1027,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt 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).data()); + log_rlc_amd_pdu_header_to_string(logger.debug, header); debug_state(); return total_len; @@ -1045,7 +1046,7 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no 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).data()); + log_rlc_am_status_pdu_to_string(logger.info, &status, "%s Rx Status PDU: %s", 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 @@ -1350,7 +1351,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).data()); + log_rlc_amd_pdu_header_to_string(logger.debug, header); // sanity check for segments not exceeding PDU length if (header.N_li > 0) { @@ -1476,7 +1477,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).data()); + log_rlc_amd_pdu_header_to_string(logger.debug, header); // Check inside rx window if (!inside_rx_window(header.sn)) { @@ -2338,8 +2339,15 @@ bool rlc_am_is_pdu_segment(uint8_t* payload) return ((*(payload) >> 6) & 0x01) == 1; } -fmt::memory_buffer rlc_am_status_pdu_to_string(rlc_status_pdu_t* status) +template +void log_rlc_am_status_pdu_to_string(srslog::log_channel& log_ch, + rlc_status_pdu_t* status, + const char* fmt, + 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) { @@ -2353,7 +2361,7 @@ fmt::memory_buffer rlc_am_status_pdu_to_string(rlc_status_pdu_t* status) } } } - return buffer; + log_ch(fmt, std::forward(args)..., to_c_str(buffer)); } std::string rlc_am_undelivered_sdu_info_to_string(const std::map& info_queue) @@ -2378,8 +2386,11 @@ std::string rlc_am_undelivered_sdu_info_to_string(const std::map Date: Tue, 9 Mar 2021 14:44:24 +0000 Subject: [PATCH 23/65] mac,bugfix - fixed formatting of MAC and scheduler user-defined types --- lib/include/srslte/adt/interval.h | 22 ++-- lib/include/srslte/common/string_helpers.h | 1 + lib/test/mac/pdu_test.cc | 6 +- srsenb/hdr/stack/mac/sched_common.h | 9 ++ srsenb/src/stack/mac/sched_carrier.cc | 19 ++-- srsenb/src/stack/mac/sched_grid.cc | 120 ++++++++++++--------- srsenb/src/stack/mac/ue.cc | 17 +-- srsenb/test/mac/sched_common_test_suite.cc | 4 +- srsue/src/stack/mac/demux.cc | 3 +- srsue/src/stack/mac/mux.cc | 3 +- 10 files changed, 122 insertions(+), 82 deletions(-) diff --git a/lib/include/srslte/adt/interval.h b/lib/include/srslte/adt/interval.h index 3f29b4722..b0c4761b4 100644 --- a/lib/include/srslte/adt/interval.h +++ b/lib/include/srslte/adt/interval.h @@ -77,8 +77,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_; @@ -134,13 +132,19 @@ interval make_intersection(const interval& lhs, const interval& rhs) return lhs & rhs; } -template -std::ostream& operator<<(std::ostream& out, const interval& interv) -{ - out << interv.to_string(); - return out; -} - } // namespace srslte +namespace fmt { + +template +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 fmt + #endif // SRSLTE_INTERVAL_H diff --git a/lib/include/srslte/common/string_helpers.h b/lib/include/srslte/common/string_helpers.h index d51ff26fd..190ba2a12 100644 --- a/lib/include/srslte/common/string_helpers.h +++ b/lib/include/srslte/common/string_helpers.h @@ -13,6 +13,7 @@ #ifndef SRSLTE_STRING_HELPERS_H #define SRSLTE_STRING_HELPERS_H +#include "srslte/srslog/bundled/fmt/format.h" #include #include #include diff --git a/lib/test/mac/pdu_test.cc b/lib/test/mac/pdu_test.cc index 2cdd536da..cd3d4fca5 100644 --- a/lib/test/mac/pdu_test.cc +++ b/lib/test/mac/pdu_test.cc @@ -508,7 +508,7 @@ int mac_sch_pdu_pack_test6() } fmt::memory_buffer str_buffer; pdu.to_string(str_buffer); - mac_logger.info("%s", str_buffer.data()); + 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 +539,7 @@ int mac_sch_pdu_pack_test6() pdu.write_packet(mac_logger); str_buffer.clear(); pdu.to_string(str_buffer); - mac_logger.info("%s", str_buffer.data()); + mac_logger.info("%s", fmt::to_string(str_buffer)); TESTASSERT(memcmp(buffer.msg, tv2, buffer.N_bytes) == 0); @@ -594,7 +594,7 @@ int mac_sch_pdu_pack_test6() pdu.write_packet(mac_logger); str_buffer.clear(); pdu.to_string(str_buffer); - mac_logger.info("%s", str_buffer.data()); + mac_logger.info("%s", fmt::to_string(str_buffer)); TESTASSERT(memcmp(buffer.msg, tv3, buffer.N_bytes) == 0); diff --git a/srsenb/hdr/stack/mac/sched_common.h b/srsenb/hdr/stack/mac/sched_common.h index 905f5257f..12a908e5d 100644 --- a/srsenb/hdr/stack/mac/sched_common.h +++ b/srsenb/hdr/stack/mac/sched_common.h @@ -109,4 +109,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/src/stack/mac/sched_carrier.cc b/srsenb/src/stack/mac/sched_carrier.cc index a871f1c8c..0b6928a64 100644 --- a/srsenb/src/stack/mac/sched_carrier.cc +++ b/srsenb/src/stack/mac/sched_carrier.cc @@ -15,6 +15,7 @@ #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/string_helpers.h" #include "srslte/interfaces/enb_rrc_interfaces.h" namespace srsenb { @@ -150,16 +151,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 a7be1f2ee..f2b8d22b6 100644 --- a/srsenb/src/stack/mac/sched_grid.cc +++ b/srsenb/src/stack/mac/sched_grid.cc @@ -13,6 +13,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; @@ -156,9 +157,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 - fmt::memory_buffer buffer; - prach_mask.to_hex(buffer); - logger.debug("SCHED: Allocated PRACH RBs for tti_tx_ul=%d. Mask: 0x%s", to_tx_ul(tti_rx).to_uint(), buffer.data()); + 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 @@ -281,12 +284,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()) { - fmt::memory_buffer ulmask_buffer, prbmask_buffer; - ul_mask.to_hex(ulmask_buffer); - prbmask.to_hex(prbmask_buffer); - logger.error("There was a collision in UL channel. current mask=0x%s, new alloc mask=0x%s", - ulmask_buffer.data(), - prbmask_buffer.data()); + 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; @@ -738,8 +738,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; @@ -749,8 +751,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, @@ -774,9 +778,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; @@ -788,13 +794,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, @@ -829,33 +837,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) { - fmt::memory_buffer buffer; - data_alloc.user_mask.to_hex(buffer); - 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, - buffer.data(), + 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 - fmt::memory_buffer buffer; - data_alloc.user_mask.to_hex(buffer); - logger.info("SCHED: DL %s rnti=0x%x, cc=%d, pid=%d, mask=%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, - buffer.data(), - 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++; } @@ -984,34 +994,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", + fmt::memory_buffer str_buffer; + fmt::format_to(str_buffer, + "SCHED: Error {} {} rnti=0x{:x}, pid={}, dci=({},{}), prb={}, bsr={}", ul_alloc.type == ul_alloc_t::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,7 +1044,9 @@ alloc_outcome_t sf_sched::alloc_msg3(sched_ue* user, const sched_interface::dl_s alloc_outcome_t ret = alloc_ul(user, msg3_alloc, sf_sched::ul_alloc_t::MSG3, 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/ue.cc b/srsenb/src/stack/mac/ue.cc index 09bbedc8f..157c23e45 100644 --- a/srsenb/src/stack/mac/ue.cc +++ b/srsenb/src/stack/mac/ue.cc @@ -16,6 +16,7 @@ #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" @@ -255,9 +256,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); - fmt::memory_buffer buffer; - mac_msg_ul.to_string(buffer); - logger.info("0x%x %s", rnti, buffer.data()); + 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); @@ -531,9 +534,11 @@ uint8_t* ue::generate_pdu(uint32_t ue_cc_idx, } } ret = mac_msg_dl.write_packet(logger); - fmt::memory_buffer str_buffer; - mac_msg_dl.to_string(str_buffer); - logger.info("0x%x %s", rnti, str_buffer.data()); + 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/test/mac/sched_common_test_suite.cc b/srsenb/test/mac/sched_common_test_suite.cc index 2d9f2b787..1e9f68710 100644 --- a/srsenb/test/mac/sched_common_test_suite.cc +++ b/srsenb/test/mac/sched_common_test_suite.cc @@ -26,12 +26,12 @@ 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(), + fmt::format("{}", alloc).c_str(), fmt::format("{:x}", ul_allocs).c_str()); } ul_allocs.fill(alloc.start(), alloc.stop(), true); diff --git a/srsue/src/stack/mac/demux.cc b/srsue/src/stack/mac/demux.cc index 995a487f7..c185c02af 100644 --- a/srsue/src/stack/mac/demux.cc +++ b/srsue/src/stack/mac/demux.cc @@ -16,6 +16,7 @@ #define Debug(fmt, ...) logger.debug(fmt, ##__VA_ARGS__) #include "srsue/hdr/stack/mac/demux.h" +#include "srslte/common/string_helpers.h" #include "srslte/interfaces/ue_phy_interfaces.h" namespace srsue { @@ -156,7 +157,7 @@ void demux::process_pdu(uint8_t* mac_pdu, uint32_t nof_bytes, srslte::pdu_queue: { fmt::memory_buffer buffer; mac_msg.to_string(buffer); - Info("%s", buffer.data()); + Info("%s", srslte::to_c_str(buffer)); } process_sch_pdu(&mac_msg); pdus.deallocate(mac_pdu); diff --git a/srsue/src/stack/mac/mux.cc b/srsue/src/stack/mac/mux.cc index 3e8d0f592..26e478e22 100644 --- a/srsue/src/stack/mac/mux.cc +++ b/srsue/src/stack/mac/mux.cc @@ -16,6 +16,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 @@ -288,7 +289,7 @@ uint8_t* mux::pdu_get(srslte::byte_buffer_t* payload, uint32_t pdu_sz) uint8_t* ret = pdu_msg.write_packet(logger); fmt::memory_buffer buffer; pdu_msg.to_string(buffer); - Info("%s", buffer.data()); + 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; From 4969c98665f22fa8db0a7b46c537868a033c3e39 Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 9 Mar 2021 14:51:47 +0000 Subject: [PATCH 24/65] gtpu,bugfix - fixed formatting of addresses in GTPU --- srsenb/src/stack/upper/gtpu.cc | 17 +++++++++-------- srsepc/src/spgw/gtpu.cc | 9 +++++---- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/srsenb/src/stack/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index e6fe14b8b..3119e2778 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -12,6 +12,7 @@ #include "srslte/upper/gtpu.h" #include "srsenb/hdr/stack/upper/gtpu.h" #include "srslte/common/network_utils.h" +#include "srslte/common/string_helpers.h" #include "srslte/interfaces/enb_interfaces.h" #include "srslte/interfaces/enb_pdcp_interfaces.h" #include @@ -153,14 +154,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 buffer; - srslte::gtpu_ntoa(buffer, htonl(addr)); + 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, - buffer.data()); + srslte::to_c_str(str_buffer)); if (props != nullptr) { if (props->flush_before_teidin_present) { @@ -534,14 +535,14 @@ void gtpu::log_message(tunnel& tun, bool is_rx, srslte::span pdu, int p srslte::gtpu_ntoa(addrbuf, htonl(tun.spgw_addr)); if (is_rx) { dir = "Rx"; - fmt::format_to(strbuf2, "{}:0x{:0x} > ", addrbuf.data(), 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); addrbuf.clear(); srslte::gtpu_ntoa(addrbuf, htonl(tx_tun.spgw_addr)); - fmt::format_to(strbuf2, "{}:0x{:0x} (forwarded), ", addrbuf.data(), tx_tun.teid_in); + fmt::format_to(strbuf2, "{}:0x{:0x} (forwarded), ", srslte::to_c_str(addrbuf), tx_tun.teid_in); } else { fmt::format_to(strbuf2, "DL, "); } @@ -551,7 +552,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}, ", addrbuf.data(), 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{}", @@ -566,12 +567,12 @@ void gtpu::log_message(tunnel& tun, bool is_rx, srslte::span pdu, int p strbuf2.clear(); srslte::gtpu_ntoa(addrbuf, ip_pkt->saddr); srslte::gtpu_ntoa(strbuf2, ip_pkt->daddr); - fmt::format_to(strbuf, " {} > {}", addrbuf.data(), strbuf2.data()); + 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(), "%s", strbuf.data()); + logger.info(pdu.data(), pdu.size(), "%s", srslte::to_c_str(strbuf)); } /**************************************************************************** diff --git a/srsepc/src/spgw/gtpu.cc b/srsepc/src/spgw/gtpu.cc index 5a2366f5e..06772f44a 100644 --- a/srsepc/src/spgw/gtpu.cc +++ b/srsepc/src/spgw/gtpu.cc @@ -12,6 +12,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 @@ -208,10 +209,10 @@ void spgw::gtpu::handle_sgi_pdu(srslte::unique_byte_buffer_t msg) m_logger.debug("SGi PDU -- IP version %d, Total length %d", int(iph->version), ntohs(iph->tot_len)); fmt::memory_buffer buffer; srslte::gtpu_ntoa(buffer, iph->saddr); - m_logger.debug("SGi PDU -- IP src addr %s", buffer.data()); + 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", buffer.data()); + 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); @@ -315,10 +316,10 @@ bool spgw::gtpu::modify_gtpu_tunnel(in_addr_t ue_ipv4, srslte::gtpc_f_teid_ie dw m_logger.info("Modifying GTP-U Tunnel."); fmt::memory_buffer buffer; srslte::gtpu_ntoa(buffer, ue_ipv4); - m_logger.info("UE IP %s", buffer.data()); + 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", buffer.data(), dw_user_fteid.teid); + 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; From ee77343f26702acbfe22f4ad98b75ac0b2ae1791 Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 9 Mar 2021 15:13:09 +0000 Subject: [PATCH 25/65] fix compilation issue for centos7 --- lib/include/srslte/common/string_helpers.h | 2 +- lib/include/srslte/upper/rlc_am_lte.h | 15 ++--- lib/src/upper/rlc_am_lte.cc | 67 +++++++++++++--------- 3 files changed, 45 insertions(+), 39 deletions(-) diff --git a/lib/include/srslte/common/string_helpers.h b/lib/include/srslte/common/string_helpers.h index 190ba2a12..ca514380a 100644 --- a/lib/include/srslte/common/string_helpers.h +++ b/lib/include/srslte/common/string_helpers.h @@ -115,7 +115,7 @@ 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) { - fmt::format_to(mem_buffer, "{}", '\0'); + mem_buffer.push_back('\0'); return mem_buffer.data(); } diff --git a/lib/include/srslte/upper/rlc_am_lte.h b/lib/include/srslte/upper/rlc_am_lte.h index 95d76c6e9..8e7dbef0e 100644 --- a/lib/include/srslte/upper/rlc_am_lte.h +++ b/lib/include/srslte/upper/rlc_am_lte.h @@ -468,16 +468,11 @@ 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); -template -void log_rlc_am_status_pdu_to_string(srslog::log_channel& log_ch, - rlc_status_pdu_t* status, - const char* fmt = "%s", - Args&&... args); -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); -bool rlc_am_not_start_aligned(const uint8_t fi); +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); +bool rlc_am_not_start_aligned(const uint8_t fi); } // namespace srslte diff --git a/lib/src/upper/rlc_am_lte.cc b/lib/src/upper/rlc_am_lte.cc index 6cf4e7093..5e73b420c 100644 --- a/lib/src/upper/rlc_am_lte.cc +++ b/lib/src/upper/rlc_am_lte.cc @@ -25,6 +25,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_, @@ -563,9 +599,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); - log_rlc_am_status_pdu_to_string(logger.debug, &tx_status); + log_rlc_am_status_pdu_to_string(logger.debug, "%s", &tx_status); if (pdu_len > 0 && nof_bytes >= static_cast(pdu_len)) { - log_rlc_am_status_pdu_to_string(logger.info, &tx_status, "%s Tx status PDU - %s", RB_NAME); + log_rlc_am_status_pdu_to_string(logger.info, "%s Tx status PDU - %s", &tx_status, RB_NAME); parent->rx.reset_status(); @@ -1046,7 +1082,7 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no rlc_status_pdu_t status; rlc_am_read_status_pdu(payload, nof_bytes, &status); - log_rlc_am_status_pdu_to_string(logger.info, &status, "%s Rx Status PDU: %s", RB_NAME); + 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 @@ -2339,31 +2375,6 @@ bool rlc_am_is_pdu_segment(uint8_t* payload) return ((*(payload) >> 6) & 0x01) == 1; } -template -void log_rlc_am_status_pdu_to_string(srslog::log_channel& log_ch, - rlc_status_pdu_t* status, - const char* fmt, - 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, std::forward(args)..., to_c_str(buffer)); -} - std::string rlc_am_undelivered_sdu_info_to_string(const std::map& info_queue) { std::string str = "\n"; From bea78512e5883bc24f64839f809d492ed7052215 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 9 Mar 2021 12:50:55 +0000 Subject: [PATCH 26/65] Make sure the eNB exits with error when some invalid configs are provided --- srsenb/src/enb_cfg_parser.cc | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 7f3e43c76..40d72d924 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -252,7 +252,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"]); @@ -260,7 +260,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? @@ -397,11 +397,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); @@ -434,6 +434,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; } } @@ -448,11 +449,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; } } @@ -463,22 +466,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; } } @@ -488,11 +495,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; } } @@ -507,18 +516,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); @@ -538,12 +550,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); @@ -737,7 +751,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"; @@ -757,11 +771,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; } } } From 20cbc48f909b88546f4e73d25094201713b88c91 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 9 Mar 2021 14:41:46 +0100 Subject: [PATCH 27/65] rlc_am_lte: refactor PDCP/RLC interface to use fix sized data structure this patch replaces the std::vector type used in the interface between PDCP and RLC to signal delivery status between both layers. The new data type is a configurable but fixed-size vector. The RLC AM doesn't need to dynamically allocate the vector for every SN but uses the tx_window for storage. --- lib/include/srslte/adt/bounded_vector.h | 1 + .../srslte/interfaces/enb_pdcp_interfaces.h | 4 +- .../srslte/interfaces/gnb_interfaces.h | 4 +- .../srslte/interfaces/pdcp_interface_types.h | 6 ++ .../srslte/interfaces/ue_pdcp_interfaces.h | 4 +- lib/include/srslte/upper/pdcp.h | 4 +- lib/include/srslte/upper/pdcp_entity_base.h | 4 +- lib/include/srslte/upper/pdcp_entity_lte.h | 4 +- lib/include/srslte/upper/pdcp_entity_nr.h | 4 +- lib/include/srslte/upper/rlc_am_lte.h | 15 ++-- lib/include/srslte/upper/rlc_common.h | 1 + lib/src/upper/pdcp.cc | 4 +- lib/src/upper/pdcp_entity_lte.cc | 4 +- lib/src/upper/pdcp_entity_nr.cc | 4 +- lib/src/upper/rlc_am_lte.cc | 70 ++++++++++++------- lib/test/upper/pdcp_lte_test_discard_sdu.cc | 6 +- lib/test/upper/rlc_am_test.cc | 4 +- lib/test/upper/rlc_common_test.cc | 4 +- lib/test/upper/rlc_stress_test.cc | 4 +- lib/test/upper/rlc_test_common.h | 4 +- srsenb/hdr/stack/upper/pdcp.h | 4 +- srsenb/hdr/stack/upper/pdcp_nr.h | 4 +- srsenb/hdr/stack/upper/rlc.h | 4 +- srsenb/hdr/stack/upper/rlc_nr.h | 4 +- srsenb/src/stack/upper/pdcp.cc | 4 +- srsenb/src/stack/upper/pdcp_nr.cc | 4 +- srsenb/src/stack/upper/rlc.cc | 4 +- srsenb/src/stack/upper/rlc_nr.cc | 4 +- 28 files changed, 109 insertions(+), 78 deletions(-) diff --git a/lib/include/srslte/adt/bounded_vector.h b/lib/include/srslte/adt/bounded_vector.h index c1cf124b9..9f4a08733 100644 --- a/lib/include/srslte/adt/bounded_vector.h +++ b/lib/include/srslte/adt/bounded_vector.h @@ -127,6 +127,7 @@ public: 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() diff --git a/lib/include/srslte/interfaces/enb_pdcp_interfaces.h b/lib/include/srslte/interfaces/enb_pdcp_interfaces.h index ba5ee32f3..719c46e4f 100644 --- a/lib/include/srslte/interfaces/enb_pdcp_interfaces.h +++ b/lib/include/srslte/interfaces/enb_pdcp_interfaces.h @@ -53,8 +53,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 dcfd6be86..dc0a36374 100644 --- a/lib/include/srslte/interfaces/gnb_interfaces.h +++ b/lib/include/srslte/interfaces/gnb_interfaces.h @@ -83,8 +83,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 e4f21a656..5db48df2e 100644 --- a/lib/include/srslte/interfaces/pdcp_interface_types.h +++ b/lib/include/srslte/interfaces/pdcp_interface_types.h @@ -18,6 +18,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 @@ -168,6 +169,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_pdcp_interfaces.h b/lib/include/srslte/interfaces/ue_pdcp_interfaces.h index 681902b54..0a66dcf88 100644 --- a/lib/include/srslte/interfaces/ue_pdcp_interfaces.h +++ b/lib/include/srslte/interfaces/ue_pdcp_interfaces.h @@ -44,8 +44,8 @@ public: 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 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/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index 12366719b..36401bfc1 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -59,8 +59,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 213738dae..1d30146fb 100644 --- a/lib/include/srslte/upper/pdcp_entity_base.h +++ b/lib/include/srslte/upper/pdcp_entity_base.h @@ -113,8 +113,8 @@ public: // 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 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; diff --git a/lib/include/srslte/upper/pdcp_entity_lte.h b/lib/include/srslte/upper/pdcp_entity_lte.h index 13a017430..259c903b9 100644 --- a/lib/include/srslte/upper/pdcp_entity_lte.h +++ b/lib/include/srslte/upper/pdcp_entity_lte.h @@ -120,8 +120,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(); diff --git a/lib/include/srslte/upper/pdcp_entity_nr.h b/lib/include/srslte/upper/pdcp_entity_nr.h index 12baf2903..02d31ea69 100644 --- a/lib/include/srslte/upper/pdcp_entity_nr.h +++ b/lib/include/srslte/upper/pdcp_entity_nr.h @@ -51,8 +51,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_; } diff --git a/lib/include/srslte/upper/rlc_am_lte.h b/lib/include/srslte/upper/rlc_am_lte.h index 8e7dbef0e..b66b83c9b 100644 --- a/lib/include/srslte/upper/rlc_am_lte.h +++ b/lib/include/srslte/upper/rlc_am_lte.h @@ -20,6 +20,7 @@ #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" @@ -42,12 +43,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 { @@ -346,7 +347,7 @@ private: // Tx windows rlc_ringbuffer_t tx_window; pdu_retx_queue retx_queue; - std::vector notify_info_vec; + pdcp_sn_vector_t notify_info_vec; // Mutexes pthread_mutex_t mutex; diff --git a/lib/include/srslte/upper/rlc_common.h b/lib/include/srslte/upper/rlc_common.h index ab32faa53..4c8e72836 100644 --- a/lib/include/srslte/upper/rlc_common.h +++ b/lib/include/srslte/upper/rlc_common.h @@ -28,6 +28,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, diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index 7d6ca647a..17f3371dc 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -285,7 +285,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); @@ -294,7 +294,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 c42740e2e..ef68ccbfa 100644 --- a/lib/src/upper/pdcp_entity_lte.cc +++ b/lib/src/upper/pdcp_entity_lte.cc @@ -652,7 +652,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; @@ -682,7 +682,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; diff --git a/lib/src/upper/pdcp_entity_nr.cc b/lib/src/upper/pdcp_entity_nr.cc index 863270e84..7cd034d84 100644 --- a/lib/src/upper/pdcp_entity_nr.cc +++ b/lib/src/upper/pdcp_entity_nr.cc @@ -203,12 +203,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()); } diff --git a/lib/src/upper/rlc_am_lte.cc b/lib/src/upper/rlc_am_lte.cc index 5e73b420c..c207a3186 100644 --- a/lib/src/upper/rlc_am_lte.cc +++ b/lib/src/upper/rlc_am_lte.cc @@ -211,7 +211,6 @@ rlc_am_lte::rlc_am_lte_tx::rlc_am_lte_tx(rlc_am_lte* parent_) : 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() @@ -226,7 +225,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 @@ -890,6 +896,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 @@ -912,22 +926,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); @@ -939,7 +951,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; } @@ -992,7 +1008,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; } @@ -1021,7 +1041,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) { @@ -1044,19 +1063,16 @@ 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); @@ -1204,7 +1220,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]; @@ -1221,7 +1237,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); + } } } } diff --git a/lib/test/upper/pdcp_lte_test_discard_sdu.cc b/lib/test/upper/pdcp_lte_test_discard_sdu.cc index d5582e307..5b700e39c 100644 --- a/lib/test/upper/pdcp_lte_test_discard_sdu.cc +++ b/lib/test/upper/pdcp_lte_test_discard_sdu.cc @@ -45,7 +45,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 @@ -103,7 +104,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/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index 2c3d20a55..fafc7cea4 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -52,7 +52,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) { @@ -62,7 +62,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 diff --git a/lib/test/upper/rlc_common_test.cc b/lib/test/upper/rlc_common_test.cc index 79d223dc6..2fae1781e 100644 --- a/lib/test/upper/rlc_common_test.cc +++ b/lib/test/upper/rlc_common_test.cc @@ -46,8 +46,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 4313f327e..b1225f76d 100644 --- a/lib/test/upper/rlc_stress_test.cc +++ b/lib/test/upper/rlc_stress_test.cc @@ -368,8 +368,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) {} - 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_test_common.h b/lib/test/upper/rlc_test_common.h index c97cf9a21..6bf75d5a3 100644 --- a/lib/test/upper/rlc_test_common.h +++ b/lib/test/upper/rlc_test_common.h @@ -51,8 +51,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/srsenb/hdr/stack/upper/pdcp.h b/srsenb/hdr/stack/upper/pdcp.h index 14d9469e5..2f9d4dfe7 100644 --- a/srsenb/hdr/stack/upper/pdcp.h +++ b/srsenb/hdr/stack/upper/pdcp.h @@ -38,8 +38,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 de50f797e..dd380711c 100644 --- a/srsenb/hdr/stack/upper/pdcp_nr.h +++ b/srsenb/hdr/stack/upper/pdcp_nr.h @@ -42,8 +42,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 diff --git a/srsenb/hdr/stack/upper/rlc.h b/srsenb/hdr/stack/upper/rlc.h index 0089ca3d3..a555b7763 100644 --- a/srsenb/hdr/stack/upper/rlc.h +++ b/srsenb/hdr/stack/upper/rlc.h @@ -71,8 +71,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 a0fc7e912..e337a1cd1 100644 --- a/srsenb/hdr/stack/upper/rlc_nr.h +++ b/srsenb/hdr/stack/upper/rlc_nr.h @@ -63,8 +63,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); diff --git a/srsenb/src/stack/upper/pdcp.cc b/srsenb/src/stack/upper/pdcp.cc index 4ca8c86ed..d323ed42e 100644 --- a/srsenb/src/stack/upper/pdcp.cc +++ b/srsenb/src/stack/upper/pdcp.cc @@ -143,14 +143,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 853112186..67ec04284 100644 --- a/srsenb/src/stack/upper/pdcp_nr.cc +++ b/srsenb/src/stack/upper/pdcp_nr.cc @@ -99,7 +99,7 @@ void pdcp_nr::write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer } } -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); @@ -108,7 +108,7 @@ void pdcp_nr::notify_delivery(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); diff --git a/srsenb/src/stack/upper/rlc.cc b/srsenb/src/stack/upper/rlc.cc index b819a5866..f439d83c2 100644 --- a/srsenb/src/stack/upper/rlc.cc +++ b/srsenb/src/stack/upper/rlc.cc @@ -269,12 +269,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 1de1ded4d..f0bfeb170 100644 --- a/srsenb/src/stack/upper/rlc_nr.cc +++ b/srsenb/src/stack/upper/rlc_nr.cc @@ -207,12 +207,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); } From 16de8668e00fe9902a652eb71570a5f6745b4b6c Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 9 Mar 2021 17:44:27 +0100 Subject: [PATCH 28/65] rlc_am_lte: convert mutexes to std::mutex replace all pthread_mutex with std::mutex and use lock_guard and unique_lock (where needed) --- lib/include/srslte/upper/rlc_am_lte.h | 6 +- lib/src/upper/rlc_am_lte.cc | 92 ++++++++------------------- 2 files changed, 30 insertions(+), 68 deletions(-) diff --git a/lib/include/srslte/upper/rlc_am_lte.h b/lib/include/srslte/upper/rlc_am_lte.h index b66b83c9b..b826ee054 100644 --- a/lib/include/srslte/upper/rlc_am_lte.h +++ b/lib/include/srslte/upper/rlc_am_lte.h @@ -350,7 +350,7 @@ private: pdcp_sn_vector_t notify_info_vec; // Mutexes - pthread_mutex_t mutex; + std::mutex mutex; }; // Receiver sub-class @@ -412,8 +412,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; diff --git a/lib/src/upper/rlc_am_lte.cc b/lib/src/upper/rlc_am_lte.cc index c207a3186..432f35dbb 100644 --- a/lib/src/upper/rlc_am_lte.cc +++ b/lib/src/upper/rlc_am_lte.cc @@ -210,12 +210,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); } 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) @@ -262,7 +260,7 @@ void rlc_am_lte::rlc_am_lte_tx::stop() { empty_queue(); - pthread_mutex_lock(&mutex); + std::lock_guard lock(mutex); tx_enabled = false; @@ -290,13 +288,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) { @@ -305,8 +301,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() @@ -350,7 +344,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; @@ -409,22 +403,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; } @@ -445,7 +436,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; } @@ -455,12 +445,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; } @@ -479,12 +467,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); @@ -492,13 +478,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 @@ -508,23 +493,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 @@ -534,7 +515,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); @@ -1091,7 +1073,7 @@ 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); @@ -1196,7 +1178,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()) { @@ -1335,13 +1317,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_) @@ -1370,7 +1349,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(); @@ -1392,8 +1371,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 @@ -1756,10 +1733,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() @@ -1772,19 +1748,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) { @@ -1792,26 +1765,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(); } /** @@ -1821,7 +1787,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); @@ -1842,13 +1808,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 @@ -1880,7 +1845,6 @@ int rlc_am_lte::rlc_am_lte_rx::get_status_pdu(rlc_status_pdu_t* status, const ui rlc_am_packed_length(status), max_pdu_size, status->N_nack); - pthread_mutex_unlock(&mutex); return 0; } break; @@ -1888,14 +1852,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; @@ -1905,7 +1868,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); } From 8e9d28e7e09bf1cf93b9d57256664b559ae07aab Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 9 Mar 2021 17:21:31 +0100 Subject: [PATCH 29/65] Change wait_for interface for wait_until in circular_buffer --- lib/include/srslte/adt/circular_buffer.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/include/srslte/adt/circular_buffer.h b/lib/include/srslte/adt/circular_buffer.h index e6df1cd47..84c3f40d5 100644 --- a/lib/include/srslte/adt/circular_buffer.h +++ b/lib/include/srslte/adt/circular_buffer.h @@ -219,7 +219,7 @@ public: pop_(obj, true); return obj; } - bool pop_wait_for(T& obj, const std::chrono::microseconds& duration) { return pop_(obj, true, &duration); } + 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); @@ -326,7 +326,7 @@ protected: return {}; } - bool pop_(T& obj, bool block, const std::chrono::microseconds* duration = nullptr) + bool pop_(T& obj, bool block, const std::chrono::system_clock::time_point* until = nullptr) { std::unique_lock lock(mutex); if (not active) { @@ -337,10 +337,10 @@ protected: return false; } nof_waiting++; - if (duration == nullptr) { + if (until == nullptr) { cvar_empty.wait(lock, [this]() { return not circ_buffer.empty() or not active; }); } else { - cvar_empty.wait_for(lock, *duration, [this]() { return not circ_buffer.empty() or not active; }); + cvar_empty.wait_until(lock, *until, [this]() { return not circ_buffer.empty() or not active; }); } nof_waiting--; if (circ_buffer.empty()) { From 82db6544fb7768ac48f08723bbec9fe47346cb2f Mon Sep 17 00:00:00 2001 From: faluco Date: Mon, 22 Feb 2021 13:14:03 +0100 Subject: [PATCH 30/65] Add instrumentation points to rlc_am_lte::rlc_am_lte_tx::handle_control_pdu using srslog. --- CMakeLists.txt | 6 ++++++ lib/include/srslte/srslog/event_trace.h | 2 +- lib/src/upper/rlc_am_lte.cc | 6 +++++- srsenb/src/main.cc | 5 +++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3513a7433..288fca1a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,6 +80,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 @@ -94,6 +96,10 @@ else(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") endif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") +if (ENABLE_SRSLOG_TRACING) + add_definitions(-DENABLE_SRSLOG_EVENT_TRACE) +endif (ENABLE_SRSLOG_TRACING) + ######################################################################## # Find dependencies ######################################################################## diff --git a/lib/include/srslte/srslog/event_trace.h b/lib/include/srslte/srslog/event_trace.h index 3afb22532..ad1386745 100644 --- a/lib/include/srslte/srslog/event_trace.h +++ b/lib/include/srslte/srslog/event_trace.h @@ -46,7 +46,7 @@ void trace_duration_end(const std::string& category, const std::string& name); /// Generates a complete event. #define trace_complete_event(C, N) \ - auto scoped_complete_event_variable = detail::scoped_complete_event(C, N) + auto scoped_complete_event_variable = srslog::detail::scoped_complete_event(C, N) #else diff --git a/lib/src/upper/rlc_am_lte.cc b/lib/src/upper/rlc_am_lte.cc index 432f35dbb..a80480bdf 100644 --- a/lib/src/upper/rlc_am_lte.cc +++ b/lib/src/upper/rlc_am_lte.cc @@ -14,7 +14,7 @@ #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 @@ -1075,6 +1075,8 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no std::unique_lock lock(mutex); + trace_complete_event("rlc_am::handle_control_pdu", "total time"); + logger.info(payload, nof_bytes, "%s Rx control PDU", RB_NAME); rlc_status_pdu_t status; @@ -1167,6 +1169,7 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no if (not notify_info_vec.empty()) { // Remove all SDUs that were fully acked + trace_complete_event("rlc_am::handle_control_pdu", "remove acked sdus"); for (uint32_t acked_pdcp_sn : notify_info_vec) { logger.debug("Erasing SDU info: PDCP_SN=%d", acked_pdcp_sn); if (not undelivered_sdu_info_queue.has_pdcp_sn(acked_pdcp_sn)) { @@ -1182,6 +1185,7 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no // Notify PDCP without holding Tx mutex if (not notify_info_vec.empty()) { + trace_complete_event("rlc_am::handle_control_pdu", "notify_delivery"); parent->pdcp->notify_delivery(parent->lcid, notify_info_vec); } notify_info_vec.clear(); diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 2a84d5453..0d30d3294 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -22,6 +22,7 @@ #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 @@ -501,6 +502,10 @@ int main(int argc, char* argv[]) 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 + srslog::event_trace_init(); +#endif + // Start the log backend. srslog::init(); From d805ce01a66a794301e9a6101f04130c3cee8673 Mon Sep 17 00:00:00 2001 From: faluco Date: Wed, 24 Feb 2021 16:42:03 +0100 Subject: [PATCH 31/65] - Add a flag in the enb confi file to control tracing. --- srsenb/enb.conf.example | 1 + srsenb/hdr/enb.h | 1 + srsenb/src/main.cc | 5 ++++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index 7b700858f..062f2d73e 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -313,6 +313,7 @@ enable = false #report_json_filename = /tmp/enb_report.json #alarms_log_enable = true #alarms_filename = /tmp/enb_alarms.log +#tracing_enable = true #pregenerate_signals = false #tx_amplitude = 0.6 #rrc_inactivity_timer = 30000 diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index 3b246bd32..f4c412345 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -89,6 +89,7 @@ struct general_args_t { bool alarms_log_enable; std::string alarms_filename; bool print_buffer_state; + bool tracing_enable; std::string eia_pref_list; std::string eea_pref_list; }; diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 0d30d3294..3eafad4a4 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -208,6 +208,7 @@ 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.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,7 +504,9 @@ int main(int argc, char* argv[]) alarms_channel.set_enabled(args.general.alarms_log_enable); #ifdef ENABLE_SRSLOG_EVENT_TRACE - srslog::event_trace_init(); + if (args.general.tracing_enable) { + srslog::event_trace_init(); + } #endif // Start the log backend. From 2b990e195c3c6c3aaec3ee452f33a2738464eddd Mon Sep 17 00:00:00 2001 From: faluco Date: Wed, 24 Feb 2021 18:41:17 +0100 Subject: [PATCH 32/65] Allow specifying a custom filename for event tracing. --- srsenb/enb.conf.example | 1 + srsenb/hdr/enb.h | 1 + srsenb/src/main.cc | 5 ++++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index 062f2d73e..0490a4519 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -314,6 +314,7 @@ enable = false #alarms_log_enable = true #alarms_filename = /tmp/enb_alarms.log #tracing_enable = true +#tracing_filename = /tmp/enb_tracing.log #pregenerate_signals = false #tx_amplitude = 0.6 #rrc_inactivity_timer = 30000 diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index f4c412345..e6c8c020b 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -90,6 +90,7 @@ struct general_args_t { std::string alarms_filename; bool print_buffer_state; bool tracing_enable; + std::string tracing_filename; std::string eia_pref_list; std::string eea_pref_list; }; diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 3eafad4a4..1e5072347 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -209,6 +209,7 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("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.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).") @@ -505,7 +506,9 @@ int main(int argc, char* argv[]) #ifdef ENABLE_SRSLOG_EVENT_TRACE if (args.general.tracing_enable) { - srslog::event_trace_init(); + srslog::sink& tracing_sink = srslog::fetch_file_sink(args.general.tracing_filename); + srslog::log_channel& c = srslog::fetch_log_channel("tracing", tracing_sink, {"TRACE", '\0', false}); + srslog::event_trace_init(c); } #endif From c7542daf438943042a4178ea6bef63aee13a5f65 Mon Sep 17 00:00:00 2001 From: faluco Date: Thu, 25 Feb 2021 12:44:35 +0100 Subject: [PATCH 33/65] Remove rlc traces and add new ones into tti run functions both in the enb and ue. --- lib/src/upper/rlc_am_lte.cc | 4 ---- srsenb/src/stack/enb_stack_lte.cc | 2 ++ srsenb/src/stack/mac/mac.cc | 2 ++ srsue/hdr/ue.h | 2 ++ srsue/src/main.cc | 17 +++++++++++++++++ srsue/src/stack/ue_stack_lte.cc | 5 ++++- srsue/ue.conf.example | 8 +++++--- 7 files changed, 32 insertions(+), 8 deletions(-) diff --git a/lib/src/upper/rlc_am_lte.cc b/lib/src/upper/rlc_am_lte.cc index a80480bdf..4bf230413 100644 --- a/lib/src/upper/rlc_am_lte.cc +++ b/lib/src/upper/rlc_am_lte.cc @@ -1075,8 +1075,6 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no std::unique_lock lock(mutex); - trace_complete_event("rlc_am::handle_control_pdu", "total time"); - logger.info(payload, nof_bytes, "%s Rx control PDU", RB_NAME); rlc_status_pdu_t status; @@ -1169,7 +1167,6 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no if (not notify_info_vec.empty()) { // Remove all SDUs that were fully acked - trace_complete_event("rlc_am::handle_control_pdu", "remove acked sdus"); for (uint32_t acked_pdcp_sn : notify_info_vec) { logger.debug("Erasing SDU info: PDCP_SN=%d", acked_pdcp_sn); if (not undelivered_sdu_info_queue.has_pdcp_sn(acked_pdcp_sn)) { @@ -1185,7 +1182,6 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no // Notify PDCP without holding Tx mutex if (not notify_info_vec.empty()) { - trace_complete_event("rlc_am::handle_control_pdu", "notify_delivery"); parent->pdcp->notify_delivery(parent->lcid, notify_info_vec); } notify_info_vec.clear(); diff --git a/srsenb/src/stack/enb_stack_lte.cc b/srsenb/src/stack/enb_stack_lte.cc index 3acaa65af..bae30116a 100644 --- a/srsenb/src/stack/enb_stack_lte.cc +++ b/srsenb/src/stack/enb_stack_lte.cc @@ -14,6 +14,7 @@ #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; @@ -166,6 +167,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(); } diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index fc55aab1e..10084d38e 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -20,6 +20,7 @@ #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; @@ -575,6 +576,7 @@ 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)); diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index 9f7e4d266..5d9e86f0a 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -62,6 +62,8 @@ typedef struct { bool metrics_csv_append; int metrics_csv_flush_period_sec; std::string metrics_csv_filename; + bool tracing_enable; + std::string tracing_filename; } general_args_t; typedef struct { diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 0418b6bc0..d177690ae 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -17,6 +17,7 @@ #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" @@ -419,6 +420,14 @@ 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") + ("stack.have_tti_time_stats", bpo::value(&args->stack.have_tti_time_stats)->default_value(true), "Calculate TTI execution statistics") @@ -642,6 +651,14 @@ int main(int argc, char* argv[]) srslte::srslog_wrapper log_wrapper(*chan); srslog::set_default_sink(*log_sink); +#ifdef ENABLE_SRSLOG_EVENT_TRACE + if (args.general.tracing_enable) { + srslog::sink& tracing_sink = srslog::fetch_file_sink(args.general.tracing_filename); + srslog::log_channel& c = srslog::fetch_log_channel("tracing", tracing_sink, {"TRACE", '\0', false}); + srslog::event_trace_init(c); + } +#endif + // Start the log backend. srslog::init(); diff --git a/srsue/src/stack/ue_stack_lte.cc b/srsue/src/stack/ue_stack_lte.cc index 9d22f6654..019c11768 100644 --- a/srsue/src/stack/ue_stack_lte.cc +++ b/srsue/src/stack/ue_stack_lte.cc @@ -13,7 +13,7 @@ #include "srsue/hdr/stack/ue_stack_lte.h" #include "srslte/common/logmap.h" #include "srslte/interfaces/ue_phy_interfaces.h" - +#include "srslte/srslog/event_trace.h" #include #include #include @@ -401,6 +401,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/ue.conf.example b/srsue/ue.conf.example index 69ae83a71..fa1083217 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -381,7 +381,9 @@ enable = false # ##################################################################### [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 From 60cd649b8fda55225d27f2467a57f9838fb0ff2a Mon Sep 17 00:00:00 2001 From: faluco Date: Tue, 9 Mar 2021 16:49:09 +0100 Subject: [PATCH 34/65] Add a short description of the tracing options inside the config files. --- srsenb/enb.conf.example | 2 ++ srsue/src/main.cc | 2 +- srsue/ue.conf.example | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index 0490a4519..805daa29c 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -294,6 +294,8 @@ 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. # 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). diff --git a/srsue/src/main.cc b/srsue/src/main.cc index d177690ae..99f61467a 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -667,7 +667,7 @@ int main(int argc, char* argv[]) srslte::check_scaling_governor(args.rf.device_name); - // Create UE instance + // Create UE instance. srsue::ue ue; if (ue.init(args, &log_wrapper)) { ue.stop(); diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index fa1083217..2f08a9485 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -377,6 +377,10 @@ 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. +# # have_tti_time_stats: Calculate TTI execution statistics using system clock # ##################################################################### From 173dcdd42197b6f5ad64dcd57a879c29908a0c3f Mon Sep 17 00:00:00 2001 From: faluco Date: Tue, 9 Mar 2021 18:19:25 +0100 Subject: [PATCH 35/65] - Import latest srslog version. - Remove string allocs in some log lines in radio.cc. Add new tracing buffer capcity options into srsenb and srsue. Add missing file. --- .../srslte/srslog/detail/log_entry_metadata.h | 2 +- .../srslog/detail/support/memory_buffer.h | 12 +- .../srslte/srslog/detail/support/work_queue.h | 4 +- lib/include/srslte/srslog/event_trace.h | 22 ++- lib/include/srslte/srslog/log_channel.h | 19 +-- lib/src/radio/radio.cc | 22 ++- lib/src/srslog/backend_worker.cpp | 7 +- lib/src/srslog/backend_worker.h | 1 + lib/src/srslog/event_trace.cpp | 33 ++++- lib/src/srslog/formatters/json_formatter.cpp | 2 +- lib/src/srslog/formatters/text_formatter.cpp | 69 ++++++--- lib/src/srslog/formatters/text_formatter.h | 51 +++++-- lib/src/srslog/sinks/file_sink.h | 4 +- lib/src/srslog/sinks/single_write_file_sink.h | 90 ++++++++++++ lib/test/srslog/CMakeLists.txt | 9 +- lib/test/srslog/json_formatter_test.cpp | 6 +- lib/test/srslog/log_channel_test.cpp | 25 ++-- lib/test/srslog/text_formatter_test.cpp | 138 ++++++++++++++---- srsenb/enb.conf.example | 2 + srsenb/hdr/enb.h | 3 +- srsenb/src/main.cc | 7 +- srsue/hdr/ue.h | 1 + srsue/src/main.cc | 10 +- srsue/src/stack/mac_nr/proc_ra_nr.cc | 2 +- srsue/ue.conf.example | 3 + 25 files changed, 407 insertions(+), 137 deletions(-) create mode 100644 lib/src/srslog/sinks/single_write_file_sink.h diff --git a/lib/include/srslte/srslog/detail/log_entry_metadata.h b/lib/include/srslte/srslog/detail/log_entry_metadata.h index be40fa791..57f306a6d 100644 --- a/lib/include/srslte/srslog/detail/log_entry_metadata.h +++ b/lib/include/srslte/srslog/detail/log_entry_metadata.h @@ -33,7 +33,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 6d85fba25..30e27bdfe 100644 --- a/lib/include/srslte/srslog/detail/support/memory_buffer.h +++ b/lib/include/srslte/srslog/detail/support/memory_buffer.h @@ -28,18 +28,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 2d2eef3cf..4f1a57d0a 100644 --- a/lib/include/srslte/srslog/detail/support/work_queue.h +++ b/lib/include/srslte/srslog/detail/support/work_queue.h @@ -51,8 +51,8 @@ public: return false; } queue.push(value); - cond_var.signal(); cond_var.unlock(); + cond_var.signal(); return true; } @@ -68,8 +68,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 ad1386745..8b894508a 100644 --- a/lib/include/srslte/srslog/event_trace.h +++ b/lib/include/srslte/srslog/event_trace.h @@ -36,6 +36,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. @@ -45,8 +52,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 = srslog::detail::scoped_complete_event(C, N) + auto SRSLOG_TRACE_COMBINE(scoped_complete_event, __LINE__) = \ + srslog::detail::scoped_complete_event(C, N) #else @@ -63,17 +73,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 0acd80146..8a5cd9678 100644 --- a/lib/include/srslte/srslog/log_channel.h +++ b/lib/include/srslte/srslog/log_channel.h @@ -89,7 +89,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; @@ -97,7 +97,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(); @@ -121,7 +122,7 @@ public: template void operator()(const uint8_t* buffer, size_t len, - const std::string& fmtstr, + const char* fmtstr, Args&&... args) { if (!enabled()) { @@ -130,7 +131,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) @@ -173,7 +175,7 @@ public: }, {std::chrono::high_resolution_clock::now(), {ctx_value, should_print_context}, - "", + nullptr, {}, log_name, log_tag}}; @@ -183,9 +185,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; @@ -193,7 +193,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/src/radio/radio.cc b/lib/src/radio/radio.cc index c918e3f46..fbfc68cf7 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -288,10 +288,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(); @@ -406,10 +409,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 f45721f53..26b63460e 100644 --- a/lib/src/srslog/backend_worker.cpp +++ b/lib/src/srslog/backend_worker.cpp @@ -88,14 +88,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 f697044aa..1dae40a90 100644 --- a/lib/src/srslog/backend_worker.h +++ b/lib/src/srslog/backend_worker.h @@ -111,6 +111,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 e039bfe85..d3bc13328 100644 --- a/lib/src/srslog/event_trace.cpp +++ b/lib/src/srslog/event_trace.cpp @@ -11,6 +11,7 @@ */ #include "srslte/srslog/event_trace.h" +#include "sinks/single_write_file_sink.h" #include "srslte/srslog/srslog.h" #include @@ -23,6 +24,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 @@ -50,6 +54,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) { @@ -104,10 +132,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 f5eb16bd6..8923107cb 100644 --- a/lib/src/srslog/formatters/json_formatter.cpp +++ b/lib/src/srslog/formatters/json_formatter.cpp @@ -49,7 +49,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 ae313607c..82d74e0ea 100644 --- a/lib/src/srslog/formatters/text_formatter.cpp +++ b/lib/src/srslog/formatters/text_formatter.cpp @@ -90,13 +90,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); } @@ -104,10 +107,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, @@ -115,21 +120,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, @@ -139,22 +149,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 b8dcf32cd..336ad326a 100644 --- a/lib/src/srslog/formatters/text_formatter.h +++ b/lib/src/srslog/formatters/text_formatter.h @@ -18,11 +18,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, @@ -50,17 +50,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, @@ -69,9 +64,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 3e7c085fd..fe61e09eb 100644 --- a/lib/src/srslog/sinks/file_sink.h +++ b/lib/src/srslog/sinks/file_sink.h @@ -28,8 +28,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/test/srslog/CMakeLists.txt b/lib/test/srslog/CMakeLists.txt index 7209b87df..b87eb04aa 100644 --- a/lib/test/srslog/CMakeLists.txt +++ b/lib/test/srslog/CMakeLists.txt @@ -42,11 +42,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 33bbd84dc..e10f1028c 100644 --- a/lib/test/srslog/json_formatter_test.cpp +++ b/lib/test/srslog/json_formatter_test.cpp @@ -82,7 +82,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); @@ -173,7 +173,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(); @@ -260,7 +260,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 8d7ec523d..1ccb6f2d5 100644 --- a/lib/test/srslog/log_channel_test.cpp +++ b/lib/test/srslog/log_channel_test.cpp @@ -89,8 +89,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); @@ -104,8 +103,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); @@ -122,11 +120,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); @@ -136,7 +133,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); @@ -155,13 +152,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); @@ -171,7 +167,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); @@ -193,11 +189,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); @@ -264,10 +258,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); @@ -277,7 +270,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 fa20f56e1..3d0e008f5 100644 --- a/lib/test/srslog/text_formatter_test.cpp +++ b/lib/test/srslog/text_formatter_test.cpp @@ -110,41 +110,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); @@ -155,21 +234,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/srsenb/enb.conf.example b/srsenb/enb.conf.example index 805daa29c..90a7f07da 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -296,6 +296,7 @@ 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. # 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). @@ -317,6 +318,7 @@ enable = false #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 e6c8c020b..9a389ad5d 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -31,7 +31,6 @@ #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" @@ -43,6 +42,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 { @@ -90,6 +90,7 @@ struct general_args_t { 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; diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 1e5072347..64b9e5291 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -210,6 +210,7 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("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).") @@ -506,9 +507,9 @@ int main(int argc, char* argv[]) #ifdef ENABLE_SRSLOG_EVENT_TRACE if (args.general.tracing_enable) { - srslog::sink& tracing_sink = srslog::fetch_file_sink(args.general.tracing_filename); - srslog::log_channel& c = srslog::fetch_log_channel("tracing", tracing_sink, {"TRACE", '\0', false}); - srslog::event_trace_init(c); + if (!srslog::event_trace_init(args.general.tracing_filename, args.general.tracing_buffcapacity)) { + return SRSLTE_ERROR; + } } #endif diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index 5d9e86f0a..9fde96bd4 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -64,6 +64,7 @@ typedef struct { std::string metrics_csv_filename; bool tracing_enable; std::string tracing_filename; + std::size_t tracing_buffcapacity; } general_args_t; typedef struct { diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 99f61467a..9c44861bb 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -428,6 +428,10 @@ static int parse_args(all_args_t* args, int argc, char* argv[]) 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") @@ -653,9 +657,9 @@ int main(int argc, char* argv[]) #ifdef ENABLE_SRSLOG_EVENT_TRACE if (args.general.tracing_enable) { - srslog::sink& tracing_sink = srslog::fetch_file_sink(args.general.tracing_filename); - srslog::log_channel& c = srslog::fetch_log_channel("tracing", tracing_sink, {"TRACE", '\0', false}); - srslog::event_trace_init(c); + if (!srslog::event_trace_init(args.general.tracing_filename, args.general.tracing_buffcapacity)) { + return SRSLTE_ERROR; + } } #endif diff --git a/srsue/src/stack/mac_nr/proc_ra_nr.cc b/srsue/src/stack/mac_nr/proc_ra_nr.cc index 6d568058f..9fdbc7a24 100644 --- a/srsue/src/stack/mac_nr/proc_ra_nr.cc +++ b/srsue/src/stack/mac_nr/proc_ra_nr.cc @@ -181,7 +181,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/ue.conf.example b/srsue/ue.conf.example index 2f08a9485..9b329182d 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -381,6 +381,8 @@ enable = false # # 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 # ##################################################################### @@ -391,3 +393,4 @@ enable = false #have_tti_time_stats = true #tracing_enable = true #tracing_filename = /tmp/ue_tracing.log +#tracing_buffcapacity = 1000000 From 837c5bdce5b0a1d7bd7512b52cc8174d14d46bab Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 5 Mar 2021 14:03:32 +0000 Subject: [PATCH 36/65] clang tidy update. applied small fixes to warnings from clang-tidy --- .clang-tidy | 2 ++ .../stack/mac/sched_ue_ctrl/sched_ue_cell.h | 2 -- .../src/stack/mac/sched_phy_ch/sched_dci.cc | 15 +++++---- .../stack/mac/sched_ue_ctrl/sched_ue_cell.cc | 33 +++++++++---------- 4 files changed, 26 insertions(+), 26 deletions(-) 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/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h index fce2c340c..d2533f78f 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 @@ -72,8 +72,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/src/stack/mac/sched_phy_ch/sched_dci.cc b/srsenb/src/stack/mac/sched_phy_ch/sched_dci.cc index cdd5b7c9d..b9d2e4ab6 100644 --- a/srsenb/src/stack/mac/sched_phy_ch/sched_dci.cc +++ b/srsenb/src/stack/mac/sched_phy_ch/sched_dci.cc @@ -20,7 +20,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} @@ -72,9 +72,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; @@ -104,12 +104,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; } @@ -138,10 +138,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_ue_ctrl/sched_ue_cell.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc index c4879434c..17cfaad96 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 @@ -30,14 +30,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; @@ -52,14 +54,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 @@ -185,20 +186,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) { @@ -288,10 +287,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) @@ -306,10 +305,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++; From 62b361526830591c1c997076658b1a11eed5acde Mon Sep 17 00:00:00 2001 From: yagoda Date: Wed, 10 Mar 2021 16:22:54 +0100 Subject: [PATCH 37/65] fixing sched config parameters --- srsenb/enb.conf.example | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index 90a7f07da..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 From 7447fefd191ba5f531d636b14d59d98d86172a6d Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 10 Mar 2021 16:24:34 +0000 Subject: [PATCH 38/65] Make sure that sending the status report sent after RLC configuration in reestablishment --- srsue/src/stack/rrc/rrc_procedures.cc | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index dda20f4a5..2030ec600 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -957,12 +957,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); } } } @@ -974,6 +972,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. @@ -1324,9 +1332,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); From d1483dc0f899be244a0b4283daac5ac86a6c19bc Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 10 Mar 2021 16:20:24 +0000 Subject: [PATCH 39/65] sched,bugfix - fix bitmask formatting. fix msg3 adaptive retx pdcch allocation --- lib/include/srslte/adt/bounded_bitset.h | 2 +- srsenb/hdr/stack/mac/sched_grid.h | 20 ++++++------ srsenb/src/stack/mac/sched_grid.cc | 31 ++++++++----------- srsenb/src/stack/mac/schedulers/sched_base.cc | 17 +++++++--- srsenb/test/mac/sched_ca_test.cc | 16 +++++----- srsenb/test/mac/sched_ue_ded_test_suite.cc | 5 +-- 6 files changed, 48 insertions(+), 43 deletions(-) diff --git a/lib/include/srslte/adt/bounded_bitset.h b/lib/include/srslte/adt/bounded_bitset.h index bef2fa36f..1b4e351ab 100644 --- a/lib/include/srslte/adt/bounded_bitset.h +++ b/lib/include/srslte/adt/bounded_bitset.h @@ -362,7 +362,7 @@ struct formatter > { auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { auto it = ctx.begin(); - while (*it != '\0' and *it != '}') { + while (it != ctx.end() and *it != '}') { if (*it == 'x') { mode = hexadecimal; } diff --git a/srsenb/hdr/stack/mac/sched_grid.h b/srsenb/hdr/stack/mac/sched_grid.h index 0c49d887d..c9e61cfa9 100644 --- a/srsenb/hdr/stack/mac/sched_grid.h +++ b/srsenb/hdr/stack/mac/sched_grid.h @@ -104,7 +104,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; @@ -174,15 +174,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; 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; @@ -212,7 +212,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); @@ -228,10 +229,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/src/stack/mac/sched_grid.cc b/srsenb/src/stack/mac/sched_grid.cc index f2b8d22b6..c58e9812f 100644 --- a/srsenb/src/stack/mac/sched_grid.cc +++ b/srsenb/src/stack/mac/sched_grid.cc @@ -232,7 +232,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; @@ -240,7 +240,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; } @@ -503,7 +503,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; } @@ -606,7 +606,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"); @@ -620,25 +621,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; @@ -656,15 +653,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) @@ -997,7 +992,7 @@ void sf_sched::set_ul_sched_result(const sf_cch_allocator::alloc_result_t& dci_r fmt::memory_buffer str_buffer; fmt::format_to(str_buffer, "SCHED: Error {} {} rnti=0x{:x}, pid={}, dci=({},{}), prb={}, bsr={}", - ul_alloc.type == ul_alloc_t::MSG3 ? "Msg3" : "UL", + ul_alloc.is_msg3 ? "Msg3" : "UL", ul_alloc.is_retx() ? "retx" : "tx", user->get_rnti(), h->get_id(), @@ -1015,7 +1010,7 @@ void sf_sched::set_ul_sched_result(const sf_cch_allocator::alloc_result_t& dci_r 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_msg3 ? "Msg3" : "UL", ul_alloc.is_retx() ? "retx" : "newtx", user->get_rnti(), cc_cfg->enb_cc_idx, @@ -1042,7 +1037,7 @@ 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) { fmt::memory_buffer str_buffer; fmt::format_to(str_buffer, "{}", msg3_alloc); diff --git a/srsenb/src/stack/mac/schedulers/sched_base.cc b/srsenb/src/stack/mac/schedulers/sched_base.cc index 863c12f8b..8c7f5c886 100644 --- a/srsenb/src/stack/mac/schedulers/sched_base.cc +++ b/srsenb/src/stack/mac/schedulers/sched_base.cc @@ -225,11 +225,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/test/mac/sched_ca_test.cc b/srsenb/test/mac/sched_ca_test.cc index 65099afcf..5987fbe1e 100644 --- a/srsenb/test/mac/sched_ca_test.cc +++ b/srsenb/test/mac/sched_ca_test.cc @@ -77,7 +77,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}; @@ -228,7 +228,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; } @@ -250,28 +251,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_ue_ded_test_suite.cc b/srsenb/test/mac/sched_ue_ded_test_suite.cc index a1da1acff..899154036 100644 --- a/srsenb/test/mac/sched_ue_ded_test_suite.cc +++ b/srsenb/test/mac/sched_ue_ded_test_suite.cc @@ -194,8 +194,9 @@ int test_ul_sched_result(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& } 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"); From fbbbf7886c05369966ce2b4194e664c5bdf1ca75 Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 10 Mar 2021 21:36:04 +0000 Subject: [PATCH 40/65] sched,bugfix - reset harq used for msg3 correctly --- srsenb/hdr/stack/mac/sched_grid.h | 2 +- srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc | 1 + srsenb/test/mac/sched_ue_ded_test_suite.cc | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/srsenb/hdr/stack/mac/sched_grid.h b/srsenb/hdr/stack/mac/sched_grid.h index c9e61cfa9..6376494e9 100644 --- a/srsenb/hdr/stack/mac/sched_grid.h +++ b/srsenb/hdr/stack/mac/sched_grid.h @@ -175,7 +175,7 @@ public: }; struct ul_alloc_t { enum type_t { NEWTX, NOADAPT_RETX, ADAPT_RETX }; - bool is_msg3; + bool is_msg3 = false; size_t dci_idx; type_t type; uint16_t rnti; 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 cde622989..96eb86a9d 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc @@ -283,6 +283,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/test/mac/sched_ue_ded_test_suite.cc b/srsenb/test/mac/sched_ue_ded_test_suite.cc index 899154036..e8c223f52 100644 --- a/srsenb/test/mac/sched_ue_ded_test_suite.cc +++ b/srsenb/test/mac/sched_ue_ded_test_suite.cc @@ -191,6 +191,8 @@ 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) { From 2ecdab87175acda3b1b26a75bda5dfc45c89f1c8 Mon Sep 17 00:00:00 2001 From: yagoda Date: Thu, 11 Feb 2021 11:49:33 +0100 Subject: [PATCH 41/65] small fixes to the eMBMS downlink, lack of pdcch decoding was causing issues with uplink --- srsue/src/phy/lte/cc_worker.cc | 7 ++++++- srsue/src/phy/lte/sf_worker.cc | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/lte/cc_worker.cc b/srsue/src/phy/lte/cc_worker.cc index 5b845ed62..649d58d91 100644 --- a/srsue/src/phy/lte/cc_worker.cc +++ b/srsue/src/phy/lte/cc_worker.cc @@ -319,7 +319,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 9ccfc61b8..78c8f2f50 100644 --- a/srsue/src/phy/lte/sf_worker.cc +++ b/srsue/src/phy/lte/sf_worker.cc @@ -179,7 +179,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(); From 770021e36487106409713172b58f3c63854ea58a Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 11 Mar 2021 11:06:05 +0000 Subject: [PATCH 42/65] remove uneeded formatting and std::string creation/allocation in scheduler --- .../hdr/stack/mac/sched_ue_ctrl/sched_lch.h | 2 +- srsenb/src/stack/mac/sched_ue.cc | 15 ++++++++----- .../src/stack/mac/sched_ue_ctrl/sched_lch.cc | 22 +++++++++++++------ 3 files changed, 26 insertions(+), 13 deletions(-) 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 059f6477b..4876fbfd1 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h @@ -55,7 +55,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/src/stack/mac/sched_ue.cc b/srsenb/src/stack/mac/sched_ue.cc index 41dba6d4e..cdd92fa45 100644 --- a/srsenb/src/stack/mac/sched_ue.cc +++ b/srsenb/src/stack/mac/sched_ue.cc @@ -15,8 +15,9 @@ #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; @@ -942,10 +943,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_lch.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc index 66711a394..c49d39cee 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc @@ -12,7 +12,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 { @@ -110,7 +111,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) @@ -120,7 +125,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) @@ -321,11 +331,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, From 7dcb703d06521a03fdd1a1959ac18fd7b215a45d Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 11 Mar 2021 11:09:21 +0000 Subject: [PATCH 43/65] adt lib,bugfix - fix bounded_bitset resize to clear bits outside of mask correctly --- lib/include/srslte/adt/bounded_bitset.h | 10 +++--- lib/test/adt/bounded_bitset_test.cc | 44 +++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/lib/include/srslte/adt/bounded_bitset.h b/lib/include/srslte/adt/bounded_bitset.h index 1b4e351ab..3ebc85762 100644 --- a/lib/include/srslte/adt/bounded_bitset.h +++ b/lib/include/srslte/adt/bounded_bitset.h @@ -33,9 +33,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; } @@ -54,7 +54,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); } } @@ -268,8 +268,8 @@ public: } 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_() { diff --git a/lib/test/adt/bounded_bitset_test.cc b/lib/test/adt/bounded_bitset_test.cc index 1eaf2970b..40f4f7279 100644 --- a/lib/test/adt/bounded_bitset_test.cc +++ b/lib/test/adt/bounded_bitset_test.cc @@ -28,7 +28,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()); @@ -95,7 +94,7 @@ int test_bitset_bitwise_oper() try { mask2 |= mask; } catch (srslte::bad_type_access& c) { - printf("Received exception \"%s\" as expected\n", c.what()); + printf("Received exception \"%s\" (as expected)\n", c.what()); caught = true; } TESTASSERT(caught); @@ -137,6 +136,46 @@ int test_bitset_print() 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); @@ -144,6 +183,7 @@ int main() 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; } From 3b491ab06b03517fbeb7511b2aa0ae0ae0d35d9c Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 11 Mar 2021 11:29:00 +0000 Subject: [PATCH 44/65] optimize .count() method of bounded_bitset to leverage popcount special instructions. Confirmed to work for gcc in -msse4 flag is passed. --- lib/include/srslte/adt/bounded_bitset.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/include/srslte/adt/bounded_bitset.h b/lib/include/srslte/adt/bounded_bitset.h index 3ebc85762..1afdd6123 100644 --- a/lib/include/srslte/adt/bounded_bitset.h +++ b/lib/include/srslte/adt/bounded_bitset.h @@ -164,10 +164,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; } From d35d7aef76548b3b3dcf6426e9a1d490d7bcad77 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 9 Mar 2021 21:54:33 +0100 Subject: [PATCH 45/65] cmake: add PARALLEL_COMPILE_JOBS option to project CMakeLists.txt this allows to limit the number of compile jobs to e.g. one or two which is needed when using parallel build systems like Ninja on resource (RAM) contrained systems, like the RPi4 --- CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 288fca1a7..f92538684 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,6 +95,13 @@ 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) From 3e9f93eb8a16e665948175b4a911d6d82816259b Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 10 Mar 2021 19:41:05 +0000 Subject: [PATCH 46/65] refactor - remove old log_filter and logmap libraries from the codebase --- lib/include/srslte/common/buffer_pool.h | 1 - lib/include/srslte/common/log.h | 150 --------- lib/include/srslte/common/log_filter.h | 90 ------ lib/include/srslte/common/log_helper.h | 36 +-- lib/include/srslte/common/logger.h | 103 ------ .../srslte/common/logger_srslog_wrapper.h | 40 --- lib/include/srslte/common/logmap.h | 94 ------ lib/include/srslte/common/netsource_handler.h | 3 - lib/include/srslte/common/test_common.h | 155 +-------- .../srslte/interfaces/enb_gtpu_interfaces.h | 2 + .../srslte/interfaces/ue_gw_interfaces.h | 1 + .../srslte/interfaces/ue_pdcp_interfaces.h | 11 +- lib/include/srslte/mac/mac_sch_pdu_nr.h | 10 +- lib/include/srslte/mac/pdu.h | 1 - lib/include/srslte/mac/pdu_queue.h | 1 - lib/include/srslte/phy/channel/channel.h | 2 +- lib/include/srslte/radio/radio.h | 3 +- lib/include/srslte/radio/radio_base.h | 1 - lib/include/srslte/radio/radio_null.h | 2 - lib/include/srslte/rrc/rrc_cfg_utils.h | 1 - lib/include/srslte/srslog/logger.h | 30 +- lib/include/srslte/upper/gtpu.h | 3 +- lib/include/srslte/upper/pdcp.h | 1 - lib/include/srslte/upper/pdcp_entity_base.h | 7 +- lib/include/srslte/upper/pdcp_entity_lte.h | 1 - lib/include/srslte/upper/pdcp_entity_nr.h | 1 - lib/include/srslte/upper/rlc.h | 1 - lib/include/srslte/upper/rlc_am_base.h | 1 - lib/include/srslte/upper/rlc_am_lte.h | 1 - lib/include/srslte/upper/rlc_am_nr.h | 1 - lib/include/srslte/upper/rlc_common.h | 1 - lib/include/srslte/upper/rlc_tm.h | 1 - lib/include/srslte/upper/rlc_um_base.h | 1 - lib/include/srslte/upper/rlc_um_lte.h | 1 - lib/include/srslte/upper/rlc_um_nr.h | 1 - lib/src/common/CMakeLists.txt | 3 - lib/src/common/log_filter.cc | 298 ------------------ lib/src/common/logger_srslog_wrapper.cc | 21 -- lib/src/common/logmap.cc | 120 ------- lib/src/common/mac_pcap.cc | 1 + lib/src/common/test/thread_pool_test.cc | 11 +- lib/src/mac/pdu.cc | 1 + lib/src/radio/radio.cc | 1 + lib/src/upper/pdcp_entity_lte.cc | 1 + lib/test/adt/span_test.cc | 1 + lib/test/asn1/asn1_utils_test.cc | 19 +- lib/test/asn1/ngap_test.cc | 1 - lib/test/asn1/rrc_nr_utils_test.cc | 3 - lib/test/asn1/rrc_test.cc | 1 - lib/test/asn1/s1ap_test.cc | 4 - lib/test/asn1/srslte_asn1_nas_test.cc | 3 - lib/test/asn1/srslte_asn1_rrc_dl_ccch_test.cc | 3 +- lib/test/asn1/srslte_asn1_rrc_dl_dcch_test.cc | 1 - lib/test/asn1/srslte_asn1_rrc_mcch_test.cc | 1 - lib/test/asn1/srslte_asn1_rrc_meas_test.cc | 2 - lib/test/asn1/srslte_asn1_rrc_nr_test.cc | 11 +- lib/test/asn1/srslte_asn1_rrc_ul_dcch_test.cc | 3 +- lib/test/common/CMakeLists.txt | 9 +- lib/test/common/choice_type_test.cc | 1 + lib/test/common/log_filter_test.cc | 219 ------------- lib/test/common/network_utils_test.cc | 1 - lib/test/common/test_common_test.cc | 72 ----- lib/test/mac/mac_pdu_nr_test.cc | 1 - lib/test/mac/pdu_test.cc | 1 - lib/test/upper/pdcp_base_test.h | 1 - lib/test/upper/rlc_am_test.cc | 10 +- lib/test/upper/rlc_common_test.cc | 1 - lib/test/upper/rlc_stress_test.cc | 14 +- lib/test/upper/rlc_um_nr_test.cc | 1 - lib/test/upper/rlc_um_test.cc | 1 - srsenb/hdr/enb.h | 6 +- srsenb/hdr/phy/nr/cc_worker.h | 1 - srsenb/hdr/phy/phy.h | 2 - srsenb/hdr/phy/phy_common.h | 3 +- srsenb/hdr/phy/prach_worker.h | 1 - srsenb/hdr/phy/txrx.h | 1 - srsenb/hdr/phy/vnf_phy_nr.h | 4 +- srsenb/hdr/stack/enb_stack_lte.h | 13 +- srsenb/hdr/stack/gnb_stack_nr.h | 4 +- srsenb/hdr/stack/mac/mac.h | 5 +- srsenb/hdr/stack/mac/mac_nr.h | 3 +- srsenb/hdr/stack/mac/sched.h | 1 - srsenb/hdr/stack/mac/sched_grid.h | 1 - srsenb/hdr/stack/mac/sched_helpers.h | 5 +- srsenb/hdr/stack/mac/sched_ue.h | 1 - .../hdr/stack/mac/sched_ue_ctrl/sched_harq.h | 1 - .../hdr/stack/mac/sched_ue_ctrl/sched_lch.h | 2 +- srsenb/hdr/stack/mac/sched_ue_ctrl/tpc.h | 1 - srsenb/hdr/stack/mac/ue.h | 3 - srsenb/hdr/stack/rrc/rrc.h | 1 - srsenb/hdr/stack/rrc/rrc_bearer_cfg.h | 1 - srsenb/hdr/stack/rrc/rrc_cell_cfg.h | 2 +- srsenb/hdr/stack/rrc/rrc_mobility.h | 1 - srsenb/hdr/stack/rrc/rrc_nr.h | 5 +- srsenb/hdr/stack/rrc/ue_rr_cfg.h | 9 +- srsenb/hdr/stack/upper/gtpu.h | 2 +- srsenb/hdr/stack/upper/pdcp_nr.h | 5 +- srsenb/hdr/stack/upper/rlc_nr.h | 5 +- srsenb/hdr/stack/upper/s1ap.h | 1 - srsenb/hdr/stack/upper/sdap.h | 1 - srsenb/src/enb.cc | 30 +- srsenb/src/enb_cfg_parser.cc | 2 +- srsenb/src/main.cc | 9 +- srsenb/src/phy/lte/cc_worker.cc | 1 - srsenb/src/phy/lte/sf_worker.cc | 5 +- srsenb/src/phy/phy.cc | 1 - srsenb/src/phy/txrx.cc | 1 - srsenb/src/phy/vnf_phy_nr.cc | 10 +- srsenb/src/stack/enb_stack_lte.cc | 20 +- srsenb/src/stack/gnb_stack_nr.cc | 6 +- srsenb/src/stack/mac/mac.cc | 25 +- srsenb/src/stack/mac/mac_nr.cc | 36 +-- srsenb/src/stack/mac/sched.cc | 1 - srsenb/src/stack/mac/sched_carrier.cc | 2 +- srsenb/src/stack/mac/sched_grid.cc | 1 - srsenb/src/stack/mac/sched_helpers.cc | 2 + srsenb/src/stack/mac/sched_ue.cc | 1 - srsenb/src/stack/mac/ue.cc | 14 +- srsenb/src/stack/rrc/rrc.cc | 1 + srsenb/src/stack/rrc/rrc_mobility.cc | 6 +- srsenb/src/stack/rrc/rrc_nr.cc | 58 ++-- srsenb/src/stack/rrc/rrc_ue.cc | 1 + srsenb/src/stack/upper/gtpu.cc | 2 + srsenb/src/stack/upper/pdcp_nr.cc | 15 +- srsenb/src/stack/upper/rlc_nr.cc | 14 +- srsenb/src/stack/upper/s1ap.cc | 14 +- srsenb/test/mac/sched_test_rand.cc | 14 +- srsenb/test/phy/enb_phy_test.cc | 1 - srsenb/test/upper/rrc_meascfg_test.cc | 1 - srsenb/test/upper/test_helpers.cc | 4 +- srsenb/test/upper/test_helpers.h | 7 +- srsepc/hdr/hss/hss.h | 3 +- srsepc/hdr/mbms-gw/mbms-gw.h | 2 - srsepc/hdr/mme/mme.h | 3 +- srsepc/hdr/mme/mme_gtpc.h | 2 - srsepc/hdr/mme/s1ap.h | 2 +- srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h | 1 - srsepc/hdr/mme/s1ap_erab_mngmt_proc.h | 1 - srsepc/hdr/mme/s1ap_mngmt_proc.h | 1 - srsepc/hdr/mme/s1ap_paging.h | 1 - srsepc/hdr/spgw/gtpc.h | 2 + srsepc/hdr/spgw/gtpu.h | 2 +- srsepc/hdr/spgw/spgw.h | 2 - srsepc/src/main.cc | 52 +-- srsepc/src/mbms-gw/main.cc | 25 -- srsepc/src/mbms-gw/mbms-gw.cc | 1 + srsue/hdr/phy/nr/cc_worker.h | 1 - srsue/hdr/phy/phy.h | 1 - srsue/hdr/phy/phy_common.h | 1 - srsue/hdr/phy/prach.h | 1 - srsue/hdr/phy/scell/intra_measure.h | 1 - srsue/hdr/phy/sync.h | 1 - srsue/hdr/phy/ue_lte_phy_base.h | 1 - srsue/hdr/phy/ue_nr_phy_base.h | 1 - srsue/hdr/phy/ue_phy_base.h | 1 - srsue/hdr/phy/vnf_phy_nr.h | 2 - srsue/hdr/stack/mac/demux.h | 1 - srsue/hdr/stack/mac/dl_harq.h | 1 - srsue/hdr/stack/mac/dl_sps.h | 1 - srsue/hdr/stack/mac/mac.h | 1 - srsue/hdr/stack/mac/mux.h | 1 - srsue/hdr/stack/mac/proc_bsr.h | 1 - srsue/hdr/stack/mac/proc_phr.h | 1 - srsue/hdr/stack/mac/proc_ra.h | 1 - srsue/hdr/stack/mac/proc_sr.h | 1 - srsue/hdr/stack/mac/ul_harq.h | 1 - srsue/hdr/stack/mac/ul_sps.h | 1 - srsue/hdr/stack/rrc/phy_controller.h | 1 - srsue/hdr/stack/rrc/rrc.h | 1 - srsue/hdr/stack/rrc/rrc_meas.h | 1 - srsue/hdr/stack/rrc/rrc_nr.h | 4 +- srsue/hdr/stack/rrc/rrc_procedures.h | 1 - srsue/hdr/stack/ue_stack_base.h | 1 - srsue/hdr/stack/ue_stack_lte.h | 1 - srsue/hdr/stack/ue_stack_nr.h | 9 +- srsue/hdr/stack/upper/gw.h | 2 - srsue/hdr/stack/upper/nas.h | 1 - srsue/hdr/stack/upper/nas_emm_state.h | 1 - srsue/hdr/stack/upper/pcsc_usim.h | 1 - srsue/hdr/stack/upper/tft_packet_filter.h | 2 - srsue/hdr/stack/upper/usim.h | 1 - srsue/hdr/stack/upper/usim_base.h | 1 - srsue/hdr/ue.h | 4 +- srsue/src/main.cc | 6 +- srsue/src/phy/lte/cc_worker.cc | 1 + srsue/src/phy/lte/sf_worker.cc | 1 + srsue/src/phy/nr/cc_worker.cc | 1 + srsue/src/phy/nr/sf_worker.cc | 1 + srsue/src/phy/phy.cc | 8 +- srsue/src/phy/prach.cc | 2 +- srsue/src/phy/search.cc | 1 + srsue/src/phy/sync.cc | 3 +- srsue/src/phy/vnf_phy_nr.cc | 1 - srsue/src/stack/mac/demux.cc | 9 +- srsue/src/stack/mac/dl_harq.cc | 1 - srsue/src/stack/mac/mac.cc | 1 - srsue/src/stack/mac/proc_ra.cc | 1 + srsue/src/stack/mac/proc_sr.cc | 1 + srsue/src/stack/mac/ul_harq.cc | 1 - srsue/src/stack/mac_nr/proc_ra_nr.cc | 1 + srsue/src/stack/rrc/rrc.cc | 2 + srsue/src/stack/rrc/rrc_nr.cc | 129 ++++---- srsue/src/stack/ue_stack_lte.cc | 3 +- srsue/src/stack/ue_stack_nr.cc | 25 +- srsue/src/stack/upper/gw.cc | 1 + srsue/src/stack/upper/nas.cc | 2 +- srsue/src/stack/upper/nas_idle_procedures.cc | 1 + srsue/src/stack/upper/pcsc_usim.cc | 1 + srsue/src/stack/upper/tft_packet_filter.cc | 1 + srsue/src/stack/upper/usim.cc | 1 + srsue/src/ue.cc | 9 +- srsue/test/mac_nr/proc_ra_nr_test.cc | 2 +- srsue/test/phy/ue_phy_test.cc | 1 - srsue/test/ttcn3/hdr/ttcn3_port_handler.h | 2 +- srsue/test/ttcn3/hdr/ttcn3_ue.h | 1 + srsue/test/ttcn3/hdr/ttcn3_ut_interface.h | 1 - srsue/test/ttcn3/src/ttcn3_dut.cc | 1 - srsue/test/ttcn3/src/ttcn3_syssim.cc | 1 - srsue/test/upper/gw_test.cc | 1 - srsue/test/upper/nas_test.cc | 2 - srsue/test/upper/rrc_meas_test.cc | 2 - srsue/test/upper/rrc_reconfig_test.cc | 1 - srsue/test/upper/tft_test.cc | 8 +- srsue/test/upper/ue_rrc_nr_test.cc | 6 +- 224 files changed, 377 insertions(+), 2018 deletions(-) delete mode 100644 lib/include/srslte/common/log.h delete mode 100644 lib/include/srslte/common/log_filter.h delete mode 100644 lib/include/srslte/common/logger.h delete mode 100644 lib/include/srslte/common/logger_srslog_wrapper.h delete mode 100644 lib/include/srslte/common/logmap.h delete mode 100644 lib/src/common/log_filter.cc delete mode 100644 lib/src/common/logger_srslog_wrapper.cc delete mode 100644 lib/src/common/logmap.cc delete mode 100644 lib/test/common/log_filter_test.cc delete mode 100644 lib/test/common/test_common_test.cc diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index 4cb1daa98..33f7d1be3 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -26,7 +26,6 @@ *******************************************************************************/ #include "srslte/common/common.h" -#include "srslte/common/log.h" #include "srslte/srslog/srslog.h" namespace srslte { diff --git a/lib/include/srslte/common/log.h b/lib/include/srslte/common/log.h deleted file mode 100644 index 03409846a..000000000 --- a/lib/include/srslte/common/log.h +++ /dev/null @@ -1,150 +0,0 @@ -/** - * - * \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. - * - */ - -/****************************************************************************** - * 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 9062b4182..000000000 --- a/lib/include/srslte/common/log_filter.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * - * \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. - * - */ - -/****************************************************************************** - * 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 0771738c2..4d04affaf 100644 --- a/lib/include/srslte/common/log_helper.h +++ b/lib/include/srslte/common/log_helper.h @@ -21,37 +21,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 be8576266..000000000 --- a/lib/include/srslte/common/logger.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - * - * \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. - * - */ - -/****************************************************************************** - * 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 7a0aca068..000000000 --- a/lib/include/srslte/common/logger_srslog_wrapper.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * - * \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_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 06aefba3f..000000000 --- a/lib/include/srslte/common/logmap.h +++ /dev/null @@ -1,94 +0,0 @@ -/** - * - * \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_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/netsource_handler.h b/lib/include/srslte/common/netsource_handler.h index 4b76717f0..eb6469625 100644 --- a/lib/include/srslte/common/netsource_handler.h +++ b/lib/include/srslte/common/netsource_handler.h @@ -18,7 +18,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 @@ -61,8 +60,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/test_common.h b/lib/include/srslte/common/test_common.h index e2f4fa4ba..224f2401e 100644 --- a/lib/include/srslte/common/test_common.h +++ b/lib/include/srslte/common/test_common.h @@ -17,73 +17,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 { @@ -188,106 +128,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/interfaces/enb_gtpu_interfaces.h b/lib/include/srslte/interfaces/enb_gtpu_interfaces.h index 9f90b9f4d..e99cf8746 100644 --- a/lib/include/srslte/interfaces/enb_gtpu_interfaces.h +++ b/lib/include/srslte/interfaces/enb_gtpu_interfaces.h @@ -13,6 +13,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/ue_gw_interfaces.h b/lib/include/srslte/interfaces/ue_gw_interfaces.h index 4fedb6c9d..f981e273a 100644 --- a/lib/include/srslte/interfaces/ue_gw_interfaces.h +++ b/lib/include/srslte/interfaces/ue_gw_interfaces.h @@ -14,6 +14,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 0a66dcf88..05874e7ee 100644 --- a/lib/include/srslte/interfaces/ue_pdcp_interfaces.h +++ b/lib/include/srslte/interfaces/ue_pdcp_interfaces.h @@ -14,6 +14,7 @@ #define SRSLTE_UE_PDCP_INTERFACES_H #include "pdcp_interface_types.h" +#include "srslte/common/byte_buffer.h" namespace srsue { @@ -39,11 +40,11 @@ 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 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; }; diff --git a/lib/include/srslte/mac/mac_sch_pdu_nr.h b/lib/include/srslte/mac/mac_sch_pdu_nr.h index 17e580626..f9ffbe59e 100644 --- a/lib/include/srslte/mac/mac_sch_pdu_nr.h +++ b/lib/include/srslte/mac/mac_sch_pdu_nr.h @@ -13,8 +13,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 @@ -101,7 +101,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 @@ -135,9 +135,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 28a3147a4..8a7651a00 100644 --- a/lib/include/srslte/mac/pdu.h +++ b/lib/include/srslte/mac/pdu.h @@ -14,7 +14,6 @@ #define SRSLTE_PDU_H #include "srslte/common/interfaces_common.h" -#include "srslte/common/logmap.h" #include "srslte/srslog/srslog.h" #include #include diff --git a/lib/include/srslte/mac/pdu_queue.h b/lib/include/srslte/mac/pdu_queue.h index 9a26ae1e5..ba89af755 100644 --- a/lib/include/srslte/mac/pdu_queue.h +++ b/lib/include/srslte/mac/pdu_queue.h @@ -16,7 +16,6 @@ #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" diff --git a/lib/include/srslte/phy/channel/channel.h b/lib/include/srslte/phy/channel/channel.h index 01a2a0406..e8f5e76e2 100644 --- a/lib/include/srslte/phy/channel/channel.h +++ b/lib/include/srslte/phy/channel/channel.h @@ -18,8 +18,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/radio/radio.h b/lib/include/srslte/radio/radio.h index a6728d076..4a4654ace 100644 --- a/lib/include/srslte/radio/radio.h +++ b/lib/include/srslte/radio/radio.h @@ -15,12 +15,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 b88a38e78..52c5b2db9 100644 --- a/lib/include/srslte/radio/radio_base.h +++ b/lib/include/srslte/radio/radio_base.h @@ -19,7 +19,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 320f37b48..b438aff72 100644 --- a/lib/include/srslte/radio/radio_null.h +++ b/lib/include/srslte/radio/radio_null.h @@ -19,8 +19,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 f790515db..cb7c6ee8a 100644 --- a/lib/include/srslte/rrc/rrc_cfg_utils.h +++ b/lib/include/srslte/rrc/rrc_cfg_utils.h @@ -15,7 +15,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/logger.h b/lib/include/srslte/srslog/logger.h index d41897823..c0444c9f7 100644 --- a/lib/include/srslte/srslog/logger.h +++ b/lib/include/srslte/srslog/logger.h @@ -28,7 +28,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: @@ -36,9 +36,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; @@ -93,16 +91,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 @@ -173,6 +171,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/gtpu.h b/lib/include/srslte/upper/gtpu.h index 502984e51..c6fa3270e 100644 --- a/lib/include/srslte/upper/gtpu.h +++ b/lib/include/srslte/upper/gtpu.h @@ -13,8 +13,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 { diff --git a/lib/include/srslte/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index 36401bfc1..c54fd4834 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -14,7 +14,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" diff --git a/lib/include/srslte/upper/pdcp_entity_base.h b/lib/include/srslte/upper/pdcp_entity_base.h index 1d30146fb..278a507f7 100644 --- a/lib/include/srslte/upper/pdcp_entity_base.h +++ b/lib/include/srslte/upper/pdcp_entity_base.h @@ -17,7 +17,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" @@ -112,9 +111,9 @@ 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 pdcp_sn_vector_t& pdcp_sns) = 0; - virtual void notify_failure(const pdcp_sn_vector_t& 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; diff --git a/lib/include/srslte/upper/pdcp_entity_lte.h b/lib/include/srslte/upper/pdcp_entity_lte.h index 259c903b9..4610d48e9 100644 --- a/lib/include/srslte/upper/pdcp_entity_lte.h +++ b/lib/include/srslte/upper/pdcp_entity_lte.h @@ -16,7 +16,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" diff --git a/lib/include/srslte/upper/pdcp_entity_nr.h b/lib/include/srslte/upper/pdcp_entity_nr.h index 02d31ea69..967aa1035 100644 --- a/lib/include/srslte/upper/pdcp_entity_nr.h +++ b/lib/include/srslte/upper/pdcp_entity_nr.h @@ -17,7 +17,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" diff --git a/lib/include/srslte/upper/rlc.h b/lib/include/srslte/upper/rlc.h index 9b361f8b1..27864ef17 100644 --- a/lib/include/srslte/upper/rlc.h +++ b/lib/include/srslte/upper/rlc.h @@ -15,7 +15,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 c81842ef1..b4ac1cf18 100644 --- a/lib/include/srslte/upper/rlc_am_base.h +++ b/lib/include/srslte/upper/rlc_am_base.h @@ -15,7 +15,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 b826ee054..27f1f29cf 100644 --- a/lib/include/srslte/upper/rlc_am_lte.h +++ b/lib/include/srslte/upper/rlc_am_lte.h @@ -17,7 +17,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/task_scheduler.h" #include "srslte/common/timeout.h" #include "srslte/interfaces/pdcp_interface_types.h" diff --git a/lib/include/srslte/upper/rlc_am_nr.h b/lib/include/srslte/upper/rlc_am_nr.h index 2f8c8e96b..aa9813b58 100644 --- a/lib/include/srslte/upper/rlc_am_nr.h +++ b/lib/include/srslte/upper/rlc_am_nr.h @@ -15,7 +15,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 4c8e72836..8df58b8be 100644 --- a/lib/include/srslte/upper/rlc_common.h +++ b/lib/include/srslte/upper/rlc_common.h @@ -14,7 +14,6 @@ #define SRSLTE_RLC_COMMON_H #include "srslte/adt/circular_buffer.h" -#include "srslte/common/logmap.h" #include "srslte/interfaces/rlc_interface_types.h" #include "srslte/upper/rlc_metrics.h" #include diff --git a/lib/include/srslte/upper/rlc_tm.h b/lib/include/srslte/upper/rlc_tm.h index 001dd6123..6fac7fc3c 100644 --- a/lib/include/srslte/upper/rlc_tm.h +++ b/lib/include/srslte/upper/rlc_tm.h @@ -15,7 +15,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 0c9ea639c..111f3bf39 100644 --- a/lib/include/srslte/upper/rlc_um_base.h +++ b/lib/include/srslte/upper/rlc_um_base.h @@ -16,7 +16,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 5e0744a15..73028087f 100644 --- a/lib/include/srslte/upper/rlc_um_lte.h +++ b/lib/include/srslte/upper/rlc_um_lte.h @@ -15,7 +15,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 d2ecf4a5e..36aafa7a4 100644 --- a/lib/include/srslte/upper/rlc_um_nr.h +++ b/lib/include/srslte/upper/rlc_um_nr.h @@ -15,7 +15,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 9d758c093..d02aa23f3 100644 --- a/lib/src/common/CMakeLists.txt +++ b/lib/src/common/CMakeLists.txt @@ -16,9 +16,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 0acf2cc9d..000000000 --- a/lib/src/common/log_filter.cc +++ /dev/null @@ -1,298 +0,0 @@ -/** - * - * \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 -#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 18bafbc27..000000000 --- a/lib/src/common/logger_srslog_wrapper.cc +++ /dev/null @@ -1,21 +0,0 @@ -/** - * - * \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/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 49b8201e2..000000000 --- a/lib/src/common/logmap.cc +++ /dev/null @@ -1,120 +0,0 @@ -/** - * - * \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/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 01d96e8d6..4f573d273 100644 --- a/lib/src/common/mac_pcap.cc +++ b/lib/src/common/mac_pcap.cc @@ -11,6 +11,7 @@ */ #include "srslte/common/mac_pcap.h" +#include "srslte/common/standard_streams.h" #include "srslte/common/threads.h" namespace srslte { diff --git a/lib/src/common/test/thread_pool_test.cc b/lib/src/common/test/thread_pool_test.cc index b95d409f2..fb4d8b05d 100644 --- a/lib/src/common/test/thread_pool_test.cc +++ b/lib/src/common/test/thread_pool_test.cc @@ -9,12 +9,11 @@ * the distribution. * */ -#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 71ae9470f..ca8c9658e 100644 --- a/lib/src/mac/pdu.cc +++ b/lib/src/mac/pdu.cc @@ -15,6 +15,7 @@ #include #include +#include "srslte/common/standard_streams.h" #include "srslte/mac/pdu.h" extern "C" { diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index fbfc68cf7..9b41c8b8c 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -11,6 +11,7 @@ */ #include "srslte/radio/radio.h" +#include "srslte/common/standard_streams.h" #include "srslte/common/string_helpers.h" #include "srslte/config.h" #include diff --git a/lib/src/upper/pdcp_entity_lte.cc b/lib/src/upper/pdcp_entity_lte.cc index ef68ccbfa..c87e23121 100644 --- a/lib/src/upper/pdcp_entity_lte.cc +++ b/lib/src/upper/pdcp_entity_lte.cc @@ -13,6 +13,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 diff --git a/lib/test/adt/span_test.cc b/lib/test/adt/span_test.cc index bbc671ade..8d43947ff 100644 --- a/lib/test/adt/span_test.cc +++ b/lib/test/adt/span_test.cc @@ -11,6 +11,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 a2b1889b4..a3084d360 100644 --- a/lib/test/asn1/asn1_utils_test.cc +++ b/lib/test/asn1/asn1_utils_test.cc @@ -22,6 +22,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 */ @@ -586,13 +588,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; } @@ -643,8 +646,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 b111934b7..20403d99a 100644 --- a/lib/test/asn1/ngap_test.cc +++ b/lib/test/asn1/ngap_test.cc @@ -337,7 +337,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 c0936d7e8..d5420f4a5 100644 --- a/lib/test/asn1/rrc_nr_utils_test.cc +++ b/lib/test/asn1/rrc_nr_utils_test.cc @@ -16,8 +16,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; @@ -70,7 +68,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 1e5d7c288..5997aa45c 100644 --- a/lib/test/asn1/rrc_test.cc +++ b/lib/test/asn1/rrc_test.cc @@ -693,7 +693,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 685a6d962..0e34bd3ed 100644 --- a/lib/test/asn1/s1ap_test.cc +++ b/lib/test/asn1/s1ap_test.cc @@ -355,10 +355,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 c8369412b..1831b2231 100644 --- a/lib/test/asn1/srslte_asn1_nas_test.cc +++ b/lib/test/asn1/srslte_asn1_nas_test.cc @@ -11,13 +11,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 2e6741e75..6bdbeb827 100644 --- a/lib/test/asn1/srslte_asn1_rrc_dl_ccch_test.cc +++ b/lib/test/asn1/srslte_asn1_rrc_dl_ccch_test.cc @@ -12,7 +12,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; @@ -115,4 +114,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 1bc40697c..c9daea4ed 100644 --- a/lib/test/asn1/srslte_asn1_rrc_dl_dcch_test.cc +++ b/lib/test/asn1/srslte_asn1_rrc_dl_dcch_test.cc @@ -12,7 +12,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 7d478c5f7..b111a92b6 100644 --- a/lib/test/asn1/srslte_asn1_rrc_mcch_test.cc +++ b/lib/test/asn1/srslte_asn1_rrc_mcch_test.cc @@ -13,7 +13,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 821eb0cf5..242054270 100644 --- a/lib/test/asn1/srslte_asn1_rrc_meas_test.cc +++ b/lib/test/asn1/srslte_asn1_rrc_meas_test.cc @@ -13,10 +13,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 189e0d6f4..57f1da08b 100644 --- a/lib/test/asn1/srslte_asn1_rrc_nr_test.cc +++ b/lib/test/asn1/srslte_asn1_rrc_nr_test.cc @@ -279,13 +279,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); @@ -297,7 +299,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); @@ -313,7 +314,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 d49fd2235..46e33935e 100644 --- a/lib/test/asn1/srslte_asn1_rrc_ul_dcch_test.cc +++ b/lib/test/asn1/srslte_asn1_rrc_ul_dcch_test.cc @@ -12,7 +12,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 @@ -169,4 +168,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 69a5ba96d..0eab93aeb 100644 --- a/lib/test/common/CMakeLists.txt +++ b/lib/test/common/CMakeLists.txt @@ -39,9 +39,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,10 +60,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) @@ -90,4 +83,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 f0d66ded1..7fa87922c 100644 --- a/lib/test/common/choice_type_test.cc +++ b/lib/test/common/choice_type_test.cc @@ -11,6 +11,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 e3c77b563..000000000 --- a/lib/test/common/log_filter_test.cc +++ /dev/null @@ -1,219 +0,0 @@ -/** - * - * \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. - * - */ - -#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/network_utils_test.cc b/lib/test/common/network_utils_test.cc index bd02fdf36..f47057b69 100644 --- a/lib/test/common/network_utils_test.cc +++ b/lib/test/common/network_utils_test.cc @@ -10,7 +10,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 1d7c9995c..000000000 --- a/lib/test/common/test_common_test.cc +++ /dev/null @@ -1,72 +0,0 @@ -/** - * - * \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/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 2b11559ae..080339cef 100644 --- a/lib/test/mac/mac_pdu_nr_test.cc +++ b/lib/test/mac/mac_pdu_nr_test.cc @@ -10,7 +10,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 cd3d4fca5..1c61005de 100644 --- a/lib/test/mac/pdu_test.cc +++ b/lib/test/mac/pdu_test.cc @@ -12,7 +12,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" diff --git a/lib/test/upper/pdcp_base_test.h b/lib/test/upper/pdcp_base_test.h index 63256179e..815f6ad81 100644 --- a/lib/test/upper/pdcp_base_test.h +++ b/lib/test/upper/pdcp_base_test.h @@ -14,7 +14,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/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index fafc7cea4..35bc611e2 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -10,7 +10,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" @@ -3415,10 +3415,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( @@ -3436,6 +3432,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(); @@ -3606,4 +3604,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 2fae1781e..86d2313f8 100644 --- a/lib/test/upper/rlc_common_test.cc +++ b/lib/test/upper/rlc_common_test.cc @@ -10,7 +10,6 @@ * */ -#include "srslte/common/log_filter.h" #include "srslte/upper/rlc.h" #include diff --git a/lib/test/upper/rlc_stress_test.cc b/lib/test/upper/rlc_stress_test.cc index b1225f76d..965c21125 100644 --- a/lib/test/upper/rlc_stress_test.cc +++ b/lib/test/upper/rlc_stress_test.cc @@ -12,7 +12,6 @@ #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" @@ -104,7 +103,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") @@ -130,7 +129,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 @@ -367,9 +368,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 srslte::pdcp_sn_vector_t& pdcp_sns) {} - void notify_failure(uint32_t lcid, const srslte::pdcp_sn_vector_t& 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() @@ -431,7 +432,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; diff --git a/lib/test/upper/rlc_um_nr_test.cc b/lib/test/upper/rlc_um_nr_test.cc index 8d369d4f2..efd5d540e 100644 --- a/lib/test/upper/rlc_um_nr_test.cc +++ b/lib/test/upper/rlc_um_nr_test.cc @@ -11,7 +11,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 5ff376e6a..10a3a490f 100644 --- a/lib/test/upper/rlc_um_test.cc +++ b/lib/test/upper/rlc_um_test.cc @@ -11,7 +11,6 @@ */ #include "rlc_test_common.h" -#include "srslte/common/log_filter.h" #include "srslte/upper/rlc_um_lte.h" #include diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index 9a389ad5d..02f57a7e0 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -34,7 +34,6 @@ #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" @@ -120,7 +119,7 @@ public: virtual ~enb(); - int init(const all_args_t& args_, srslte::logger* logger_); + int init(const all_args_t& args_); void stop(); @@ -139,7 +138,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; @@ -157,8 +155,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 64f7a9543..2e42a2ec1 100644 --- a/srsenb/hdr/phy/nr/cc_worker.h +++ b/srsenb/hdr/phy/nr/cc_worker.h @@ -13,7 +13,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 243fae977..a29072eb3 100644 --- a/srsenb/hdr/phy/phy.h +++ b/srsenb/hdr/phy/phy.h @@ -16,8 +16,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 98770a847..4e85a404a 100644 --- a/srsenb/hdr/phy/phy_common.h +++ b/srsenb/hdr/phy/phy_common.h @@ -17,13 +17,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 84355415d..7d503bf13 100644 --- a/srsenb/hdr/phy/prach_worker.h +++ b/srsenb/hdr/phy/prach_worker.h @@ -15,7 +15,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 cfe9443c6..761ea2f57 100644 --- a/srsenb/hdr/phy/txrx.h +++ b/srsenb/hdr/phy/txrx.h @@ -17,7 +17,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 8136c0ae5..664828b21 100644 --- a/srsenb/hdr/phy/vnf_phy_nr.h +++ b/srsenb/hdr/phy/vnf_phy_nr.h @@ -16,8 +16,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" @@ -62,4 +60,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 f0ca26a6b..0aec62c8d 100644 --- a/srsenb/hdr/stack/enb_stack_lte.h +++ b/srsenb/hdr/stack/enb_stack_lte.h @@ -40,7 +40,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 @@ -145,17 +145,6 @@ 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; diff --git a/srsenb/hdr/stack/gnb_stack_nr.h b/srsenb/hdr/stack/gnb_stack_nr.h index 4497df060..55accca04 100644 --- a/srsenb/hdr/stack/gnb_stack_nr.h +++ b/srsenb/hdr/stack/gnb_stack_nr.h @@ -26,8 +26,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" @@ -81,6 +79,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 82d9060c7..16a95cee5 100644 --- a/srsenb/hdr/stack/mac/mac.h +++ b/srsenb/hdr/stack/mac/mac.h @@ -15,7 +15,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" @@ -41,8 +40,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_); @@ -120,7 +118,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 = {}; diff --git a/srsenb/hdr/stack/mac/mac_nr.h b/srsenb/hdr/stack/mac/mac_nr.h index 437f1168c..858199488 100644 --- a/srsenb/hdr/stack/mac/mac_nr.h +++ b/srsenb/hdr/stack/mac/mac_nr.h @@ -14,7 +14,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" @@ -82,8 +81,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 b09fcd1e4..ff5fbad48 100644 --- a/srsenb/hdr/stack/mac/sched.h +++ b/srsenb/hdr/stack/mac/sched.h @@ -15,7 +15,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_grid.h b/srsenb/hdr/stack/mac/sched_grid.h index 6376494e9..3ef27c71b 100644 --- a/srsenb/hdr/stack/mac/sched_grid.h +++ b/srsenb/hdr/stack/mac/sched_grid.h @@ -17,7 +17,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 diff --git a/srsenb/hdr/stack/mac/sched_helpers.h b/srsenb/hdr/stack/mac/sched_helpers.h index bba6bcced..a2424ca56 100644 --- a/srsenb/hdr/stack/mac/sched_helpers.h +++ b/srsenb/hdr/stack/mac/sched_helpers.h @@ -14,7 +14,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" @@ -56,7 +55,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; } } @@ -78,7 +77,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_ue.h b/srsenb/hdr/stack/mac/sched_ue.h index c70891c7f..dbe259e6a 100644 --- a/srsenb/hdr/stack/mac/sched_ue.h +++ b/srsenb/hdr/stack/mac/sched_ue.h @@ -14,7 +14,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 6ecfb50f4..42b9a8ea6 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_harq.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_harq.h @@ -14,7 +14,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" 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 4876fbfd1..75fb0942a 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h @@ -13,10 +13,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 { diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/tpc.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/tpc.h index 377b3c109..adfc42434 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/tpc.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/tpc.h @@ -15,7 +15,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 887e1f6f4..451bb4723 100644 --- a/srsenb/hdr/stack/mac/ue.h +++ b/srsenb/hdr/stack/mac/ue.h @@ -16,7 +16,6 @@ #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/interfaces/sched_interface.h" @@ -84,7 +83,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, @@ -168,7 +166,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 b9c93c39c..15ad5ebcb 100644 --- a/srsenb/hdr/stack/rrc/rrc.h +++ b/srsenb/hdr/stack/rrc/rrc.h @@ -21,7 +21,6 @@ #include "srslte/adt/mem_pool.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" diff --git a/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h b/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h index 9a79fcb21..1ed8fc16a 100644 --- a/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h +++ b/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h @@ -15,7 +15,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 928571eb4..baea1e199 100644 --- a/srsenb/hdr/stack/rrc/rrc_cell_cfg.h +++ b/srsenb/hdr/stack/rrc/rrc_cell_cfg.h @@ -14,7 +14,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 5e30e2bc3..78d73cfac 100644 --- a/srsenb/hdr/stack/rrc/rrc_mobility.h +++ b/srsenb/hdr/stack/rrc/rrc_mobility.h @@ -16,7 +16,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 141527841..086277886 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -20,7 +20,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" @@ -128,11 +127,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/ue_rr_cfg.h b/srsenb/hdr/stack/rrc/ue_rr_cfg.h index 9e8f46de3..7a95e214f 100644 --- a/srsenb/hdr/stack/rrc/ue_rr_cfg.h +++ b/srsenb/hdr/stack/rrc/ue_rr_cfg.h @@ -35,7 +35,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 { @@ -46,15 +45,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 9f897fa8d..d22875ea5 100644 --- a/srsenb/hdr/stack/upper/gtpu.h +++ b/srsenb/hdr/stack/upper/gtpu.h @@ -12,10 +12,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_nr.h b/srsenb/hdr/stack/upper/pdcp_nr.h index dd380711c..223d42141 100644 --- a/srsenb/hdr/stack/upper/pdcp_nr.h +++ b/srsenb/hdr/stack/upper/pdcp_nr.h @@ -10,9 +10,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" @@ -104,7 +101,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; @@ -112,6 +108,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_nr.h b/srsenb/hdr/stack/upper/rlc_nr.h index e337a1cd1..9514c86c9 100644 --- a/srsenb/hdr/stack/upper/rlc_nr.h +++ b/srsenb/hdr/stack/upper/rlc_nr.h @@ -13,9 +13,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 @@ -80,11 +77,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 4f3e275dd..acc1674cd 100644 --- a/srsenb/hdr/stack/upper/s1ap.h +++ b/srsenb/hdr/stack/upper/s1ap.h @@ -18,7 +18,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 0c51fa0ce..a7e600028 100644 --- a/srsenb/hdr/stack/upper/sdap.h +++ b/srsenb/hdr/stack/upper/sdap.h @@ -15,7 +15,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 1fbe1f777..1b47f6917 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -11,13 +11,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 { @@ -34,13 +34,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()); @@ -54,7 +52,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; @@ -200,7 +198,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; } @@ -209,24 +207,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 40d72d924..b3c84198f 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -1133,7 +1133,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 64b9e5291..24ebf7414 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -19,8 +19,6 @@ #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" @@ -498,8 +496,6 @@ 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}); @@ -516,8 +512,7 @@ int main(int argc, char* argv[]) // 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); @@ -535,7 +530,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 d31856e87..99f80f107 100644 --- a/srsenb/src/phy/lte/cc_worker.cc +++ b/srsenb/src/phy/lte/cc_worker.cc @@ -10,7 +10,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 74def64ac..33708ea3d 100644 --- a/srsenb/src/phy/lte/sf_worker.cc +++ b/srsenb/src/phy/lte/sf_worker.cc @@ -10,7 +10,6 @@ * */ -#include "srslte/common/log.h" #include "srslte/common/threads.h" #include "srslte/srslte.h" @@ -273,8 +272,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 3ad653fc6..006347110 100644 --- a/srsenb/src/phy/phy.cc +++ b/srsenb/src/phy/phy.cc @@ -19,7 +19,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 9635b0633..1c48f2b56 100644 --- a/srsenb/src/phy/txrx.cc +++ b/srsenb/src/phy/txrx.cc @@ -12,7 +12,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 74163dd18..e64a8dcba 100644 --- a/srsenb/src/phy/vnf_phy_nr.cc +++ b/srsenb/src/phy/vnf_phy_nr.cc @@ -10,19 +10,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; @@ -72,4 +64,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 bae30116a..5054ac028 100644 --- a/srsenb/src/stack/enb_stack_lte.cc +++ b/srsenb/src/stack/enb_stack_lte.cc @@ -20,7 +20,7 @@ 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)), @@ -36,7 +36,6 @@ 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(), pending_stack_metrics(64) { @@ -73,37 +72,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 @@ -132,7 +116,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; } diff --git a/srsenb/src/stack/gnb_stack_nr.cc b/srsenb/src/stack/gnb_stack_nr.cc index fa921d1c6..f4fa1ae72 100644 --- a/srsenb/src/stack/gnb_stack_nr.cc +++ b/srsenb/src/stack/gnb_stack_nr.cc @@ -16,7 +16,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")); @@ -70,8 +70,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 10084d38e..4ec63739a 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -14,8 +14,8 @@ #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" @@ -43,16 +43,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_; @@ -282,7 +280,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)) { @@ -304,7 +301,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)) { @@ -348,7 +344,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)) { @@ -364,7 +359,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)) { @@ -380,7 +374,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)) { @@ -396,7 +389,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)) { @@ -424,7 +416,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)) { @@ -504,7 +495,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(); @@ -562,7 +552,7 @@ 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())); + 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; @@ -578,7 +568,6 @@ int mac::get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res_list) 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 @@ -779,7 +768,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); @@ -890,7 +878,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) { @@ -994,8 +981,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 de01a0f21..ac0b89d2d 100644 --- a/srsenb/src/stack/mac/mac_nr.cc +++ b/srsenb/src/stack/mac/mac_nr.cc @@ -20,7 +20,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(); @@ -50,15 +50,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\n"); started = true; @@ -87,7 +87,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\n", 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; @@ -98,7 +98,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\n"); } } @@ -106,7 +106,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\n", 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; @@ -134,18 +134,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\n", 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\n", 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)\n", + 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; @@ -173,7 +173,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); @@ -216,14 +216,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)\n", 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\n", i, ue_rx_pdu.get_num_subpdus(), subpdu.get_lcid(), @@ -246,10 +246,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\n", sib.index); } - log_h->info("Including SIB %d into SI scheduling\n", sib.index); + logger.info("Including SIB %d into SI scheduling\n", 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 07e8487bc..336320c6e 100644 --- a/srsenb/src/stack/mac/sched.cc +++ b/srsenb/src/stack/mac/sched.cc @@ -16,7 +16,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 0b6928a64..dc075e5c6 100644 --- a/srsenb/src/stack/mac/sched_carrier.cc +++ b/srsenb/src/stack/mac/sched_carrier.cc @@ -14,7 +14,7 @@ #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" diff --git a/srsenb/src/stack/mac/sched_grid.cc b/srsenb/src/stack/mac/sched_grid.cc index c58e9812f..d8d896f0c 100644 --- a/srsenb/src/stack/mac/sched_grid.cc +++ b/srsenb/src/stack/mac/sched_grid.cc @@ -12,7 +12,6 @@ #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; diff --git a/srsenb/src/stack/mac/sched_helpers.cc b/srsenb/src/stack/mac/sched_helpers.cc index 46531973d..ad1a8cae3 100644 --- a/srsenb/src/stack/mac/sched_helpers.cc +++ b/srsenb/src/stack/mac/sched_helpers.cc @@ -11,8 +11,10 @@ */ #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, ...) get_mac_logger().debug(fmt, ##__VA_ARGS__) diff --git a/srsenb/src/stack/mac/sched_ue.cc b/srsenb/src/stack/mac/sched_ue.cc index cdd92fa45..e6a68575c 100644 --- a/srsenb/src/stack/mac/sched_ue.cc +++ b/srsenb/src/stack/mac/sched_ue.cc @@ -15,7 +15,6 @@ #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/logmap.h" #include "srslte/common/string_helpers.h" #include "srslte/srslog/bundled/fmt/ranges.h" diff --git a/srsenb/src/stack/mac/ue.cc b/srsenb/src/stack/mac/ue.cc index 157c23e45..99105e6e2 100644 --- a/srsenb/src/stack/mac/ue.cc +++ b/srsenb/src/stack/mac/ue.cc @@ -97,8 +97,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_) : @@ -108,12 +107,11 @@ 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_, 128), nof_rx_harq_proc(nof_rx_harq_proc_), nof_tx_harq_proc(nof_tx_harq_proc_), ta_fsm(this), diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index 37233748a..9674dd95e 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -17,6 +17,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" diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index 4b85964ad..afe7f6b46 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -20,11 +20,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 @@ -64,6 +66,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] = {}; @@ -80,8 +83,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 f764ddfc5..4e6be18f0 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -19,7 +19,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_, @@ -40,8 +40,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; @@ -50,7 +50,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\n", 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); @@ -64,7 +64,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\n"); running = true; } @@ -83,23 +83,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)\n", + source.c_str(), + dir == Tx ? "Tx" : "Rx", + msg.msg.c1().type().to_string().c_str(), + pdu->N_bytes); + logger.debug("Content:\n%s\n", json_writer.to_string().c_str()); + } else if (logger.info.enabled()) { + logger.info("%s - %s %s (%d B)\n", 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()); } } @@ -170,9 +170,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\n", rnti); } else { - m_log->error("Adding user rnti=0x%x (already exists)\n", rnti); + logger.error("Adding user rnti=0x%x (already exists)\n", rnti); } } @@ -189,7 +189,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\n", sched_cfg.nrb_pucch); // Copy Cell configuration sched_cfg.cell = cfg.cell; @@ -209,7 +209,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)\n", mib_buf->N_bytes); mib_buffer = std::move(mib_buf); } @@ -269,12 +269,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.\n", 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)\n", sib_index, buffer->get_tailroom(), sib_buffer[sib_index]->N_bytes); @@ -295,7 +295,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) { @@ -308,11 +308,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\n", rnti); } } @@ -369,11 +369,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\n"); } 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.\n"); } 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 0f5de24d0..9233e8a6c 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -18,6 +18,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" diff --git a/srsenb/src/stack/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index 3119e2778..f4027bb10 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -12,9 +12,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 diff --git a/srsenb/src/stack/upper/pdcp_nr.cc b/srsenb/src/stack/upper/pdcp_nr.cc index 67ec04284..6075a22ec 100644 --- a/srsenb/src/stack/upper/pdcp_nr.cc +++ b/srsenb/src/stack/upper/pdcp_nr.cc @@ -15,7 +15,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_, @@ -28,8 +29,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() @@ -95,7 +96,7 @@ 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.\n", rnti); } } @@ -104,7 +105,7 @@ void pdcp_nr::notify_delivery(uint16_t rnti, uint32_t lcid, const srslte::pdcp_s 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.\n", rnti); } } @@ -113,7 +114,7 @@ void pdcp_nr::notify_failure(uint16_t rnti, uint32_t lcid, const srslte::pdcp_sn 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.\n", rnti); } } @@ -122,7 +123,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.\n", rnti); } } diff --git a/srsenb/src/stack/upper/rlc_nr.cc b/srsenb/src/stack/upper/rlc_nr.cc index f0bfeb170..41474ed45 100644 --- a/srsenb/src/stack/upper/rlc_nr.cc +++ b/srsenb/src/stack/upper/rlc_nr.cc @@ -15,7 +15,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_, @@ -44,7 +44,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); } @@ -56,7 +56,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\n", rnti); } } @@ -67,7 +67,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\n", rnti); } } @@ -107,7 +107,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\n", rnti, lcid, tx_queue); m_mac->rlc_buffer_state(rnti, lcid, tx_queue, retx_queue); } else { ret = SRSLTE_ERROR; @@ -124,7 +124,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\n", rnti, lcid, tx_queue); m_mac->rlc_buffer_state(rnti, lcid, tx_queue, retx_queue); } } @@ -152,7 +152,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\n", rnti, lcid, tx_queue); } } diff --git a/srsenb/src/stack/upper/s1ap.cc b/srsenb/src/stack/upper/s1ap.cc index 83f418548..695e565c0 100644 --- a/srsenb/src/stack/upper/s1ap.cc +++ b/srsenb/src/stack/upper/s1ap.cc @@ -16,7 +16,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() @@ -1524,17 +1524,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))); @@ -1543,9 +1544,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_test_rand.cc b/srsenb/test/mac/sched_test_rand.cc index 707a491f4..631626cba 100644 --- a/srsenb/test/mac/sched_test_rand.cc +++ b/srsenb/test/mac/sched_test_rand.cc @@ -19,7 +19,6 @@ #include #include -#include "srslte/common/log_filter.h" #include "srslte/interfaces/sched_interface.h" #include "srslte/phy/utils/debug.h" @@ -30,7 +29,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; @@ -151,8 +150,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; } @@ -235,7 +234,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; @@ -243,7 +242,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 @@ -352,7 +352,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/phy/enb_phy_test.cc b/srsenb/test/phy/enb_phy_test.cc index b4c0c2fca..156d66e43 100644 --- a/srsenb/test/phy/enb_phy_test.cc +++ b/srsenb/test/phy/enb_phy_test.cc @@ -20,7 +20,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 e521c6760..309acc84d 100644 --- a/srsenb/test/upper/rrc_meascfg_test.cc +++ b/srsenb/test/upper/rrc_meascfg_test.cc @@ -326,7 +326,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 a08b901f2..4839906c4 100644 --- a/srsenb/test/upper/test_helpers.cc +++ b/srsenb/test/upper/test_helpers.cc @@ -16,8 +16,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 cf64ed631..a05a46be4 100644 --- a/srsenb/test/upper/test_helpers.h +++ b/srsenb/test/upper/test_helpers.h @@ -16,15 +16,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) { @@ -42,7 +41,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 ee06bf4ee..685ab00f9 100644 --- a/srsepc/hdr/hss/hss.h +++ b/srsepc/hdr/hss/hss.h @@ -20,8 +20,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 7c6cbceab..58ec5cf8a 100644 --- a/srsepc/hdr/mbms-gw/mbms-gw.h +++ b/srsepc/hdr/mbms-gw/mbms-gw.h @@ -21,8 +21,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 3f33d9ce3..185b7dcf0 100644 --- a/srsepc/hdr/mme/mme.h +++ b/srsepc/hdr/mme/mme.h @@ -21,8 +21,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 4ba058d4d..9239a608f 100644 --- a/srsepc/hdr/mme/mme_gtpc.h +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -15,8 +15,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 5e849d44b..d70d39c65 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -24,8 +24,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 e4b2f8d50..ad227d1fc 100644 --- a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h @@ -17,7 +17,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 7b3549c39..9e5dd6ce7 100644 --- a/srsepc/hdr/mme/s1ap_erab_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_erab_mngmt_proc.h @@ -17,7 +17,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 cf376990d..7f5936fe2 100644 --- a/srsepc/hdr/mme/s1ap_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_mngmt_proc.h @@ -15,7 +15,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 1af3560f3..bfdfb32f5 100644 --- a/srsepc/hdr/mme/s1ap_paging.h +++ b/srsepc/hdr/mme/s1ap_paging.h @@ -15,7 +15,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 73f311013..f79ea9b8b 100644 --- a/srsepc/hdr/spgw/gtpc.h +++ b/srsepc/hdr/spgw/gtpc.h @@ -14,8 +14,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 7d79b5f19..9bfd2fa16 100644 --- a/srsepc/hdr/spgw/gtpu.h +++ b/srsepc/hdr/spgw/gtpu.h @@ -16,7 +16,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 baff8d17e..5a1138bb3 100644 --- a/srsepc/hdr/spgw/spgw.h +++ b/srsepc/hdr/spgw/spgw.h @@ -21,8 +21,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 241b19ff8..0ce423ad3 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -18,13 +18,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; @@ -329,24 +327,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()); @@ -390,8 +370,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. srslog::init(); @@ -401,60 +379,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 d3bf88256..69e8575d1 100644 --- a/srsepc/src/mbms-gw/main.cc +++ b/srsepc/src/mbms-gw/main.cc @@ -12,7 +12,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 @@ -42,24 +41,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 ***********************************************************************/ @@ -194,7 +175,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. @@ -205,11 +185,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 63967d150..89592e4df 100644 --- a/srsepc/src/mbms-gw/mbms-gw.cc +++ b/srsepc/src/mbms-gw/mbms-gw.cc @@ -11,6 +11,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/srsue/hdr/phy/nr/cc_worker.h b/srsue/hdr/phy/nr/cc_worker.h index 74047058a..97d2650ef 100644 --- a/srsue/hdr/phy/nr/cc_worker.h +++ b/srsue/hdr/phy/nr/cc_worker.h @@ -13,7 +13,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/phy.h b/srsue/hdr/phy/phy.h index 643fc0178..3d90ee33f 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -16,7 +16,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 6522c9ea4..bd5b87cd3 100644 --- a/srsue/hdr/phy/phy_common.h +++ b/srsue/hdr/phy/phy_common.h @@ -16,7 +16,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 0c4b62423..a045e52c1 100644 --- a/srsue/hdr/phy/prach.h +++ b/srsue/hdr/phy/prach.h @@ -13,7 +13,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 47045f652..96b2a6e65 100644 --- a/srsue/hdr/phy/scell/intra_measure.h +++ b/srsue/hdr/phy/scell/intra_measure.h @@ -12,7 +12,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 eaab9e73b..7367570ab 100644 --- a/srsue/hdr/phy/sync.h +++ b/srsue/hdr/phy/sync.h @@ -24,7 +24,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 a6dd7fc7b..5f8c63888 100644 --- a/srsue/hdr/phy/ue_lte_phy_base.h +++ b/srsue/hdr/phy/ue_lte_phy_base.h @@ -18,7 +18,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 fa5253dda..37fb7ce56 100644 --- a/srsue/hdr/phy/ue_nr_phy_base.h +++ b/srsue/hdr/phy/ue_nr_phy_base.h @@ -18,7 +18,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 4b2bd87bb..474477263 100644 --- a/srsue/hdr/phy/ue_phy_base.h +++ b/srsue/hdr/phy/ue_phy_base.h @@ -18,7 +18,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 2dea24f40..ff3638b0d 100644 --- a/srsue/hdr/phy/vnf_phy_nr.h +++ b/srsue/hdr/phy/vnf_phy_nr.h @@ -15,8 +15,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 353563fc0..94dc1479c 100644 --- a/srsue/hdr/stack/mac/demux.h +++ b/srsue/hdr/stack/mac/demux.h @@ -13,7 +13,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 a7ee3c5eb..fe942a632 100644 --- a/srsue/hdr/stack/mac/dl_harq.h +++ b/srsue/hdr/stack/mac/dl_harq.h @@ -15,7 +15,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 b49d4bb0c..0416cc147 100644 --- a/srsue/hdr/stack/mac/dl_sps.h +++ b/srsue/hdr/stack/mac/dl_sps.h @@ -13,7 +13,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 59e80ef02..11a99ca26 100644 --- a/srsue/hdr/stack/mac/mac.h +++ b/srsue/hdr/stack/mac/mac.h @@ -21,7 +21,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 885d7d7ba..e9ef07690 100644 --- a/srsue/hdr/stack/mac/mux.h +++ b/srsue/hdr/stack/mac/mux.h @@ -20,7 +20,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 43a95461e..55aa1b375 100644 --- a/srsue/hdr/stack/mac/proc_bsr.h +++ b/srsue/hdr/stack/mac/proc_bsr.h @@ -17,7 +17,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 bf5eca692..c03625d00 100644 --- a/srsue/hdr/stack/mac/proc_phr.h +++ b/srsue/hdr/stack/mac/proc_phr.h @@ -13,7 +13,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 ae018a523..39e03cf32 100644 --- a/srsue/hdr/stack/mac/proc_ra.h +++ b/srsue/hdr/stack/mac/proc_ra.h @@ -19,7 +19,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 a5f8264bd..ef5f6f838 100644 --- a/srsue/hdr/stack/mac/proc_sr.h +++ b/srsue/hdr/stack/mac/proc_sr.h @@ -13,7 +13,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 4696f583a..1917119dc 100644 --- a/srsue/hdr/stack/mac/ul_harq.h +++ b/srsue/hdr/stack/mac/ul_harq.h @@ -16,7 +16,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 7a18c4d93..fcdb6a471 100644 --- a/srsue/hdr/stack/mac/ul_sps.h +++ b/srsue/hdr/stack/mac/ul_sps.h @@ -13,7 +13,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 0d88082ff..4235e32f6 100644 --- a/srsue/hdr/stack/rrc/phy_controller.h +++ b/srsue/hdr/stack/rrc/phy_controller.h @@ -15,7 +15,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 69f811384..7cfe55a46 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -21,7 +21,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 cf54722c2..f1be850a7 100644 --- a/srsue/hdr/stack/rrc/rrc_meas.h +++ b/srsue/hdr/stack/rrc/rrc_meas.h @@ -15,7 +15,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 42032e0b2..bb084260a 100644 --- a/srsue/hdr/stack/rrc/rrc_nr.h +++ b/srsue/hdr/stack/rrc/rrc_nr.h @@ -17,7 +17,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" @@ -133,6 +132,7 @@ private: uint16_t lcid; }; + srslog::basic_logger& logger; bool running = false; srslte::block_queue cmd_q; @@ -145,8 +145,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 d5565f7e5..a63ed4983 100644 --- a/srsue/hdr/stack/rrc/rrc_procedures.h +++ b/srsue/hdr/stack/rrc/rrc_procedures.h @@ -11,7 +11,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 72af1eaed..bf449386c 100644 --- a/srsue/hdr/stack/ue_stack_base.h +++ b/srsue/hdr/stack/ue_stack_base.h @@ -13,7 +13,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 34609ca00..acc6f5611 100644 --- a/srsue/hdr/stack/ue_stack_lte.h +++ b/srsue/hdr/stack/ue_stack_lte.h @@ -32,7 +32,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 c7fcf8e96..d2f07d91a 100644 --- a/srsue/hdr/stack/ue_stack_nr.h +++ b/srsue/hdr/stack/ue_stack_nr.h @@ -27,7 +27,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" @@ -50,7 +49,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; @@ -111,9 +110,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 da7690dbe..9161aa36e 100644 --- a/srsue/hdr/stack/upper/gw.h +++ b/srsue/hdr/stack/upper/gw.h @@ -17,8 +17,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 ae059d85b..cd2ac7663 100644 --- a/srsue/hdr/stack/upper/nas.h +++ b/srsue/hdr/stack/upper/nas.h @@ -16,7 +16,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 df6215246..fefac3eaf 100644 --- a/srsue/hdr/stack/upper/nas_emm_state.h +++ b/srsue/hdr/stack/upper/nas_emm_state.h @@ -13,7 +13,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 9ef9585ef..096a6e54a 100644 --- a/srsue/hdr/stack/upper/pcsc_usim.h +++ b/srsue/hdr/stack/upper/pcsc_usim.h @@ -14,7 +14,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 ca8f4a292..6c76f691d 100644 --- a/srsue/hdr/stack/upper/tft_packet_filter.h +++ b/srsue/hdr/stack/upper/tft_packet_filter.h @@ -15,8 +15,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 fa6cdaae3..f4bf1bb0e 100644 --- a/srsue/hdr/stack/upper/usim.h +++ b/srsue/hdr/stack/upper/usim.h @@ -14,7 +14,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 993ec89ac..729002966 100644 --- a/srsue/hdr/stack/upper/usim_base.h +++ b/srsue/hdr/stack/upper/usim_base.h @@ -14,7 +14,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 9fde96bd4..79ede96d9 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -25,7 +25,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" @@ -90,7 +89,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(); @@ -109,7 +108,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 9c44861bb..24e48402c 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -13,8 +13,6 @@ #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" @@ -652,7 +650,6 @@ 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 @@ -666,14 +663,13 @@ int main(int argc, char* argv[]) // 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. 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 649d58d91..d9aaa251e 100644 --- a/srsue/src/phy/lte/cc_worker.cc +++ b/srsue/src/phy/lte/cc_worker.cc @@ -12,6 +12,7 @@ #include "srslte/srslte.h" +#include "srslte/common/standard_streams.h" #include "srsue/hdr/phy/lte/cc_worker.h" #define Error(fmt, ...) \ diff --git a/srsue/src/phy/lte/sf_worker.cc b/srsue/src/phy/lte/sf_worker.cc index 78c8f2f50..d46566d54 100644 --- a/srsue/src/phy/lte/sf_worker.cc +++ b/srsue/src/phy/lte/sf_worker.cc @@ -12,6 +12,7 @@ #include "srslte/srslte.h" +#include "srslte/common/standard_streams.h" #include "srsue/hdr/phy/lte/sf_worker.h" #include diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index 3cd314902..7915c185d 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -11,6 +11,7 @@ */ #include "srsue/hdr/phy/nr/cc_worker.h" +#include "srslte/common/buffer_pool.h" #include "srslte/srslte.h" namespace srsue { diff --git a/srsue/src/phy/nr/sf_worker.cc b/srsue/src/phy/nr/sf_worker.cc index fea8876d2..a0f764bb5 100644 --- a/srsue/src/phy/nr/sf_worker.cc +++ b/srsue/src/phy/nr/sf_worker.cc @@ -11,6 +11,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 9cd686267..39a36df40 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -10,16 +10,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 504232a53..b95f629d0 100644 --- a/srsue/src/phy/prach.cc +++ b/srsue/src/phy/prach.cc @@ -11,7 +11,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 26df3340f..704d324b5 100644 --- a/srsue/src/phy/search.cc +++ b/srsue/src/phy/search.cc @@ -11,6 +11,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 61b8bdcbe..e8d264c69 100644 --- a/srsue/src/phy/sync.cc +++ b/srsue/src/phy/sync.cc @@ -11,10 +11,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 f18d6df1f..507699741 100644 --- a/srsue/src/phy/vnf_phy_nr.cc +++ b/srsue/src/phy/vnf_phy_nr.cc @@ -19,7 +19,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 c185c02af..0b6c8c86a 100644 --- a/srsue/src/stack/mac/demux.cc +++ b/srsue/src/stack/mac/demux.cc @@ -10,15 +10,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/common/string_helpers.h" -#include "srslte/interfaces/ue_phy_interfaces.h" - namespace srsue { demux::demux(srslog::basic_logger& logger) : diff --git a/srsue/src/stack/mac/dl_harq.cc b/srsue/src/stack/mac/dl_harq.cc index e869c9ab8..8e988b69d 100644 --- a/srsue/src/stack/mac/dl_harq.cc +++ b/srsue/src/stack/mac/dl_harq.cc @@ -16,7 +16,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 e7d86238a..4ce2d54d3 100644 --- a/srsue/src/stack/mac/mac.cc +++ b/srsue/src/stack/mac/mac.cc @@ -18,7 +18,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/proc_ra.cc b/srsue/src/stack/mac/proc_ra.cc index e4b1bb835..a5cf40b8c 100644 --- a/srsue/src/stack/mac/proc_ra.cc +++ b/srsue/src/stack/mac/proc_ra.cc @@ -11,6 +11,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 1e73791ee..a6a7745c8 100644 --- a/srsue/src/stack/mac/proc_sr.cc +++ b/srsue/src/stack/mac/proc_sr.cc @@ -16,6 +16,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 f9b235d15..28805efed 100644 --- a/srsue/src/stack/mac/ul_harq.cc +++ b/srsue/src/stack/mac/ul_harq.cc @@ -17,7 +17,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 9fdbc7a24..3525c4ec4 100644 --- a/srsue/src/stack/mac_nr/proc_ra_nr.cc +++ b/srsue/src/stack/mac_nr/proc_ra_nr.cc @@ -11,6 +11,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" diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index f136395af..787a0088b 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -14,6 +14,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" @@ -22,6 +23,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 4193145fe..c7166494c 100644 --- a/srsue/src/stack/rrc/rrc_nr.cc +++ b/srsue/src/stack/rrc/rrc_nr.cc @@ -12,14 +12,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; @@ -28,7 +29,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; @@ -65,7 +68,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); @@ -86,9 +89,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; @@ -115,19 +118,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); } } @@ -138,29 +141,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; } @@ -174,7 +177,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; } @@ -311,7 +314,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; @@ -328,7 +331,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; } @@ -341,7 +344,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; } @@ -355,7 +358,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; } @@ -365,7 +368,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; } } @@ -374,7 +377,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; } @@ -385,7 +388,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); @@ -431,7 +434,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; }; @@ -439,13 +442,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; @@ -455,7 +458,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() @@ -483,7 +486,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; } @@ -494,13 +497,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; } @@ -520,20 +523,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(); @@ -541,15 +544,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; } @@ -587,7 +590,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); @@ -598,7 +601,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; } @@ -606,17 +609,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(); @@ -624,7 +627,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()); } @@ -639,7 +642,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"); } } @@ -658,7 +661,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; } @@ -677,7 +680,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/ue_stack_lte.cc b/srsue/src/stack/ue_stack_lte.cc index 019c11768..f452deffb 100644 --- a/srsue/src/stack/ue_stack_lte.cc +++ b/srsue/src/stack/ue_stack_lte.cc @@ -11,9 +11,10 @@ */ #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 #include diff --git a/srsue/src/stack/ue_stack_nr.cc b/srsue/src/stack/ue_stack_nr.cc index 3211f8fb4..0f9f31002 100644 --- a/srsue/src/stack/ue_stack_nr.cc +++ b/srsue/src/stack/ue_stack_nr.cc @@ -17,8 +17,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)); @@ -55,15 +59,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()); @@ -156,7 +157,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 2eee881dc..5aefebf0b 100644 --- a/srsue/src/stack/upper/gw.cc +++ b/srsue/src/stack/upper/gw.cc @@ -11,6 +11,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 107429eaa..ac9e36254 100644 --- a/srsue/src/stack/upper/nas.cc +++ b/srsue/src/stack/upper/nas.cc @@ -19,7 +19,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 d74898e76..796fe46e3 100644 --- a/srsue/src/stack/upper/nas_idle_procedures.cc +++ b/srsue/src/stack/upper/nas_idle_procedures.cc @@ -11,6 +11,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 dc6c67059..8e70cbd89 100644 --- a/srsue/src/stack/upper/pcsc_usim.cc +++ b/srsue/src/stack/upper/pcsc_usim.cc @@ -13,6 +13,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 2e9977898..21b4f170c 100644 --- a/srsue/src/stack/upper/tft_packet_filter.cc +++ b/srsue/src/stack/upper/tft_packet_filter.cc @@ -11,6 +11,7 @@ */ #include "srsue/hdr/stack/upper/tft_packet_filter.h" +#include "srslte/srslte.h" #include "srslte/upper/ipv6.h" #include #include diff --git a/srsue/src/stack/upper/usim.cc b/srsue/src/stack/upper/usim.cc index 8c33346e1..5a6d9c06b 100644 --- a/srsue/src/stack/upper/usim.cc +++ b/srsue/src/stack/upper/usim.cc @@ -12,6 +12,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 72e5ebe4c..653747612 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -29,7 +29,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; @@ -40,10 +40,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); @@ -121,7 +120,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 c29e717dd..7374c85bf 100644 --- a/srsue/test/mac_nr/proc_ra_nr_test.cc +++ b/srsue/test/mac_nr/proc_ra_nr_test.cc @@ -9,8 +9,8 @@ * the distribution. * */ +#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 591568923..e843c3ed4 100644 --- a/srsue/test/phy/ue_phy_test.cc +++ b/srsue/test/phy/ue_phy_test.cc @@ -10,7 +10,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 3bc554b4c..e31e7d0b9 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_port_handler.h +++ b/srsue/test/ttcn3/hdr/ttcn3_port_handler.h @@ -19,7 +19,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 34590644c..a0219a7ee 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_ue.h +++ b/srsue/test/ttcn3/hdr/ttcn3_ue.h @@ -14,6 +14,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 640f4cbfd..97fa104cd 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_ut_interface.h +++ b/srsue/test/ttcn3/hdr/ttcn3_ut_interface.h @@ -15,7 +15,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 ae41cf840..05d4eb55f 100644 --- a/srsue/test/ttcn3/src/ttcn3_dut.cc +++ b/srsue/test/ttcn3/src/ttcn3_dut.cc @@ -11,7 +11,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 4005994e1..d2b199c84 100644 --- a/srsue/test/ttcn3/src/ttcn3_syssim.cc +++ b/srsue/test/ttcn3/src/ttcn3_syssim.cc @@ -12,7 +12,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" diff --git a/srsue/test/upper/gw_test.cc b/srsue/test/upper/gw_test.cc index 4a5958f4f..bb68ab019 100644 --- a/srsue/test/upper/gw_test.cc +++ b/srsue/test/upper/gw_test.cc @@ -10,7 +10,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 dcd45e980..5a7d410db 100644 --- a/srsue/test/upper/nas_test.cc +++ b/srsue/test/upper/nas_test.cc @@ -11,8 +11,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 d5090a907..1b502dcb9 100644 --- a/srsue/test/upper/rrc_meas_test.cc +++ b/srsue/test/upper/rrc_meas_test.cc @@ -12,7 +12,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" @@ -1217,7 +1216,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 4c538373c..a4343ecd1 100644 --- a/srsue/test/upper/rrc_reconfig_test.cc +++ b/srsue/test/upper/rrc_reconfig_test.cc @@ -12,7 +12,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 fdf8ed41e..6f07a931e 100644 --- a/srsue/test/upper/tft_test.cc +++ b/srsue/test/upper/tft_test.cc @@ -11,13 +11,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 40bbabfce..524d22a19 100644 --- a/srsue/test/upper/ue_rrc_nr_test.cc +++ b/srsue/test/upper/ue_rrc_nr_test.cc @@ -17,9 +17,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); From d1ab4aae66609519ba2874c71b4791f664943aa0 Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 10 Mar 2021 20:04:22 +0000 Subject: [PATCH 47/65] fix ipv6 related compilation issue --- srsue/src/stack/upper/tft_packet_filter.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/srsue/src/stack/upper/tft_packet_filter.cc b/srsue/src/stack/upper/tft_packet_filter.cc index 21b4f170c..eb9bd19b8 100644 --- a/srsue/src/stack/upper/tft_packet_filter.cc +++ b/srsue/src/stack/upper/tft_packet_filter.cc @@ -11,8 +11,9 @@ */ #include "srsue/hdr/stack/upper/tft_packet_filter.h" -#include "srslte/srslte.h" #include "srslte/upper/ipv6.h" + +#include "srslte/srslte.h" #include #include #include From d01f6806f07a942893386b2114622232dc79fa43 Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 10 Mar 2021 20:20:02 +0000 Subject: [PATCH 48/65] fix regression - set correctly log sink in epc --- srsepc/src/main.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index 0ce423ad3..38731a628 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -370,6 +370,7 @@ int main(int argc, char* argv[]) if (!chan) { return SRSLTE_ERROR; } + srslog::set_default_sink(*log_sink); // Start the log backend. srslog::init(); From 68c938267f6f8d22544cb2b275fa1f97a84db5ae Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 10 Mar 2021 20:57:38 +0000 Subject: [PATCH 49/65] fix srslte include that causes a compilation issue --- srsue/src/stack/upper/tft_packet_filter.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/srsue/src/stack/upper/tft_packet_filter.cc b/srsue/src/stack/upper/tft_packet_filter.cc index eb9bd19b8..3a85df9cb 100644 --- a/srsue/src/stack/upper/tft_packet_filter.cc +++ b/srsue/src/stack/upper/tft_packet_filter.cc @@ -13,7 +13,10 @@ #include "srsue/hdr/stack/upper/tft_packet_filter.h" #include "srslte/upper/ipv6.h" -#include "srslte/srslte.h" +extern "C" { +#include "srslte/config.h" +} + #include #include #include From 31b03fdd8a19fc24aee3a770570be8afaeb0b282 Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 11 Mar 2021 12:12:37 +0000 Subject: [PATCH 50/65] fix scheduler UL harq reset for msg3 case --- srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc | 6 ++++++ 1 file changed, 6 insertions(+) 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 96eb86a9d..e7050ae60 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc @@ -273,8 +273,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; } From d41b6187c153fa30e836e1662d2af0481434c986 Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 11 Mar 2021 16:27:20 +0000 Subject: [PATCH 51/65] bugfix - remove extra \n from logging calls --- srsenb/src/stack/mac/mac_nr.cc | 22 +++++++++++----------- srsenb/src/stack/rrc/rrc_nr.cc | 28 ++++++++++++++-------------- srsenb/src/stack/upper/pdcp_nr.cc | 8 ++++---- srsenb/src/stack/upper/rlc_nr.cc | 10 +++++----- 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/srsenb/src/stack/mac/mac_nr.cc b/srsenb/src/stack/mac/mac_nr.cc index ac0b89d2d..85fcfec0a 100644 --- a/srsenb/src/stack/mac/mac_nr.cc +++ b/srsenb/src/stack/mac/mac_nr.cc @@ -58,7 +58,7 @@ int mac_nr::init(const mac_nr_args_t& args_, pcap->open(args.pcap.filename); } - logger.info("Started\n"); + logger.info("Started"); started = true; @@ -87,7 +87,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) { - logger.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; @@ -98,7 +98,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 { - logger.error("Couldn't read BCH payload from RRC\n"); + logger.error("Couldn't read BCH payload from RRC"); } } @@ -106,7 +106,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) { - logger.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; @@ -134,9 +134,9 @@ void mac_nr::get_dl_config(const uint32_t tti, // Only create PDU if RLC has something to tx if (pdu_len > 0) { - logger.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; - logger.info(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); @@ -144,7 +144,7 @@ void mac_nr::get_dl_config(const uint32_t tti, logger.debug(ue_tx_buffer.at(buffer_index)->msg, ue_tx_buffer.at(buffer_index)->N_bytes, - "Generated MAC PDU (%d B)\n", + "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; @@ -216,14 +216,14 @@ void mac_nr::process_pdus() int mac_nr::handle_pdu(srslte::unique_byte_buffer_t pdu) { - logger.info(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); - logger.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(), @@ -246,10 +246,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) { - logger.error("Couldn't read SIB %d from RRC\n", sib.index); + logger.error("Couldn't read SIB %d from RRC", sib.index); } - logger.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/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 4e6be18f0..2a6895c8f 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -50,7 +50,7 @@ void rrc_nr::init(const rrc_nr_cfg_t& cfg_, config_mac(); // add dummy user - logger.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); @@ -64,7 +64,7 @@ void rrc_nr::init(const rrc_nr_cfg_t& cfg_, false}; pdcp->add_bearer(cfg.coreless.rnti, cfg.coreless.drb_lcid, pdcp_cnfg); - logger.info("Started\n"); + logger.info("Started"); running = true; } @@ -88,14 +88,14 @@ void rrc_nr::log_rrc_message(const std::string& source, msg.to_json(json_writer); logger.debug(pdu->msg, pdu->N_bytes, - "%s - %s %s (%d B)\n", + "%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\n", json_writer.to_string().c_str()); + logger.debug("Content:\n%s", json_writer.to_string().c_str()); } else if (logger.info.enabled()) { - logger.info("%s - %s %s (%d B)\n", + logger.info("%s - %s %s (%d B)", source.c_str(), dir == Tx ? "Tx" : "Rx", msg.msg.c1().type().to_string().c_str(), @@ -170,9 +170,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); - logger.info("Added new user rnti=0x%x\n", rnti); + logger.info("Added new user rnti=0x%x", rnti); } else { - logger.error("Adding user rnti=0x%x (already exists)\n", rnti); + logger.error("Adding user rnti=0x%x (already exists)", rnti); } } @@ -189,7 +189,7 @@ void rrc_nr::config_mac() // PUCCH width sched_cfg.nrb_pucch = SRSLTE_MAX(cfg.sr_cfg.nof_prb, cfg.cqi_cfg.nof_prb); - logger.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; @@ -209,7 +209,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(); - logger.debug(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); } @@ -269,12 +269,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()) { - logger.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) { - logger.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); @@ -312,7 +312,7 @@ void rrc_nr::handle_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer break; } } else { - logger.warning("Discarding PDU for removed rnti=0x%x\n", rnti); + logger.warning("Discarding PDU for removed rnti=0x%x", rnti); } } @@ -369,11 +369,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->logger.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->logger.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/upper/pdcp_nr.cc b/srsenb/src/stack/upper/pdcp_nr.cc index 6075a22ec..19ae3e1f8 100644 --- a/srsenb/src/stack/upper/pdcp_nr.cc +++ b/srsenb/src/stack/upper/pdcp_nr.cc @@ -96,7 +96,7 @@ 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 { - logger.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); } } @@ -105,7 +105,7 @@ void pdcp_nr::notify_delivery(uint16_t rnti, uint32_t lcid, const srslte::pdcp_s if (users.count(rnti)) { users[rnti].pdcp->notify_delivery(lcid, pdcp_sns); } else { - logger.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); } } @@ -114,7 +114,7 @@ void pdcp_nr::notify_failure(uint16_t rnti, uint32_t lcid, const srslte::pdcp_sn if (users.count(rnti)) { users[rnti].pdcp->notify_failure(lcid, pdcp_sns); } else { - logger.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); } } @@ -123,7 +123,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 { - logger.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_nr.cc b/srsenb/src/stack/upper/rlc_nr.cc index 41474ed45..db1b2130a 100644 --- a/srsenb/src/stack/upper/rlc_nr.cc +++ b/srsenb/src/stack/upper/rlc_nr.cc @@ -56,7 +56,7 @@ void rlc_nr::rem_user(uint16_t rnti) users[rnti].m_rlc->stop(); users.erase(rnti); } else { - logger.error("Removing rnti=0x%x. Already removed\n", rnti); + logger.error("Removing rnti=0x%x. Already removed", rnti); } } @@ -67,7 +67,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); } - logger.info("Cleared buffer rnti=0x%x\n", rnti); + logger.info("Cleared buffer rnti=0x%x", rnti); } } @@ -107,7 +107,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; - logger.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; @@ -124,7 +124,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; - logger.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); } } @@ -152,7 +152,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); - logger.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); } } From 20928651c7523d76f9bf126c892eae4eb730d426 Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 25 Feb 2021 14:38:40 +0000 Subject: [PATCH 52/65] created batch allocator that leverages background worker pool --- lib/include/srslte/adt/mem_pool.h | 91 +++++++++++++++++++++++++++++++ srsenb/hdr/stack/rrc/rrc.h | 2 - srsenb/hdr/stack/rrc/rrc_ue.h | 2 + srsenb/src/stack/rrc/rrc.cc | 5 +- srsenb/src/stack/rrc/rrc_ue.cc | 17 +++--- 5 files changed, 104 insertions(+), 13 deletions(-) diff --git a/lib/include/srslte/adt/mem_pool.h b/lib/include/srslte/adt/mem_pool.h index a73de0249..1277e3d8d 100644 --- a/lib/include/srslte/adt/mem_pool.h +++ b/lib/include/srslte/adt/mem_pool.h @@ -13,6 +13,7 @@ #ifndef SRSLTE_MEM_POOL_H #define SRSLTE_MEM_POOL_H +#include "srslte/common/thread_pool.h" #include #include #include @@ -196,6 +197,96 @@ 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); + 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/srsenb/hdr/stack/rrc/rrc.h b/srsenb/hdr/stack/rrc/rrc.h index 15ad5ebcb..a8685eb8f 100644 --- a/srsenb/hdr/stack/rrc/rrc.h +++ b/srsenb/hdr/stack/rrc/rrc.h @@ -200,8 +200,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_ue.h b/srsenb/hdr/stack/rrc/rrc_ue.h index 725abaeb5..9505fcd06 100644 --- a/srsenb/hdr/stack/rrc/rrc_ue.h +++ b/srsenb/hdr/stack/rrc/rrc_ue.h @@ -119,6 +119,8 @@ public: void operator delete(void* ptr)noexcept; void operator delete[](void* ptr) = delete; + static srslte::background_allocator_obj_pool* get_ue_pool(); + private: // args srslte::timer_handler::unique_timer activity_timer; diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index 9674dd95e..36840741c 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -35,7 +35,7 @@ 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() {} @@ -1019,7 +1019,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_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 9233e8a6c..da1eaacb9 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -63,18 +63,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 srslte::background_allocator_obj_pool 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() From 6159cb3817af7ef70392b4ca71e78755054b7a12 Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 11 Mar 2021 20:41:54 +0000 Subject: [PATCH 53/65] add assert to ensure a valid ptr is passed to memory pool deallocator --- lib/include/srslte/adt/mem_pool.h | 1 + srsenb/hdr/stack/rrc/rrc.h | 1 - srsenb/hdr/stack/rrc/rrc_ue.h | 4 +++- srsenb/src/stack/rrc/rrc_ue.cc | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/include/srslte/adt/mem_pool.h b/lib/include/srslte/adt/mem_pool.h index 1277e3d8d..935e6a733 100644 --- a/lib/include/srslte/adt/mem_pool.h +++ b/lib/include/srslte/adt/mem_pool.h @@ -254,6 +254,7 @@ public: void deallocate_node(void* p) { std::lock_guard lock(mutex); + assert(p != nullptr); if (p != nullptr) { obj_cache.push(static_cast(p)); } diff --git a/srsenb/hdr/stack/rrc/rrc.h b/srsenb/hdr/stack/rrc/rrc.h index a8685eb8f..713f8f41a 100644 --- a/srsenb/hdr/stack/rrc/rrc.h +++ b/srsenb/hdr/stack/rrc/rrc.h @@ -18,7 +18,6 @@ #include "rrc_metrics.h" #include "srsenb/hdr/stack/upper/common_enb.h" #include "srslte/adt/circular_buffer.h" -#include "srslte/adt/mem_pool.h" #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" #include "srslte/common/stack_procedure.h" diff --git a/srsenb/hdr/stack/rrc/rrc_ue.h b/srsenb/hdr/stack/rrc/rrc_ue.h index 9505fcd06..fab63a10f 100644 --- a/srsenb/hdr/stack/rrc/rrc_ue.h +++ b/srsenb/hdr/stack/rrc/rrc_ue.h @@ -15,6 +15,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" @@ -119,7 +120,8 @@ public: void operator delete(void* ptr)noexcept; void operator delete[](void* ptr) = delete; - static srslte::background_allocator_obj_pool* get_ue_pool(); + using ue_pool_t = srslte::background_allocator_obj_pool; + static ue_pool_t* get_ue_pool(); private: // args diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index da1eaacb9..134f75738 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -67,7 +67,7 @@ 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 srslte::background_allocator_obj_pool ue_pool(true); + static rrc::ue::ue_pool_t ue_pool(true); return &ue_pool; } From 3f79cd628143422fcd9671dc4b9cb5ef0d12685a Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 4 Mar 2021 11:32:35 +0000 Subject: [PATCH 54/65] Changed generation of status report to use rx_counts instead of undeliverd_sdus_queue. Added a queue to store information about rx_counts received. Added unit test for when the SNs wrap-around in status report genaration --- lib/include/srslte/upper/pdcp_entity_lte.h | 25 ++- lib/src/upper/pdcp_entity_lte.cc | 45 +++-- lib/test/upper/pdcp_lte_test_status_report.cc | 174 +++++++++++------- 3 files changed, 157 insertions(+), 87 deletions(-) diff --git a/lib/include/srslte/upper/pdcp_entity_lte.h b/lib/include/srslte/upper/pdcp_entity_lte.h index 4610d48e9..b1b2f4c9d 100644 --- a/lib/include/srslte/upper/pdcp_entity_lte.h +++ b/lib/include/srslte/upper/pdcp_entity_lte.h @@ -21,6 +21,8 @@ #include "srslte/interfaces/ue_rrc_interfaces.h" #include "srslte/upper/pdcp_entity_base.h" +#include + namespace srsue { class gw_interface_pdcp; @@ -165,9 +167,30 @@ 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; + std::set 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/src/upper/pdcp_entity_lte.cc b/lib/src/upper/pdcp_entity_lte.cc index c87e23121..6d9eac2f1 100644 --- a/lib/src/upper/pdcp_entity_lte.cc +++ b/lib/src/upper/pdcp_entity_lte.cc @@ -404,10 +404,27 @@ 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) +{ + // The received COUNT is the first missing COUNT + if (rx_count == fmc) { + fmc++; + // Update the queue for the Status report bitmap, if NEXT_PDCP_RX_SN changed + while (not rx_counts_info.empty() && *rx_counts_info.begin() == fmc) { + rx_counts_info.erase(fmc); + fmc++; + } + } else { + rx_counts_info.insert(rx_count); + } +} /**************************************************************************** * Control handler functions (Status Report) * Ref: 3GPP TS 36.323 v10.1.0 Section 5.1.3 @@ -434,15 +451,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(); @@ -451,7 +463,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); @@ -474,8 +486,9 @@ 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 + uint32_t lms = *rx_counts_info.rbegin(); int32_t diff = lms - (fms - 1); uint32_t nof_sns = 1u << cfg.sn_len; if (diff > (int32_t)(nof_sns / 2)) { @@ -494,13 +507,12 @@ void pdcp_entity_lte::send_status_report() lms, 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; } @@ -575,6 +587,7 @@ void pdcp_entity_lte::handle_status_report_pdu(unique_byte_buffer_t pdu) undelivered_sdus->clear_sdu(sn); } } + /**************************************************************************** * TX PDUs Queue Helper ***************************************************************************/ diff --git a/lib/test/upper/pdcp_lte_test_status_report.cc b/lib/test/upper/pdcp_lte_test_status_report.cc index 925c28731..d2509ea4d 100644 --- a/lib/test/upper/pdcp_lte_test_status_report.cc +++ b/lib/test/upper/pdcp_lte_test_status_report.cc @@ -17,40 +17,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}; + 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}; - 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; + 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}; - pdcp_hlp.set_pdcp_initial_state(init_state); + // 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 | @@ -62,33 +83,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; } @@ -97,37 +121,57 @@ 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}; - 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; + 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_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(); 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 @@ -142,19 +186,22 @@ 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(); 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 @@ -167,10 +214,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; } /* @@ -233,20 +280,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; } @@ -259,7 +292,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 = { + .next_pdcp_tx_sn = 0, .tx_hfn = 0, .rx_hfn = 0, .next_pdcp_rx_sn = 0, .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); From d2ef5419578f0942ad2e5c277fb5c5871196de40 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 5 Mar 2021 18:45:11 +0000 Subject: [PATCH 55/65] Changed the structure to store rx_counts info to std::vector, to reduce memory allocations. Update the rx_count_info queue if the queue size is too large. --- lib/include/srslte/upper/pdcp_entity_lte.h | 9 ++-- lib/src/upper/pdcp_entity_lte.cc | 44 ++++++++++++------- lib/test/upper/pdcp_lte_test_status_report.cc | 12 ++++- 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/lib/include/srslte/upper/pdcp_entity_lte.h b/lib/include/srslte/upper/pdcp_entity_lte.h index b1b2f4c9d..81db900d3 100644 --- a/lib/include/srslte/upper/pdcp_entity_lte.h +++ b/lib/include/srslte/upper/pdcp_entity_lte.h @@ -21,8 +21,6 @@ #include "srslte/interfaces/ue_rrc_interfaces.h" #include "srslte/upper/pdcp_entity_base.h" -#include - namespace srsue { class gw_interface_pdcp; @@ -172,9 +170,10 @@ private: std::unique_ptr undelivered_sdus; // Rx info queue - uint32_t fmc = 0; - std::set rx_counts_info; // Keeps the RX_COUNT for generation of the stauts report - void update_rx_counts_queue(uint32_t rx_count); + 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 diff --git a/lib/src/upper/pdcp_entity_lte.cc b/lib/src/upper/pdcp_entity_lte.cc index 6d9eac2f1..792d6e8bc 100644 --- a/lib/src/upper/pdcp_entity_lte.cc +++ b/lib/src/upper/pdcp_entity_lte.cc @@ -74,6 +74,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 @@ -413,16 +414,33 @@ void pdcp_entity_lte::handle_am_drb_pdu(srslte::unique_byte_buffer_t pdu) void pdcp_entity_lte::update_rx_counts_queue(uint32_t rx_count) { + std::sort(rx_counts_info.begin(), rx_counts_info.end(), std::greater()); + + // 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 NEXT_PDCP_RX_SN changed - while (not rx_counts_info.empty() && *rx_counts_info.begin() == fmc) { - rx_counts_info.erase(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.insert(rx_count); + rx_counts_info.push_back(rx_count); + } + + // 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) { + fmc++; + while (not rx_counts_info.empty() && rx_counts_info.back() == fmc) { + rx_counts_info.pop_back(); + fmc++; + } } } /**************************************************************************** @@ -488,23 +506,19 @@ void pdcp_entity_lte::send_status_report() // Add bitmap of missing PDUs, if necessary if (not rx_counts_info.empty()) { // First check size of bitmap - uint32_t lms = *rx_counts_info.rbegin(); - 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 rx_count : rx_counts_info) { diff --git a/lib/test/upper/pdcp_lte_test_status_report.cc b/lib/test/upper/pdcp_lte_test_status_report.cc index d2509ea4d..7bb1c2c2b 100644 --- a/lib/test/upper/pdcp_lte_test_status_report.cc +++ b/lib/test/upper/pdcp_lte_test_status_report.cc @@ -159,6 +159,10 @@ int test_tx_wraparound_status_report(const srslte::pdcp_lte_state_t& init_state, 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_tx->write_sdu(std::move(sdu)); pdcp_tx->notify_delivery({i}); @@ -187,6 +191,10 @@ int test_tx_wraparound_status_report(const srslte::pdcp_lte_state_t& init_state, 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_tx->write_sdu(std::move(sdu)); if (i != 4080 && i != 4081 && i != 4110 && i != 4111) { @@ -292,8 +300,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 = { - .next_pdcp_tx_sn = 0, .tx_hfn = 0, .rx_hfn = 0, .next_pdcp_rx_sn = 0, .last_submitted_pdcp_rx_sn = 4095}; + 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); From f02694dd3ef2fe2002b1cb8da2af07252e760e0c Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 11 Mar 2021 12:17:33 +0000 Subject: [PATCH 56/65] PDCP status report: Fix issue in keeping track of Rx'ed COUNTs after eNB reestablishment. Fixed issue in logic that limits the size of the rx_counts info vector. --- lib/include/srslte/upper/pdcp_entity_base.h | 4 +-- lib/include/srslte/upper/pdcp_entity_lte.h | 2 +- lib/include/srslte/upper/pdcp_entity_nr.h | 2 +- lib/src/upper/pdcp.cc | 2 +- lib/src/upper/pdcp_entity_lte.cc | 30 ++++++++++++++++++--- lib/src/upper/pdcp_entity_nr.cc | 2 +- lib/test/upper/pdcp_lte_test.h | 2 +- 7 files changed, 34 insertions(+), 10 deletions(-) diff --git a/lib/include/srslte/upper/pdcp_entity_base.h b/lib/include/srslte/upper/pdcp_entity_base.h index 278a507f7..632aa2505 100644 --- a/lib/include/srslte/upper/pdcp_entity_base.h +++ b/lib/include/srslte/upper/pdcp_entity_base.h @@ -115,8 +115,8 @@ public: 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 81db900d3..6ab00d07e 100644 --- a/lib/include/srslte/upper/pdcp_entity_lte.h +++ b/lib/include/srslte/upper/pdcp_entity_lte.h @@ -137,7 +137,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; diff --git a/lib/include/srslte/upper/pdcp_entity_nr.h b/lib/include/srslte/upper/pdcp_entity_nr.h index 967aa1035..893772f61 100644 --- a/lib/include/srslte/upper/pdcp_entity_nr.h +++ b/lib/include/srslte/upper/pdcp_entity_nr.h @@ -60,7 +60,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/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index 17f3371dc..faee2cd09 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -237,7 +237,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; } diff --git a/lib/src/upper/pdcp_entity_lte.cc b/lib/src/upper/pdcp_entity_lte.cc index 792d6e8bc..68ed25c94 100644 --- a/lib/src/upper/pdcp_entity_lte.cc +++ b/lib/src/upper/pdcp_entity_lte.cc @@ -414,7 +414,9 @@ void pdcp_entity_lte::handle_am_drb_pdu(srslte::unique_byte_buffer_t pdu) void pdcp_entity_lte::update_rx_counts_queue(uint32_t rx_count) { - std::sort(rx_counts_info.begin(), rx_counts_info.end(), std::greater()); + if (rx_count < fmc) { + return; + } // Update largest RX_COUNT if (rx_count > largest_rx_count) { @@ -431,16 +433,35 @@ void pdcp_entity_lte::update_rx_counts_queue(uint32_t rx_count) } } 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) { - fmc++; + 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()); } } /**************************************************************************** @@ -765,9 +786,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() diff --git a/lib/src/upper/pdcp_entity_nr.cc b/lib/src/upper/pdcp_entity_nr.cc index 7cd034d84..610163c04 100644 --- a/lib/src/upper/pdcp_entity_nr.cc +++ b/lib/src/upper/pdcp_entity_nr.cc @@ -286,7 +286,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/test/upper/pdcp_lte_test.h b/lib/test/upper/pdcp_lte_test.h index 9f44b0831..df40b4ba7 100644 --- a/lib/test/upper/pdcp_lte_test.h +++ b/lib/test/upper/pdcp_lte_test.h @@ -67,7 +67,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; From 611c5e9814e35ca045ec6acde33632183436ecbb Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 12 Mar 2021 14:28:38 +0000 Subject: [PATCH 57/65] Fix RRC tx in eNB to only send messages with NAS on SRB2 --- srsenb/src/stack/rrc/rrc_ue.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 134f75738..ff365e859 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -1089,9 +1089,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); From 7b33c48fe777292b438ef5e277abc2fc66422916 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 10 Mar 2021 21:25:11 +0100 Subject: [PATCH 58/65] Use static queue in pdu_queue --- lib/include/srslte/common/buffer_pool.h | 1 + lib/include/srslte/mac/pdu_queue.h | 10 ++++------ lib/src/mac/pdu_queue.cc | 4 +++- srsenb/src/stack/mac/ue.cc | 10 +++++----- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index 33f7d1be3..a2e23cb55 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -50,6 +50,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/mac/pdu_queue.h b/lib/include/srslte/mac/pdu_queue.h index ba89af755..9a6d40639 100644 --- a/lib/include/srslte/mac/pdu_queue.h +++ b/lib/include/srslte/mac/pdu_queue.h @@ -33,9 +33,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_q(pool_size) - {} + 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); @@ -47,7 +45,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 { @@ -60,8 +58,8 @@ private: } pdu_t; - dyn_blocking_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/src/mac/pdu_queue.cc b/lib/src/mac/pdu_queue.cc index 77b790cb2..3cb39415e 100644 --- a/lib/src/mac/pdu_queue.cc +++ b/lib/src/mac/pdu_queue.cc @@ -58,7 +58,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_blocking(pdu); + if (!pdu_q.try_push(pdu)) { + logger.warning("Error pushing pdu: queue is full"); + } } else { logger.warning("Error pushing pdu: ptr is empty"); } diff --git a/srsenb/src/stack/mac/ue.cc b/srsenb/src/stack/mac/ue.cc index 99105e6e2..d04a7a969 100644 --- a/srsenb/src/stack/mac/ue.cc +++ b/srsenb/src/stack/mac/ue.cc @@ -107,11 +107,11 @@ ue::ue(uint16_t rnti_, rrc(rrc_), rlc(rlc_), phy(phy_), - 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), From c6fff54f9ecf40fe0b37b02e479fa51459528bae Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 11 Mar 2021 17:33:00 +0000 Subject: [PATCH 59/65] compilation issue fix - wrong number of argments in ttcn3_syssim creation --- srsue/test/ttcn3/src/ttcn3_syssim.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/test/ttcn3/src/ttcn3_syssim.cc b/srsue/test/ttcn3/src/ttcn3_syssim.cc index d2b199c84..0d9da2b45 100644 --- a/srsue/test/ttcn3/src/ttcn3_syssim.cc +++ b/srsue/test/ttcn3/src/ttcn3_syssim.cc @@ -47,7 +47,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); }) From d27e0be6091bb56b618b018f1b5edc25dc962828 Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 11 Mar 2021 20:24:28 +0000 Subject: [PATCH 60/65] created special class to manage mac::ue currently allocated rx UL buffers. This class avoids mallocs --- lib/include/srslte/adt/bounded_vector.h | 4 +- srsenb/hdr/stack/mac/ue.h | 42 +++++- srsenb/src/stack/mac/ue.cc | 162 ++++++++++++++++-------- 3 files changed, 148 insertions(+), 60 deletions(-) diff --git a/lib/include/srslte/adt/bounded_vector.h b/lib/include/srslte/adt/bounded_vector.h index 9f4a08733..fd121d6d8 100644 --- a/lib/include/srslte/adt/bounded_vector.h +++ b/lib/include/srslte/adt/bounded_vector.h @@ -31,11 +31,11 @@ public: bounded_vector() = default; template ::value, int>::type = 0> - bounded_vector(size_type N) + explicit bounded_vector(size_type N) { append(N); } - template ::value, int>::type = 0> + template ::value, int>::type = 0> bounded_vector(size_type N, const U& init_val) { append(N, T(init_val)); diff --git a/srsenb/hdr/stack/mac/ue.h b/srsenb/hdr/stack/mac/ue.h index 451bb4723..ea6ab45ea 100644 --- a/srsenb/hdr/stack/mac/ue.h +++ b/srsenb/hdr/stack/mac/ue.h @@ -18,10 +18,12 @@ #include "srslte/common/block_queue.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 @@ -32,6 +34,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); + + void remove_pdu(tti_point tti); + + bool try_deallocate_pdu(tti_point tti); + + void clear(); + + uint8_t*& operator[](tti_point tti); + + bool has_tti(tti_point tti) const; + +private: + 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: @@ -40,7 +70,9 @@ 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(cc_buffer_handler&&) noexcept = default; + cc_buffer_handler& operator=(cc_buffer_handler&&) noexcept = default; ~cc_buffer_handler(); void reset(); @@ -57,7 +89,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 @@ -66,9 +98,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; diff --git a/srsenb/src/stack/mac/ue.cc b/srsenb/src/stack/mac/ue.cc index d04a7a969..97a6ea4b3 100644 --- a/srsenb/src/stack/mac/ue.cc +++ b/srsenb/src/stack/mac/ue.cc @@ -23,7 +23,101 @@ 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 { + 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) { + remove_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) { @@ -114,9 +208,12 @@ ue::ue(uint16_t rnti_, 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) { + cc_buffers.reserve(nof_cells_); + for (size_t i = 0; i < nof_cells_; ++i) { + cc_buffers.emplace_back(pdus); + } pdus.init(this); // Allocate buffer for PCell @@ -125,14 +222,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(); } } @@ -182,17 +274,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.at(ue_cc_idx).get_rx_used_buffers().request_pdu(tti_point(tti), len); } else { logger.error("UE buffers: Requesting buffer for zero bytes"); } @@ -205,20 +287,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}); } } @@ -353,11 +422,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.at(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, @@ -368,18 +433,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.at(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); } } From 196bf710c00b691f17181827223ccda30034b407 Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 11 Mar 2021 20:57:08 +0000 Subject: [PATCH 61/65] fix compilation issue in mac::ue --- srsenb/src/stack/mac/ue.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/srsenb/src/stack/mac/ue.cc b/srsenb/src/stack/mac/ue.cc index 97a6ea4b3..d93eb40ca 100644 --- a/srsenb/src/stack/mac/ue.cc +++ b/srsenb/src/stack/mac/ue.cc @@ -201,11 +201,11 @@ ue::ue(uint16_t rnti_, rrc(rrc_), rlc(rlc_), phy(phy_), - logger(logger), - mac_msg_dl(20, logger), - mch_mac_msg_dl(10, logger), - mac_msg_ul(20, logger), - pdus(logger), + 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) From ca7fe1349ea753c79ff0c6217967897cce4e985f Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 12 Mar 2021 13:13:20 +0000 Subject: [PATCH 62/65] remove unnecessary sfinae from bounded_vector. Use bounded_vector for UE cc buffers. Set ue cc used buffers remove_pdu method to private --- lib/include/srslte/adt/bounded_vector.h | 37 +++++++++++++------------ srsenb/hdr/stack/mac/ue.h | 6 ++-- srsenb/src/stack/mac/ue.cc | 9 +++--- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/lib/include/srslte/adt/bounded_vector.h b/lib/include/srslte/adt/bounded_vector.h index fd121d6d8..0a0997d12 100644 --- a/lib/include/srslte/adt/bounded_vector.h +++ b/lib/include/srslte/adt/bounded_vector.h @@ -30,19 +30,12 @@ public: using value_type = T; bounded_vector() = default; - template ::value, int>::type = 0> - explicit 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(); @@ -114,13 +107,13 @@ 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 @@ -159,19 +152,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)...); @@ -182,9 +178,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; @@ -215,12 +216,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/srsenb/hdr/stack/mac/ue.h b/srsenb/hdr/stack/mac/ue.h index ea6ab45ea..421801fdf 100644 --- a/srsenb/hdr/stack/mac/ue.h +++ b/srsenb/hdr/stack/mac/ue.h @@ -45,8 +45,6 @@ public: void clear_old_pdus(tti_point current_tti); - void remove_pdu(tti_point tti); - bool try_deallocate_pdu(tti_point tti); void clear(); @@ -56,6 +54,8 @@ public: bool has_tti(tti_point tti) const; private: + void remove_pdu(tti_point tti); + srslog::basic_logger* logger; srslte::pdu_queue* shared_pdu_queue; @@ -183,7 +183,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; diff --git a/srsenb/src/stack/mac/ue.cc b/srsenb/src/stack/mac/ue.cc index d93eb40ca..51a446982 100644 --- a/srsenb/src/stack/mac/ue.cc +++ b/srsenb/src/stack/mac/ue.cc @@ -210,7 +210,6 @@ ue::ue(uint16_t rnti_, nof_tx_harq_proc(nof_tx_harq_proc_), ta_fsm(this) { - cc_buffers.reserve(nof_cells_); for (size_t i = 0; i < nof_cells_; ++i) { cc_buffers.emplace_back(pdus); } @@ -255,7 +254,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* @@ -274,7 +273,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) { - pdu = cc_buffers.at(ue_cc_idx).get_rx_used_buffers().request_pdu(tti_point(tti), len); + 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"); } @@ -422,7 +421,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 (not cc_buffers.at(ue_cc_idx).get_rx_used_buffers().try_deallocate_pdu(tti_point(tti))) { + 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, @@ -433,7 +432,7 @@ 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 (not cc_buffers.at(ue_cc_idx).get_rx_used_buffers().push_pdu(tti_point(tti), len)) { + 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); } From 6feb311e178ca69d0982b4bdd64953396d87696a Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 12 Mar 2021 13:36:16 +0000 Subject: [PATCH 63/65] remove instantiations of move-constructors and move assignment operators from cc_buffer_handler --- srsenb/hdr/stack/mac/ue.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/srsenb/hdr/stack/mac/ue.h b/srsenb/hdr/stack/mac/ue.h index 421801fdf..648a5cf38 100644 --- a/srsenb/hdr/stack/mac/ue.h +++ b/srsenb/hdr/stack/mac/ue.h @@ -71,8 +71,6 @@ public: using cc_softbuffer_rx_list_t = std::vector; explicit cc_buffer_handler(srslte::pdu_queue& shared_pdu_queue_); - cc_buffer_handler(cc_buffer_handler&&) noexcept = default; - cc_buffer_handler& operator=(cc_buffer_handler&&) noexcept = default; ~cc_buffer_handler(); void reset(); From 64e8a17ea82813ca4715aec155038a8aa95df6d3 Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 12 Mar 2021 16:43:17 +0000 Subject: [PATCH 64/65] mac,bugfix - fix incorrect deallocation of PDU --- srsenb/src/stack/mac/ue.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/srsenb/src/stack/mac/ue.cc b/srsenb/src/stack/mac/ue.cc index 51a446982..4d53de2e0 100644 --- a/srsenb/src/stack/mac/ue.cc +++ b/srsenb/src/stack/mac/ue.cc @@ -36,6 +36,7 @@ bool cc_used_buffers_map::push_pdu(tti_point tti, uint32_t len) 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 @@ -90,7 +91,7 @@ void cc_used_buffers_map::remove_pdu(tti_point tti) bool cc_used_buffers_map::try_deallocate_pdu(tti_point tti) { - if (pdu_map[tti.to_uint()].second == nullptr) { + if (pdu_map[tti.to_uint()].second != nullptr) { remove_pdu(tti); return true; } @@ -100,7 +101,7 @@ bool cc_used_buffers_map::try_deallocate_pdu(tti_point tti) void cc_used_buffers_map::clear() { for (auto& pdu : pdu_map) { - remove_pdu(pdu.first); + try_deallocate_pdu(pdu.first); } } From 16b5e1fd4de8104c66a0415c37a1a937e36937b3 Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 12 Mar 2021 16:21:39 +0000 Subject: [PATCH 65/65] fix collision detection of n1pucch for the ACK and SR in the scheduler --- .../stack/mac/sched_phy_ch/sf_cch_allocator.h | 7 +++++-- .../stack/mac/sched_phy_ch/sf_cch_allocator.cc | 17 +++++++++-------- srsenb/test/mac/sched_test_rand.cc | 3 +++ srsenb/test/mac/sched_test_utils.h | 10 +++++----- srsenb/test/mac/sched_ue_ded_test_suite.cc | 8 ++++++++ 5 files changed, 30 insertions(+), 15 deletions(-) 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 ca5ba2674..aa86fc6f0 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 @@ -74,8 +74,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; @@ -111,6 +111,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/src/stack/mac/sched_phy_ch/sf_cch_allocator.cc b/srsenb/src/stack/mac/sched_phy_ch/sf_cch_allocator.cc index 5934f3c31..304978dac 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 @@ -159,8 +159,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); } @@ -172,10 +172,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; } @@ -209,14 +209,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; diff --git a/srsenb/test/mac/sched_test_rand.cc b/srsenb/test/mac/sched_test_rand.cc index 631626cba..20ee20174 100644 --- a/srsenb/test/mac/sched_test_rand.cc +++ b/srsenb/test/mac/sched_test_rand.cc @@ -285,6 +285,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()); diff --git a/srsenb/test/mac/sched_test_utils.h b/srsenb/test/mac/sched_test_utils.h index 7a3a83645..4adc9e091 100644 --- a/srsenb/test/mac/sched_test_utils.h +++ b/srsenb/test/mac/sched_test_utils.h @@ -73,6 +73,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; } @@ -117,11 +121,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 e8c223f52..637cededd 100644 --- a/srsenb/test/mac/sched_ue_ded_test_suite.cc +++ b/srsenb/test/mac/sched_ue_ded_test_suite.cc @@ -13,6 +13,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 { @@ -65,6 +66,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"); @@ -107,6 +109,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; }