diff --git a/srsue/hdr/stack/mac_nr/mac_nr.h b/srsue/hdr/stack/mac_nr/mac_nr.h index 40a9b7462..10ba5910c 100644 --- a/srsue/hdr/stack/mac_nr/mac_nr.h +++ b/srsue/hdr/stack/mac_nr/mac_nr.h @@ -21,7 +21,7 @@ #include "srslte/interfaces/ue_nr_interfaces.h" #include "srslte/mac/mac_sch_pdu_nr.h" #include "srslte/srslog/srslog.h" -#include "srsue/hdr/stack/mac/mux.h" +#include "srsue/hdr/stack/mac_nr/mux_nr.h" #include "srsue/hdr/stack/ue_stack_base.h" namespace srsue { @@ -77,10 +77,11 @@ public: uint16_t get_c_rnti(); void set_c_rnti(uint64_t c_rnti_); - bool msg3_is_transmitted() { return true; } - void msg3_flush() {} - void msg3_prepare() {} - bool msg3_is_empty() { return true; } + void msg3_flush() { mux.msg3_flush(); } + bool msg3_is_transmitted() { return mux.msg3_is_transmitted(); } + void msg3_prepare() { mux.msg3_prepare(); } + bool msg3_is_pending() { return mux.msg3_is_pending(); } + bool msg3_is_empty() { return mux.msg3_is_empty(); } /// stack interface void process_pdus(); @@ -140,6 +141,7 @@ private: // MAC Uplink-related procedures proc_ra_nr proc_ra; + mux_nr mux; }; } // namespace srsue diff --git a/srsue/hdr/stack/mac_nr/mux_nr.h b/srsue/hdr/stack/mac_nr/mux_nr.h new file mode 100644 index 000000000..c07c95869 --- /dev/null +++ b/srsue/hdr/stack/mac_nr/mux_nr.h @@ -0,0 +1,46 @@ +/** + * + * \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 SRSUE_MUX_NR_H +#define SRSUE_MUX_NR_H + +#include "srslte/common/byte_buffer.h" +#include "srslte/common/common.h" +#include "srslte/srslog/srslog.h" +#include "srslte/srslte.h" + +namespace srsue { +class mux_nr +{ +public: + explicit mux_nr(srslog::basic_logger& logger); + ~mux_nr(){}; + void reset(); + void init(); + + void step(); + + void msg3_flush(); + void msg3_prepare(); + bool msg3_is_transmitted(); + bool msg3_is_pending(); + bool msg3_is_empty(); + +private: + srslog::basic_logger& logger; + srslte::unique_byte_buffer_t msg3_buff = nullptr; + typedef enum { none, pending, transmitted } msg3_state_t; + msg3_state_t msg3_state = none; +}; +} // namespace srsue + +#endif // SRSUE_MUX_NR_H diff --git a/srsue/hdr/stack/mac_nr/proc_ra_nr.h b/srsue/hdr/stack/mac_nr/proc_ra_nr.h index 1afe8a1bd..7d63beffb 100644 --- a/srsue/hdr/stack/mac_nr/proc_ra_nr.h +++ b/srsue/hdr/stack/mac_nr/proc_ra_nr.h @@ -37,7 +37,9 @@ public: bool is_rar_opportunity(uint32_t tti); uint16_t get_rar_rnti(); - + bool has_temp_rnti(); + uint16_t get_temp_rnti(); + // PHY interfaces void prach_sent(uint32_t tti, uint32_t s_id, uint32_t t_id, uint32_t f_id, uint32_t ul_carrier_id); void handle_rar_pdu(mac_interface_phy_nr::mac_nr_grant_dl_t& grant); diff --git a/srsue/src/stack/mac_nr/CMakeLists.txt b/srsue/src/stack/mac_nr/CMakeLists.txt index c4ced3176..2003bb81b 100644 --- a/srsue/src/stack/mac_nr/CMakeLists.txt +++ b/srsue/src/stack/mac_nr/CMakeLists.txt @@ -6,6 +6,6 @@ # the distribution. # -set(SOURCES mac_nr.cc proc_ra_nr.cc) +set(SOURCES mac_nr.cc proc_ra_nr.cc mux_nr.cc) add_library(srsue_mac_nr STATIC ${SOURCES}) target_link_libraries(srsue_mac_nr srslte_mac) \ No newline at end of file diff --git a/srsue/src/stack/mac_nr/mac_nr.cc b/srsue/src/stack/mac_nr/mac_nr.cc index 1ca19c888..5c46c071e 100644 --- a/srsue/src/stack/mac_nr/mac_nr.cc +++ b/srsue/src/stack/mac_nr/mac_nr.cc @@ -17,7 +17,7 @@ namespace srsue { mac_nr::mac_nr(srslte::ext_task_sched_handle task_sched_) : - task_sched(task_sched_), logger(srslog::fetch_basic_logger("MAC")), proc_ra(logger) + task_sched(task_sched_), logger(srslog::fetch_basic_logger("MAC")), proc_ra(logger), mux(logger) { tx_buffer = srslte::make_byte_buffer(); rlc_buffer = srslte::make_byte_buffer(); @@ -45,6 +45,8 @@ int mac_nr::init(const mac_nr_args_t& args_, phy_interface_mac_nr* phy_, rlc_int proc_ra.init(phy, this, &task_sched); + mux.init(); + started = true; return SRSLTE_SUCCESS; @@ -104,11 +106,9 @@ mac_interface_phy_nr::sched_rnti_t mac_nr::get_dl_sched_rnti_nr(const uint32_t t return {proc_ra.get_rar_rnti(), srslte_rnti_type_ra}; } -#if 0 if (proc_ra.has_temp_rnti() && has_crnti() == false) { - return proc_ra->get_temp_rnti(); + return {proc_ra.get_temp_rnti(), srslte_rnti_type_c}; } -#endif if (has_crnti()) { return {get_crnti(), srslte_rnti_type_c}; @@ -159,7 +159,7 @@ void mac_nr::write_pcap(const uint32_t cc_idx, mac_nr_grant_dl_t& grant) if (pcap) { for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; ++i) { if (grant.tb[i] != nullptr) { - if (SRSLTE_RNTI_ISRAR(grant.rnti)) { // TODO: replace with proc_ra->get_rar_rnti() + if (grant.rnti == proc_ra.get_rar_rnti()) { pcap->write_dl_ra_rnti_nr(grant.tb[i]->msg, grant.tb[i]->N_bytes, grant.rnti, true, grant.tti); } else if (grant.rnti == SRSLTE_PRNTI) { pcap->write_dl_pch_nr(grant.tb[i]->msg, grant.tb[i]->N_bytes, grant.rnti, true, grant.tti); @@ -219,23 +219,35 @@ void mac_nr::get_ul_data(const mac_nr_grant_ul_t& grant, phy_interface_stack_nr: tx_buffer->clear(); tx_pdu.init_tx(tx_buffer.get(), grant.tbs, true); - while (tx_pdu.get_remaing_len() >= MIN_RLC_PDU_LEN) { - // read RLC PDU - rlc_buffer->clear(); - uint8_t* rd = rlc_buffer->msg; - int pdu_len = rlc->read_pdu(args.drb_lcid, rd, tx_pdu.get_remaing_len() - 2); + if (mux.msg3_is_pending()) { + // If message 3 is pending pack message 3 for uplink transmission + tx_pdu.add_crnti_ce(proc_ra.get_temp_rnti()); - // Add SDU if RLC has something to tx - if (pdu_len > 0) { - rlc_buffer->N_bytes = pdu_len; - logger.info(rlc_buffer->msg, rlc_buffer->N_bytes, "Read %d B from RLC", rlc_buffer->N_bytes); + srslte::mac_sch_subpdu_nr::lcg_bsr_t sbsr = {}; + sbsr.lcg_id = 0; + sbsr.buffer_size = 1; + tx_pdu.add_sbsr_ce(sbsr); - // add to MAC PDU and pack - if (tx_pdu.add_sdu(args.drb_lcid, rlc_buffer->msg, rlc_buffer->N_bytes) != SRSLTE_SUCCESS) { - logger.error("Error packing MAC PDU"); + } else { + // Pack normal UL data PDU + while (tx_pdu.get_remaing_len() >= MIN_RLC_PDU_LEN) { + // read RLC PDU + rlc_buffer->clear(); + uint8_t* rd = rlc_buffer->msg; + int pdu_len = rlc->read_pdu(args.drb_lcid, rd, tx_pdu.get_remaing_len() - 2); + + // Add SDU if RLC has something to tx + if (pdu_len > 0) { + rlc_buffer->N_bytes = pdu_len; + logger.info(rlc_buffer->msg, rlc_buffer->N_bytes, "Read %d B from RLC", rlc_buffer->N_bytes); + + // add to MAC PDU and pack + if (tx_pdu.add_sdu(args.drb_lcid, rlc_buffer->msg, rlc_buffer->N_bytes) != SRSLTE_SUCCESS) { + logger.error("Error packing MAC PDU"); + } + } else { + break; } - } else { - break; } } diff --git a/srsue/src/stack/mac_nr/mux_nr.cc b/srsue/src/stack/mac_nr/mux_nr.cc new file mode 100644 index 000000000..1d5b0c8d0 --- /dev/null +++ b/srsue/src/stack/mac_nr/mux_nr.cc @@ -0,0 +1,51 @@ +/** + * + * \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 "srsue/hdr/stack/mac_nr/mux_nr.h" +#include "srslte/common/buffer_pool.h" + +namespace srsue { + +mux_nr::mux_nr(srslog::basic_logger& logger_) : logger(logger_) +{ + msg3_buff = srslte::make_byte_buffer(); +}; + +void mux_nr::init() {} + +void mux_nr::msg3_flush() +{ + msg3_buff->clear(); + msg3_state = msg3_state_t::none; +} + +void mux_nr::msg3_prepare() +{ + msg3_state = msg3_state_t::pending; +} + +bool mux_nr::msg3_is_transmitted() +{ + return msg3_state == msg3_state_t::transmitted; +} + +bool mux_nr::msg3_is_pending() +{ + return msg3_state == msg3_state_t::pending; +} + +bool mux_nr::msg3_is_empty() +{ + return msg3_buff->N_bytes == 0; +} + +} // namespace srsue diff --git a/srsue/src/stack/mac_nr/proc_ra_nr.cc b/srsue/src/stack/mac_nr/proc_ra_nr.cc index f855360a5..454052e7e 100644 --- a/srsue/src/stack/mac_nr/proc_ra_nr.cc +++ b/srsue/src/stack/mac_nr/proc_ra_nr.cc @@ -93,6 +93,16 @@ uint16_t proc_ra_nr::get_rar_rnti() return rar_rnti; } +bool proc_ra_nr::has_temp_rnti() +{ + return temp_rnti != SRSLTE_INVALID_RNTI; +} + +uint16_t proc_ra_nr::get_temp_rnti() +{ + return temp_rnti; +} + void proc_ra_nr::timer_expired(uint32_t timer_id) { if (prach_send_timer.id() == timer_id) { @@ -228,7 +238,7 @@ void proc_ra_nr::ra_completion() mac->set_c_rnti(temp_rnti); srslte::console("Random Access Complete. c-rnti=0x%x, ta=%d\n", mac->get_c_rnti(), current_ta); logger.info("Random Access Complete. c-rnti=0x%x, ta=%d", mac->get_c_rnti(), current_ta); - temp_rnti = 0; + temp_rnti = SRSLTE_INVALID_RNTI; reset(); }