From faf120501a14fa96f571924ebfa11d2098aa95c9 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 23 Jun 2017 12:27:42 +0200 Subject: [PATCH 01/19] make DL and UL harq header-only - move src of DL and UL harq in to header in prep for templating both - add commong MAC header --- srsue/hdr/mac/dl_harq.h | 308 +++++++++++++++++++++++++---- srsue/hdr/mac/mac_common.h | 45 +++++ srsue/hdr/mac/ul_harq.h | 351 +++++++++++++++++++++++++++++---- srsue/src/mac/dl_harq.cc | 337 ------------------------------- srsue/src/mac/ul_harq.cc | 394 ------------------------------------- 5 files changed, 631 insertions(+), 804 deletions(-) create mode 100644 srsue/hdr/mac/mac_common.h delete mode 100644 srsue/src/mac/dl_harq.cc delete mode 100644 srsue/src/mac/ul_harq.cc diff --git a/srsue/hdr/mac/dl_harq.h b/srsue/hdr/mac/dl_harq.h index e64e204c6..3b9c25e28 100644 --- a/srsue/hdr/mac/dl_harq.h +++ b/srsue/hdr/mac/dl_harq.h @@ -27,9 +27,15 @@ #ifndef DL_HARQ_H #define DL_HARQ_H +#define Error(fmt, ...) log_h->error_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__) +#define Warning(fmt, ...) log_h->warning_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__) +#define Info(fmt, ...) log_h->info_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__) +#define Debug(fmt, ...) log_h->debug_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__) + #include "srslte/common/log.h" #include "srslte/common/timers.h" #include "mac/demux.h" +#include "mac/mac_common.h" #include "mac/dl_sps.h" #include "srslte/common/mac_pcap.h" @@ -47,58 +53,294 @@ public: const static uint32_t NOF_HARQ_PROC = 8; const static uint32_t HARQ_BCCH_PID = NOF_HARQ_PROC; - dl_harq_entity(); - bool init(srslte::log *log_h_, mac_interface_rrc::mac_cfg_t *mac_cfg, srslte::timers *timers_, demux *demux_unit); - - + dl_harq_entity() + { + pcap = NULL; + } + + bool init(srslte::log *log_h_, mac_interface_rrc::mac_cfg_t *mac_cfg_, srslte::timers *timers_, demux *demux_unit_) + { + timers_db = timers_; + demux_unit = demux_unit_; + mac_cfg = mac_cfg_; + si_window_start = 0; + log_h = log_h_; + for (uint32_t i=0;iMAC interface for DL processes **************************/ - void new_grant_dl(mac_interface_phy::mac_grant_t grant, mac_interface_phy::tb_action_dl_t *action); - void tb_decoded(bool ack, srslte_rnti_type_t rnti_type, uint32_t harq_pid); - - - void reset(); - void start_pcap(srslte::mac_pcap* pcap); - int get_current_tbs(uint32_t harq_pid); + void new_grant_dl(mac_interface_phy::mac_grant_t grant, mac_interface_phy::tb_action_dl_t *action) + { + if (grant.rnti_type != SRSLTE_RNTI_SPS) { + uint32_t harq_pid; + // Set BCCH PID for SI RNTI + if (grant.rnti_type == SRSLTE_RNTI_SI) { + harq_pid = HARQ_BCCH_PID; + } else { + harq_pid = grant.pid%NOF_HARQ_PROC; + } + if (grant.rnti_type == SRSLTE_RNTI_TEMP && last_temporal_crnti != grant.rnti) { + grant.ndi = true; + Info("Set NDI=1 for Temp-RNTI DL grant\n"); + last_temporal_crnti = grant.rnti; + } + if (grant.rnti_type == SRSLTE_RNTI_USER && proc[harq_pid].is_sps()) { + grant.ndi = true; + Info("Set NDI=1 for C-RNTI DL grant\n"); + } + proc[harq_pid].new_grant_dl(grant, action); + } else { + /* This is for SPS scheduling */ + uint32_t harq_pid = get_harq_sps_pid(grant.tti)%NOF_HARQ_PROC; + if (grant.ndi) { + grant.ndi = false; + proc[harq_pid].new_grant_dl(grant, action); + } else { + if (grant.is_sps_release) { + dl_sps_assig.clear(); + if (timers_db->get(TIME_ALIGNMENT)->is_running()) { + //phy_h->send_sps_ack(); + Warning("PHY Send SPS ACK not implemented\n"); + } + } else { + Error("SPS not implemented\n"); + //dl_sps_assig.reset(grant.tti, grant); + //grant.ndi = true; + //procs[harq_pid].save_grant(); + } + } + } + } + + + void tb_decoded(bool ack, srslte_rnti_type_t rnti_type, uint32_t harq_pid) + { + if (rnti_type == SRSLTE_RNTI_SI) { + proc[NOF_HARQ_PROC].tb_decoded(ack); + } else { + proc[harq_pid%NOF_HARQ_PROC].tb_decoded(ack); + } + } + + + void reset() + { + for (uint32_t i=0;ilog_h; + return true; + } + } + + void reset() + { + ack = false; + payload_buffer_ptr = NULL; + bzero(&cur_grant, sizeof(mac_interface_phy::mac_grant_t)); + if (is_initiated) { + srslte_softbuffer_rx_reset(&softbuffer); + } + } - private: - bool calc_is_new_transmission(mac_interface_phy::mac_grant_t grant); + void new_grant_dl(mac_interface_phy::mac_grant_t grant, mac_interface_phy::tb_action_dl_t *action) + { + // Compute RV for BCCH when not specified in PDCCH format + if (pid == HARQ_BCCH_PID && grant.rv == -1) { + uint32_t k; + if ((grant.tti/10)%2 == 0 && grant.tti%10 == 5) { // This is SIB1, k is different + k = (grant.tti/20)%4; + grant.rv = ((uint32_t) ceilf((float)1.5*k))%4; + } else if (grant.rv == -1) { + k = (grant.tti-harq_entity->si_window_start)%4; + grant.rv = ((uint32_t) ceilf((float)1.5*k))%4; + } + } + calc_is_new_transmission(grant); + if (is_new_transmission) { + ack = false; + srslte_softbuffer_rx_reset_tbs(&softbuffer, cur_grant.n_bytes*8); + n_retx = 0; + } + + // Save grant + grant.last_ndi = cur_grant.ndi; + grant.last_tti = cur_grant.tti; + memcpy(&cur_grant, &grant, sizeof(mac_interface_phy::mac_grant_t)); + + // Fill action structure + bzero(action, sizeof(mac_interface_phy::tb_action_dl_t)); + action->default_ack = ack; + action->generate_ack = true; + action->decode_enabled = false; + + // If data has not yet been successfully decoded + if (ack == false) { + + // Instruct the PHY To combine the received data and attempt to decode it + payload_buffer_ptr = harq_entity->demux_unit->request_buffer(pid, cur_grant.n_bytes); + action->payload_ptr = payload_buffer_ptr; + if (!action->payload_ptr) { + action->decode_enabled = false; + Error("Can't get a buffer for TBS=%d\n", cur_grant.n_bytes); + return; + } + action->decode_enabled = true; + action->rv = cur_grant.rv; + action->rnti = cur_grant.rnti; + action->softbuffer = &softbuffer; + memcpy(&action->phy_grant, &cur_grant.phy_grant, sizeof(srslte_phy_grant_t)); + n_retx++; + + } else { + Warning("DL PID %d: Received duplicate TB. Discarting and retransmitting ACK\n", pid); + } + + if (pid == HARQ_BCCH_PID || harq_entity->timers_db->get(TIME_ALIGNMENT)->is_expired()) { + // Do not generate ACK + Debug("Not generating ACK\n"); + action->generate_ack = false; + } else { + if (cur_grant.rnti_type == SRSLTE_RNTI_TEMP && ack == false) { + // Postpone ACK after contention resolution is resolved + action->generate_ack_callback = harq_entity->generate_ack_callback; + action->generate_ack_callback_arg = harq_entity->demux_unit; + Debug("ACK pending contention resolution\n"); + } else { + Debug("Generating ACK\n"); + } + } + } + void tb_decoded(bool ack_) + { + ack = ack_; + if (ack == true) { + if (pid == HARQ_BCCH_PID) { + if (harq_entity->pcap) { + harq_entity->pcap->write_dl_sirnti(payload_buffer_ptr, cur_grant.n_bytes, ack, cur_grant.tti); + } + Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (BCCH)\n", cur_grant.n_bytes); + harq_entity->demux_unit->push_pdu(pid, payload_buffer_ptr, cur_grant.n_bytes, cur_grant.tti); + } else { + if (harq_entity->pcap) { + harq_entity->pcap->write_dl_crnti(payload_buffer_ptr, cur_grant.n_bytes, cur_grant.rnti, ack, cur_grant.tti); + } + if (ack) { + if (cur_grant.rnti_type == SRSLTE_RNTI_TEMP) { + Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (Temporal C-RNTI)\n", cur_grant.n_bytes); + harq_entity->demux_unit->push_pdu_temp_crnti(payload_buffer_ptr, cur_grant.n_bytes); + } else { + Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit\n", cur_grant.n_bytes); + harq_entity->demux_unit->push_pdu(pid, payload_buffer_ptr, cur_grant.n_bytes, cur_grant.tti); + + // Compute average number of retransmissions per packet + harq_entity->average_retx = SRSLTE_VEC_CMA((float) n_retx, harq_entity->average_retx, harq_entity->nof_pkts++); + } + } + } + } else { + harq_entity->demux_unit->deallocate(payload_buffer_ptr); + } + + Info("DL %d: %s tbs=%d, rv=%d, ack=%s, ndi=%d (%d), tti=%d (%d)\n", + pid, is_new_transmission?"newTX":"reTX ", + cur_grant.n_bytes, cur_grant.rv, ack?"OK":"KO", + cur_grant.ndi, cur_grant.last_ndi, cur_grant.tti, cur_grant.last_tti); + + if (ack && pid == HARQ_BCCH_PID) { + reset(); + } + } + + bool is_sps() { return false; } + + int get_current_tbs() { return cur_grant.n_bytes*8; } + + private: + bool calc_is_new_transmission(mac_interface_phy::mac_grant_t grant) + { + bool is_new_tb = true; + if ((srslte_tti_interval(grant.tti, cur_grant.tti) <= 8 && (grant.n_bytes == cur_grant.n_bytes)) || + pid == HARQ_BCCH_PID) + { + is_new_tb = false; + } + + if ((grant.ndi != cur_grant.ndi && !is_new_tb) || // NDI toggled for same TB + is_new_tb || // is new TB + (pid == HARQ_BCCH_PID && grant.rv == 0)) // Broadcast PID and 1st TX (RV=0) + { + is_new_transmission = true; + Debug("Set HARQ for new transmission\n"); + } else { + is_new_transmission = false; + Debug("Set HARQ for retransmission\n"); + } + + return is_new_transmission; + } + bool is_initiated; dl_harq_entity *harq_entity; srslte::log *log_h; - bool is_new_transmission; + bool is_new_transmission; uint32_t pid; uint8_t *payload_buffer_ptr; bool ack; - uint32_t n_retx; + uint32_t n_retx; mac_interface_phy::mac_grant_t cur_grant; srslte_softbuffer_rx_t softbuffer; - }; - static bool generate_ack_callback(void *arg); + + // Private members of dl_harq_entity + + static bool generate_ack_callback(void *arg) + { + demux *demux_unit = (demux*) arg; + return demux_unit->get_uecrid_successful(); + } - uint32_t get_harq_sps_pid(uint32_t tti); + uint32_t get_harq_sps_pid(uint32_t tti) { return 0; } dl_sps dl_sps_assig; @@ -109,9 +351,9 @@ private: srslte::log *log_h; srslte::mac_pcap *pcap; uint16_t last_temporal_crnti; - int si_window_start; + int si_window_start; - float average_retx; + float average_retx; uint64_t nof_pkts; }; diff --git a/srsue/hdr/mac/mac_common.h b/srsue/hdr/mac/mac_common.h new file mode 100644 index 000000000..d40d179eb --- /dev/null +++ b/srsue/hdr/mac/mac_common.h @@ -0,0 +1,45 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of the srsUE library. + * + * srsUE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsUE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +#ifndef MAC_COMMON_H +#define MAC_COMMON_H + +namespace srsue { + +typedef enum { + HARQ_RTT, + TIME_ALIGNMENT, + CONTENTION_TIMER, + BSR_TIMER_PERIODIC, + BSR_TIMER_RETX, + PHR_TIMER_PERIODIC, + PHR_TIMER_PROHIBIT, + NOF_MAC_TIMERS +} mac_timers_t; + +} // namespace srsue + +#endif // MAC_COMMON_H diff --git a/srsue/hdr/mac/ul_harq.h b/srsue/hdr/mac/ul_harq.h index cea469e33..38046b099 100644 --- a/srsue/hdr/mac/ul_harq.h +++ b/srsue/hdr/mac/ul_harq.h @@ -27,24 +27,31 @@ #ifndef ULHARQ_H #define ULHARQ_H +#define Error(fmt, ...) log_h->error_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__) +#define Warning(fmt, ...) log_h->warning_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__) +#define Info(fmt, ...) log_h->info_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__) +#define Debug(fmt, ...) log_h->debug_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__) + #include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/log.h" #include "mac/mux.h" +#include "mac/mac_common.h" #include "mac/ul_sps.h" #include "srslte/common/mac_pcap.h" #include "srslte/common/timers.h" +#include "srslte/common/interfaces_common.h" /* Uplink HARQ entity as defined in 5.4.2 of 36.321 */ - - namespace srsue { class ul_harq_entity { public: - const static uint32_t NOF_HARQ_PROC = 8; - static uint32_t pidof(uint32_t tti); + static uint32_t pidof(uint32_t tti) + { + return (uint32_t) tti%NOF_HARQ_PROC; + } ul_harq_entity() { pcap = NULL; @@ -56,46 +63,228 @@ public: average_retx = 0; nof_pkts = 0; } - bool init(srslte::log *log_h, - mac_interface_rrc::ue_rnti_t *rntis, - mac_interface_rrc::mac_cfg_t *mac_cfg, - srslte::timers* timers_, - mux *mux_unit); - void reset(); - void reset_ndi(); - void start_pcap(srslte::mac_pcap* pcap); + bool init(srslte::log *log_h_, + mac_interface_rrc::ue_rnti_t *rntis_, + mac_interface_rrc::mac_cfg_t *mac_cfg_, + srslte::timers* timers_db_, + mux *mux_unit_) + { + log_h = log_h_; + mux_unit = mux_unit_; + mac_cfg = mac_cfg_; + rntis = rntis_; + timers_db = timers_db_; + for (uint32_t i=0;iMAC interface for UL processes **************************/ - void new_grant_ul(mac_interface_phy::mac_grant_t grant, mac_interface_phy::tb_action_ul_t *action); - void new_grant_ul_ack(mac_interface_phy::mac_grant_t grant, bool ack, mac_interface_phy::tb_action_ul_t *action); - void harq_recv(uint32_t tti, bool ack, mac_interface_phy::tb_action_ul_t *action); + void new_grant_ul(mac_interface_phy::mac_grant_t grant, mac_interface_phy::tb_action_ul_t *action) + { + if (grant.rnti_type == SRSLTE_RNTI_USER || + grant.rnti_type == SRSLTE_RNTI_TEMP || + grant.rnti_type == SRSLTE_RNTI_RAR) + { + if (grant.rnti_type == SRSLTE_RNTI_USER && proc[pidof(grant.tti)].is_sps()) { + grant.ndi = true; + } + run_tti(grant.tti, &grant, action); + } else if (grant.rnti_type == SRSLTE_RNTI_SPS) { + if (grant.ndi) { + grant.ndi = proc[pidof(grant.tti)].get_ndi(); + run_tti(grant.tti, &grant, action); + } else { + Info("Not implemented\n"); + } + } + } + + void new_grant_ul_ack(mac_interface_phy::mac_grant_t grant, bool ack, mac_interface_phy::tb_action_ul_t *action) + { + set_ack(grant.tti, ack); + new_grant_ul(grant, action); + } - int get_current_tbs(uint32_t tti); + void harq_recv(uint32_t tti, bool ack, mac_interface_phy::tb_action_ul_t *action) + { + set_ack(tti, ack); + run_tti(tti, NULL, action); + } + + int get_current_tbs(uint32_t tti) + { + int tti_harq = (int) tti-4; + if (tti_harq < 0) { + tti_harq += 10240; + } + uint32_t pid_harq = pidof(tti_harq); + return proc[pid_harq].get_current_tbs(); + } - float get_average_retx(); + float get_average_retx() + { + return average_retx; + } -private: - +private: class ul_harq_process { public: - ul_harq_process(); - bool init(uint32_t pid, ul_harq_entity *parent); - void reset(); - void reset_ndi(); + ul_harq_process() + { + current_tx_nb = 0; + current_irv = 0; + is_initiated = false; + is_grant_configured = false; + tti_last_tx = 0; + bzero(&cur_grant, sizeof(mac_interface_phy::mac_grant_t)); + } + + bool init(uint32_t pid_, ul_harq_entity *parent) + { + if (srslte_softbuffer_tx_init(&softbuffer, 110)) { + fprintf(stderr, "Error initiating soft buffer\n"); + return false; + } else { + is_initiated = true; + harq_entity = parent; + log_h = harq_entity->log_h; + pid = pid_; + payload_buffer = (uint8_t*) srslte_vec_malloc(payload_buffer_len*sizeof(uint8_t)); + if (!payload_buffer) { + Error("Allocating memory\n"); + return false; + } + pdu_ptr = payload_buffer; + return true; + } + } + + void reset() + { + current_tx_nb = 0; + current_irv = 0; + tti_last_tx = 0; + is_grant_configured = false; + bzero(&cur_grant, sizeof(mac_interface_phy::mac_grant_t)); + } + + void reset_ndi() { ndi = false; } - void run_tti(uint32_t tti, mac_interface_phy::mac_grant_t *grant, mac_interface_phy::tb_action_ul_t* action); + void run_tti(uint32_t tti_tx, mac_interface_phy::mac_grant_t *grant, mac_interface_phy::tb_action_ul_t* action) + { + uint32_t max_retx; + if (is_msg3) { + max_retx = harq_entity->mac_cfg->rach.max_harq_msg3_tx; + } else { + max_retx = liblte_rrc_max_harq_tx_num[harq_entity->mac_cfg->main.ulsch_cnfg.max_harq_tx]; + } + + // Receive and route HARQ feedbacks + if (grant) { + if ((!(grant->rnti_type == SRSLTE_RNTI_TEMP) && grant->ndi != get_ndi()) || + (grant->rnti_type == SRSLTE_RNTI_USER && !has_grant()) || + grant->is_from_rar) + { + // New transmission - uint32_t get_rv(); - bool has_grant(); + // Uplink grant in a RAR + if (grant->is_from_rar) { + Debug("Getting Msg3 buffer payload, grant size=%d bytes\n", grant->n_bytes); + pdu_ptr = harq_entity->mux_unit->msg3_get(payload_buffer, grant->n_bytes); + if (pdu_ptr) { + generate_new_tx(tti_tx, true, grant, action); + } else { + Warning("UL RAR grant available but no Msg3 on buffer\n"); + } - void set_harq_feedback(bool ack); - bool get_ndi(); - bool is_sps(); - uint32_t last_tx_tti(); - uint32_t get_nof_retx(); - int get_current_tbs(); + // Normal UL grant + } else { + // Request a MAC PDU from the Multiplexing & Assemble Unit + pdu_ptr = harq_entity->mux_unit->pdu_get(payload_buffer, grant->n_bytes, tti_tx, pid); + if (pdu_ptr) { + generate_new_tx(tti_tx, false, grant, action); + } else { + Warning("Uplink grant but no MAC PDU in Multiplex Unit buffer\n"); + } + } + } else { + // Adaptive Re-TX + if (current_tx_nb >= max_retx) { + Info("UL %d: Maximum number of ReTX reached (%d). Discarting TB.\n", pid, max_retx); + reset(); + action->expect_ack = false; + } else { + generate_retx(tti_tx, grant, action); + } + } + } else if (has_grant()) { + // Non-Adaptive Re-Tx + if (current_tx_nb >= max_retx) { + Info("UL %d: Maximum number of ReTX reached (%d). Discarting TB.\n", pid, max_retx); + reset(); + action->expect_ack = false; + } else { + generate_retx(tti_tx, action); + } + } + if (harq_entity->pcap && grant) { + if (grant->is_from_rar) { + grant->rnti = harq_entity->rntis->temp_rnti; + } + harq_entity->pcap->write_ul_crnti(pdu_ptr, grant->n_bytes, grant->rnti, get_nof_retx(), tti_tx); + } + } + + void set_harq_feedback(bool ack) + { + harq_feedback = ack; + // UL packet successfully delivered + if (ack) { + Info("UL %d: HARQ = ACK for UL transmission. Discarting TB.\n", pid); + reset(); + } else { + Info("UL %d: HARQ = NACK for UL transmission\n", pid); + } + } + + uint32_t get_rv() + { + int rv_of_irv[4] = {0, 2, 3, 1}; + return rv_of_irv[current_irv%4]; + } + + bool has_grant() { return is_grant_configured; } + bool get_ndi() { return ndi; } + bool is_sps() { return false; } + uint32_t last_tx_tti() { return tti_last_tx; } + uint32_t get_nof_retx() { return current_tx_nb; } + int get_current_tbs() { return cur_grant.n_bytes*8; } private: mac_interface_phy::mac_grant_t cur_grant; @@ -118,17 +307,99 @@ private: uint8_t *payload_buffer; uint8_t *pdu_ptr; - void generate_retx(uint32_t tti_tx, mac_interface_phy::tb_action_ul_t *action); + void generate_retx(uint32_t tti_tx, mac_interface_phy::tb_action_ul_t *action) + { + generate_retx(tti_tx, NULL, action); + } + + // Retransmission with or w/o grant (Section 5.4.2.2) void generate_retx(uint32_t tti_tx, mac_interface_phy::mac_grant_t *grant, - mac_interface_phy::tb_action_ul_t *action); - void generate_new_tx(uint32_t tti_tx, bool is_msg3, mac_interface_phy::mac_grant_t *grant, - mac_interface_phy::tb_action_ul_t *action); - void generate_tx(uint32_t tti_tx, mac_interface_phy::tb_action_ul_t *action); + mac_interface_phy::tb_action_ul_t *action) + { + int irv_of_rv[4] = {0, 3, 1, 2}; + if (grant) { + // HARQ entity requests an adaptive transmission + if (grant->rv) { + current_irv = irv_of_rv[grant->rv%4]; + } + memcpy(&cur_grant, grant, sizeof(mac_interface_phy::mac_grant_t)); + harq_feedback = false; + Info("UL %d: Adaptive retx=%d, RV=%d, TBS=%d\n", + pid, current_tx_nb, get_rv(), grant->n_bytes); + generate_tx(tti_tx, action); + } else { + Info("UL %d: Non-Adaptive retx=%d, RV=%d, TBS=%d\n", + pid, current_tx_nb, get_rv(), cur_grant.n_bytes); + // HARQ entity requests a non-adaptive transmission + if (!harq_feedback) { + generate_tx(tti_tx, action); + } + } + + // On every Msg3 retransmission, restart mac-ContentionResolutionTimer as defined in Section 5.1.5 + if (is_msg3) { + harq_entity->timers_db->get(CONTENTION_TIMER)->reset(); + } + + harq_entity->mux_unit->pusch_retx(tti_tx, pid); + } + + // New transmission (Section 5.4.2.2) + void generate_new_tx(uint32_t tti_tx, bool is_msg3_, mac_interface_phy::mac_grant_t *grant, + mac_interface_phy::tb_action_ul_t *action) + { + if (grant) { + // Compute average number of retransmissions per packet considering previous packet + harq_entity->average_retx = SRSLTE_VEC_CMA((float) current_tx_nb, harq_entity->average_retx, harq_entity->nof_pkts++); + memcpy(&cur_grant, grant, sizeof(mac_interface_phy::mac_grant_t)); + harq_feedback = false; + is_grant_configured = true; + current_tx_nb = 0; + current_irv = 0; + is_msg3 = is_msg3_; + Info("UL %d: New TX%s, RV=%d, TBS=%d, RNTI=%d\n", + pid, is_msg3?" for Msg3":"", get_rv(), cur_grant.n_bytes, cur_grant.rnti); + generate_tx(tti_tx, action); + } + } + + // Transmission of pending frame (Section 5.4.2.2) + void generate_tx(uint32_t tti_tx, mac_interface_phy::tb_action_ul_t *action) + { + action->current_tx_nb = current_tx_nb; + current_tx_nb++; + action->expect_ack = true; + action->rnti = is_msg3?harq_entity->rntis->temp_rnti:cur_grant.rnti; + action->rv = cur_grant.rv>0?cur_grant.rv:get_rv(); + action->softbuffer = &softbuffer; + action->tx_enabled = true; + action->payload_ptr = pdu_ptr; + memcpy(&action->phy_grant, &cur_grant.phy_grant, sizeof(srslte_phy_grant_t)); + + current_irv = (current_irv+1)%4; + tti_last_tx = tti_tx; + } }; - - void run_tti(uint32_t tti, mac_interface_phy::mac_grant_t *grant, mac_interface_phy::tb_action_ul_t* action); - void set_ack(uint32_t tti, bool ack); + // Implements Section 5.4.2.1 + // Called with UL grant + void run_tti(uint32_t tti, mac_interface_phy::mac_grant_t *grant, mac_interface_phy::tb_action_ul_t* action) + { + uint32_t tti_tx = (tti+4)%10240; + proc[pidof(tti_tx)].run_tti(tti_tx, grant, action); + } + + void set_ack(uint32_t tti, bool ack) + { + int tti_harq = (int) tti - 4; + if (tti_harq < 0) { + tti_harq += 10240; + } + uint32_t pid_harq = pidof(tti_harq); + if (proc[pid_harq].has_grant() && (proc[pid_harq].last_tx_tti() <= (uint32_t)tti_harq)) { + proc[pid_harq].set_harq_feedback(ack); + } + } ul_sps ul_sps_assig; diff --git a/srsue/src/mac/dl_harq.cc b/srsue/src/mac/dl_harq.cc deleted file mode 100644 index 685224786..000000000 --- a/srsue/src/mac/dl_harq.cc +++ /dev/null @@ -1,337 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 Software Radio Systems Limited - * - * \section LICENSE - * - * This file is part of the srsUE library. - * - * srsUE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsUE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#define Error(fmt, ...) log_h->error_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__) -#define Warning(fmt, ...) log_h->warning_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__) -#define Info(fmt, ...) log_h->info_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__) -#define Debug(fmt, ...) log_h->debug_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__) - -#include "mac/mac.h" -#include "mac/dl_harq.h" - - -namespace srsue { - - - /*********************************************************** - * - * HARQ ENTITY - * - *********************************************************/ - -dl_harq_entity::dl_harq_entity() -{ - pcap = NULL; -} - -bool dl_harq_entity::init(srslte::log* log_h_, mac_interface_rrc::mac_cfg_t *mac_cfg_, srslte::timers* timers_, demux *demux_unit_) -{ - timers_db = timers_; - demux_unit = demux_unit_; - mac_cfg = mac_cfg_; - si_window_start = 0; - log_h = log_h_; - for (uint32_t i=0;iget(mac::TIME_ALIGNMENT)->is_running()) { - //phy_h->send_sps_ack(); - Warning("PHY Send SPS ACK not implemented\n"); - } - } else { - Error("SPS not implemented\n"); - //dl_sps_assig.reset(grant.tti, grant); - //grant.ndi = true; - //procs[harq_pid].save_grant(); - } - } - } -} - -void dl_harq_entity::tb_decoded(bool ack, srslte_rnti_type_t rnti_type, uint32_t harq_pid) -{ - if (rnti_type == SRSLTE_RNTI_SI) { - proc[NOF_HARQ_PROC].tb_decoded(ack); - } else { - proc[harq_pid%NOF_HARQ_PROC].tb_decoded(ack); - } -} - -int dl_harq_entity::get_current_tbs(uint32_t harq_pid) -{ - return proc[harq_pid%NOF_HARQ_PROC].get_current_tbs(); -} - - -bool dl_harq_entity::generate_ack_callback(void *arg) -{ - demux *demux_unit = (demux*) arg; - return demux_unit->get_uecrid_successful(); -} - -void dl_harq_entity::set_si_window_start(int si_window_start_) -{ - si_window_start = si_window_start_; -} - -float dl_harq_entity::get_average_retx() -{ - return average_retx; -} - - /*********************************************************** - * - * HARQ PROCESS - * - *********************************************************/ - -dl_harq_entity::dl_harq_process::dl_harq_process() { - is_initiated = false; - ack = false; - bzero(&cur_grant, sizeof(mac_interface_phy::mac_grant_t)); -} - -void dl_harq_entity::dl_harq_process::reset() { - ack = false; - payload_buffer_ptr = NULL; - bzero(&cur_grant, sizeof(mac_interface_phy::mac_grant_t)); - if (is_initiated) { - srslte_softbuffer_rx_reset(&softbuffer); - } -} - -bool dl_harq_entity::dl_harq_process::init(uint32_t pid_, dl_harq_entity *parent) { - if (srslte_softbuffer_rx_init(&softbuffer, 110)) { - Error("Error initiating soft buffer\n"); - return false; - } else { - pid = pid_; - is_initiated = true; - harq_entity = parent; - log_h = harq_entity->log_h; - return true; - } -} - -bool dl_harq_entity::dl_harq_process::is_sps() -{ - return false; -} - -bool dl_harq_entity::dl_harq_process::calc_is_new_transmission(mac_interface_phy::mac_grant_t grant) { - - bool is_new_tb = true; - if ((srslte_tti_interval(grant.tti, cur_grant.tti) <= 8 && (grant.n_bytes == cur_grant.n_bytes)) || - pid == HARQ_BCCH_PID) - { - is_new_tb = false; - } - - if ((grant.ndi != cur_grant.ndi && !is_new_tb) || // NDI toggled for same TB - is_new_tb || // is new TB - (pid == HARQ_BCCH_PID && grant.rv == 0)) // Broadcast PID and 1st TX (RV=0) - { - is_new_transmission = true; - Debug("Set HARQ for new transmission\n"); - } else { - is_new_transmission = false; - Debug("Set HARQ for retransmission\n"); - } - - return is_new_transmission; -} - -void dl_harq_entity::dl_harq_process::new_grant_dl(mac_interface_phy::mac_grant_t grant, mac_interface_phy::tb_action_dl_t* action) -{ - // Compute RV for BCCH when not specified in PDCCH format - if (pid == HARQ_BCCH_PID && grant.rv == -1) { - uint32_t k; - if ((grant.tti/10)%2 == 0 && grant.tti%10 == 5) { // This is SIB1, k is different - k = (grant.tti/20)%4; - grant.rv = ((uint32_t) ceilf((float)1.5*k))%4; - } else if (grant.rv == -1) { - k = (grant.tti-harq_entity->si_window_start)%4; - grant.rv = ((uint32_t) ceilf((float)1.5*k))%4; - } - } - calc_is_new_transmission(grant); - if (is_new_transmission) { - ack = false; - srslte_softbuffer_rx_reset_tbs(&softbuffer, cur_grant.n_bytes*8); - n_retx = 0; - } - - // Save grant - grant.last_ndi = cur_grant.ndi; - grant.last_tti = cur_grant.tti; - memcpy(&cur_grant, &grant, sizeof(mac_interface_phy::mac_grant_t)); - - // Fill action structure - bzero(action, sizeof(mac_interface_phy::tb_action_dl_t)); - action->default_ack = ack; - action->generate_ack = true; - action->decode_enabled = false; - - // If data has not yet been successfully decoded - if (ack == false) { - - // Instruct the PHY To combine the received data and attempt to decode it - payload_buffer_ptr = harq_entity->demux_unit->request_buffer(pid, cur_grant.n_bytes); - action->payload_ptr = payload_buffer_ptr; - if (!action->payload_ptr) { - action->decode_enabled = false; - Error("Can't get a buffer for TBS=%d\n", cur_grant.n_bytes); - return; - } - action->decode_enabled = true; - action->rv = cur_grant.rv; - action->rnti = cur_grant.rnti; - action->softbuffer = &softbuffer; - memcpy(&action->phy_grant, &cur_grant.phy_grant, sizeof(srslte_phy_grant_t)); - n_retx++; - - } else { - Warning("DL PID %d: Received duplicate TB. Discarting and retransmitting ACK\n", pid); - } - - if (pid == HARQ_BCCH_PID || harq_entity->timers_db->get(mac::TIME_ALIGNMENT)->is_expired()) { - // Do not generate ACK - Debug("Not generating ACK\n"); - action->generate_ack = false; - } else { - if (cur_grant.rnti_type == SRSLTE_RNTI_TEMP && ack == false) { - // Postpone ACK after contention resolution is resolved - action->generate_ack_callback = harq_entity->generate_ack_callback; - action->generate_ack_callback_arg = harq_entity->demux_unit; - Debug("ACK pending contention resolution\n"); - } else { - Debug("Generating ACK\n"); - } - } -} - -int dl_harq_entity::dl_harq_process::get_current_tbs() -{ - return cur_grant.n_bytes*8; -} - -void dl_harq_entity::dl_harq_process::tb_decoded(bool ack_) -{ - ack = ack_; - if (ack == true) { - if (pid == HARQ_BCCH_PID) { - if (harq_entity->pcap) { - harq_entity->pcap->write_dl_sirnti(payload_buffer_ptr, cur_grant.n_bytes, ack, cur_grant.tti); - } - Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (BCCH)\n", cur_grant.n_bytes); - harq_entity->demux_unit->push_pdu(pid, payload_buffer_ptr, cur_grant.n_bytes, cur_grant.tti); - } else { - if (harq_entity->pcap) { - harq_entity->pcap->write_dl_crnti(payload_buffer_ptr, cur_grant.n_bytes, cur_grant.rnti, ack, cur_grant.tti); - } - if (ack) { - if (cur_grant.rnti_type == SRSLTE_RNTI_TEMP) { - Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (Temporal C-RNTI)\n", cur_grant.n_bytes); - harq_entity->demux_unit->push_pdu_temp_crnti(payload_buffer_ptr, cur_grant.n_bytes); - } else { - Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit\n", cur_grant.n_bytes); - harq_entity->demux_unit->push_pdu(pid, payload_buffer_ptr, cur_grant.n_bytes, cur_grant.tti); - - // Compute average number of retransmissions per packet - harq_entity->average_retx = SRSLTE_VEC_CMA((float) n_retx, harq_entity->average_retx, harq_entity->nof_pkts++); - } - } - } - } else { - harq_entity->demux_unit->deallocate(payload_buffer_ptr); - } - - Info("DL %d: %s tbs=%d, rv=%d, ack=%s, ndi=%d (%d), tti=%d (%d)\n", - pid, is_new_transmission?"newTX":"reTX ", - cur_grant.n_bytes, cur_grant.rv, ack?"OK":"KO", - cur_grant.ndi, cur_grant.last_ndi, cur_grant.tti, cur_grant.last_tti); - - if (ack && pid == HARQ_BCCH_PID) { - reset(); - } -} - - - -} diff --git a/srsue/src/mac/ul_harq.cc b/srsue/src/mac/ul_harq.cc deleted file mode 100644 index da28d62b3..000000000 --- a/srsue/src/mac/ul_harq.cc +++ /dev/null @@ -1,394 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 Software Radio Systems Limited - * - * \section LICENSE - * - * This file is part of the srsUE library. - * - * srsUE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsUE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#define Error(fmt, ...) log_h->error_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__) -#define Warning(fmt, ...) log_h->warning_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__) -#define Info(fmt, ...) log_h->info_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__) -#define Debug(fmt, ...) log_h->debug_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__) - -#include "srslte/common/log.h" -#include "mac/mac.h" -#include "mac/ul_harq.h" - - - namespace srsue { - - /*********************************************************** - * - * HARQ ENTITY - * - *********************************************************/ - -bool ul_harq_entity::init(srslte::log *log_h_, - mac_interface_rrc::ue_rnti_t *rntis_, - mac_interface_rrc::mac_cfg_t *mac_cfg_, - srslte::timers *timers_db_, - mux *mux_unit_) { - log_h = log_h_; - mux_unit = mux_unit_; - mac_cfg = mac_cfg_; - rntis = rntis_; - timers_db = timers_db_; - for (uint32_t i=0;ilog_h; - pid = pid_; - payload_buffer = (uint8_t*) srslte_vec_malloc(payload_buffer_len*sizeof(uint8_t)); - if (!payload_buffer) { - Error("Allocating memory\n"); - return false; - } - pdu_ptr = payload_buffer; - return true; - } -} - -void ul_harq_entity::ul_harq_process::run_tti(uint32_t tti_tx, mac_interface_phy::mac_grant_t* grant, mac_interface_phy::tb_action_ul_t* action) -{ - - - uint32_t max_retx; - if (is_msg3) { - max_retx = harq_entity->mac_cfg->rach.max_harq_msg3_tx; - } else { - max_retx = liblte_rrc_max_harq_tx_num[harq_entity->mac_cfg->main.ulsch_cnfg.max_harq_tx]; - } - - - // Receive and route HARQ feedbacks - if (grant) { - if ((!(grant->rnti_type == SRSLTE_RNTI_TEMP) && grant->ndi != get_ndi()) || - (grant->rnti_type == SRSLTE_RNTI_USER && !has_grant()) || - grant->is_from_rar) - { - // New transmission - - // Uplink grant in a RAR - if (grant->is_from_rar) { - Debug("Getting Msg3 buffer payload, grant size=%d bytes\n", grant->n_bytes); - pdu_ptr = harq_entity->mux_unit->msg3_get(payload_buffer, grant->n_bytes); - if (pdu_ptr) { - generate_new_tx(tti_tx, true, grant, action); - } else { - Warning("UL RAR grant available but no Msg3 on buffer\n"); - } - - // Normal UL grant - } else { - // Request a MAC PDU from the Multiplexing & Assemble Unit - pdu_ptr = harq_entity->mux_unit->pdu_get(payload_buffer, grant->n_bytes, tti_tx, pid); - if (pdu_ptr) { - generate_new_tx(tti_tx, false, grant, action); - } else { - Warning("Uplink grant but no MAC PDU in Multiplex Unit buffer\n"); - } - } - } else { - // Adaptive Re-TX - if (current_tx_nb >= max_retx) { - Info("UL %d: Maximum number of ReTX reached (%d). Discarting TB.\n", pid, max_retx); - reset(); - action->expect_ack = false; - } else { - generate_retx(tti_tx, grant, action); - } - } - } else if (has_grant()) { - // Non-Adaptive Re-Tx - if (current_tx_nb >= max_retx) { - Info("UL %d: Maximum number of ReTX reached (%d). Discarting TB.\n", pid, max_retx); - reset(); - action->expect_ack = false; - } else { - generate_retx(tti_tx, action); - } - } - if (harq_entity->pcap && grant) { - if (grant->is_from_rar) { - grant->rnti = harq_entity->rntis->temp_rnti; - } - harq_entity->pcap->write_ul_crnti(pdu_ptr, grant->n_bytes, grant->rnti, get_nof_retx(), tti_tx); - } - - - -} - -int ul_harq_entity::ul_harq_process::get_current_tbs() -{ - return cur_grant.n_bytes*8; -} - -void ul_harq_entity::ul_harq_process::generate_retx(uint32_t tti_tx, mac_interface_phy::tb_action_ul_t *action) -{ - generate_retx(tti_tx, NULL, action); -} - -// Retransmission with or w/o grant (Section 5.4.2.2) -void ul_harq_entity::ul_harq_process::generate_retx(uint32_t tti_tx, mac_interface_phy::mac_grant_t *grant, - mac_interface_phy::tb_action_ul_t *action) -{ - if (grant) { - // HARQ entity requests an adaptive transmission - if (grant->rv) { - current_irv = irv_of_rv[grant->rv%4]; - } - memcpy(&cur_grant, grant, sizeof(mac_interface_phy::mac_grant_t)); - harq_feedback = false; - Info("UL %d: Adaptive retx=%d, RV=%d, TBS=%d\n", - pid, current_tx_nb, get_rv(), grant->n_bytes); - generate_tx(tti_tx, action); - } else { - Info("UL %d: Non-Adaptive retx=%d, RV=%d, TBS=%d\n", - pid, current_tx_nb, get_rv(), cur_grant.n_bytes); - // HARQ entity requests a non-adaptive transmission - if (!harq_feedback) { - generate_tx(tti_tx, action); - } - } - - // On every Msg3 retransmission, restart mac-ContentionResolutionTimer as defined in Section 5.1.5 - if (is_msg3) { - harq_entity->timers_db->get(mac::CONTENTION_TIMER)->reset(); - } - - harq_entity->mux_unit->pusch_retx(tti_tx, pid); -} - -// New transmission (Section 5.4.2.2) -void ul_harq_entity::ul_harq_process::generate_new_tx(uint32_t tti_tx, bool is_msg3_, - mac_interface_phy::mac_grant_t *grant, - mac_interface_phy::tb_action_ul_t *action) -{ - if (grant) { - - // Compute average number of retransmissions per packet considering previous packet - harq_entity->average_retx = SRSLTE_VEC_CMA((float) current_tx_nb, harq_entity->average_retx, harq_entity->nof_pkts++); - - - memcpy(&cur_grant, grant, sizeof(mac_interface_phy::mac_grant_t)); - harq_feedback = false; - is_grant_configured = true; - current_tx_nb = 0; - current_irv = 0; - is_msg3 = is_msg3_; - Info("UL %d: New TX%s, RV=%d, TBS=%d, RNTI=%d\n", - pid, is_msg3?" for Msg3":"", get_rv(), cur_grant.n_bytes, cur_grant.rnti); - generate_tx(tti_tx, action); - } -} - -// Transmission of pending frame (Section 5.4.2.2) -void ul_harq_entity::ul_harq_process::generate_tx(uint32_t tti_tx, mac_interface_phy::tb_action_ul_t *action) -{ - action->current_tx_nb = current_tx_nb; - current_tx_nb++; - action->expect_ack = true; - action->rnti = is_msg3?harq_entity->rntis->temp_rnti:cur_grant.rnti; - action->rv = cur_grant.rv>0?cur_grant.rv:get_rv(); - action->softbuffer = &softbuffer; - action->tx_enabled = true; - action->payload_ptr = pdu_ptr; - memcpy(&action->phy_grant, &cur_grant.phy_grant, sizeof(srslte_phy_grant_t)); - - current_irv = (current_irv+1)%4; - tti_last_tx = tti_tx; -} - -bool ul_harq_entity::ul_harq_process::is_sps() -{ - return false; -} - -uint32_t ul_harq_entity::ul_harq_process::last_tx_tti() -{ - return tti_last_tx; -} - -uint32_t ul_harq_entity::ul_harq_process::get_nof_retx() -{ - return current_tx_nb; -} - -} From 869786a27c8a532d2f18974076d00f2f7471b70b Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 23 Jun 2017 12:55:54 +0200 Subject: [PATCH 02/19] adapt MAC procedures to also use MAC timers defined in mac_common.h --- srsue/hdr/mac/mac.h | 11 ---------- srsue/src/mac/demux.cc | 4 ++-- srsue/src/mac/mac.cc | 2 +- srsue/src/mac/proc_bsr.cc | 42 +++++++++++++++++++-------------------- srsue/src/mac/proc_phr.cc | 26 ++++++++++++------------ srsue/src/mac/proc_ra.cc | 20 +++++++++---------- 6 files changed, 47 insertions(+), 58 deletions(-) diff --git a/srsue/hdr/mac/mac.h b/srsue/hdr/mac/mac.h index f6f22f334..82a7b1e76 100644 --- a/srsue/hdr/mac/mac.h +++ b/srsue/hdr/mac/mac.h @@ -98,17 +98,6 @@ public: u_int32_t get_unique_id(); uint32_t get_current_tti(); - - enum { - HARQ_RTT, - TIME_ALIGNMENT, - CONTENTION_TIMER, - BSR_TIMER_PERIODIC, - BSR_TIMER_RETX, - PHR_TIMER_PERIODIC, - PHR_TIMER_PROHIBIT, - NOF_MAC_TIMERS - } mac_timers_t; static const int MAC_NOF_UPPER_TIMERS = 20; diff --git a/srsue/src/mac/demux.cc b/srsue/src/mac/demux.cc index c7c73a14b..71ad0cc58 100644 --- a/srsue/src/mac/demux.cc +++ b/srsue/src/mac/demux.cc @@ -190,8 +190,8 @@ bool demux::process_ce(srslte::sch_subh *subh) { Info("Received TA=%d\n", subh->get_ta_cmd()); // Start or restart timeAlignmentTimer - timers_db->get(mac::TIME_ALIGNMENT)->reset(); - timers_db->get(mac::TIME_ALIGNMENT)->run(); + timers_db->get(TIME_ALIGNMENT)->reset(); + timers_db->get(TIME_ALIGNMENT)->run(); break; case srslte::sch_subh::PADDING: break; diff --git a/srsue/src/mac/mac.cc b/srsue/src/mac/mac.cc index f583dd2df..9a461ca05 100644 --- a/srsue/src/mac/mac.cc +++ b/srsue/src/mac/mac.cc @@ -308,7 +308,7 @@ void mac::new_grant_ul(mac_interface_phy::mac_grant_t grant, mac_interface_phy:: /* Start PHR Periodic timer on first UL grant */ if (is_first_ul_grant) { is_first_ul_grant = false; - timers_db.get(mac::PHR_TIMER_PERIODIC)->run(); + timers_db.get(PHR_TIMER_PERIODIC)->run(); } if (grant.rnti_type == SRSLTE_RNTI_USER && ra_procedure.is_contention_resolution()) { ra_procedure.pdcch_to_crnti(true); diff --git a/srsue/src/mac/proc_bsr.cc b/srsue/src/mac/proc_bsr.cc index d93b7f0f4..3117eeffc 100644 --- a/srsue/src/mac/proc_bsr.cc +++ b/srsue/src/mac/proc_bsr.cc @@ -57,10 +57,10 @@ void bsr_proc::init(rlc_interface_mac *rlc_, srslte::log* log_h_, mac_interface_ void bsr_proc::reset() { - timers_db->get(mac::BSR_TIMER_PERIODIC)->stop(); - timers_db->get(mac::BSR_TIMER_PERIODIC)->reset(); - timers_db->get(mac::BSR_TIMER_RETX)->stop(); - timers_db->get(mac::BSR_TIMER_RETX)->reset(); + timers_db->get(BSR_TIMER_PERIODIC)->stop(); + timers_db->get(BSR_TIMER_PERIODIC)->reset(); + timers_db->get(BSR_TIMER_RETX)->stop(); + timers_db->get(BSR_TIMER_RETX)->reset(); reset_sr = false; sr_is_sent = false; @@ -78,14 +78,14 @@ void bsr_proc::reset() /* Process Periodic BSR */ void bsr_proc::timer_expired(uint32_t timer_id) { switch(timer_id) { - case mac::BSR_TIMER_PERIODIC: + case BSR_TIMER_PERIODIC: if (triggered_bsr_type == NONE) { // Check condition 4 in Sec 5.4.5 triggered_bsr_type = PERIODIC; Debug("BSR: Triggering Periodic BSR\n"); } break; - case mac::BSR_TIMER_RETX: + case BSR_TIMER_RETX: // Enable reTx of SR only if periodic timer is not infinity int periodic = liblte_rrc_periodic_bsr_timer_num[mac_cfg->main.ulsch_cnfg.periodic_bsr_timer]; if (periodic >= 0) { @@ -222,17 +222,17 @@ void bsr_proc::step(uint32_t tti) } int periodic = liblte_rrc_periodic_bsr_timer_num[mac_cfg->main.ulsch_cnfg.periodic_bsr_timer]; - if (periodic > 0 && (uint32_t)periodic != timers_db->get(mac::BSR_TIMER_PERIODIC)->get_timeout()) + if (periodic > 0 && (uint32_t)periodic != timers_db->get(BSR_TIMER_PERIODIC)->get_timeout()) { - timers_db->get(mac::BSR_TIMER_PERIODIC)->set(this, periodic); - timers_db->get(mac::BSR_TIMER_PERIODIC)->run(); + timers_db->get(BSR_TIMER_PERIODIC)->set(this, periodic); + timers_db->get(BSR_TIMER_PERIODIC)->run(); Info("BSR: Configured timer periodic %d ms\n", periodic); } int retx = liblte_rrc_retransmission_bsr_timer_num[mac_cfg->main.ulsch_cnfg.retx_bsr_timer]; - if (retx > 0 && (uint32_t)retx != timers_db->get(mac::BSR_TIMER_RETX)->get_timeout()) + if (retx > 0 && (uint32_t)retx != timers_db->get(BSR_TIMER_RETX)->get_timeout()) { - timers_db->get(mac::BSR_TIMER_RETX)->set(this, retx); - timers_db->get(mac::BSR_TIMER_RETX)->run(); + timers_db->get(BSR_TIMER_RETX)->set(this, retx); + timers_db->get(BSR_TIMER_RETX)->run(); Info("BSR: Configured timer reTX %d ms\n", retx); } @@ -309,18 +309,18 @@ bool bsr_proc::need_to_send_bsr_on_ul_grant(uint32_t grant_size, bsr_t *bsr) grant_size, total_data, bsr_sz); ret = true; } - if (timers_db->get(mac::BSR_TIMER_PERIODIC)->get_timeout() && bsr->format != TRUNC_BSR) { - timers_db->get(mac::BSR_TIMER_PERIODIC)->reset(); - timers_db->get(mac::BSR_TIMER_PERIODIC)->run(); + if (timers_db->get(BSR_TIMER_PERIODIC)->get_timeout() && bsr->format != TRUNC_BSR) { + timers_db->get(BSR_TIMER_PERIODIC)->reset(); + timers_db->get(BSR_TIMER_PERIODIC)->run(); } } // Cancel all triggered BSR and SR triggered_bsr_type = NONE; reset_sr = true; // Restart or Start ReTX timer - if (timers_db->get(mac::BSR_TIMER_RETX)->get_timeout()) { - timers_db->get(mac::BSR_TIMER_RETX)->reset(); - timers_db->get(mac::BSR_TIMER_RETX)->run(); + if (timers_db->get(BSR_TIMER_RETX)->get_timeout()) { + timers_db->get(BSR_TIMER_RETX)->reset(); + timers_db->get(BSR_TIMER_RETX)->run(); } return ret; } @@ -340,9 +340,9 @@ bool bsr_proc::generate_padding_bsr(uint32_t nof_padding_bytes, bsr_t *bsr) bsr_type_tostring(triggered_bsr_type), bsr_format_tostring(bsr->format), bsr->buff_size[0], bsr->buff_size[1], bsr->buff_size[2], bsr->buff_size[3]); - if (timers_db->get(mac::BSR_TIMER_PERIODIC)->get_timeout() && bsr->format != TRUNC_BSR) { - timers_db->get(mac::BSR_TIMER_PERIODIC)->reset(); - timers_db->get(mac::BSR_TIMER_PERIODIC)->run(); + if (timers_db->get(BSR_TIMER_PERIODIC)->get_timeout() && bsr->format != TRUNC_BSR) { + timers_db->get(BSR_TIMER_PERIODIC)->reset(); + timers_db->get(BSR_TIMER_PERIODIC)->run(); } } diff --git a/srsue/src/mac/proc_phr.cc b/srsue/src/mac/proc_phr.cc index b432f1c06..11828f306 100644 --- a/srsue/src/mac/proc_phr.cc +++ b/srsue/src/mac/proc_phr.cc @@ -76,13 +76,13 @@ bool phr_proc::pathloss_changed() { /* Trigger PHR when timers exire */ void phr_proc::timer_expired(uint32_t timer_id) { switch(timer_id) { - case mac::PHR_TIMER_PERIODIC: - timers_db->get(mac::PHR_TIMER_PERIODIC)->reset(); - timers_db->get(mac::PHR_TIMER_PERIODIC)->run(); + case PHR_TIMER_PERIODIC: + timers_db->get(PHR_TIMER_PERIODIC)->reset(); + timers_db->get(PHR_TIMER_PERIODIC)->run(); Debug("PHR: Triggered by timer periodic (timer expired).\n"); phr_is_triggered = true; break; - case mac::PHR_TIMER_PROHIBIT: + case PHR_TIMER_PROHIBIT: int pathloss_db = liblte_rrc_dl_pathloss_change_num[mac_cfg->main.phr_cnfg.dl_pathloss_change]; if (pathloss_changed()) { Info("PHR: Triggered by pathloss difference. cur_pathloss_db=%f (timer expired)\n", last_pathloss_db); @@ -105,8 +105,8 @@ void phr_proc::step(uint32_t tti) if (timer_periodic != cfg_timer_periodic && cfg_timer_periodic > 0) { timer_periodic = cfg_timer_periodic; - timers_db->get(mac::PHR_TIMER_PERIODIC)->set(this, timer_periodic); - timers_db->get(mac::PHR_TIMER_PERIODIC)->run(); + timers_db->get(PHR_TIMER_PERIODIC)->set(this, timer_periodic); + timers_db->get(PHR_TIMER_PERIODIC)->run(); phr_is_triggered = true; Info("PHR: Configured timer periodic %d ms\n", timer_periodic); } @@ -118,12 +118,12 @@ void phr_proc::step(uint32_t tti) if (timer_prohibit != cfg_timer_prohibit && cfg_timer_prohibit > 0) { timer_prohibit = cfg_timer_prohibit; - timers_db->get(mac::PHR_TIMER_PROHIBIT)->set(this, timer_prohibit); - timers_db->get(mac::PHR_TIMER_PROHIBIT)->run(); + timers_db->get(PHR_TIMER_PROHIBIT)->set(this, timer_prohibit); + timers_db->get(PHR_TIMER_PROHIBIT)->run(); Info("PHR: Configured timer prohibit %d ms\n", timer_prohibit); phr_is_triggered = true; } - if (pathloss_changed() && timers_db->get(mac::PHR_TIMER_PROHIBIT)->is_expired()) + if (pathloss_changed() && timers_db->get(PHR_TIMER_PROHIBIT)->is_expired()) { Info("PHR: Triggered by pathloss difference. cur_pathloss_db=%f\n", last_pathloss_db); phr_is_triggered = true; @@ -140,10 +140,10 @@ bool phr_proc::generate_phr_on_ul_grant(float *phr) Debug("PHR: Generating PHR=%f\n", phr?*phr:0.0); - timers_db->get(mac::PHR_TIMER_PERIODIC)->reset(); - timers_db->get(mac::PHR_TIMER_PROHIBIT)->reset(); - timers_db->get(mac::PHR_TIMER_PERIODIC)->run(); - timers_db->get(mac::PHR_TIMER_PROHIBIT)->run(); + timers_db->get(PHR_TIMER_PERIODIC)->reset(); + timers_db->get(PHR_TIMER_PROHIBIT)->reset(); + timers_db->get(PHR_TIMER_PERIODIC)->run(); + timers_db->get(PHR_TIMER_PROHIBIT)->run(); phr_is_triggered = false; diff --git a/srsue/src/mac/proc_ra.cc b/srsue/src/mac/proc_ra.cc index 495c9945f..73b51d61c 100644 --- a/srsue/src/mac/proc_ra.cc +++ b/srsue/src/mac/proc_ra.cc @@ -115,7 +115,7 @@ void ra_proc::read_params() { delta_preamble_db = delta_preamble_db_table[configIndex%5]; if (contentionResolutionTimer > 0) { - timers_db->get(mac::CONTENTION_TIMER)->set(this, contentionResolutionTimer); + timers_db->get(CONTENTION_TIMER)->set(this, contentionResolutionTimer); } } @@ -165,14 +165,14 @@ void ra_proc::process_timeadv_cmd(uint32_t ta) { if (preambleIndex == 0) { // Preamble not selected by UE MAC phy_h->set_timeadv_rar(ta); - timers_db->get(mac::TIME_ALIGNMENT)->reset(); - timers_db->get(mac::TIME_ALIGNMENT)->run(); + timers_db->get(TIME_ALIGNMENT)->reset(); + timers_db->get(TIME_ALIGNMENT)->run(); Debug("Applying RAR TA CMD %d\n", ta); } else { // Preamble selected by UE MAC - if (!timers_db->get(mac::TIME_ALIGNMENT)->is_running()) { + if (!timers_db->get(TIME_ALIGNMENT)->is_running()) { phy_h->set_timeadv_rar(ta); - timers_db->get(mac::TIME_ALIGNMENT)->run(); + timers_db->get(TIME_ALIGNMENT)->run(); Debug("Applying RAR TA CMD %d\n", ta); } else { // Ignore TA CMD @@ -355,8 +355,8 @@ void ra_proc::tb_decoded_ok() { state = CONTENTION_RESOLUTION; // Start contention resolution timer - timers_db->get(mac::CONTENTION_TIMER)->reset(); - timers_db->get(mac::CONTENTION_TIMER)->run(); + timers_db->get(CONTENTION_TIMER)->reset(); + timers_db->get(CONTENTION_TIMER)->run(); } } else { rDebug("Found RAR for preamble %d\n", rar_pdu_msg.get()->get_rapid()); @@ -417,7 +417,7 @@ bool ra_proc::contention_resolution_id_received(uint64_t rx_contention_id) { rDebug("MAC PDU Contains Contention Resolution ID CE\n"); // MAC PDU successfully decoded and contains MAC CE contention Id - timers_db->get(mac::CONTENTION_TIMER)->stop(); + timers_db->get(CONTENTION_TIMER)->stop(); if (transmitted_contention_id == rx_contention_id) { @@ -453,7 +453,7 @@ void ra_proc::step_contention_resolution() { (started_by_pdcch && pdcch_to_crnti_received != PDCCH_CRNTI_NOT_RECEIVED)) { rDebug("PDCCH for C-RNTI received\n"); - timers_db->get(mac::CONTENTION_TIMER)->stop(); + timers_db->get(CONTENTION_TIMER)->stop(); rntis->temp_rnti = 0; state = COMPLETION; } @@ -559,7 +559,7 @@ void ra_proc::pdcch_to_crnti(bool contains_uplink_grant) { void ra_proc::harq_retx() { - timers_db->get(mac::CONTENTION_TIMER)->reset(); + timers_db->get(CONTENTION_TIMER)->reset(); } } From 704b8c3dc46d8661e9af4bb51c66d268ec26a6d0 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 23 Jun 2017 13:19:18 +0200 Subject: [PATCH 03/19] make DL and UL harq template classes --- srsue/hdr/mac/dl_harq.h | 43 +++++++++++++++++----------------- srsue/hdr/mac/mac.h | 7 +++--- srsue/hdr/mac/ul_harq.h | 52 ++++++++++++++++++++--------------------- 3 files changed, 52 insertions(+), 50 deletions(-) diff --git a/srsue/hdr/mac/dl_harq.h b/srsue/hdr/mac/dl_harq.h index 3b9c25e28..25677dd84 100644 --- a/srsue/hdr/mac/dl_harq.h +++ b/srsue/hdr/mac/dl_harq.h @@ -45,15 +45,15 @@ namespace srsue { - + +template class dl_harq_entity { public: - const static uint32_t NOF_HARQ_PROC = 8; - const static uint32_t HARQ_BCCH_PID = NOF_HARQ_PROC; + const static uint32_t HARQ_BCCH_PID = N; - dl_harq_entity() + dl_harq_entity() : proc(N+1) { pcap = NULL; } @@ -65,7 +65,7 @@ public: mac_cfg = mac_cfg_; si_window_start = 0; log_h = log_h_; - for (uint32_t i=0;iMAC interface for DL processes **************************/ - void new_grant_dl(mac_interface_phy::mac_grant_t grant, mac_interface_phy::tb_action_dl_t *action) + void new_grant_dl(Tgrant grant, Taction *action) { if (grant.rnti_type != SRSLTE_RNTI_SPS) { uint32_t harq_pid; @@ -82,7 +82,7 @@ public: if (grant.rnti_type == SRSLTE_RNTI_SI) { harq_pid = HARQ_BCCH_PID; } else { - harq_pid = grant.pid%NOF_HARQ_PROC; + harq_pid = grant.pid%N; } if (grant.rnti_type == SRSLTE_RNTI_TEMP && last_temporal_crnti != grant.rnti) { grant.ndi = true; @@ -96,7 +96,7 @@ public: proc[harq_pid].new_grant_dl(grant, action); } else { /* This is for SPS scheduling */ - uint32_t harq_pid = get_harq_sps_pid(grant.tti)%NOF_HARQ_PROC; + uint32_t harq_pid = get_harq_sps_pid(grant.tti)%N; if (grant.ndi) { grant.ndi = false; proc[harq_pid].new_grant_dl(grant, action); @@ -121,16 +121,16 @@ public: void tb_decoded(bool ack, srslte_rnti_type_t rnti_type, uint32_t harq_pid) { if (rnti_type == SRSLTE_RNTI_SI) { - proc[NOF_HARQ_PROC].tb_decoded(ack); + proc[N].tb_decoded(ack); } else { - proc[harq_pid%NOF_HARQ_PROC].tb_decoded(ack); + proc[harq_pid%N].tb_decoded(ack); } } void reset() { - for (uint32_t i=0;idefault_ack = ack; action->generate_ack = true; action->decode_enabled = false; @@ -224,7 +224,7 @@ private: action->rv = cur_grant.rv; action->rnti = cur_grant.rnti; action->softbuffer = &softbuffer; - memcpy(&action->phy_grant, &cur_grant.phy_grant, sizeof(srslte_phy_grant_t)); + memcpy(&action->phy_grant, &cur_grant.phy_grant, sizeof(Tphygrant)); n_retx++; } else { @@ -293,7 +293,7 @@ private: int get_current_tbs() { return cur_grant.n_bytes*8; } private: - bool calc_is_new_transmission(mac_interface_phy::mac_grant_t grant) + bool calc_is_new_transmission(Tgrant grant) { bool is_new_tb = true; if ((srslte_tti_interval(grant.tti, cur_grant.tti) <= 8 && (grant.n_bytes == cur_grant.n_bytes)) || @@ -328,7 +328,7 @@ private: uint32_t n_retx; - mac_interface_phy::mac_grant_t cur_grant; + Tgrant cur_grant; srslte_softbuffer_rx_t softbuffer; }; @@ -344,7 +344,8 @@ private: dl_sps dl_sps_assig; - dl_harq_process proc[NOF_HARQ_PROC+1]; + + std::vector proc; srslte::timers *timers_db; mac_interface_rrc::mac_cfg_t *mac_cfg; demux *demux_unit; diff --git a/srsue/hdr/mac/mac.h b/srsue/hdr/mac/mac.h index 82a7b1e76..660f7fbba 100644 --- a/srsue/hdr/mac/mac.h +++ b/srsue/hdr/mac/mac.h @@ -106,6 +106,7 @@ private: static const int MAC_MAIN_THREAD_PRIO = 5; static const int MAC_PDU_THREAD_PRIO = 6; + static const int MAC_NOF_HARQ_PROC = 8; // Interaction with PHY srslte::tti_sync_cv ttisync; @@ -130,9 +131,9 @@ private: mux mux_unit; demux demux_unit; - /* DL/UL HARQ */ - dl_harq_entity dl_harq; - ul_harq_entity ul_harq; + /* DL/UL HARQ */ + dl_harq_entity dl_harq; + ul_harq_entity ul_harq; /* MAC Uplink-related Procedures */ ra_proc ra_procedure; diff --git a/srsue/hdr/mac/ul_harq.h b/srsue/hdr/mac/ul_harq.h index 38046b099..21c4a9602 100644 --- a/srsue/hdr/mac/ul_harq.h +++ b/srsue/hdr/mac/ul_harq.h @@ -43,17 +43,18 @@ /* Uplink HARQ entity as defined in 5.4.2 of 36.321 */ namespace srsue { - + +template class ul_harq_entity { public: - const static uint32_t NOF_HARQ_PROC = 8; static uint32_t pidof(uint32_t tti) { - return (uint32_t) tti%NOF_HARQ_PROC; + return (uint32_t) tti%N; } - ul_harq_entity() { + ul_harq_entity() : proc(N) + { pcap = NULL; timers_db = NULL; mux_unit = NULL; @@ -61,7 +62,7 @@ public: mac_cfg = NULL; rntis = NULL; average_retx = 0; - nof_pkts = 0; + nof_pkts = 0; } bool init(srslte::log *log_h_, @@ -75,7 +76,7 @@ public: mac_cfg = mac_cfg_; rntis = rntis_; timers_db = timers_db_; - for (uint32_t i=0;iMAC interface for UL processes **************************/ - void new_grant_ul(mac_interface_phy::mac_grant_t grant, mac_interface_phy::tb_action_ul_t *action) + void new_grant_ul(Tgrant grant, Taction *action) { if (grant.rnti_type == SRSLTE_RNTI_USER || grant.rnti_type == SRSLTE_RNTI_TEMP || @@ -125,13 +126,13 @@ public: } } - void new_grant_ul_ack(mac_interface_phy::mac_grant_t grant, bool ack, mac_interface_phy::tb_action_ul_t *action) + void new_grant_ul_ack(Tgrant grant, bool ack, Taction *action) { set_ack(grant.tti, ack); new_grant_ul(grant, action); } - void harq_recv(uint32_t tti, bool ack, mac_interface_phy::tb_action_ul_t *action) + void harq_recv(uint32_t tti, bool ack, Taction *action) { set_ack(tti, ack); run_tti(tti, NULL, action); @@ -162,7 +163,7 @@ private: is_initiated = false; is_grant_configured = false; tti_last_tx = 0; - bzero(&cur_grant, sizeof(mac_interface_phy::mac_grant_t)); + bzero(&cur_grant, sizeof(Tgrant)); } bool init(uint32_t pid_, ul_harq_entity *parent) @@ -191,12 +192,12 @@ private: current_irv = 0; tti_last_tx = 0; is_grant_configured = false; - bzero(&cur_grant, sizeof(mac_interface_phy::mac_grant_t)); + bzero(&cur_grant, sizeof(Tgrant)); } void reset_ndi() { ndi = false; } - void run_tti(uint32_t tti_tx, mac_interface_phy::mac_grant_t *grant, mac_interface_phy::tb_action_ul_t* action) + void run_tti(uint32_t tti_tx, Tgrant *grant, Taction* action) { uint32_t max_retx; if (is_msg3) { @@ -287,7 +288,7 @@ private: int get_current_tbs() { return cur_grant.n_bytes*8; } private: - mac_interface_phy::mac_grant_t cur_grant; + Tgrant cur_grant; uint32_t pid; uint32_t current_tx_nb; @@ -307,14 +308,14 @@ private: uint8_t *payload_buffer; uint8_t *pdu_ptr; - void generate_retx(uint32_t tti_tx, mac_interface_phy::tb_action_ul_t *action) + void generate_retx(uint32_t tti_tx, Taction *action) { generate_retx(tti_tx, NULL, action); } // Retransmission with or w/o grant (Section 5.4.2.2) - void generate_retx(uint32_t tti_tx, mac_interface_phy::mac_grant_t *grant, - mac_interface_phy::tb_action_ul_t *action) + void generate_retx(uint32_t tti_tx, Tgrant *grant, + Taction *action) { int irv_of_rv[4] = {0, 3, 1, 2}; if (grant) { @@ -322,7 +323,7 @@ private: if (grant->rv) { current_irv = irv_of_rv[grant->rv%4]; } - memcpy(&cur_grant, grant, sizeof(mac_interface_phy::mac_grant_t)); + memcpy(&cur_grant, grant, sizeof(Tgrant)); harq_feedback = false; Info("UL %d: Adaptive retx=%d, RV=%d, TBS=%d\n", pid, current_tx_nb, get_rv(), grant->n_bytes); @@ -345,13 +346,12 @@ private: } // New transmission (Section 5.4.2.2) - void generate_new_tx(uint32_t tti_tx, bool is_msg3_, mac_interface_phy::mac_grant_t *grant, - mac_interface_phy::tb_action_ul_t *action) + void generate_new_tx(uint32_t tti_tx, bool is_msg3_, Tgrant *grant, Taction *action) { if (grant) { // Compute average number of retransmissions per packet considering previous packet harq_entity->average_retx = SRSLTE_VEC_CMA((float) current_tx_nb, harq_entity->average_retx, harq_entity->nof_pkts++); - memcpy(&cur_grant, grant, sizeof(mac_interface_phy::mac_grant_t)); + memcpy(&cur_grant, grant, sizeof(Tgrant)); harq_feedback = false; is_grant_configured = true; current_tx_nb = 0; @@ -364,7 +364,7 @@ private: } // Transmission of pending frame (Section 5.4.2.2) - void generate_tx(uint32_t tti_tx, mac_interface_phy::tb_action_ul_t *action) + void generate_tx(uint32_t tti_tx, Taction *action) { action->current_tx_nb = current_tx_nb; current_tx_nb++; @@ -374,7 +374,7 @@ private: action->softbuffer = &softbuffer; action->tx_enabled = true; action->payload_ptr = pdu_ptr; - memcpy(&action->phy_grant, &cur_grant.phy_grant, sizeof(srslte_phy_grant_t)); + memcpy(&action->phy_grant, &cur_grant.phy_grant, sizeof(Tphygrant)); current_irv = (current_irv+1)%4; tti_last_tx = tti_tx; @@ -383,7 +383,7 @@ private: // Implements Section 5.4.2.1 // Called with UL grant - void run_tti(uint32_t tti, mac_interface_phy::mac_grant_t *grant, mac_interface_phy::tb_action_ul_t* action) + void run_tti(uint32_t tti, Tgrant *grant, Taction* action) { uint32_t tti_tx = (tti+4)%10240; proc[pidof(tti_tx)].run_tti(tti_tx, grant, action); @@ -405,7 +405,7 @@ private: srslte::timers *timers_db; mux *mux_unit; - ul_harq_process proc[NOF_HARQ_PROC]; + std::vector proc; srslte::log *log_h; srslte::mac_pcap *pcap; From 583aa2d180ded3ca5369774a75631b01efbb045e Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 23 Jun 2017 14:19:53 +0200 Subject: [PATCH 04/19] move MAC structs shared between multiple RATs out RAT specific interface --- lib/include/srslte/interfaces/ue_interfaces.h | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 62b2a7ef7..a05f117a4 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -309,9 +309,27 @@ public: }; +/* Interface RRC -> MAC shared between different RATs */ +class mac_interface_rrc_common +{ +public: + // Class to handle UE specific RNTIs between RRC and MAC + typedef struct { + uint16_t crnti; + uint16_t temp_rnti; + uint16_t tpc_rnti; + uint16_t sps_rnti; + uint64_t contention_id; + } ue_rnti_t; + + typedef struct { + uint32_t max_harq_msg3_tx; + uint32_t max_harq_tx; + } ul_harq_params_t; +}; /* Interface RRC -> MAC */ -class mac_interface_rrc +class mac_interface_rrc : public mac_interface_rrc_common { public: @@ -319,19 +337,10 @@ public: LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT main; LIBLTE_RRC_RACH_CONFIG_COMMON_STRUCT rach; LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT sr; + ul_harq_params_t ul_harq_params; uint32_t prach_config_index; } mac_cfg_t; - - // Class to handle UE specific RNTIs between RRC and MAC - typedef struct { - uint16_t crnti; - uint16_t temp_rnti; - uint16_t tpc_rnti; - uint16_t sps_rnti; - uint64_t contention_id; - } ue_rnti_t; - /* Instructs the MAC to start receiving BCCH */ virtual void bcch_start_rx() = 0; virtual void bcch_stop_rx() = 0; From 9f3b4bf9a516f43bfdd65d2caeec6dd8adf98810 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 23 Jun 2017 14:30:51 +0200 Subject: [PATCH 05/19] use dedicated UL harq config - this patch changes the UL harq config to a dedicated one instead of passing the whole MAC config which may be specific to a specific RAT - it also extends the RRC to fill the harq specific config field in the MAC config - clean up dl_harq and remove unused mac config --- srsue/hdr/mac/dl_harq.h | 4 +--- srsue/hdr/mac/ul_harq.h | 16 ++++++++-------- srsue/src/mac/mac.cc | 12 ++++++------ srsue/src/upper/rrc.cc | 11 +++++++++-- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/srsue/hdr/mac/dl_harq.h b/srsue/hdr/mac/dl_harq.h index 25677dd84..809ecd151 100644 --- a/srsue/hdr/mac/dl_harq.h +++ b/srsue/hdr/mac/dl_harq.h @@ -58,11 +58,10 @@ public: pcap = NULL; } - bool init(srslte::log *log_h_, mac_interface_rrc::mac_cfg_t *mac_cfg_, srslte::timers *timers_, demux *demux_unit_) + bool init(srslte::log *log_h_, srslte::timers *timers_, demux *demux_unit_) { timers_db = timers_; demux_unit = demux_unit_; - mac_cfg = mac_cfg_; si_window_start = 0; log_h = log_h_; for (uint32_t i=0;i proc; srslte::timers *timers_db; - mac_interface_rrc::mac_cfg_t *mac_cfg; demux *demux_unit; srslte::log *log_h; srslte::mac_pcap *pcap; diff --git a/srsue/hdr/mac/ul_harq.h b/srsue/hdr/mac/ul_harq.h index 21c4a9602..107683ebb 100644 --- a/srsue/hdr/mac/ul_harq.h +++ b/srsue/hdr/mac/ul_harq.h @@ -59,21 +59,21 @@ public: timers_db = NULL; mux_unit = NULL; log_h = NULL; - mac_cfg = NULL; + params = NULL; rntis = NULL; average_retx = 0; nof_pkts = 0; } bool init(srslte::log *log_h_, - mac_interface_rrc::ue_rnti_t *rntis_, - mac_interface_rrc::mac_cfg_t *mac_cfg_, + mac_interface_rrc_common::ue_rnti_t *rntis_, + mac_interface_rrc_common::ul_harq_params_t *params_, srslte::timers* timers_db_, mux *mux_unit_) { log_h = log_h_; mux_unit = mux_unit_; - mac_cfg = mac_cfg_; + params = params_; rntis = rntis_; timers_db = timers_db_; for (uint32_t i=0;imac_cfg->rach.max_harq_msg3_tx; + max_retx = harq_entity->params->max_harq_msg3_tx; } else { - max_retx = liblte_rrc_max_harq_tx_num[harq_entity->mac_cfg->main.ulsch_cnfg.max_harq_tx]; + max_retx = harq_entity->params->max_harq_tx; } // Receive and route HARQ feedbacks @@ -409,8 +409,8 @@ private: srslte::log *log_h; srslte::mac_pcap *pcap; - mac_interface_rrc::ue_rnti_t *rntis; - mac_interface_rrc::mac_cfg_t *mac_cfg; + mac_interface_rrc_common::ue_rnti_t *rntis; + mac_interface_rrc_common::ul_harq_params_t *params; float average_retx; uint64_t nof_pkts; diff --git a/srsue/src/mac/mac.cc b/srsue/src/mac/mac.cc index 9a461ca05..9fe08166f 100644 --- a/srsue/src/mac/mac.cc +++ b/srsue/src/mac/mac.cc @@ -66,13 +66,13 @@ bool mac::init(phy_interface_mac *phy, rlc_interface_mac *rlc, rrc_interface_mac srslte_softbuffer_rx_init(&pch_softbuffer, 100); bsr_procedure.init( rlc_h, log_h, &config, &timers_db); - phr_procedure.init(phy_h, log_h, &config, &timers_db); - mux_unit.init ( rlc_h, log_h, &bsr_procedure, &phr_procedure); - demux_unit.init (phy_h, rlc_h, log_h, &timers_db); - ra_procedure.init (phy_h, rrc, log_h, &uernti, &config, &timers_db, &mux_unit, &demux_unit); + phr_procedure.init(phy_h, log_h, &config, &timers_db); + mux_unit.init ( rlc_h, log_h, &bsr_procedure, &phr_procedure); + demux_unit.init (phy_h, rlc_h, log_h, &timers_db); + ra_procedure.init (phy_h, rrc, log_h, &uernti, &config, &timers_db, &mux_unit, &demux_unit); sr_procedure.init (phy_h, rrc, log_h, &config); - ul_harq.init ( log_h, &uernti, &config, &timers_db, &mux_unit); - dl_harq.init ( log_h, &config, &timers_db, &demux_unit); + ul_harq.init ( log_h, &uernti, &config.ul_harq_params, &timers_db, &mux_unit); + dl_harq.init ( log_h, &timers_db, &demux_unit); reset(); diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index a1805a1e9..144d98711 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -989,7 +989,8 @@ void rrc::apply_sib2_configs() mac->get_config(&cfg); cfg.main.time_alignment_timer = sib2.time_alignment_timer; memcpy(&cfg.rach, &sib2.rr_config_common_sib.rach_cnfg, sizeof(LIBLTE_RRC_RACH_CONFIG_COMMON_STRUCT)); - cfg.prach_config_index = sib2.rr_config_common_sib.prach_cnfg.root_sequence_index; + cfg.prach_config_index = sib2.rr_config_common_sib.prach_cnfg.root_sequence_index; + cfg.ul_harq_params.max_harq_msg3_tx = cfg.rach.max_harq_msg3_tx; mac->set_config(&cfg); rrc_log->info("Set RACH ConfigCommon: NofPreambles=%d, ResponseWindow=%d, ContentionResolutionTimer=%d ms\n", @@ -1218,7 +1219,13 @@ void rrc::apply_mac_config_dedicated(LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT *mac_cnfg } // Setup MAC configuration - mac->set_config_main(&default_cfg); + mac->set_config_main(&default_cfg); + + // Update UL HARQ config + mac_interface_rrc::mac_cfg_t cfg; + mac->get_config(&cfg); + cfg.ul_harq_params.max_harq_tx = liblte_rrc_max_harq_tx_num[default_cfg.ulsch_cnfg.max_harq_tx]; + mac->set_config(&cfg); rrc_log->info("Set MAC main config: harq-MaxReTX=%d, bsr-TimerReTX=%d, bsr-TimerPeriodic=%d\n", liblte_rrc_max_harq_tx_num[default_cfg.ulsch_cnfg.max_harq_tx], From f26969db8b0aa468500aaba3c674d8605919c6b4 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 23 Jun 2017 15:00:41 +0200 Subject: [PATCH 06/19] adding UE base class - this patch moves common code shared between multiple UE types, i.e., UEs for different RATs into a commong base class - it also introduces a switch during UE startup to instantiate the selected UE type --- srsue/hdr/ue.h | 83 +------------------- srsue/hdr/ue_base.h | 164 +++++++++++++++++++++++++++++++++++++++ srsue/src/CMakeLists.txt | 2 +- srsue/src/main.cc | 20 +++-- srsue/src/ue.cc | 70 +---------------- srsue/src/ue_base.cc | 111 ++++++++++++++++++++++++++ 6 files changed, 296 insertions(+), 154 deletions(-) create mode 100644 srsue/hdr/ue_base.h create mode 100644 srsue/src/ue_base.cc diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index 6fb593d55..c69dbddeb 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -37,6 +37,7 @@ #include #include +#include "ue_base.h" #include "srslte/radio/radio_multi.h" #include "phy/phy.h" #include "mac/mac.h" @@ -56,89 +57,15 @@ namespace srsue { -/******************************************************************************* - UE Parameters -*******************************************************************************/ - -typedef struct { - float dl_freq; - float ul_freq; - float rx_gain; - float tx_gain; - uint32_t nof_rx_ant; - std::string device_name; - std::string device_args; - std::string time_adv_nsamples; - std::string burst_preamble; -}rf_args_t; - -typedef struct { - bool enable; - std::string filename; -}pcap_args_t; - -typedef struct { - bool enable; - std::string phy_filename; - std::string radio_filename; -}trace_args_t; - -typedef struct { - std::string phy_level; - std::string mac_level; - std::string rlc_level; - std::string pdcp_level; - std::string rrc_level; - std::string gw_level; - std::string nas_level; - std::string usim_level; - std::string all_level; - int phy_hex_limit; - int mac_hex_limit; - int rlc_hex_limit; - int pdcp_hex_limit; - int rrc_hex_limit; - int gw_hex_limit; - int nas_hex_limit; - int usim_hex_limit; - int all_hex_limit; - std::string filename; -}log_args_t; - -typedef struct { - bool enable; -}gui_args_t; - -typedef struct { - phy_args_t phy; - float metrics_period_secs; - bool pregenerate_signals; - int ue_cateogry; - -}expert_args_t; - -typedef struct { - rf_args_t rf; - rf_cal_t rf_cal; - pcap_args_t pcap; - trace_args_t trace; - log_args_t log; - gui_args_t gui; - usim_args_t usim; - expert_args_t expert; -}all_args_t; - /******************************************************************************* Main UE class *******************************************************************************/ class ue - :public ue_interface - ,public ue_metrics_interface + :public ue_base { public: - static ue* get_instance(void); - static void cleanup(void); + ue(); bool init(all_args_t *args_); void stop(); @@ -158,8 +85,6 @@ public: private: - static ue *instance; - ue(); virtual ~ue(); srslte::radio_multi radio; @@ -189,8 +114,6 @@ private: all_args_t *args; bool started; rf_metrics_t rf_metrics; - - srslte::LOG_LEVEL_ENUM level(std::string l); bool check_srslte_version(); }; diff --git a/srsue/hdr/ue_base.h b/srsue/hdr/ue_base.h new file mode 100644 index 000000000..06c3f3e24 --- /dev/null +++ b/srsue/hdr/ue_base.h @@ -0,0 +1,164 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of the srsUE library. + * + * srsUE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsUE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +/****************************************************************************** + * File: ue_base.h + * Description: Base class for UEs. + *****************************************************************************/ + +#ifndef UE_BASE_H +#define UE_BASE_H + +#include +#include +#include +#include "srslte/radio/radio_multi.h" +#include "phy/phy.h" +#include "upper/usim.h" +#include "srslte/interfaces/ue_interfaces.h" + +#include "srslte/common/logger.h" +#include "srslte/common/log_filter.h" + +#include "ue_metrics_interface.h" + +namespace srsue { + +/******************************************************************************* + UE Parameters +*******************************************************************************/ + +typedef struct { + float dl_freq; + float ul_freq; + float rx_gain; + float tx_gain; + uint32_t nof_rx_ant; + std::string device_name; + std::string device_args; + std::string time_adv_nsamples; + std::string burst_preamble; +}rf_args_t; + +typedef struct { + bool enable; + std::string filename; +}pcap_args_t; + +typedef struct { + bool enable; + std::string phy_filename; + std::string radio_filename; +}trace_args_t; + +typedef struct { + std::string phy_level; + std::string mac_level; + std::string rlc_level; + std::string pdcp_level; + std::string rrc_level; + std::string gw_level; + std::string nas_level; + std::string usim_level; + std::string all_level; + int phy_hex_limit; + int mac_hex_limit; + int rlc_hex_limit; + int pdcp_hex_limit; + int rrc_hex_limit; + int gw_hex_limit; + int nas_hex_limit; + int usim_hex_limit; + int all_hex_limit; + std::string filename; +}log_args_t; + +typedef struct { + bool enable; +}gui_args_t; + +typedef struct { + phy_args_t phy; + float metrics_period_secs; + bool pregenerate_signals; + std::string ue_cateogry; +}expert_args_t; + +typedef struct { + rf_args_t rf; + rf_cal_t rf_cal; + pcap_args_t pcap; + trace_args_t trace; + log_args_t log; + gui_args_t gui; + usim_args_t usim; + expert_args_t expert; +}all_args_t; + +typedef enum { + LTE = 0, + SRSUE_INSTANCE_TYPE_NITEMS +} srsue_instance_type_t; +static const char srsue_instance_type_text[SRSUE_INSTANCE_TYPE_NITEMS][10] = { "LTE" }; + + +/******************************************************************************* + Main UE class +*******************************************************************************/ + +class ue_base + :public ue_interface + ,public ue_metrics_interface +{ +public: + ue_base() {} + virtual ~ue_base() {} + + static ue_base* get_instance(srsue_instance_type_t type); + + void cleanup(void); + + virtual bool init(all_args_t *args_) = 0; + virtual void stop() = 0; + virtual bool is_attached() = 0; + virtual void start_plot() = 0; + + void handle_rf_msg(srslte_rf_error_t error); + + // UE metrics interface + virtual bool get_metrics(ue_metrics_t &m) = 0; + + virtual void pregenerate_signals(bool enable) = 0; + + srslte::log_filter rf_log; + rf_metrics_t rf_metrics; + srslte::LOG_LEVEL_ENUM level(std::string l); +}; + +} // namespace srsue + +#endif // UE_BASE_H + diff --git a/srsue/src/CMakeLists.txt b/srsue/src/CMakeLists.txt index 4b2a7e282..3a3b9ebfe 100644 --- a/srsue/src/CMakeLists.txt +++ b/srsue/src/CMakeLists.txt @@ -31,7 +31,7 @@ if (RPATH) set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) endif (RPATH) -add_executable(srsue main.cc ue.cc metrics_stdout.cc) +add_executable(srsue main.cc ue_base.cc ue.cc metrics_stdout.cc) target_link_libraries(srsue srsue_mac srsue_phy srsue_upper diff --git a/srsue/src/main.cc b/srsue/src/main.cc index f114c0606..16e0cb59f 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -126,7 +126,7 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { "index of the core used by the sync thread") ("expert.ue_category", - bpo::value(&args->expert.ue_cateogry)->default_value(4), + bpo::value(&args->expert.ue_cateogry)->default_value("4"), "UE Category (1 to 5)") ("expert.metrics_period_secs", @@ -342,18 +342,26 @@ void *input_loop(void *m) { return NULL; } -int main(int argc, char *argv[]) { +int main(int argc, char *argv[]) +{ signal(SIGINT, sig_int_handler); all_args_t args; - metrics_stdout metrics; - ue *ue = ue::get_instance(); + parse_args(&args, argc, argv); - cout << "--- Software Radio Systems LTE UE ---" << endl << endl; - parse_args(&args, argc, argv); + srsue_instance_type_t type = LTE; + ue_base *ue = ue_base::get_instance(type); + if (!ue) { + cout << "Error creating UE instance." << endl << endl; + exit(1); + } + + cout << "--- Software Radio Systems " << srsue_instance_type_text[type] << " UE ---" << endl << endl; if (!ue->init(&args)) { exit(1); } + + metrics_stdout metrics; metrics.init(ue, args.expert.metrics_period_secs); pthread_t input; diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 97f59c15e..dea1c3751 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -26,7 +26,6 @@ #include "ue.h" -//#include "srslte_version_check.h" #include "srslte/srslte.h" #include #include @@ -38,28 +37,6 @@ using namespace srslte; namespace srsue{ -ue* ue::instance = NULL; -pthread_mutex_t ue_instance_mutex = PTHREAD_MUTEX_INITIALIZER; - -ue* ue::get_instance(void) -{ - pthread_mutex_lock(&ue_instance_mutex); - if(NULL == instance) { - instance = new ue(); - } - pthread_mutex_unlock(&ue_instance_mutex); - return(instance); -} -void ue::cleanup(void) -{ - pthread_mutex_lock(&ue_instance_mutex); - if(NULL != instance) { - delete instance; - instance = NULL; - } - pthread_mutex_unlock(&ue_instance_mutex); -} - ue::ue() :started(false) { @@ -188,7 +165,7 @@ bool ue::init(all_args_t *args_) pdcp.init(&rlc, &rrc, &gw, &pdcp_log, SECURITY_DIRECTION_UPLINK); rrc.init(&phy, &mac, &rlc, &pdcp, &nas, &usim, &mac, &rrc_log); - rrc.set_ue_category(args->expert.ue_cateogry); + rrc.set_ue_category(atoi(args->expert.ue_cateogry.c_str())); nas.init(&usim, &rrc, &gw, &nas_log); gw.init(&pdcp, &rrc, this, &gw_log); @@ -271,49 +248,8 @@ bool ue::get_metrics(ue_metrics_t &m) void ue::rf_msg(srslte_rf_error_t error) { - ue *u = ue::get_instance(); - u->handle_rf_msg(error); -} - -void ue::handle_rf_msg(srslte_rf_error_t error) -{ - if(error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_OVERFLOW) { - rf_metrics.rf_o++; - rf_metrics.rf_error = true; - rf_log.warning("Overflow\n"); - }else if(error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_UNDERFLOW) { - rf_metrics.rf_u++; - rf_metrics.rf_error = true; - rf_log.warning("Underflow\n"); - } else if(error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_LATE) { - rf_metrics.rf_l++; - rf_metrics.rf_error = true; - rf_log.warning("Late\n"); - } else if (error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_OTHER) { - std::string str(error.msg); - str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); - str.erase(std::remove(str.begin(), str.end(), '\r'), str.end()); - str.push_back('\n'); - rf_log.info(str); - } -} - -srslte::LOG_LEVEL_ENUM ue::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; - } + ue_base *ue = ue_base::get_instance(LTE); + ue->handle_rf_msg(error); } } // namespace srsue diff --git a/srsue/src/ue_base.cc b/srsue/src/ue_base.cc new file mode 100644 index 000000000..61cbafb2c --- /dev/null +++ b/srsue/src/ue_base.cc @@ -0,0 +1,111 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of the srsUE library. + * + * srsUE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsUE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + + +#include "ue_base.h" +#include "ue.h" +#include "srslte/srslte.h" +#include +#include +#include +#include +#include + +using namespace srslte; + +namespace srsue{ + +static ue_base* instance = NULL; +pthread_mutex_t ue_instance_mutex = PTHREAD_MUTEX_INITIALIZER; + +ue_base* ue_base::get_instance(srsue_instance_type_t type) +{ + pthread_mutex_lock(&ue_instance_mutex); + if(NULL == instance) { + switch (type) { + case LTE: + instance = new ue(); + break; + default: + perror("Unknown UE type.\n"); + } + } + pthread_mutex_unlock(&ue_instance_mutex); + return(instance); +} + +void ue_base::cleanup(void) +{ + pthread_mutex_lock(&ue_instance_mutex); + if(NULL != instance) { + delete instance; + instance = NULL; + } + pthread_mutex_unlock(&ue_instance_mutex); +} + +void ue_base::handle_rf_msg(srslte_rf_error_t error) +{ + if(error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_OVERFLOW) { + rf_metrics.rf_o++; + rf_metrics.rf_error = true; + rf_log.warning("Overflow\n"); + }else if(error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_UNDERFLOW) { + rf_metrics.rf_u++; + rf_metrics.rf_error = true; + rf_log.warning("Underflow\n"); + } else if(error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_LATE) { + rf_metrics.rf_l++; + rf_metrics.rf_error = true; + rf_log.warning("Late\n"); + } else if (error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_OTHER) { + std::string str(error.msg); + str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); + str.erase(std::remove(str.begin(), str.end(), '\r'), str.end()); + str.push_back('\n'); + rf_log.info(str); + } +} + +srslte::LOG_LEVEL_ENUM ue_base::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; + } +} + +} // namespace srsue From 20a004a7681848da6db743c81fdad10ab6e6c3f1 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 23 Jun 2017 15:24:51 +0200 Subject: [PATCH 07/19] add seperate interface for MUX to query BSR procedure - this is also intented to make MUX RAT-agnostic --- lib/include/srslte/interfaces/ue_interfaces.h | 25 +++++++++++++++++++ srsue/hdr/mac/mux.h | 4 +-- srsue/hdr/mac/proc_bsr.h | 14 +---------- srsue/src/mac/mux.cc | 2 +- 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index a05f117a4..41b90bf9f 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -230,6 +230,31 @@ public: }; +//BSR interface for MUX +class bsr_interface_mux +{ +public: + typedef enum { + LONG_BSR, + SHORT_BSR, + TRUNC_BSR + } bsr_format_t; + + typedef struct { + bsr_format_t format; + uint32_t buff_size[4]; + } bsr_t; + + /* MUX calls BSR to check if it can fit a BSR into PDU */ + virtual bool need_to_send_bsr_on_ul_grant(uint32_t grant_size, bsr_t *bsr) = 0; + + /* MUX calls BSR to let it generate a padding BSR if there is space in PDU */ + virtual bool generate_padding_bsr(uint32_t nof_padding_bytes, bsr_t *bsr) = 0; + + /* MAX calls BSR to set the Tx TTI */ + virtual void set_tx_tti(uint32_t tti) = 0; +}; + /** MAC interface * diff --git a/srsue/hdr/mac/mux.h b/srsue/hdr/mac/mux.h index db98ebe78..b33cf0d19 100644 --- a/srsue/hdr/mac/mux.h +++ b/srsue/hdr/mac/mux.h @@ -57,7 +57,7 @@ class mux public: mux(); void reset(); - void init(rlc_interface_mac *rlc, srslte::log *log_h, bsr_proc *bsr_procedure, phr_proc *phr_procedure_); + void init(rlc_interface_mac *rlc, srslte::log *log_h, bsr_interface_mux *bsr_procedure, phr_proc *phr_procedure_); bool is_pending_any_sdu(); bool is_pending_sdu(uint32_t lcid); @@ -94,7 +94,7 @@ private: srslte::log *log_h; rlc_interface_mac *rlc; - bsr_proc *bsr_procedure; + bsr_interface_mux *bsr_procedure; phr_proc *phr_procedure; uint16_t pending_crnti_ce; diff --git a/srsue/hdr/mac/proc_bsr.h b/srsue/hdr/mac/proc_bsr.h index bbfaa1c90..21f278e29 100644 --- a/srsue/hdr/mac/proc_bsr.h +++ b/srsue/hdr/mac/proc_bsr.h @@ -37,7 +37,7 @@ namespace srsue { -class bsr_proc : public srslte::timer_callback +class bsr_proc : public srslte::timer_callback, public bsr_interface_mux { public: bsr_proc(); @@ -48,18 +48,6 @@ public: void set_priority(uint32_t lcid, uint32_t priority); void timer_expired(uint32_t timer_id); uint32_t get_buffer_state(); - - typedef enum { - LONG_BSR, - SHORT_BSR, - TRUNC_BSR - } bsr_format_t; - - typedef struct { - bsr_format_t format; - uint32_t buff_size[4]; - } bsr_t; - bool need_to_send_bsr_on_ul_grant(uint32_t grant_size, bsr_t *bsr); bool generate_padding_bsr(uint32_t nof_padding_bytes, bsr_t *bsr); bool need_to_send_sr(uint32_t tti); diff --git a/srsue/src/mac/mux.cc b/srsue/src/mac/mux.cc index 58ba3d57f..38a71649a 100644 --- a/srsue/src/mac/mux.cc +++ b/srsue/src/mac/mux.cc @@ -51,7 +51,7 @@ mux::mux() : pdu_msg(MAX_NOF_SUBHEADERS) msg3_flush(); } -void mux::init(rlc_interface_mac *rlc_, srslte::log *log_h_, bsr_proc *bsr_procedure_, phr_proc *phr_procedure_) +void mux::init(rlc_interface_mac *rlc_, srslte::log *log_h_, bsr_interface_mux *bsr_procedure_, phr_proc *phr_procedure_) { log_h = log_h_; rlc = rlc_; From c247f1103d1dd99a04fb70de712ce379141b5ed1 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 26 Jun 2017 10:08:55 +0200 Subject: [PATCH 08/19] parameterize TTI offset between UL grant and UL tx and UL tx and HARQ rx --- lib/include/srslte/interfaces/ue_interfaces.h | 1 + srsue/hdr/mac/ul_harq.h | 10 +++++----- srsue/src/phy/phch_worker.cc | 3 +++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 41b90bf9f..3cffaae1e 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -300,6 +300,7 @@ public: uint32_t rv; uint16_t rnti; uint32_t current_tx_nb; + int32_t tti_offset; // relative offset between grant and UL tx/HARQ rx srslte_softbuffer_tx_t *softbuffer; srslte_phy_grant_t phy_grant; uint8_t *payload_ptr; diff --git a/srsue/hdr/mac/ul_harq.h b/srsue/hdr/mac/ul_harq.h index 107683ebb..2ef1ed2b6 100644 --- a/srsue/hdr/mac/ul_harq.h +++ b/srsue/hdr/mac/ul_harq.h @@ -128,13 +128,13 @@ public: void new_grant_ul_ack(Tgrant grant, bool ack, Taction *action) { - set_ack(grant.tti, ack); + set_ack(grant.tti, ack, action); new_grant_ul(grant, action); } void harq_recv(uint32_t tti, bool ack, Taction *action) { - set_ack(tti, ack); + set_ack(tti, ack, action); run_tti(tti, NULL, action); } @@ -385,13 +385,13 @@ private: // Called with UL grant void run_tti(uint32_t tti, Tgrant *grant, Taction* action) { - uint32_t tti_tx = (tti+4)%10240; + uint32_t tti_tx = (tti+action->tti_offset)%10240; proc[pidof(tti_tx)].run_tti(tti_tx, grant, action); } - void set_ack(uint32_t tti, bool ack) + void set_ack(uint32_t tti, bool ack, Taction *action) { - int tti_harq = (int) tti - 4; + int tti_harq = (int) tti - action->tti_offset; if (tti_harq < 0) { tti_harq += 10240; } diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 14de9b51a..c2796e2ad 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -240,6 +240,9 @@ void phch_worker::work_imp() set_uci_periodic_cqi(); } + /* TTI offset for UL is always 4 for LTE */ + ul_action.tti_offset = 4; + /* Send UL grant or HARQ information (from PHICH) to MAC */ if (ul_grant_available && ul_ack_available) { phy->mac->new_grant_ul_ack(ul_mac_grant, ul_ack, &ul_action); From ce1e565c793b3095cc5eed0a39b439a1656b6606 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 26 Jun 2017 10:21:20 +0200 Subject: [PATCH 09/19] move RRC states definition into common header --- srsue/hdr/upper/rrc.h | 19 +------------ srsue/hdr/upper/rrc_common.h | 52 ++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 18 deletions(-) create mode 100644 srsue/hdr/upper/rrc_common.h diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index cc1a22fd1..a36fdacc0 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -29,6 +29,7 @@ #include "pthread.h" +#include "rrc_common.h" #include "srslte/common/buffer_pool.h" #include "srslte/common/log.h" #include "srslte/common/common.h" @@ -41,24 +42,6 @@ using srslte::byte_buffer_t; namespace srsue { -// RRC states (3GPP 36.331 v10.0.0) -typedef enum{ - RRC_STATE_IDLE = 0, - RRC_STATE_SIB1_SEARCH, - RRC_STATE_SIB2_SEARCH, - RRC_STATE_WAIT_FOR_CON_SETUP, - RRC_STATE_COMPLETING_SETUP, - RRC_STATE_RRC_CONNECTED, - RRC_STATE_N_ITEMS, -}rrc_state_t; -static const char rrc_state_text[RRC_STATE_N_ITEMS][100] = {"IDLE", - "SIB1_SEARCH", - "SIB2_SEARCH", - "WAIT FOR CON SETUP", - "COMPLETING SETUP", - "RRC CONNECTED"}; - - class rrc :public rrc_interface_nas ,public rrc_interface_phy diff --git a/srsue/hdr/upper/rrc_common.h b/srsue/hdr/upper/rrc_common.h new file mode 100644 index 000000000..692a20cb3 --- /dev/null +++ b/srsue/hdr/upper/rrc_common.h @@ -0,0 +1,52 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of the srsUE library. + * + * srsUE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsUE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +#ifndef RRC_COMMON_H +#define RRC_COMMON_H + +namespace srsue { + +// RRC states (3GPP 36.331 v10.0.0) +typedef enum{ + RRC_STATE_IDLE = 0, + RRC_STATE_SIB1_SEARCH, + RRC_STATE_SIB2_SEARCH, + RRC_STATE_WAIT_FOR_CON_SETUP, + RRC_STATE_COMPLETING_SETUP, + RRC_STATE_RRC_CONNECTED, + RRC_STATE_N_ITEMS, +}rrc_state_t; +static const char rrc_state_text[RRC_STATE_N_ITEMS][100] = {"IDLE", + "SIB1_SEARCH", + "SIB2_SEARCH", + "WAIT FOR CON SETUP", + "COMPLETING SETUP", + "RRC CONNECTED"}; + +} // namespace srsue + + +#endif // RRC_COMMON_H From cbfcb281a971d2605ca82fccc17cca33767b27b7 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 26 Jun 2017 13:37:36 +0200 Subject: [PATCH 10/19] seperate RAT agnostic bits from various interfaces --- lib/include/srslte/interfaces/ue_interfaces.h | 60 +++++++++++-------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 3cffaae1e..3fb3d354b 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -104,11 +104,16 @@ public: }; // RRC interface for MAC -class rrc_interface_mac +class rrc_interface_mac_common +{ +public: + virtual void ra_problem() = 0; +}; + +class rrc_interface_mac : public rrc_interface_mac_common { public: virtual void release_pucch_srs() = 0; - virtual void ra_problem() = 0; }; // RRC interface for PHY @@ -426,46 +431,51 @@ typedef struct { float estimator_fil_w; bool rssi_sensor_enabled; } phy_args_t; - -/* Interface MAC -> PHY */ -class phy_interface_mac + + +/* RAT agnostic Interface MAC -> PHY */ +class phy_interface_mac_common { public: - /* Configure PRACH using parameters written by RRC */ - virtual void configure_prach_params() = 0; - /* Start synchronization with strongest cell in the current carrier frequency */ - virtual void sync_start() = 0; + virtual void sync_start() = 0; virtual void sync_stop() = 0; - + /* Sets a C-RNTI allowing the PHY to pregenerate signals if necessary */ - virtual void set_crnti(uint16_t rnti) = 0; - + virtual void set_crnti(uint16_t rnti) = 0; + + /* Time advance commands */ + virtual void set_timeadv_rar(uint32_t ta_cmd) = 0; + virtual void set_timeadv(uint32_t ta_cmd) = 0; + + /* Sets RAR grant payload */ + virtual void set_rar_grant(uint32_t tti, uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN]) = 0; + + virtual uint32_t get_current_tti() = 0; + + virtual float get_phr() = 0; + virtual float get_pathloss_db() = 0; +}; + +/* Interface MAC -> PHY */ +class phy_interface_mac : public phy_interface_mac_common +{ +public: + /* Configure PRACH using parameters written by RRC */ + virtual void configure_prach_params() = 0; + virtual void prach_send(uint32_t preamble_idx, int allowed_subframe, float target_power_dbm) = 0; virtual int prach_tx_tti() = 0; /* Indicates the transmission of a SR signal in the next opportunity */ virtual void sr_send() = 0; virtual int sr_last_tx_tti() = 0; - - /* Time advance commands */ - virtual void set_timeadv_rar(uint32_t ta_cmd) = 0; - virtual void set_timeadv(uint32_t ta_cmd) = 0; - - /* Sets RAR grant payload */ - virtual void set_rar_grant(uint32_t tti, uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN]) = 0; /* Instruct the PHY to decode PDCCH with the CRC scrambled with given RNTI */ virtual void pdcch_ul_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start = -1, int tti_end = -1) = 0; virtual void pdcch_dl_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start = -1, int tti_end = -1) = 0; virtual void pdcch_ul_search_reset() = 0; virtual void pdcch_dl_search_reset() = 0; - - virtual uint32_t get_current_tti() = 0; - - virtual float get_phr() = 0; - virtual float get_pathloss_db() = 0; - }; class phy_interface_rrc From 83c358d33f070eff4cf19bc9ef589c3834979c5f Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 26 Jun 2017 13:49:12 +0200 Subject: [PATCH 11/19] let demux use common interface --- srsue/hdr/mac/demux.h | 10 +++++----- srsue/src/mac/demux.cc | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/srsue/hdr/mac/demux.h b/srsue/hdr/mac/demux.h index 773181220..8c9fb3a02 100644 --- a/srsue/hdr/mac/demux.h +++ b/srsue/hdr/mac/demux.h @@ -42,7 +42,7 @@ class demux : public srslte::pdu_queue::process_callback { public: demux(); - void init(phy_interface_mac* phy_h_, rlc_interface_mac *rlc, srslte::log* log_h_, srslte::timers* timers_db_); + void init(phy_interface_mac_common* phy_h_, rlc_interface_mac *rlc, srslte::log* log_h_, srslte::timers* timers_db_); bool process_pdus(); uint8_t* request_buffer(uint32_t pid, uint32_t len); @@ -73,10 +73,10 @@ private: bool is_uecrid_successful; - phy_interface_mac *phy_h; - srslte::log *log_h; - srslte::timers *timers_db; - rlc_interface_mac *rlc; + phy_interface_mac_common *phy_h; + srslte::log *log_h; + srslte::timers *timers_db; + rlc_interface_mac *rlc; // Buffer of PDUs srslte::pdu_queue pdus; diff --git a/srsue/src/mac/demux.cc b/srsue/src/mac/demux.cc index 71ad0cc58..227bcc364 100644 --- a/srsue/src/mac/demux.cc +++ b/srsue/src/mac/demux.cc @@ -40,7 +40,7 @@ demux::demux() : mac_msg(20), pending_mac_msg(20) { } -void demux::init(phy_interface_mac* phy_h_, rlc_interface_mac *rlc_, srslte::log* log_h_, srslte::timers* timers_db_) +void demux::init(phy_interface_mac_common* phy_h_, rlc_interface_mac *rlc_, srslte::log* log_h_, srslte::timers* timers_db_) { phy_h = phy_h_; log_h = log_h_; From 60da04ef5843b00ff8f912d1fd19df84a179b12a Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 28 Jun 2017 13:21:56 +0200 Subject: [PATCH 12/19] make LCID of GW object a parameter --- lib/include/srslte/upper/gw.h | 11 ++++++----- lib/src/upper/gw.cc | 5 +++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/include/srslte/upper/gw.h b/lib/include/srslte/upper/gw.h index a01413829..ce5936b71 100644 --- a/lib/include/srslte/upper/gw.h +++ b/lib/include/srslte/upper/gw.h @@ -46,7 +46,7 @@ class gw { public: gw(); - void init(srsue::pdcp_interface_gw *pdcp_, srsue::rrc_interface_gw *rrc_, srsue::ue_interface *ue_, log *gw_log_); + void init(srsue::pdcp_interface_gw *pdcp_, srsue::rrc_interface_gw *rrc_, srsue::ue_interface *ue_, log *gw_log_, uint32_t lcid_); void stop(); void get_metrics(gw_metrics_t &m); @@ -56,11 +56,11 @@ public: // NAS interface error_t setup_if_addr(uint32_t ip_addr, char *err_str); - + private: - - static const int GW_THREAD_PRIO = 7; - + + static const int GW_THREAD_PRIO = 7; + srsue::pdcp_interface_gw *pdcp; srsue::rrc_interface_gw *rrc; srsue::ue_interface *ue; @@ -73,6 +73,7 @@ private: struct ifreq ifr; int32 sock; bool if_up; + uint32_t lcid; long ul_tput_bytes; long dl_tput_bytes; diff --git a/lib/src/upper/gw.cc b/lib/src/upper/gw.cc index beb003c51..685803a4d 100644 --- a/lib/src/upper/gw.cc +++ b/lib/src/upper/gw.cc @@ -44,13 +44,14 @@ gw::gw() :if_up(false) {} -void gw::init(srsue::pdcp_interface_gw *pdcp_, srsue::rrc_interface_gw *rrc_, srsue::ue_interface *ue_, log *gw_log_) +void gw::init(srsue::pdcp_interface_gw *pdcp_, srsue::rrc_interface_gw *rrc_, srsue::ue_interface *ue_, log *gw_log_, uint32_t lcid_) { pool = byte_buffer_pool::get_instance(); pdcp = pdcp_; rrc = rrc_; ue = ue_; gw_log = gw_log_; + lcid = lcid_; run_enable = true; gettimeofday(&metrics_time[1], NULL); @@ -261,7 +262,7 @@ void gw::run_thread() // Send PDU directly to PDCP pdu->set_timestamp(); ul_tput_bytes += pdu->N_bytes; - pdcp->write_sdu(RB_ID_DRB1, pdu); + pdcp->write_sdu(lcid, pdu); do { pdu = pool_allocate; From 8dbabb2834a1d018e9bf6e5b0b267b407f030f23 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 28 Jun 2017 13:31:43 +0200 Subject: [PATCH 13/19] rework bearer/LCID handling This is a larger patch that reworks the LCID handling throughout the code. - It first moves the RB/LCID mapping out of common.h into the RRC object because different RATs may have different mappings. - It adds a interface to RRC that other objects like RLC/PDCP/etc. may use to get the bearer name of a specific LCID. - The patch also introduces a PDCP config class. --- lib/include/srslte/common/common.h | 26 ------ lib/include/srslte/common/interfaces_common.h | 21 +++++ lib/include/srslte/interfaces/ue_interfaces.h | 5 +- lib/include/srslte/upper/pdcp.h | 4 +- lib/include/srslte/upper/pdcp_entity.h | 11 +-- lib/include/srslte/upper/rlc.h | 5 +- lib/src/upper/pdcp.cc | 19 ++-- lib/src/upper/pdcp_entity.cc | 92 +++++++------------ lib/src/upper/rlc.cc | 23 +++-- lib/src/upper/rlc_am.cc | 76 +++++++-------- lib/src/upper/rlc_tm.cc | 8 +- lib/src/upper/rlc_um.cc | 40 ++++---- lib/test/upper/rlc_am_test.cc | 1 + lib/test/upper/rlc_um_test.cc | 1 + srsenb/hdr/upper/common_enb.h | 26 ++++++ srsenb/hdr/upper/pdcp.h | 1 + srsenb/hdr/upper/rlc.h | 2 + srsenb/src/upper/pdcp.cc | 21 ++++- srsenb/src/upper/rlc.cc | 8 +- srsenb/src/upper/rrc.cc | 14 ++- srsenb/test/upper/ip_test.cc | 3 +- srsue/hdr/upper/nas.h | 4 +- srsue/hdr/upper/rrc.h | 18 ++++ srsue/src/ue.cc | 11 ++- srsue/src/upper/nas.cc | 16 ++-- srsue/src/upper/rrc.cc | 44 +++++++-- srsue/test/upper/ip_test.cc | 3 +- 27 files changed, 287 insertions(+), 216 deletions(-) diff --git a/lib/include/srslte/common/common.h b/lib/include/srslte/common/common.h index 5f13ab214..ad88d9dcc 100644 --- a/lib/include/srslte/common/common.h +++ b/lib/include/srslte/common/common.h @@ -83,32 +83,6 @@ static const char error_text[ERROR_N_ITEMS][20] = { "None", "Can't start", "Already started"}; -typedef enum{ - RB_ID_SRB0 = 0, - RB_ID_SRB1, - RB_ID_SRB2, - RB_ID_DRB1, - RB_ID_DRB2, - RB_ID_DRB3, - RB_ID_DRB4, - RB_ID_DRB5, - RB_ID_DRB6, - RB_ID_DRB7, - RB_ID_DRB8, - RB_ID_N_ITEMS, -}rb_id_t; -static const char rb_id_text[RB_ID_N_ITEMS][20] = { "SRB0", - "SRB1", - "SRB2", - "DRB1", - "DRB2", - "DRB3", - "DRB4", - "DRB5", - "DRB6", - "DRB7", - "DRB8"}; - /****************************************************************************** * Byte and Bit buffers * diff --git a/lib/include/srslte/common/interfaces_common.h b/lib/include/srslte/common/interfaces_common.h index 76025a64f..5ef45cf54 100644 --- a/lib/include/srslte/common/interfaces_common.h +++ b/lib/include/srslte/common/interfaces_common.h @@ -28,9 +28,30 @@ #define INTERFACE_COMMON_H #include "srslte/common/timers.h" +#include "srslte/common/security.h" namespace srslte { +class srslte_pdcp_config_t +{ +public: + srslte_pdcp_config_t(bool is_control_ = false) + :direction(SECURITY_DIRECTION_UPLINK) + ,is_control(is_control_) + ,is_data(false) + ,do_security(false) + ,sn_len(12) {} + + u_int8_t direction; + bool is_control; + bool is_data; + bool do_security; + uint8_t sn_len; + + // TODO: Support the following configurations + // bool do_rohc; +}; + class mac_interface_timers { public: diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 3fb3d354b..ca9b4540b 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -132,6 +132,7 @@ public: virtual uint16_t get_mcc() = 0; virtual uint16_t get_mnc() = 0; virtual void enable_capabilities() = 0; + virtual std::string get_rb_name(uint32_t lcid) = 0; }; // RRC interface for GW @@ -151,6 +152,7 @@ public: virtual void write_pdu_bcch_bch(srslte::byte_buffer_t *pdu) = 0; virtual void write_pdu_bcch_dlsch(srslte::byte_buffer_t *pdu) = 0; virtual void write_pdu_pcch(srslte::byte_buffer_t *pdu) = 0; + virtual std::string get_rb_name(uint32_t lcid) = 0; }; // RRC interface for RLC @@ -158,6 +160,7 @@ class rrc_interface_rlc { public: virtual void max_retx_attempted() = 0; + virtual std::string get_rb_name(uint32_t lcid) = 0; }; // PDCP interface for GW @@ -173,7 +176,7 @@ class pdcp_interface_rrc public: virtual void reset() = 0; virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; - virtual void add_bearer(uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg=NULL) = 0; + virtual void add_bearer(uint32_t lcid, srslte::srslte_pdcp_config_t cnfg = srslte::srslte_pdcp_config_t()) = 0; virtual void config_security(uint32_t lcid, uint8_t *k_rrc_enc_, uint8_t *k_rrc_int_, diff --git a/lib/include/srslte/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index 857806810..abdbeeaea 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -46,13 +46,14 @@ public: srsue::rrc_interface_pdcp *rrc_, srsue::gw_interface_pdcp *gw_, log *pdcp_log_, + uint32_t lcid_, uint8_t direction_); void stop(); // RRC interface void reset(); void write_sdu(uint32_t lcid, byte_buffer_t *sdu); - void add_bearer(uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg = NULL); + void add_bearer(uint32_t lcid, srslte_pdcp_config_t cnfg = srslte_pdcp_config_t()); void config_security(uint32_t lcid, uint8_t *k_rrc_enc, uint8_t *k_rrc_int, @@ -72,6 +73,7 @@ private: log *pdcp_log; pdcp_entity pdcp_array[SRSLTE_N_RADIO_BEARERS]; + uint32_t lcid; // default LCID that is maintained active by PDCP instance uint8_t direction; bool valid_lcid(uint32_t lcid); diff --git a/lib/include/srslte/upper/pdcp_entity.h b/lib/include/srslte/upper/pdcp_entity.h index 2c1c988a0..0ff005d07 100644 --- a/lib/include/srslte/upper/pdcp_entity.h +++ b/lib/include/srslte/upper/pdcp_entity.h @@ -67,9 +67,7 @@ public: srsue::gw_interface_pdcp *gw_, srslte::log *log_, uint32_t lcid_, - uint8_t direction_, - LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg = NULL - ); + srslte_pdcp_config_t cfg_); void reset(); bool is_active(); @@ -94,12 +92,7 @@ private: bool active; uint32_t lcid; - bool do_security; - u_int8_t direction; - - uint8_t sn_len; - // TODO: Support the following configurations - // bool do_rohc; + srslte_pdcp_config_t cfg; uint32_t rx_count; uint32_t tx_count; diff --git a/lib/include/srslte/upper/rlc.h b/lib/include/srslte/upper/rlc.h index 9d7f7ff39..4a95f1a46 100644 --- a/lib/include/srslte/upper/rlc.h +++ b/lib/include/srslte/upper/rlc.h @@ -55,13 +55,15 @@ public: srsue::rrc_interface_rlc *rrc_, srsue::ue_interface *ue_, log *rlc_log_, - mac_interface_timers *mac_timers_); + mac_interface_timers *mac_timers_, + uint32_t lcid_); void stop(); void get_metrics(rlc_metrics_t &m); // PDCP interface void write_sdu(uint32_t lcid, byte_buffer_t *sdu); + std::string get_rb_name(uint32_t lcid); // MAC interface uint32_t get_buffer_state(uint32_t lcid); @@ -87,6 +89,7 @@ private: srslte::mac_interface_timers *mac_timers; srsue::ue_interface *ue; srslte::rlc_entity rlc_array[SRSLTE_N_RADIO_BEARERS]; + uint32_t default_lcid; long ul_tput_bytes[SRSLTE_N_RADIO_BEARERS]; long dl_tput_bytes[SRSLTE_N_RADIO_BEARERS]; diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index e729118ce..f28eac974 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -32,15 +32,16 @@ namespace srslte { pdcp::pdcp() {} -void pdcp::init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_, srsue::gw_interface_pdcp *gw_, log *pdcp_log_, uint8_t direction_) +void pdcp::init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_, srsue::gw_interface_pdcp *gw_, log *pdcp_log_, uint32_t lcid_, uint8_t direction_) { rlc = rlc_; rrc = rrc_; gw = gw_; pdcp_log = pdcp_log_; + lcid = lcid_; direction = direction_; - pdcp_array[0].init(rlc, rrc, gw, pdcp_log, RB_ID_SRB0, direction); // SRB0 + pdcp_array[0].init(rlc, rrc, gw, pdcp_log, lcid, direction); } void pdcp::stop() @@ -52,7 +53,7 @@ void pdcp::reset() pdcp_array[i].reset(); } - pdcp_array[0].init(rlc, rrc, gw, pdcp_log, RB_ID_SRB0, direction); // SRB0 + pdcp_array[0].init(rlc, rrc, gw, pdcp_log, lcid, direction); } /******************************************************************************* @@ -64,17 +65,17 @@ void pdcp::write_sdu(uint32_t lcid, byte_buffer_t *sdu) pdcp_array[lcid].write_sdu(sdu); } -void pdcp::add_bearer(uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg) +void pdcp::add_bearer(uint32_t lcid, srslte_pdcp_config_t cfg) { - if(lcid < 0 || lcid >= SRSLTE_N_RADIO_BEARERS) { + if(lcid >= SRSLTE_N_RADIO_BEARERS) { pdcp_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid); return; } if (!pdcp_array[lcid].is_active()) { - pdcp_array[lcid].init(rlc, rrc, gw, pdcp_log, lcid, direction, cnfg); - pdcp_log->info("Added bearer %s\n", rb_id_text[lcid]); + pdcp_array[lcid].init(rlc, rrc, gw, pdcp_log, lcid, cfg); + pdcp_log->info("Added bearer %s\n", rrc->get_rb_name(lcid).c_str()); } else { - pdcp_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rb_id_text[lcid]); + pdcp_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rrc->get_rb_name(lcid)); } } @@ -116,7 +117,7 @@ void pdcp::write_pdu_pcch(byte_buffer_t *sdu) *******************************************************************************/ bool pdcp::valid_lcid(uint32_t lcid) { - if(lcid < 0 || lcid >= SRSLTE_N_RADIO_BEARERS) { + if(lcid >= SRSLTE_N_RADIO_BEARERS) { pdcp_log->error("Radio bearer id must be in [0:%d] - %d", SRSLTE_N_RADIO_BEARERS, lcid); return false; } diff --git a/lib/src/upper/pdcp_entity.cc b/lib/src/upper/pdcp_entity.cc index 23fe8768d..9f658a577 100644 --- a/lib/src/upper/pdcp_entity.cc +++ b/lib/src/upper/pdcp_entity.cc @@ -34,8 +34,6 @@ pdcp_entity::pdcp_entity() :active(false) ,tx_count(0) ,rx_count(0) - ,do_security(false) - ,sn_len(12) { pool = byte_buffer_pool::get_instance(); } @@ -45,38 +43,27 @@ void pdcp_entity::init(srsue::rlc_interface_pdcp *rlc_, srsue::gw_interface_pdcp *gw_, srslte::log *log_, uint32_t lcid_, - u_int8_t direction_, - LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg) + srslte_pdcp_config_t cfg_) { rlc = rlc_; rrc = rrc_; gw = gw_; log = log_; lcid = lcid_; - direction = direction_; + cfg = cfg_; active = true; tx_count = 0; rx_count = 0; - do_security = false; - if(cnfg) - { - if(cnfg->rlc_um_pdcp_sn_size_present) { - if(LIBLTE_RRC_PDCP_SN_SIZE_7_BITS == cnfg->rlc_um_pdcp_sn_size) { - sn_len = 7; - } - } - // TODO: handle remainder of cnfg - } - log->debug("Init %s\n", rb_id_text[lcid]); + log->debug("Init %s\n", rrc->get_rb_name(lcid).c_str()); } void pdcp_entity::reset() { active = false; if(log) - log->debug("Reset %s\n", rb_id_text[lcid]); + log->debug("Reset %s\n", rrc->get_rb_name(lcid).c_str()); } bool pdcp_entity::is_active() @@ -87,44 +74,32 @@ bool pdcp_entity::is_active() // RRC interface void pdcp_entity::write_sdu(byte_buffer_t *sdu) { - log->info_hex(sdu->msg, sdu->N_bytes, "TX %s SDU, do_security = %s", rb_id_text[lcid], (do_security)?"true":"false"); + log->info_hex(sdu->msg, sdu->N_bytes, "TX %s SDU, do_security = %s", rrc->get_rb_name(lcid).c_str(), (cfg.do_security)?"true":"false"); - // Handle SRB messages - switch(lcid) - { - case RB_ID_SRB0: - rlc->write_sdu(lcid, sdu); - break; - case RB_ID_SRB1: // Intentional fall-through - case RB_ID_SRB2: + if (cfg.is_control) { pdcp_pack_control_pdu(tx_count, sdu); - if(do_security) + if(cfg.do_security) { integrity_generate(&k_rrc_int[16], tx_count, lcid-1, - direction, + cfg.direction, sdu->msg, sdu->N_bytes-4, &sdu->msg[sdu->N_bytes-4]); } tx_count++; - rlc->write_sdu(lcid, sdu); - - break; } - // Handle DRB messages - if(lcid >= RB_ID_DRB1) - { - if(12 == sn_len) - { + if (cfg.is_data) { + if(12 == cfg.sn_len) { pdcp_pack_data_pdu_long_sn(tx_count++, sdu); } else { pdcp_pack_data_pdu_short_sn(tx_count++, sdu); } - rlc->write_sdu(lcid, sdu); } + + rlc->write_sdu(lcid, sdu); } void pdcp_entity::config_security(uint8_t *k_rrc_enc_, @@ -132,7 +107,7 @@ void pdcp_entity::config_security(uint8_t *k_rrc_enc_, CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) { - do_security = true; + cfg.do_security = true; for(int i=0; i<32; i++) { k_rrc_enc[i] = k_rrc_enc_[i]; @@ -145,37 +120,32 @@ void pdcp_entity::config_security(uint8_t *k_rrc_enc_, // RLC interface void pdcp_entity::write_pdu(byte_buffer_t *pdu) { - // Handle SRB messages - switch(lcid) - { - case RB_ID_SRB0: - // Simply pass on to RRC - log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU", rb_id_text[lcid]); - rrc->write_pdu(RB_ID_SRB0, pdu); - break; - case RB_ID_SRB1: // Intentional fall-through - case RB_ID_SRB2: - uint32_t sn; - log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU", rb_id_text[lcid]); - pdcp_unpack_control_pdu(pdu, &sn); - log->info_hex(pdu->msg, pdu->N_bytes, "RX %s SDU SN: %d", - rb_id_text[lcid], sn); - rrc->write_pdu(lcid, pdu); - break; - } - // Handle DRB messages - if(lcid >= RB_ID_DRB1) - { + + + + + if (cfg.is_data) { uint32_t sn; - if(12 == sn_len) + if(12 == cfg.sn_len) { pdcp_unpack_data_pdu_long_sn(pdu, &sn); } else { pdcp_unpack_data_pdu_short_sn(pdu, &sn); } - log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU: %d", rb_id_text[lcid], sn); + log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU: %d", rrc->get_rb_name(lcid).c_str(), sn); gw->write_pdu(lcid, pdu); + } else { + if (cfg.is_control) { + uint32_t sn; + pdcp_unpack_control_pdu(pdu, &sn); + log->info_hex(pdu->msg, pdu->N_bytes, "RX %s SDU SN: %d", + rrc->get_rb_name(lcid).c_str(), sn); + } else { + log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU", rrc->get_rb_name(lcid).c_str()); + } + // pass to RRC + rrc->write_pdu(lcid, pdu); } } diff --git a/lib/src/upper/rlc.cc b/lib/src/upper/rlc.cc index becb15c37..c840de10d 100644 --- a/lib/src/upper/rlc.cc +++ b/lib/src/upper/rlc.cc @@ -41,18 +41,20 @@ void rlc::init(srsue::pdcp_interface_rlc *pdcp_, srsue::rrc_interface_rlc *rrc_, srsue::ue_interface *ue_, log *rlc_log_, - mac_interface_timers *mac_timers_) + mac_interface_timers *mac_timers_, + uint32_t lcid_) { pdcp = pdcp_; rrc = rrc_; ue = ue_; rlc_log = rlc_log_; mac_timers = mac_timers_; + default_lcid = lcid_; gettimeofday(&metrics_time[1], NULL); reset_metrics(); - rlc_array[0].init(RLC_MODE_TM, rlc_log, RB_ID_SRB0, pdcp, rrc, mac_timers); // SRB0 + rlc_array[0].init(RLC_MODE_TM, rlc_log, default_lcid, pdcp, rrc, mac_timers); // SRB0 } void rlc::reset_metrics() @@ -97,7 +99,7 @@ void rlc::reset() rlc_array[i].reset(); } - rlc_array[0].init(RLC_MODE_TM, rlc_log, RB_ID_SRB0, pdcp, rrc, mac_timers); // SRB0 + rlc_array[0].init(RLC_MODE_TM, rlc_log, default_lcid, pdcp, rrc, mac_timers); // SRB0 } /******************************************************************************* @@ -110,6 +112,11 @@ void rlc::write_sdu(uint32_t lcid, byte_buffer_t *sdu) } } +std::string rlc::get_rb_name(uint32_t lcid) +{ + return rrc->get_rb_name(lcid); +} + /******************************************************************************* MAC interface *******************************************************************************/ @@ -188,7 +195,7 @@ void rlc::add_bearer(uint32_t lcid) { // No config provided - use defaults for lcid LIBLTE_RRC_RLC_CONFIG_STRUCT cnfg; - if(RB_ID_SRB1 == lcid || RB_ID_SRB2 == lcid) + if(default_lcid == lcid || (default_lcid+1) == lcid) { if (!rlc_array[lcid].active()) { cnfg.rlc_mode = LIBLTE_RRC_RLC_MODE_AM; @@ -200,11 +207,11 @@ void rlc::add_bearer(uint32_t lcid) cnfg.dl_am_rlc.t_status_prohibit = LIBLTE_RRC_T_STATUS_PROHIBIT_MS0; add_bearer(lcid, &cnfg); } else { - rlc_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rb_id_text[lcid]); + rlc_log->warning("Bearer %s already configured. Reconfiguration not supported\n", get_rb_name(lcid).c_str()); } }else{ rlc_log->error("Radio bearer %s does not support default RLC configuration.", - rb_id_text[lcid]); + get_rb_name(lcid).c_str()); } } @@ -218,7 +225,7 @@ void rlc::add_bearer(uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) if (!rlc_array[lcid].active()) { rlc_log->info("Adding radio bearer %s with mode %s\n", - rb_id_text[lcid], liblte_rrc_rlc_mode_text[cnfg->rlc_mode]); + get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg->rlc_mode]); switch(cnfg->rlc_mode) { case LIBLTE_RRC_RLC_MODE_AM: @@ -238,7 +245,7 @@ void rlc::add_bearer(uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) return; } } else { - rlc_log->warning("Bearer %s already created.\n", rb_id_text[lcid]); + rlc_log->warning("Bearer %s already created.\n", get_rb_name(lcid).c_str()); } rlc_array[lcid].configure(cnfg); diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 416a141c8..d25b2d2ef 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -86,7 +86,7 @@ void rlc_am::configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) log->info("%s configured: t_poll_retx=%d, poll_pdu=%d, poll_byte=%d, max_retx_thresh=%d, " "t_reordering=%d, t_status_prohibit=%d\n", - rb_id_text[lcid], t_poll_retx, poll_pdu, poll_byte, max_retx_thresh, + rrc->get_rb_name(lcid).c_str(), t_poll_retx, poll_pdu, poll_byte, max_retx_thresh, t_reordering, t_status_prohibit); } @@ -176,7 +176,7 @@ uint32_t rlc_am::get_bearer() void rlc_am::write_sdu(byte_buffer_t *sdu) { - log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU", rb_id_text[lcid]); + log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU", rrc->get_rb_name(lcid).c_str()); tx_sdu_queue.write(sdu); } @@ -347,7 +347,7 @@ void rlc_am::check_reordering_timeout() if(reordering_timeout.is_running() && reordering_timeout.expired()) { reordering_timeout.reset(); - log->debug("%s reordering timeout expiry - updating vr_ms\n", rb_id_text[lcid]); + log->debug("%s reordering timeout expiry - updating vr_ms\n", rrc->get_rb_name(lcid).c_str()); // 36.322 v10 Section 5.1.3.2.4 vr_ms = vr_x; @@ -409,7 +409,7 @@ int rlc_am::build_status_pdu(uint8_t *payload, uint32_t nof_bytes) if(pdu_len > 0 && nof_bytes >= (uint32_t)pdu_len) { log->info("%s Tx status PDU - %s\n", - rb_id_text[lcid], rlc_am_to_string(&status).c_str()); + rrc->get_rb_name(lcid).c_str(), rlc_am_to_string(&status).c_str()); do_status = false; poll_received = false; @@ -420,7 +420,7 @@ int rlc_am::build_status_pdu(uint8_t *payload, uint32_t nof_bytes) return rlc_am_write_status_pdu(&status, payload); }else{ log->warning("%s Cannot tx status PDU - %d bytes available, %d bytes required\n", - rb_id_text[lcid], nof_bytes, pdu_len); + rrc->get_rb_name(lcid).c_str(), nof_bytes, pdu_len); return 0; } } @@ -437,7 +437,7 @@ int rlc_am::build_retx_pdu(uint8_t *payload, uint32_t nof_bytes) // Is resegmentation needed? if(retx.is_segment || required_buffer_size(retx) > (int)nof_bytes) { - log->debug("%s build_retx_pdu - resegmentation required\n", rb_id_text[lcid]); + log->debug("%s build_retx_pdu - resegmentation required\n", rrc->get_rb_name(lcid).c_str()); return build_segment(payload, nof_bytes, retx); } @@ -462,7 +462,7 @@ int rlc_am::build_retx_pdu(uint8_t *payload, uint32_t nof_bytes) if(tx_window[retx.sn].retx_count >= max_retx_thresh) rrc->max_retx_attempted(); log->info("%s Retx PDU scheduled for tx. SN: %d, retx count: %d\n", - rb_id_text[lcid], retx.sn, tx_window[retx.sn].retx_count); + rrc->get_rb_name(lcid).c_str(), retx.sn, tx_window[retx.sn].retx_count); debug_state(); return (ptr-payload) + tx_window[retx.sn].buf->N_bytes; @@ -495,7 +495,7 @@ int rlc_am::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_retx_t r if(nof_bytes <= head_len) { log->warning("%s Cannot build a PDU segment - %d bytes available, %d bytes required for header\n", - rb_id_text[lcid], nof_bytes, head_len); + rrc->get_rb_name(lcid).c_str(), nof_bytes, head_len); return 0; } pdu_space = nof_bytes-head_len; @@ -561,15 +561,15 @@ int rlc_am::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_retx_t r memcpy(ptr, data, len); log->info("%s Retx PDU segment scheduled for tx. SN: %d, SO: %d\n", - rb_id_text[lcid], retx.sn, retx.so_start); + rrc->get_rb_name(lcid).c_str(), retx.sn, retx.so_start); debug_state(); int pdu_len = (ptr-payload) + len; if(pdu_len > (int)nof_bytes) { log->error("%s Retx PDU segment length error. Available: %d, Used: %d\n", - rb_id_text[lcid], nof_bytes, pdu_len); + rrc->get_rb_name(lcid).c_str(), nof_bytes, pdu_len); log->debug("%s Retx PDU segment length error. Header len: %d, Payload len: %d, N_li: %d\n", - rb_id_text[lcid], (ptr-payload), len, new_header.N_li); + rrc->get_rb_name(lcid).c_str(), (ptr-payload), len, new_header.N_li); } return pdu_len; @@ -617,13 +617,13 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) if(pdu_space <= head_len) { log->warning("%s Cannot build a PDU - %d bytes available, %d bytes required for header\n", - rb_id_text[lcid], nof_bytes, head_len); + rrc->get_rb_name(lcid).c_str(), nof_bytes, head_len); pool->deallocate(pdu); return 0; } log->debug("%s Building PDU - pdu_space: %d, head_len: %d \n", - rb_id_text[lcid], pdu_space, head_len); + rrc->get_rb_name(lcid).c_str(), pdu_space, head_len); // Check for SDU segment if(tx_sdu) @@ -638,7 +638,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) if(tx_sdu->N_bytes == 0) { log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", - rb_id_text[lcid], tx_sdu->get_latency_us()); + rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us()); pool->deallocate(tx_sdu); tx_sdu = NULL; } @@ -649,7 +649,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) header.fi |= RLC_FI_FIELD_NOT_START_ALIGNED; // First byte does not correspond to first byte of SDU log->debug("%s Building PDU - added SDU segment (len:%d) - pdu_space: %d, head_len: %d \n", - rb_id_text[lcid], to_move, pdu_space, head_len); + rrc->get_rb_name(lcid).c_str(), to_move, pdu_space, head_len); } // Pull SDUs from queue @@ -673,7 +673,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) if(tx_sdu->N_bytes == 0) { log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", - rb_id_text[lcid], tx_sdu->get_latency_us()); + rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us()); pool->deallocate(tx_sdu); tx_sdu = NULL; } @@ -683,7 +683,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) pdu_space = 0; log->debug("%s Building PDU - added SDU segment (len:%d) - pdu_space: %d, head_len: %d \n", - rb_id_text[lcid], to_move, pdu_space, head_len); + rrc->get_rb_name(lcid).c_str(), to_move, pdu_space, head_len); } if(tx_sdu) @@ -692,11 +692,11 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) // Set Poll bit pdu_without_poll++; byte_without_poll += (pdu->N_bytes + head_len); - log->debug("%s pdu_without_poll: %d\n", rb_id_text[lcid], pdu_without_poll); - log->debug("%s byte_without_poll: %d\n", rb_id_text[lcid], byte_without_poll); + log->debug("%s pdu_without_poll: %d\n", rrc->get_rb_name(lcid).c_str(), pdu_without_poll); + log->debug("%s byte_without_poll: %d\n", rrc->get_rb_name(lcid).c_str(), byte_without_poll); if(poll_required()) { - log->debug("%s setting poll bit to request status\n", rb_id_text[lcid]); + log->debug("%s setting poll bit to request status\n", rrc->get_rb_name(lcid).c_str()); header.p = 1; poll_sn = vt_s; pdu_without_poll = 0; @@ -707,7 +707,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) // Set SN header.sn = vt_s; vt_s = (vt_s + 1)%MOD; - log->info("%s PDU scheduled for tx. SN: %d\n", rb_id_text[lcid], header.sn); + log->info("%s PDU scheduled for tx. SN: %d\n", rrc->get_rb_name(lcid).c_str(), header.sn); // Place PDU in tx_window, write header and TX tx_window[header.sn].buf = pdu; @@ -728,26 +728,26 @@ void rlc_am::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_h std::map::iterator it; log->info_hex(payload, nof_bytes, "%s Rx data PDU SN: %d", - rb_id_text[lcid], header.sn); + rrc->get_rb_name(lcid).c_str(), header.sn); if(!inside_rx_window(header.sn)) { if(header.p) { - log->info("%s Status packet requested through polling bit\n", rb_id_text[lcid]); + log->info("%s Status packet requested through polling bit\n", rrc->get_rb_name(lcid).c_str()); do_status = true; } log->info("%s SN: %d outside rx window [%d:%d] - discarding\n", - rb_id_text[lcid], header.sn, vr_r, vr_mr); + rrc->get_rb_name(lcid).c_str(), header.sn, vr_r, vr_mr); return; } it = rx_window.find(header.sn); if(rx_window.end() != it) { if(header.p) { - log->info("%s Status packet requested through polling bit\n", rb_id_text[lcid]); + log->info("%s Status packet requested through polling bit\n", rrc->get_rb_name(lcid).c_str()); do_status = true; } log->info("%s Discarding duplicate SN: %d\n", - rb_id_text[lcid], header.sn); + rrc->get_rb_name(lcid).c_str(), header.sn); return; } @@ -780,7 +780,7 @@ void rlc_am::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_h // Check poll bit if(header.p) { - log->info("%s Status packet requested through polling bit\n", rb_id_text[lcid]); + log->info("%s Status packet requested through polling bit\n", rrc->get_rb_name(lcid).c_str()); poll_received = true; // 36.322 v10 Section 5.2.3 @@ -825,16 +825,16 @@ void rlc_am::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a std::map::iterator it; log->info_hex(payload, nof_bytes, "%s Rx data PDU segment. SN: %d, SO: %d", - rb_id_text[lcid], header.sn, header.so); + rrc->get_rb_name(lcid).c_str(), header.sn, header.so); // Check inside rx window if(!inside_rx_window(header.sn)) { if(header.p) { - log->info("%s Status packet requested through polling bit\n", rb_id_text[lcid]); + log->info("%s Status packet requested through polling bit\n", rrc->get_rb_name(lcid).c_str()); do_status = true; } log->info("%s SN: %d outside rx window [%d:%d] - discarding\n", - rb_id_text[lcid], header.sn, vr_r, vr_mr); + rrc->get_rb_name(lcid).c_str(), header.sn, vr_r, vr_mr); return; } @@ -853,7 +853,7 @@ void rlc_am::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a if(rx_segments.end() != it) { if(header.p) { - log->info("%s Status packet requested through polling bit\n", rb_id_text[lcid]); + log->info("%s Status packet requested through polling bit\n", rrc->get_rb_name(lcid).c_str()); do_status = true; } @@ -883,7 +883,7 @@ void rlc_am::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a // Check poll bit if(header.p) { - log->info("%s Status packet requested through polling bit\n", rb_id_text[lcid]); + log->info("%s Status packet requested through polling bit\n", rrc->get_rb_name(lcid).c_str()); poll_received = true; // 36.322 v10 Section 5.2.3 @@ -901,12 +901,12 @@ void rlc_am::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_bytes, rlc_a void rlc_am::handle_control_pdu(uint8_t *payload, uint32_t nof_bytes) { - log->info_hex(payload, nof_bytes, "%s Rx control PDU", rb_id_text[lcid]); + log->info_hex(payload, nof_bytes, "%s Rx control PDU", rrc->get_rb_name(lcid).c_str()); rlc_status_pdu_t status; rlc_am_read_status_pdu(payload, nof_bytes, &status); - log->info("%s Rx Status PDU: %s\n", rb_id_text[lcid], rlc_am_to_string(&status).c_str()); + log->info("%s Rx Status PDU: %s\n", rrc->get_rb_name(lcid).c_str(), rlc_am_to_string(&status).c_str()); poll_retx_timeout.reset(); @@ -944,7 +944,7 @@ void rlc_am::handle_control_pdu(uint8_t *payload, uint32_t nof_bytes) } } else { log->warning("%s invalid segment NACK received for SN %d. so_start: %d, so_end: %d, N_bytes: %d\n", - rb_id_text[lcid], i, status.nacks[j].so_start, status.nacks[j].so_end, it->second.buf->N_bytes); + rrc->get_rb_name(lcid).c_str(), i, status.nacks[j].so_start, status.nacks[j].so_end, it->second.buf->N_bytes); } } @@ -998,7 +998,7 @@ void rlc_am::reassemble_rx_sdus() rx_sdu->N_bytes += len; rx_window[vr_r].buf->msg += len; rx_window[vr_r].buf->N_bytes -= len; - log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU", rb_id_text[lcid]); + log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU", rrc->get_rb_name(lcid).c_str()); rx_sdu->set_timestamp(); pdcp->write_pdu(lcid, rx_sdu); rx_sdu = pool_allocate; @@ -1014,7 +1014,7 @@ void rlc_am::reassemble_rx_sdus() rx_sdu->N_bytes += rx_window[vr_r].buf->N_bytes; if(rlc_am_end_aligned(rx_window[vr_r].header.fi)) { - log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU", rb_id_text[lcid]); + log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU", rrc->get_rb_name(lcid).c_str()); rx_sdu->set_timestamp(); pdcp->write_pdu(lcid, rx_sdu); rx_sdu = pool_allocate; @@ -1058,7 +1058,7 @@ void rlc_am::debug_state() { log->debug("%s vt_a = %d, vt_ms = %d, vt_s = %d, poll_sn = %d " "vr_r = %d, vr_mr = %d, vr_x = %d, vr_ms = %d, vr_h = %d\n", - rb_id_text[lcid], vt_a, vt_ms, vt_s, poll_sn, + rrc->get_rb_name(lcid).c_str(), vt_a, vt_ms, vt_s, poll_sn, vr_r, vr_mr, vr_x, vr_ms, vr_h); } diff --git a/lib/src/upper/rlc_tm.cc b/lib/src/upper/rlc_tm.cc index a515a77a5..b97b78be7 100644 --- a/lib/src/upper/rlc_tm.cc +++ b/lib/src/upper/rlc_tm.cc @@ -79,7 +79,7 @@ uint32_t rlc_tm::get_bearer() // PDCP interface void rlc_tm::write_sdu(byte_buffer_t *sdu) { - log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU", rb_id_text[lcid]); + log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU", rrc->get_rb_name(lcid).c_str()); ul_queue.write(sdu); } @@ -99,7 +99,7 @@ int rlc_tm::read_pdu(uint8_t *payload, uint32_t nof_bytes) uint32_t pdu_size = ul_queue.size_tail_bytes(); if(pdu_size > nof_bytes) { - log->error("TX %s PDU size larger than MAC opportunity\n", rb_id_text[lcid]); + log->error("TX %s PDU size larger than MAC opportunity\n", rrc->get_rb_name(lcid).c_str()); return 0; } byte_buffer_t *buf; @@ -107,9 +107,9 @@ int rlc_tm::read_pdu(uint8_t *payload, uint32_t nof_bytes) pdu_size = buf->N_bytes; memcpy(payload, buf->msg, buf->N_bytes); log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", - rb_id_text[lcid], buf->get_latency_us()); + rrc->get_rb_name(lcid).c_str(), buf->get_latency_us()); pool->deallocate(buf); - log->info_hex(payload, pdu_size, "TX %s, %s PDU", rb_id_text[lcid], rlc_mode_text[RLC_MODE_TM]); + log->info_hex(payload, pdu_size, "TX %s, %s PDU", rrc->get_rb_name(lcid).c_str(), rlc_mode_text[RLC_MODE_TM]); return pdu_size; } diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 78fc0a68b..8724e0f28 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -78,7 +78,7 @@ void rlc_um::configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) tx_mod = (RLC_UMD_SN_SIZE_5_BITS == tx_sn_field_length) ? 32 : 1024; log->info("%s configured in %s mode: " "t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits\n", - rb_id_text[lcid], liblte_rrc_rlc_mode_text[cnfg->rlc_mode], + rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg->rlc_mode], t_reordering, rlc_umd_sn_size_num[rx_sn_field_length], rlc_umd_sn_size_num[tx_sn_field_length]); @@ -87,7 +87,7 @@ void rlc_um::configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) tx_sn_field_length = (rlc_umd_sn_size_t)cnfg->ul_um_uni_rlc.sn_field_len; tx_mod = (RLC_UMD_SN_SIZE_5_BITS == tx_sn_field_length) ? 32 : 1024; log->info("%s configured in %s mode: tx_sn_field_length=%u bits\n", - rb_id_text[lcid], liblte_rrc_rlc_mode_text[cnfg->rlc_mode], + rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg->rlc_mode], rlc_umd_sn_size_num[tx_sn_field_length]); break; case LIBLTE_RRC_RLC_MODE_UM_UNI_DL: @@ -97,7 +97,7 @@ void rlc_um::configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) rx_mod = (RLC_UMD_SN_SIZE_5_BITS == rx_sn_field_length) ? 32 : 1024; log->info("%s configured in %s mode: " "t_reordering=%d ms, rx_sn_field_length=%u bits\n", - rb_id_text[lcid], liblte_rrc_rlc_mode_text[cnfg->rlc_mode], + rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg->rlc_mode], liblte_rrc_t_reordering_num[t_reordering], rlc_umd_sn_size_num[rx_sn_field_length]); break; @@ -159,7 +159,7 @@ uint32_t rlc_um::get_bearer() void rlc_um::write_sdu(byte_buffer_t *sdu) { - log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU", rb_id_text[lcid]); + log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU", rrc->get_rb_name(lcid).c_str()); tx_sdu_queue.write(sdu); } @@ -222,7 +222,7 @@ void rlc_um::timer_expired(uint32_t timeout_id) // 36.322 v10 Section 5.1.2.2.4 log->info("%s reordering timeout expiry - updating vr_ur and reassembling\n", - rb_id_text[lcid]); + rrc->get_rb_name(lcid).c_str()); log->warning("Lost PDU SN: %d\n", vr_ur); pdu_lost = true; @@ -286,7 +286,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) if(pdu_space <= head_len) { log->warning("%s Cannot build a PDU - %d bytes available, %d bytes required for header\n", - rb_id_text[lcid], nof_bytes, head_len); + rrc->get_rb_name(lcid).c_str(), nof_bytes, head_len); return 0; } @@ -296,7 +296,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) uint32_t space = pdu_space-head_len; to_move = space >= tx_sdu->N_bytes ? tx_sdu->N_bytes : space; log->debug("%s adding remainder of SDU segment - %d bytes of %d remaining\n", - rb_id_text[lcid], to_move, tx_sdu->N_bytes); + rrc->get_rb_name(lcid).c_str(), to_move, tx_sdu->N_bytes); memcpy(pdu_ptr, tx_sdu->msg, to_move); last_li = to_move; pdu_ptr += to_move; @@ -306,7 +306,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) if(tx_sdu->N_bytes == 0) { log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", - rb_id_text[lcid], tx_sdu->get_latency_us()); + rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us()); pool->deallocate(tx_sdu); tx_sdu = NULL; } @@ -325,7 +325,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) uint32_t space = pdu_space-head_len; to_move = space >= tx_sdu->N_bytes ? tx_sdu->N_bytes : space; log->debug("%s adding new SDU segment - %d bytes of %d remaining\n", - rb_id_text[lcid], to_move, tx_sdu->N_bytes); + rrc->get_rb_name(lcid).c_str(), to_move, tx_sdu->N_bytes); memcpy(pdu_ptr, tx_sdu->msg, to_move); last_li = to_move; pdu_ptr += to_move; @@ -335,7 +335,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) if(tx_sdu->N_bytes == 0) { log->info("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", - rb_id_text[lcid], tx_sdu->get_latency_us()); + rrc->get_rb_name(lcid).c_str(), tx_sdu->get_latency_us()); pool->deallocate(tx_sdu); tx_sdu = NULL; } @@ -350,11 +350,11 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) vt_us = (vt_us + 1)%tx_mod; // Add header and TX - log->debug("%s packing PDU with length %d\n", rb_id_text[lcid], pdu->N_bytes); + log->debug("%s packing PDU with length %d\n", rrc->get_rb_name(lcid).c_str(), pdu->N_bytes); rlc_um_write_data_pdu_header(&header, pdu); memcpy(payload, pdu->msg, pdu->N_bytes); uint32_t ret = pdu->N_bytes; - log->debug("%sreturning length %d\n", rb_id_text[lcid], pdu->N_bytes); + log->debug("%sreturning length %d\n", rrc->get_rb_name(lcid).c_str(), pdu->N_bytes); pool->deallocate(pdu); debug_state(); @@ -368,20 +368,20 @@ void rlc_um::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes) rlc_um_read_data_pdu_header(payload, nof_bytes, rx_sn_field_length, &header); log->info_hex(payload, nof_bytes, "RX %s Rx data PDU SN: %d", - rb_id_text[lcid], header.sn); + rrc->get_rb_name(lcid).c_str(), header.sn); if(RX_MOD_BASE(header.sn) >= RX_MOD_BASE(vr_uh-rx_window_size) && RX_MOD_BASE(header.sn) < RX_MOD_BASE(vr_ur)) { log->info("%s SN: %d outside rx window [%d:%d] - discarding\n", - rb_id_text[lcid], header.sn, vr_ur, vr_uh); + rrc->get_rb_name(lcid).c_str(), header.sn, vr_ur, vr_uh); return; } it = rx_window.find(header.sn); if(rx_window.end() != it) { log->info("%s Discarding duplicate SN: %d\n", - rb_id_text[lcid], header.sn); + rrc->get_rb_name(lcid).c_str(), header.sn); return; } @@ -456,7 +456,7 @@ void rlc_um::reassemble_rx_sdus() log->warning("Dropping remainder of lost PDU (lower edge middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)\n", vr_ur, vr_ur_in_rx_sdu); rx_sdu->reset(); } else { - log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d, i=%d (lower edge middle segments)", rb_id_text[lcid], vr_ur, i); + log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d, i=%d (lower edge middle segments)", rrc->get_rb_name(lcid).c_str(), vr_ur, i); rx_sdu->set_timestamp(); pdcp->write_pdu(lcid, rx_sdu); rx_sdu = pool_allocate; @@ -476,7 +476,7 @@ void rlc_um::reassemble_rx_sdus() log->warning("Dropping remainder of lost PDU (lower edge last segments)\n"); rx_sdu->reset(); } else { - log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (lower edge last segments)", rb_id_text[lcid], vr_ur); + log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (lower edge last segments)", rrc->get_rb_name(lcid).c_str(), vr_ur); rx_sdu->set_timestamp(); pdcp->write_pdu(lcid, rx_sdu); rx_sdu = pool_allocate; @@ -510,7 +510,7 @@ void rlc_um::reassemble_rx_sdus() log->warning("Dropping remainder of lost PDU (update vr_ur middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)\n", vr_ur, vr_ur_in_rx_sdu); rx_sdu->reset(); } else { - log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d, i=%d, (update vr_ur middle segments)", rb_id_text[lcid], vr_ur, i); + log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d, i=%d, (update vr_ur middle segments)", rrc->get_rb_name(lcid).c_str(), vr_ur, i); rx_sdu->set_timestamp(); pdcp->write_pdu(lcid, rx_sdu); rx_sdu = pool_allocate; @@ -530,7 +530,7 @@ void rlc_um::reassemble_rx_sdus() log->warning("Dropping remainder of lost PDU (update vr_ur last segments)\n"); rx_sdu->reset(); } else { - log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (update vr_ur last segments)", rb_id_text[lcid], vr_ur); + log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (update vr_ur last segments)", rrc->get_rb_name(lcid).c_str(), vr_ur); rx_sdu->set_timestamp(); pdcp->write_pdu(lcid, rx_sdu); rx_sdu = pool_allocate; @@ -560,7 +560,7 @@ bool rlc_um::inside_reordering_window(uint16_t sn) void rlc_um::debug_state() { log->debug("%s vt_us = %d, vr_ur = %d, vr_ux = %d, vr_uh = %d \n", - rb_id_text[lcid], vt_us, vr_ur, vr_ux, vr_uh); + rrc->get_rb_name(lcid).c_str(), vt_us, vr_ur, vr_ux, vr_uh); } diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index dfe62905e..261a66548 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -67,6 +67,7 @@ public: // RRC interface void max_retx_attempted(){} + std::string get_rb_name(uint32_t lcid) { return std::string(""); } byte_buffer_t *sdus[10]; int n_sdus; diff --git a/lib/test/upper/rlc_um_test.cc b/lib/test/upper/rlc_um_test.cc index 491d816cc..739c9ebf8 100644 --- a/lib/test/upper/rlc_um_test.cc +++ b/lib/test/upper/rlc_um_test.cc @@ -71,6 +71,7 @@ public: // RRC interface void max_retx_attempted(){} + std::string get_rb_name(uint32_t lcid) { return std::string(""); } byte_buffer_t *sdus[5]; int n_sdus; diff --git a/srsenb/hdr/upper/common_enb.h b/srsenb/hdr/upper/common_enb.h index 9f15b69ae..d04869c54 100644 --- a/srsenb/hdr/upper/common_enb.h +++ b/srsenb/hdr/upper/common_enb.h @@ -43,6 +43,32 @@ namespace srsenb { #define SRSENB_N_DRB 8 #define SRSENB_N_RADIO_BEARERS 11 +typedef enum{ + RB_ID_SRB0 = 0, + RB_ID_SRB1, + RB_ID_SRB2, + RB_ID_DRB1, + RB_ID_DRB2, + RB_ID_DRB3, + RB_ID_DRB4, + RB_ID_DRB5, + RB_ID_DRB6, + RB_ID_DRB7, + RB_ID_DRB8, + RB_ID_N_ITEMS, +}rb_id_t; +static const char rb_id_text[RB_ID_N_ITEMS][20] = { "SRB0", + "SRB1", + "SRB2", + "DRB1", + "DRB2", + "DRB3", + "DRB4", + "DRB5", + "DRB6", + "DRB7", + "DRB8"}; + // Cat 3 UE - Max number of DL-SCH transport block bits received within a TTI // 3GPP 36.306 Table 4.1.1 #define SRSENB_MAX_BUFFER_SIZE_BITS 102048 diff --git a/srsenb/hdr/upper/pdcp.h b/srsenb/hdr/upper/pdcp.h index 44c59b8e6..1d047db3e 100644 --- a/srsenb/hdr/upper/pdcp.h +++ b/srsenb/hdr/upper/pdcp.h @@ -89,6 +89,7 @@ private: void write_pdu_bcch_bch(srslte::byte_buffer_t *pdu); void write_pdu_bcch_dlsch(srslte::byte_buffer_t *pdu); void write_pdu_pcch(srslte::byte_buffer_t *pdu); + std::string get_rb_name(uint32_t lcid); }; class user_interface diff --git a/srsenb/hdr/upper/rlc.h b/srsenb/hdr/upper/rlc.h index c979f6af8..d0c165d73 100644 --- a/srsenb/hdr/upper/rlc.h +++ b/srsenb/hdr/upper/rlc.h @@ -54,6 +54,7 @@ public: // rlc_interface_pdcp void write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu); + std::string get_rb_name(uint32_t lcid); // rlc_interface_mac int read_pdu(uint16_t rnti, uint32_t lcid, uint8_t *payload, uint32_t nof_bytes); @@ -73,6 +74,7 @@ private: void write_pdu_bcch_dlsch(srslte::byte_buffer_t *sdu); void write_pdu_pcch(srslte::byte_buffer_t *sdu); void max_retx_attempted(); + std::string get_rb_name(uint32_t lcid); uint16_t rnti; srsenb::pdcp_interface_rlc *pdcp; diff --git a/srsenb/src/upper/pdcp.cc b/srsenb/src/upper/pdcp.cc index 772184fbd..ee65ae9e8 100644 --- a/srsenb/src/upper/pdcp.cc +++ b/srsenb/src/upper/pdcp.cc @@ -25,6 +25,7 @@ */ #include "upper/pdcp.h" +#include "upper/common_enb.h" namespace srsenb { @@ -50,7 +51,7 @@ void pdcp::add_user(uint16_t rnti) { if (users.count(rnti) == 0) { srslte::pdcp *obj = new srslte::pdcp; - obj->init(&users[rnti].rlc_itf, &users[rnti].rrc_itf, &users[rnti].gtpu_itf, log_h, SECURITY_DIRECTION_DOWNLINK); + obj->init(&users[rnti].rlc_itf, &users[rnti].rrc_itf, &users[rnti].gtpu_itf, log_h, RB_ID_SRB0, SECURITY_DIRECTION_DOWNLINK); users[rnti].rlc_itf.rnti = rnti; users[rnti].gtpu_itf.rnti = rnti; users[rnti].rrc_itf.rnti = rnti; @@ -72,10 +73,16 @@ void pdcp::rem_user(uint16_t rnti) } } -void pdcp::add_bearer(uint16_t rnti, uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT* cnfg) +void pdcp::add_bearer(uint16_t rnti, uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT* cnfg_) { if (users.count(rnti)) { - users[rnti].pdcp->add_bearer(lcid, cnfg); + srslte::srslte_pdcp_config_t cfg; + if(cnfg_->rlc_um_pdcp_sn_size_present) { + if(LIBLTE_RRC_PDCP_SN_SIZE_7_BITS == cnfg_->rlc_um_pdcp_sn_size) { + cfg.sn_len = 7; + } + } + users[rnti].pdcp->add_bearer(lcid, cfg); } } @@ -143,6 +150,10 @@ void pdcp::user_interface_rrc::write_pdu_pcch(srslte::byte_buffer_t* pdu) { fprintf(stderr, "Error: Received PCCH from ue=%d\n", rnti); } - - + +std::string pdcp::user_interface_rrc::get_rb_name(uint32_t lcid) +{ + return std::string(rb_id_text[lcid]); +} + } diff --git a/srsenb/src/upper/rlc.cc b/srsenb/src/upper/rlc.cc index 1af7a76de..e826e7f34 100644 --- a/srsenb/src/upper/rlc.cc +++ b/srsenb/src/upper/rlc.cc @@ -25,6 +25,7 @@ */ #include "upper/rlc.h" +#include "upper/common_enb.h" namespace srsenb { @@ -53,7 +54,7 @@ void rlc::add_user(uint16_t rnti) { if (users.count(rnti) == 0) { srslte::rlc *obj = new srslte::rlc; - obj->init(&users[rnti], &users[rnti], &users[rnti], log_h, mac_timers); + obj->init(&users[rnti], &users[rnti], &users[rnti], log_h, mac_timers, RB_ID_SRB0); users[rnti].rnti = rnti; users[rnti].pdcp = pdcp; users[rnti].rrc = rrc; @@ -184,4 +185,9 @@ void rlc::user_interface::write_pdu_pcch(srslte::byte_buffer_t* sdu) fprintf(stderr, "Error: Received PCCH from ue=%d\n", rnti); } +std::string rlc::user_interface::get_rb_name(uint32_t lcid) +{ + return std::string(rb_id_text[lcid]); +} + } diff --git a/srsenb/src/upper/rrc.cc b/srsenb/src/upper/rrc.cc index 259fac714..3bdd46c70 100644 --- a/srsenb/src/upper/rrc.cc +++ b/srsenb/src/upper/rrc.cc @@ -27,10 +27,8 @@ #include "srslte/asn1/liblte_mme.h" #include "upper/rrc.h" -using srslte::rb_id_text; using srslte::byte_buffer_t; using srslte::bit_buffer_t; -using srslte::rb_id_t; namespace srsenb { @@ -607,11 +605,11 @@ void rrc::run_thread() } switch(p.lcid) { - case srslte::RB_ID_SRB0: + case RB_ID_SRB0: parse_ul_ccch(p.rnti, p.pdu); break; - case srslte::RB_ID_SRB1: - case srslte::RB_ID_SRB2: + case RB_ID_SRB1: + case RB_ID_SRB2: parse_ul_dcch(p.rnti, p.lcid, p.pdu); break; case LCID_REM_USER: @@ -919,7 +917,7 @@ void rrc::ue::set_security_key(uint8_t* key, uint32_t length) k_up_enc, k_up_int); - parent->configure_security(rnti, srslte::RB_ID_SRB1, + parent->configure_security(rnti, RB_ID_SRB1, k_rrc_enc, k_rrc_int, k_up_enc, k_up_int, cipher_algo, integ_algo); @@ -1432,7 +1430,7 @@ void rrc::ue::send_dl_ccch(LIBLTE_RRC_DL_CCCH_MSG_STRUCT *dl_ccch_msg) rnti, liblte_rrc_dl_ccch_msg_type_text[dl_ccch_msg->msg_type]); - parent->pdcp->write_sdu(rnti, srslte::RB_ID_SRB0, pdu); + parent->pdcp->write_sdu(rnti, RB_ID_SRB0, pdu); } else { parent->rrc_log->error("Allocating pdu\n"); @@ -1453,7 +1451,7 @@ void rrc::ue::send_dl_dcch(LIBLTE_RRC_DL_DCCH_MSG_STRUCT *dl_dcch_msg, byte_buff rnti, liblte_rrc_dl_dcch_msg_type_text[dl_dcch_msg->msg_type]); - parent->pdcp->write_sdu(rnti, srslte::RB_ID_SRB1, pdu); + parent->pdcp->write_sdu(rnti, RB_ID_SRB1, pdu); } else { parent->rrc_log->error("Allocating pdu\n"); diff --git a/srsenb/test/upper/ip_test.cc b/srsenb/test/upper/ip_test.cc index 41c430f29..2b789cf27 100644 --- a/srsenb/test/upper/ip_test.cc +++ b/srsenb/test/upper/ip_test.cc @@ -155,6 +155,7 @@ public: void set_activity_user(uint16_t rnti) {} bool is_paging_opportunity(uint32_t tti, uint32_t *payload_len) {return false;} void read_pdu_pcch(uint8_t* payload, uint32_t buffer_size) {} + std::string get_rb_name(uint32_t lcid) { return std::string("lcid"); } void write_pdu(uint32_t lcid, srslte::byte_buffer_t *sdu) { @@ -566,7 +567,7 @@ int main(int argc, char *argv[]) my_phy.init(&phy_args, &phy_cfg, &my_radio, &my_mac, &log_phy); my_mac.init(&mac_args, &mac_cfg.cell, &my_phy, &my_tester, &my_tester, &log_mac); - my_rlc.init(&my_tester, &my_tester, &my_tester, &log_rlc, &my_mac); + my_rlc.init(&my_tester, &my_tester, &my_tester, &log_rlc, &my_mac, 0 /* SRB0 */); my_tester.init(&my_rlc, &my_mac, &my_phy, &log_tester, prog_args.ip_address); if (prog_args.enable_gui) { diff --git a/srsue/hdr/upper/nas.h b/srsue/hdr/upper/nas.h index 5e3a8b098..ae3dfe246 100644 --- a/srsue/hdr/upper/nas.h +++ b/srsue/hdr/upper/nas.h @@ -65,7 +65,8 @@ public: void init(usim_interface_nas *usim_, rrc_interface_nas *rrc_, gw_interface_nas *gw_, - srslte::log *nas_log_); + srslte::log *nas_log_, + uint32_t lcid_); void stop(); emm_state_t get_state(); @@ -83,6 +84,7 @@ private: rrc_interface_nas *rrc; usim_interface_nas *usim; gw_interface_nas *gw; + uint32_t default_lcid; emm_state_t state; diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index a36fdacc0..c758622fb 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -144,6 +144,23 @@ private: void write_pdu_bcch_dlsch(byte_buffer_t *pdu); void write_pdu_pcch(byte_buffer_t *pdu); + // Radio bearers + typedef enum{ + RB_ID_SRB0 = 0, + RB_ID_SRB1, + RB_ID_SRB2, + RB_ID_DRB1, + RB_ID_DRB2, + RB_ID_DRB3, + RB_ID_DRB4, + RB_ID_DRB5, + RB_ID_DRB6, + RB_ID_DRB7, + RB_ID_DRB8 + } rb_id_t; + std::map bearers; + std::string get_rb_name(uint32_t lcid) { return bearers.at(lcid); } + // RLC interface void max_retx_attempted(); @@ -185,6 +202,7 @@ private: void set_phy_default(); void set_mac_default(); void set_rrc_default(); + void set_bearers(); }; diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index dea1c3751..0110a1a14 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -161,14 +161,15 @@ bool ue::init(all_args_t *args_) phy_log.console("Setting frequency: DL=%.1f Mhz, UL=%.1f MHz\n", args->rf.dl_freq/1e6, args->rf.ul_freq/1e6); mac.init(&phy, &rlc, &rrc, &mac_log); - rlc.init(&pdcp, &rrc, this, &rlc_log, &mac); - pdcp.init(&rlc, &rrc, &gw, &pdcp_log, SECURITY_DIRECTION_UPLINK); + rlc.init(&pdcp, &rrc, this, &rlc_log, &mac, 0 /* RB_ID_SRB0 */); + + pdcp.init(&rlc, &rrc, &gw, &pdcp_log, 0 /* RB_ID_SRB0 */, SECURITY_DIRECTION_UPLINK); + rrc.init(&phy, &mac, &rlc, &pdcp, &nas, &usim, &mac, &rrc_log); - rrc.set_ue_category(atoi(args->expert.ue_cateogry.c_str())); - nas.init(&usim, &rrc, &gw, &nas_log); - gw.init(&pdcp, &rrc, this, &gw_log); + nas.init(&usim, &rrc, &gw, &nas_log, 1 /* RB_ID_SRB1 */); + gw.init(&pdcp, &rrc, this, &gw_log, 3 /* RB_ID_DRB1 */); usim.init(&args->usim, &usim_log); started = true; diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 15dc154ae..440ac77e4 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -43,13 +43,15 @@ nas::nas() void nas::init(usim_interface_nas *usim_, rrc_interface_nas *rrc_, gw_interface_nas *gw_, - srslte::log *nas_log_) + srslte::log *nas_log_, + uint32_t lcid_) { pool = byte_buffer_pool::get_instance(); usim = usim_; rrc = rrc_; gw = gw_; nas_log = nas_log_; + default_lcid = lcid_; } void nas::stop() @@ -85,7 +87,7 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) uint8 pd; uint8 msg_type; - nas_log->info_hex(pdu->msg, pdu->N_bytes, "DL %s PDU", rb_id_text[lcid]); + nas_log->info_hex(pdu->msg, pdu->N_bytes, "DL %s PDU", rrc->get_rb_name(lcid).c_str()); // Parse the message liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)pdu, &pd, &msg_type); @@ -492,8 +494,8 @@ void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu) pdu->N_bytes-5, &pdu->msg[1]); nas_log->info("Sending Security Mode Complete nas_count_ul=%d, RB=%s\n", - count_ul, - rb_id_text[lcid]); + count_ul, + rrc->get_rb_name(lcid).c_str()); success = true; } } @@ -572,7 +574,7 @@ void nas::send_attach_request() liblte_mme_pack_attach_request_msg(&attach_req, (LIBLTE_BYTE_MSG_STRUCT*)msg); nas_log->info("Sending attach request\n"); - rrc->write_sdu(RB_ID_SRB1, msg); + rrc->write_sdu(default_lcid, msg); } void nas::gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg) @@ -614,7 +616,7 @@ void nas::send_service_request() uint8_t mac[4]; integrity_generate(&k_nas_int[16], count_ul, - RB_ID_SRB1-1, + default_lcid-1, SECURITY_DIRECTION_UPLINK, &msg->msg[0], 2, @@ -625,7 +627,7 @@ void nas::send_service_request() msg->msg[3] = mac[3]; msg->N_bytes++; nas_log->info("Sending service request\n"); - rrc->write_sdu(RB_ID_SRB1, msg); + rrc->write_sdu(default_lcid, msg); } void nas::send_esm_information_response(){} diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 144d98711..0d0bf636c 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -32,6 +32,7 @@ #include "srslte/phy/utils/bit.h" #include "srslte/common/security.h" #include "srslte/common/bcd_helpers.h" +#include "boost/assign.hpp" #define TIMEOUT_RESYNC_REESTABLISH 100 @@ -42,7 +43,9 @@ namespace srsue{ rrc::rrc() :state(RRC_STATE_IDLE) ,drb_up(false) -{} +{ + set_bearers(); +} static void liblte_rrc_handler(void *ctx, char *str) { rrc *r = (rrc*) ctx; @@ -116,7 +119,7 @@ void rrc::set_ue_category(int category) void rrc::write_sdu(uint32_t lcid, byte_buffer_t *sdu) { - rrc_log->info_hex(sdu->msg, sdu->N_bytes, "RX %s SDU", rb_id_text[lcid]); + rrc_log->info_hex(sdu->msg, sdu->N_bytes, "RX %s SDU", bearers.at(lcid)); switch(state) { @@ -227,7 +230,7 @@ bool rrc::have_drb() void rrc::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { - rrc_log->info_hex(pdu->msg, pdu->N_bytes, "TX %s PDU", rb_id_text[lcid]); + rrc_log->info_hex(pdu->msg, pdu->N_bytes, "TX %s PDU", bearers.at(lcid)); rrc_log->info("TX PDU Stack latency: %ld us\n", pdu->get_latency_us()); switch(lcid) @@ -793,7 +796,7 @@ void rrc::parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu) liblte_rrc_unpack_dl_dcch_msg((LIBLTE_BIT_MSG_STRUCT*)&bit_buf, &dl_dcch_msg); rrc_log->info("%s - Received %s\n", - rb_id_text[lcid], + bearers.at(lcid), liblte_rrc_dl_dcch_msg_type_text[dl_dcch_msg.msg_type]); // Reset and reuse pdu buffer if possible @@ -1326,9 +1329,10 @@ void rrc::handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGU void rrc::add_srb(LIBLTE_RRC_SRB_TO_ADD_MOD_STRUCT *srb_cnfg) { // Setup PDCP - pdcp->add_bearer(srb_cnfg->srb_id); - if(RB_ID_SRB2 == srb_cnfg->srb_id) + pdcp->add_bearer(srb_cnfg->srb_id, srslte_pdcp_config_t(true)); // Set PDCP config control flag + if(RB_ID_SRB2 == srb_cnfg->srb_id) { pdcp->config_security(srb_cnfg->srb_id, k_rrc_enc, k_rrc_int, cipher_algo, integ_algo); + } // Setup RLC if(srb_cnfg->rlc_cnfg_present) @@ -1372,7 +1376,7 @@ void rrc::add_srb(LIBLTE_RRC_SRB_TO_ADD_MOD_STRUCT *srb_cnfg) } srbs[srb_cnfg->srb_id] = *srb_cnfg; - rrc_log->info("Added radio bearer %s\n", rb_id_text[srb_cnfg->srb_id]); + rrc_log->info("Added radio bearer %s\n", bearers.at(srb_cnfg->srb_id)); } void rrc::add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg) @@ -1394,7 +1398,14 @@ void rrc::add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg) } // Setup PDCP - pdcp->add_bearer(lcid, &drb_cnfg->pdcp_cnfg); + srslte_pdcp_config_t pdcp_cfg; + pdcp_cfg.is_data = true; + if (drb_cnfg->pdcp_cnfg.rlc_um_pdcp_sn_size_present) { + if (LIBLTE_RRC_PDCP_SN_SIZE_7_BITS == drb_cnfg->pdcp_cnfg.rlc_um_pdcp_sn_size) { + pdcp_cfg.sn_len = 7; + } + } + pdcp->add_bearer(lcid, pdcp_cfg); // TODO: setup PDCP security (using k_up_enc) // Setup RLC @@ -1426,7 +1437,7 @@ void rrc::add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg) drbs[lcid] = *drb_cnfg; drb_up = true; - rrc_log->info("Added radio bearer %s\n", rb_id_text[lcid]); + rrc_log->info("Added radio bearer %s\n", bearers.at(lcid)); } void rrc::release_drb(uint8_t lcid) @@ -1486,4 +1497,19 @@ void rrc::set_rrc_default() { mac_timers->get(safe_reset_timer)->set(this, 10); } +void rrc::set_bearers() +{ + boost::assign::insert(bearers) (RB_ID_SRB0, "SRB0") + (RB_ID_SRB1, "SRB1") + (RB_ID_SRB2, "SRB2") + (RB_ID_DRB1, "DRB1") + (RB_ID_DRB2, "DRB2") + (RB_ID_DRB3, "DRB3") + (RB_ID_DRB4, "DRB4") + (RB_ID_DRB5, "DRB5") + (RB_ID_DRB6, "DRB6") + (RB_ID_DRB7, "DRB7") + (RB_ID_DRB8, "DRB8"); +} + } // namespace srsue diff --git a/srsue/test/upper/ip_test.cc b/srsue/test/upper/ip_test.cc index 93021cd2b..afed88ebc 100644 --- a/srsue/test/upper/ip_test.cc +++ b/srsue/test/upper/ip_test.cc @@ -269,6 +269,7 @@ public: } void write_pdu_pcch(srslte::byte_buffer_t *sdu) {} void max_retx_attempted(){} + std::string get_rb_name(uint32_t lcid) { return std::string("rb"); } void in_sync() {}; void out_of_sync() {}; @@ -543,7 +544,7 @@ int main(int argc, char *argv[]) my_phy.init(&my_radio, &my_mac, &my_tester, &log_phy, NULL); my_mac.init(&my_phy, &rlc, &my_tester, &log_mac); - rlc.init(&my_tester, &my_tester, &my_tester, &log_rlc, &my_mac); + rlc.init(&my_tester, &my_tester, &my_tester, &log_rlc, &my_mac, 0 /* SRB0 */); my_tester.init(&my_phy, &my_mac, &rlc, &log_tester, prog_args.ip_address); From 4bc7b19595f24dcbde923743d7cff13181c439c5 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 28 Jun 2017 17:10:19 +0200 Subject: [PATCH 14/19] only call PHR procedure in MUX when it's registered --- srsue/src/mac/mux.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/srsue/src/mac/mux.cc b/srsue/src/mac/mux.cc index 38a71649a..f81bcdfd2 100644 --- a/srsue/src/mac/mux.cc +++ b/srsue/src/mac/mux.cc @@ -189,13 +189,17 @@ uint8_t* mux::pdu_get(uint8_t *payload, uint32_t pdu_sz, uint32_t tx_tti, uint32 bsr_is_inserted = true; } } + // MAC control element for PHR - float phr_value; - if (phr_procedure->generate_phr_on_ul_grant(&phr_value)) { - if (pdu_msg.new_subh()) { - pdu_msg.get()->set_phr(phr_value); + if (phr_procedure) { + float phr_value; + if (phr_procedure->generate_phr_on_ul_grant(&phr_value)) { + if (pdu_msg.new_subh()) { + pdu_msg.get()->set_phr(phr_value); + } } } + // Update buffer states for all logical channels int sdu_space = pdu_msg.get_sdu_space(); for (uint32_t i=0;i Date: Wed, 28 Jun 2017 17:11:47 +0200 Subject: [PATCH 15/19] make number of HARQ processes a parameter for mux/demux objects --- srsue/hdr/mac/demux.h | 4 ++-- srsue/hdr/mac/mux.h | 8 +++----- srsue/src/mac/demux.cc | 10 +++++----- srsue/src/mac/mac.cc | 4 +++- srsue/src/mac/mux.cc | 6 +++--- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/srsue/hdr/mac/demux.h b/srsue/hdr/mac/demux.h index 8c9fb3a02..2f38a4dfc 100644 --- a/srsue/hdr/mac/demux.h +++ b/srsue/hdr/mac/demux.h @@ -41,7 +41,7 @@ namespace srsue { class demux : public srslte::pdu_queue::process_callback { public: - demux(); + demux(uint8_t nof_harq_proc_); void init(phy_interface_mac_common* phy_h_, rlc_interface_mac *rlc, srslte::log* log_h_, srslte::timers* timers_db_); bool process_pdus(); @@ -57,7 +57,6 @@ public: void process_pdu(uint8_t *pdu, uint32_t nof_bytes, uint32_t tstamp); private: - const static int NOF_HARQ_PID = 8; const static int MAX_PDU_LEN = 150*1024/8; // ~ 150 Mbps const static int NOF_BUFFER_PDUS = 64; // Number of PDU buffers per HARQ pid uint8_t bcch_buffer[1024]; // BCCH PID has a dedicated buffer @@ -77,6 +76,7 @@ private: srslte::log *log_h; srslte::timers *timers_db; rlc_interface_mac *rlc; + uint8_t nof_harq_proc; // Buffer of PDUs srslte::pdu_queue pdus; diff --git a/srsue/hdr/mac/mux.h b/srsue/hdr/mac/mux.h index b33cf0d19..1167af752 100644 --- a/srsue/hdr/mac/mux.h +++ b/srsue/hdr/mac/mux.h @@ -55,7 +55,7 @@ namespace srsue { class mux { public: - mux(); + mux(uint8_t nof_harq_proc_); void reset(); void init(rlc_interface_mac *rlc, srslte::log *log_h, bsr_interface_mux *bsr_procedure, phr_proc *phr_procedure_); @@ -87,7 +87,7 @@ private: std::vector lch; // Keep track of the PIDs that transmitted BSR reports - bool pid_has_bsr[MAX_HARQ_PROC]; + std::vector pid_has_bsr; // Mutex for exclusive access pthread_mutex_t mutex; @@ -97,6 +97,7 @@ private: bsr_interface_mux *bsr_procedure; phr_proc *phr_procedure; uint16_t pending_crnti_ce; + uint8_t nof_harq_proc; /* Msg3 Buffer */ static const uint32_t MSG3_BUFF_SZ = 128; @@ -105,9 +106,6 @@ private: /* PDU Buffer */ srslte::sch_pdu pdu_msg; bool msg3_has_been_transmitted; - - - }; } // namespace srsue diff --git a/srsue/src/mac/demux.cc b/srsue/src/mac/demux.cc index 227bcc364..4fcb402fc 100644 --- a/srsue/src/mac/demux.cc +++ b/srsue/src/mac/demux.cc @@ -36,7 +36,7 @@ namespace srsue { -demux::demux() : mac_msg(20), pending_mac_msg(20) +demux::demux(uint8_t nof_harq_proc_) : mac_msg(20), pending_mac_msg(20), nof_harq_proc(nof_harq_proc_) { } @@ -68,9 +68,9 @@ void demux::deallocate(uint8_t* payload_buffer_ptr) uint8_t* demux::request_buffer(uint32_t pid, uint32_t len) { uint8_t *buff = NULL; - if (pid < NOF_HARQ_PID) { + if (pid < nof_harq_proc) { return pdus.request(len); - } else if (pid == NOF_HARQ_PID) { + } else if (pid == nof_harq_proc) { buff = bcch_buffer; } else { Error("Requested buffer for invalid PID=%d\n", pid); @@ -119,9 +119,9 @@ void demux::push_pdu_temp_crnti(uint8_t *buff, uint32_t nof_bytes) */ void demux::push_pdu(uint32_t pid, uint8_t *buff, uint32_t nof_bytes, uint32_t tstamp) { - if (pid < NOF_HARQ_PID) { + if (pid < nof_harq_proc) { return pdus.push(buff, nof_bytes, tstamp); - } else if (pid == NOF_HARQ_PID) { + } else if (pid == nof_harq_proc) { /* Demultiplexing of MAC PDU associated with SI-RNTI. The PDU passes through * the MAC in transparent mode. * Warning: In this case function sends the message to RLC now, since SI blocks do not diff --git a/srsue/src/mac/mac.cc b/srsue/src/mac/mac.cc index 9fe08166f..e1426780e 100644 --- a/srsue/src/mac/mac.cc +++ b/srsue/src/mac/mac.cc @@ -42,7 +42,9 @@ namespace srsue { mac::mac() : ttisync(10240), - timers_db((uint32_t) NOF_MAC_TIMERS), + timers_db((uint32_t) NOF_MAC_TIMERS), + mux_unit(MAC_NOF_HARQ_PROC), + demux_unit(MAC_NOF_HARQ_PROC), pdu_process_thread(&demux_unit) { started = false; diff --git a/srsue/src/mac/mux.cc b/srsue/src/mac/mux.cc index f81bcdfd2..5ab58fb50 100644 --- a/srsue/src/mac/mux.cc +++ b/srsue/src/mac/mux.cc @@ -37,7 +37,7 @@ namespace srsue { -mux::mux() : pdu_msg(MAX_NOF_SUBHEADERS) +mux::mux(uint8_t nof_harq_proc_) : pdu_msg(MAX_NOF_SUBHEADERS), pid_has_bsr(nof_harq_proc_), nof_harq_proc(nof_harq_proc_) { pthread_mutex_init(&mutex, NULL); @@ -141,7 +141,7 @@ srslte::sch_subh::cetype bsr_format_convert(bsr_proc::bsr_format_t format) { void mux::pusch_retx(uint32_t tx_tti, uint32_t pid) { - if (pid_has_bsr[pid%MAX_HARQ_PROC]) { + if (pid_has_bsr[pid%nof_harq_proc]) { bsr_procedure->set_tx_tti(tx_tti); } } @@ -256,7 +256,7 @@ uint8_t* mux::pdu_get(uint8_t *payload, uint32_t pdu_sz, uint32_t tx_tti, uint32 /* Generate MAC PDU and save to buffer */ uint8_t *ret = pdu_msg.write_packet(log_h); - pid_has_bsr[pid%MAX_HARQ_PROC] = bsr_is_inserted; + pid_has_bsr[pid%nof_harq_proc] = bsr_is_inserted; if (bsr_is_inserted) { bsr_procedure->set_tx_tti(tx_tti); } From 7ca0988ea363cec4e0f6117d3248cedc316f3034 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 4 Jul 2017 16:29:33 +0200 Subject: [PATCH 16/19] refactor RLC to use RAT-agnostic config --- .../srslte/interfaces/enb_interfaces.h | 3 +- lib/include/srslte/interfaces/ue_interfaces.h | 3 +- lib/include/srslte/upper/rlc.h | 3 +- lib/include/srslte/upper/rlc_am.h | 12 +- lib/include/srslte/upper/rlc_common.h | 12 +- lib/include/srslte/upper/rlc_entity.h | 2 +- lib/include/srslte/upper/rlc_interface.h | 126 ++++++++++++++++++ lib/include/srslte/upper/rlc_tm.h | 2 +- lib/include/srslte/upper/rlc_um.h | 9 +- lib/src/upper/rlc.cc | 13 +- lib/src/upper/rlc_am.cc | 33 ++--- lib/src/upper/rlc_entity.cc | 2 +- lib/src/upper/rlc_tm.cc | 2 +- lib/src/upper/rlc_um.cc | 63 ++++----- lib/test/upper/rlc_am_test.cc | 10 ++ srsenb/hdr/upper/rlc.h | 2 +- srsenb/src/upper/rlc.cc | 2 +- srsue/src/upper/rrc.cc | 4 +- 18 files changed, 201 insertions(+), 102 deletions(-) create mode 100644 lib/include/srslte/upper/rlc_interface.h diff --git a/lib/include/srslte/interfaces/enb_interfaces.h b/lib/include/srslte/interfaces/enb_interfaces.h index 8806ded58..5ba0213c1 100644 --- a/lib/include/srslte/interfaces/enb_interfaces.h +++ b/lib/include/srslte/interfaces/enb_interfaces.h @@ -29,6 +29,7 @@ #include "srslte/common/common.h" #include "srslte/common/security.h" #include "srslte/interfaces/sched_interface.h" +#include "srslte/upper/rlc_interface.h" #include "srslte/asn1/liblte_rrc.h" #include "srslte/asn1/liblte_s1ap.h" @@ -156,7 +157,7 @@ public: virtual void add_user(uint16_t rnti) = 0; virtual void rem_user(uint16_t rnti) = 0; virtual void add_bearer(uint16_t rnti, uint32_t lcid) = 0; - virtual void add_bearer(uint16_t rnti, uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) = 0; + virtual void add_bearer(uint16_t rnti, uint32_t lcid, srslte::srslte_rlc_config_t cnfg) = 0; }; // PDCP interface for GTPU diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index ca9b4540b..81ed67b74 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -39,6 +39,7 @@ #include "srslte/common/interfaces_common.h" #include "srslte/common/common.h" #include "srslte/common/security.h" +#include "srslte/upper/rlc_interface.h" namespace srsue { @@ -201,7 +202,7 @@ class rlc_interface_rrc public: virtual void reset() = 0; virtual void add_bearer(uint32_t lcid) = 0; - virtual void add_bearer(uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) = 0; + virtual void add_bearer(uint32_t lcid, srslte::srslte_rlc_config_t cnfg) = 0; }; // RLC interface for PDCP diff --git a/lib/include/srslte/upper/rlc.h b/lib/include/srslte/upper/rlc.h index 4a95f1a46..11ce507d5 100644 --- a/lib/include/srslte/upper/rlc.h +++ b/lib/include/srslte/upper/rlc.h @@ -34,6 +34,7 @@ #include "srslte/common/msg_queue.h" #include "srslte/upper/rlc_entity.h" #include "srslte/upper/rlc_metrics.h" +#include "srslte/upper/rlc_common.h" namespace srslte { @@ -77,7 +78,7 @@ public: // RRC interface void reset(); void add_bearer(uint32_t lcid); - void add_bearer(uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg); + void add_bearer(uint32_t lcid, srslte_rlc_config_t cnfg); private: void reset_metrics(); diff --git a/lib/include/srslte/upper/rlc_am.h b/lib/include/srslte/upper/rlc_am.h index 5fcf31c94..a92c9a0ad 100644 --- a/lib/include/srslte/upper/rlc_am.h +++ b/lib/include/srslte/upper/rlc_am.h @@ -76,7 +76,7 @@ public: srsue::pdcp_interface_rlc *pdcp_, srsue::rrc_interface_rlc *rrc_, mac_interface_timers *mac_timers); - void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg); + void configure(srslte_rlc_config_t cnfg); void reset(); void empty_queue(); @@ -128,15 +128,7 @@ private: * Ref: 3GPP TS 36.322 v10.0.0 Section 7 ***************************************************************************/ - // TX configs - int32_t t_poll_retx; // Poll retx timeout (ms) - int32_t poll_pdu; // Insert poll bit after this many PDUs - int32_t poll_byte; // Insert poll bit after this much data (KB) - uint32_t max_retx_thresh; // Max number of retx - - // RX configs - int32_t t_reordering; // Timer used by rx to detect PDU loss (ms) - int32_t t_status_prohibit; // Timer used by rx to prohibit tx of status PDU (ms) + srslte_rlc_am_config_t cfg; /**************************************************************************** * State variables and counters diff --git a/lib/include/srslte/upper/rlc_common.h b/lib/include/srslte/upper/rlc_common.h index 0c545b60f..c68e3e6f3 100644 --- a/lib/include/srslte/upper/rlc_common.h +++ b/lib/include/srslte/upper/rlc_common.h @@ -27,6 +27,8 @@ #ifndef RLC_COMMON_H #define RLC_COMMON_H +#include "srslte/upper/rlc_interface.h" + namespace srslte { /**************************************************************************** @@ -66,14 +68,6 @@ typedef enum{ static const char rlc_dc_field_text[RLC_DC_FIELD_N_ITEMS][20] = {"Control PDU", "Data PDU"}; -typedef enum{ - RLC_UMD_SN_SIZE_5_BITS = 0, - RLC_UMD_SN_SIZE_10_BITS, - RLC_UMD_SN_SIZE_N_ITEMS, -}rlc_umd_sn_size_t; -static const char rlc_umd_sn_size_text[RLC_UMD_SN_SIZE_N_ITEMS][20] = {"5 bits", "10 bits"}; -static const uint16_t rlc_umd_sn_size_num[RLC_UMD_SN_SIZE_N_ITEMS] = {5, 10}; - // UMD PDU Header typedef struct{ uint8_t fi; // Framing info @@ -162,7 +156,7 @@ public: srsue::pdcp_interface_rlc *pdcp_, srsue::rrc_interface_rlc *rrc_, srslte::mac_interface_timers *mac_timers_) = 0; - virtual void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) = 0; + virtual void configure(srslte_rlc_config_t cnfg) = 0; virtual void reset() = 0; virtual void empty_queue() = 0; diff --git a/lib/include/srslte/upper/rlc_entity.h b/lib/include/srslte/upper/rlc_entity.h index cf09c19d2..3747f9410 100644 --- a/lib/include/srslte/upper/rlc_entity.h +++ b/lib/include/srslte/upper/rlc_entity.h @@ -54,7 +54,7 @@ public: srsue::rrc_interface_rlc *rrc_, mac_interface_timers *mac_timers_); - void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg); + void configure(srslte_rlc_config_t cnfg); void reset(); bool active(); diff --git a/lib/include/srslte/upper/rlc_interface.h b/lib/include/srslte/upper/rlc_interface.h new file mode 100644 index 000000000..feddac1cc --- /dev/null +++ b/lib/include/srslte/upper/rlc_interface.h @@ -0,0 +1,126 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of the srsUE library. + * + * srsUE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsUE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +#ifndef RLC_INTERFACE_H +#define RLC_INTERFACE_H + +// for custom constructors +#include "srslte/asn1/liblte_rrc.h" + +namespace srslte { + + +typedef enum{ + RLC_UMD_SN_SIZE_5_BITS = 0, + RLC_UMD_SN_SIZE_10_BITS, + RLC_UMD_SN_SIZE_N_ITEMS, +}rlc_umd_sn_size_t; +static const char rlc_umd_sn_size_text[RLC_UMD_SN_SIZE_N_ITEMS][20] = {"5 bits", "10 bits"}; +static const uint16_t rlc_umd_sn_size_num[RLC_UMD_SN_SIZE_N_ITEMS] = {5, 10}; + + +typedef struct { + /**************************************************************************** + * Configurable parameters + * Ref: 3GPP TS 36.322 v10.0.0 Section 7 + ***************************************************************************/ + + // TX configs + int32_t t_poll_retx; // Poll retx timeout (ms) + int32_t poll_pdu; // Insert poll bit after this many PDUs + int32_t poll_byte; // Insert poll bit after this much data (KB) + uint32_t max_retx_thresh; // Max number of retx + + // RX configs + int32_t t_reordering; // Timer used by rx to detect PDU loss (ms) + int32_t t_status_prohibit; // Timer used by rx to prohibit tx of status PDU (ms) +} srslte_rlc_am_config_t; + + +typedef struct { + /**************************************************************************** + * Configurable parameters + * Ref: 3GPP TS 36.322 v10.0.0 Section 7 + ***************************************************************************/ + + int32_t t_reordering; // Timer used by rx to detect PDU loss (ms) + rlc_umd_sn_size_t tx_sn_field_length; // Number of bits used for tx (UL) sequence number + rlc_umd_sn_size_t rx_sn_field_length; // Number of bits used for rx (DL) sequence number + + uint32_t rx_window_size; + uint32_t rx_mod; // Rx counter modulus + uint32_t tx_mod; // Tx counter modulus +} srslte_rlc_um_config_t; + + +class srslte_rlc_config_t +{ +public: + LIBLTE_RRC_RLC_MODE_ENUM rlc_mode; + srslte_rlc_am_config_t am; + srslte_rlc_um_config_t um; + + // Constructor based on liblte's RLC config + srslte_rlc_config_t(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) : rlc_mode(cnfg->rlc_mode), am(), um() + { + switch(rlc_mode) + { + case LIBLTE_RRC_RLC_MODE_AM: + am.t_poll_retx = liblte_rrc_t_poll_retransmit_num[cnfg->ul_am_rlc.t_poll_retx]; + am.poll_pdu = liblte_rrc_poll_pdu_num[cnfg->ul_am_rlc.poll_pdu]; + am.poll_byte = liblte_rrc_poll_byte_num[cnfg->ul_am_rlc.poll_byte]*1000; // KB + am.max_retx_thresh = liblte_rrc_max_retx_threshold_num[cnfg->ul_am_rlc.max_retx_thresh]; + am.t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_am_rlc.t_reordering]; + am.t_status_prohibit = liblte_rrc_t_status_prohibit_num[cnfg->dl_am_rlc.t_status_prohibit]; + break; + case LIBLTE_RRC_RLC_MODE_UM_BI: + um.t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_um_bi_rlc.t_reordering]; + um.rx_sn_field_length = (rlc_umd_sn_size_t)cnfg->dl_um_bi_rlc.sn_field_len; + um.rx_window_size = (RLC_UMD_SN_SIZE_5_BITS == um.rx_sn_field_length) ? 16 : 512; + um.rx_mod = (RLC_UMD_SN_SIZE_5_BITS == um.rx_sn_field_length) ? 32 : 1024; + um.tx_sn_field_length = (rlc_umd_sn_size_t)cnfg->ul_um_bi_rlc.sn_field_len; + um.tx_mod = (RLC_UMD_SN_SIZE_5_BITS == um.tx_sn_field_length) ? 32 : 1024; + break; + case LIBLTE_RRC_RLC_MODE_UM_UNI_UL: + um.tx_sn_field_length = (rlc_umd_sn_size_t)cnfg->ul_um_uni_rlc.sn_field_len; + um.tx_mod = (RLC_UMD_SN_SIZE_5_BITS == um.tx_sn_field_length) ? 32 : 1024; + break; + case LIBLTE_RRC_RLC_MODE_UM_UNI_DL: + um.t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_um_uni_rlc.t_reordering]; + um.rx_sn_field_length = (rlc_umd_sn_size_t)cnfg->dl_um_uni_rlc.sn_field_len; + um.rx_window_size = (RLC_UMD_SN_SIZE_5_BITS == um.rx_sn_field_length) ? 16 : 512; + um.rx_mod = (RLC_UMD_SN_SIZE_5_BITS == um.rx_sn_field_length) ? 32 : 1024; + break; + default: + // Handle default case + break; + } + } +}; + +} // namespace srslte + +#endif // RLC_INTERFACE_H diff --git a/lib/include/srslte/upper/rlc_tm.h b/lib/include/srslte/upper/rlc_tm.h index d8034cd38..def968a92 100644 --- a/lib/include/srslte/upper/rlc_tm.h +++ b/lib/include/srslte/upper/rlc_tm.h @@ -46,7 +46,7 @@ public: srsue::pdcp_interface_rlc *pdcp_, srsue::rrc_interface_rlc *rrc_, mac_interface_timers *mac_timers); - void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg); + void configure(srslte_rlc_config_t cnfg); void reset(); void empty_queue(); diff --git a/lib/include/srslte/upper/rlc_um.h b/lib/include/srslte/upper/rlc_um.h index 8e95dcb71..4325bd029 100644 --- a/lib/include/srslte/upper/rlc_um.h +++ b/lib/include/srslte/upper/rlc_um.h @@ -56,7 +56,7 @@ public: srsue::pdcp_interface_rlc *pdcp_, srsue::rrc_interface_rlc *rrc_, mac_interface_timers *mac_timers_); - void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg); + void configure(srslte_rlc_config_t cnfg); void reset(); void empty_queue(); @@ -92,9 +92,6 @@ private: // Rx window std::map rx_window; - uint32_t rx_window_size; - uint32_t rx_mod; // Rx counter modulus - uint32_t tx_mod; // Tx counter modulus // RX SDU buffers byte_buffer_t *rx_sdu; @@ -108,9 +105,7 @@ private: * Ref: 3GPP TS 36.322 v10.0.0 Section 7 ***************************************************************************/ - int32_t t_reordering; // Timer used by rx to detect PDU loss (ms) - rlc_umd_sn_size_t tx_sn_field_length; // Number of bits used for tx (UL) sequence number - rlc_umd_sn_size_t rx_sn_field_length; // Number of bits used for rx (DL) sequence number + srslte_rlc_um_config_t cfg; /**************************************************************************** * State variables and counters diff --git a/lib/src/upper/rlc.cc b/lib/src/upper/rlc.cc index c840de10d..378b539b9 100644 --- a/lib/src/upper/rlc.cc +++ b/lib/src/upper/rlc.cc @@ -194,10 +194,10 @@ void rlc::write_pdu_pcch(uint8_t *payload, uint32_t nof_bytes) void rlc::add_bearer(uint32_t lcid) { // No config provided - use defaults for lcid - LIBLTE_RRC_RLC_CONFIG_STRUCT cnfg; if(default_lcid == lcid || (default_lcid+1) == lcid) { if (!rlc_array[lcid].active()) { + LIBLTE_RRC_RLC_CONFIG_STRUCT cnfg; cnfg.rlc_mode = LIBLTE_RRC_RLC_MODE_AM; cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS45; cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_INFINITY; @@ -205,7 +205,7 @@ void rlc::add_bearer(uint32_t lcid) cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4; cnfg.dl_am_rlc.t_reordering = LIBLTE_RRC_T_REORDERING_MS35; cnfg.dl_am_rlc.t_status_prohibit = LIBLTE_RRC_T_STATUS_PROHIBIT_MS0; - add_bearer(lcid, &cnfg); + add_bearer(lcid, srslte_rlc_config_t(&cnfg)); } else { rlc_log->warning("Bearer %s already configured. Reconfiguration not supported\n", get_rb_name(lcid).c_str()); } @@ -215,18 +215,17 @@ void rlc::add_bearer(uint32_t lcid) } } -void rlc::add_bearer(uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) +void rlc::add_bearer(uint32_t lcid, srslte_rlc_config_t cnfg) { if(lcid < 0 || lcid >= SRSLTE_N_RADIO_BEARERS) { rlc_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid); return; } - - + if (!rlc_array[lcid].active()) { rlc_log->info("Adding radio bearer %s with mode %s\n", - get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg->rlc_mode]); - switch(cnfg->rlc_mode) + get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg.rlc_mode]); + switch(cnfg.rlc_mode) { case LIBLTE_RRC_RLC_MODE_AM: rlc_array[lcid].init(RLC_MODE_AM, rlc_log, lcid, pdcp, rrc, mac_timers); diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index d25b2d2ef..f0055a534 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -74,20 +74,13 @@ void rlc_am::init(srslte::log *log_, rrc = rrc_; } -void rlc_am::configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) +void rlc_am::configure(srslte_rlc_config_t cfg_) { - t_poll_retx = liblte_rrc_t_poll_retransmit_num[cnfg->ul_am_rlc.t_poll_retx]; - poll_pdu = liblte_rrc_poll_pdu_num[cnfg->ul_am_rlc.poll_pdu]; - poll_byte = liblte_rrc_poll_byte_num[cnfg->ul_am_rlc.poll_byte]*1000; // KB - max_retx_thresh = liblte_rrc_max_retx_threshold_num[cnfg->ul_am_rlc.max_retx_thresh]; - - t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_am_rlc.t_reordering]; - t_status_prohibit = liblte_rrc_t_status_prohibit_num[cnfg->dl_am_rlc.t_status_prohibit]; - + cfg = cfg_.am; log->info("%s configured: t_poll_retx=%d, poll_pdu=%d, poll_byte=%d, max_retx_thresh=%d, " "t_reordering=%d, t_status_prohibit=%d\n", - rrc->get_rb_name(lcid).c_str(), t_poll_retx, poll_pdu, poll_byte, max_retx_thresh, - t_reordering, t_status_prohibit); + rrc->get_rb_name(lcid).c_str(), cfg.t_poll_retx, cfg.poll_pdu, cfg.poll_byte, cfg.max_retx_thresh, + cfg.t_reordering, cfg.t_status_prohibit); } @@ -362,7 +355,7 @@ void rlc_am::check_reordering_timeout() if(RX_MOD_BASE(vr_h) > RX_MOD_BASE(vr_ms)) { - reordering_timeout.start(t_reordering); + reordering_timeout.start(cfg.t_reordering); vr_x = vr_h; } @@ -376,9 +369,9 @@ void rlc_am::check_reordering_timeout() bool rlc_am::poll_required() { - if(poll_pdu > 0 && pdu_without_poll > (uint32_t)poll_pdu) + if(cfg.poll_pdu > 0 && pdu_without_poll > (uint32_t)cfg.poll_pdu) return true; - if(poll_byte > 0 && byte_without_poll > (uint32_t)poll_byte) + if(cfg.poll_byte > 0 && byte_without_poll > (uint32_t)cfg.poll_byte) return true; if(poll_retx()) return true; @@ -414,8 +407,8 @@ int rlc_am::build_status_pdu(uint8_t *payload, uint32_t nof_bytes) do_status = false; poll_received = false; - if(t_status_prohibit > 0) - status_prohibit_timeout.start(t_status_prohibit); + if(cfg.t_status_prohibit > 0) + status_prohibit_timeout.start(cfg.t_status_prohibit); debug_state(); return rlc_am_write_status_pdu(&status, payload); }else{ @@ -450,7 +443,7 @@ int rlc_am::build_retx_pdu(uint8_t *payload, uint32_t nof_bytes) poll_sn = vt_s; pdu_without_poll = 0; byte_without_poll = 0; - poll_retx_timeout.start(t_poll_retx); + poll_retx_timeout.start(cfg.t_poll_retx); } uint8_t *ptr = payload; @@ -459,7 +452,7 @@ int rlc_am::build_retx_pdu(uint8_t *payload, uint32_t nof_bytes) retx_queue.pop_front(); tx_window[retx.sn].retx_count++; - if(tx_window[retx.sn].retx_count >= max_retx_thresh) + if(tx_window[retx.sn].retx_count >= cfg.max_retx_thresh) rrc->max_retx_attempted(); log->info("%s Retx PDU scheduled for tx. SN: %d, retx count: %d\n", rrc->get_rb_name(lcid).c_str(), retx.sn, tx_window[retx.sn].retx_count); @@ -701,7 +694,7 @@ int rlc_am::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) poll_sn = vt_s; pdu_without_poll = 0; byte_without_poll = 0; - poll_retx_timeout.start(t_poll_retx); + poll_retx_timeout.start(cfg.t_poll_retx); } // Set SN @@ -812,7 +805,7 @@ void rlc_am::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rlc_amd_pdu_h { if(RX_MOD_BASE(vr_h) > RX_MOD_BASE(vr_r)) { - reordering_timeout.start(t_reordering); + reordering_timeout.start(cfg.t_reordering); vr_x = vr_h; } } diff --git a/lib/src/upper/rlc_entity.cc b/lib/src/upper/rlc_entity.cc index ace991b10..541649897 100644 --- a/lib/src/upper/rlc_entity.cc +++ b/lib/src/upper/rlc_entity.cc @@ -64,7 +64,7 @@ void rlc_entity::init(rlc_mode_t mode, rlc->init(rlc_entity_log_, lcid_, pdcp_, rrc_, mac_timers_); } -void rlc_entity::configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) +void rlc_entity::configure(srslte_rlc_config_t cnfg) { if(rlc) rlc->configure(cnfg); diff --git a/lib/src/upper/rlc_tm.cc b/lib/src/upper/rlc_tm.cc index b97b78be7..9b7cd8f00 100644 --- a/lib/src/upper/rlc_tm.cc +++ b/lib/src/upper/rlc_tm.cc @@ -46,7 +46,7 @@ void rlc_tm::init(srslte::log *log_, rrc = rrc_; } -void rlc_tm::configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) +void rlc_tm::configure(srslte_rlc_config_t cnfg) { log->error("Attempted to configure TM RLC entity"); } diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 8724e0f28..133bca9a8 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -27,7 +27,7 @@ #include "srslte/upper/rlc_um.h" -#define RX_MOD_BASE(x) (x-vr_uh-rx_window_size)%rx_mod +#define RX_MOD_BASE(x) (x-vr_uh-cfg.rx_window_size)%cfg.rx_mod namespace srslte { @@ -65,41 +65,28 @@ void rlc_um::init(srslte::log *log_, reordering_timeout_id = mac_timers->get_unique_id(); } -void rlc_um::configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) +void rlc_um::configure(srslte_rlc_config_t cnfg_) { - switch(cnfg->rlc_mode) + cfg = cnfg_.um; + + switch(cnfg_.rlc_mode) { case LIBLTE_RRC_RLC_MODE_UM_BI: - t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_um_bi_rlc.t_reordering]; - rx_sn_field_length = (rlc_umd_sn_size_t)cnfg->dl_um_bi_rlc.sn_field_len; - rx_window_size = (RLC_UMD_SN_SIZE_5_BITS == rx_sn_field_length) ? 16 : 512; - rx_mod = (RLC_UMD_SN_SIZE_5_BITS == rx_sn_field_length) ? 32 : 1024; - tx_sn_field_length = (rlc_umd_sn_size_t)cnfg->ul_um_bi_rlc.sn_field_len; - tx_mod = (RLC_UMD_SN_SIZE_5_BITS == tx_sn_field_length) ? 32 : 1024; log->info("%s configured in %s mode: " "t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits\n", - rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg->rlc_mode], - t_reordering, - rlc_umd_sn_size_num[rx_sn_field_length], - rlc_umd_sn_size_num[tx_sn_field_length]); + rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode], + cfg.t_reordering, cfg.rx_sn_field_length, cfg.tx_sn_field_length); break; case LIBLTE_RRC_RLC_MODE_UM_UNI_UL: - tx_sn_field_length = (rlc_umd_sn_size_t)cnfg->ul_um_uni_rlc.sn_field_len; - tx_mod = (RLC_UMD_SN_SIZE_5_BITS == tx_sn_field_length) ? 32 : 1024; log->info("%s configured in %s mode: tx_sn_field_length=%u bits\n", - rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg->rlc_mode], - rlc_umd_sn_size_num[tx_sn_field_length]); + rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode], + cfg.tx_sn_field_length); break; case LIBLTE_RRC_RLC_MODE_UM_UNI_DL: - t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_um_uni_rlc.t_reordering]; - rx_sn_field_length = (rlc_umd_sn_size_t)cnfg->dl_um_uni_rlc.sn_field_len; - rx_window_size = (RLC_UMD_SN_SIZE_5_BITS == rx_sn_field_length) ? 16 : 512; - rx_mod = (RLC_UMD_SN_SIZE_5_BITS == rx_sn_field_length) ? 32 : 1024; log->info("%s configured in %s mode: " "t_reordering=%d ms, rx_sn_field_length=%u bits\n", - rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg->rlc_mode], - liblte_rrc_t_reordering_num[t_reordering], - rlc_umd_sn_size_num[rx_sn_field_length]); + rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode], + cfg.t_reordering, cfg.rx_sn_field_length); break; default: log->error("RLC configuration mode not recognized\n"); @@ -229,7 +216,7 @@ void rlc_um::timer_expired(uint32_t timeout_id) rx_sdu->reset(); while(RX_MOD_BASE(vr_ur) < RX_MOD_BASE(vr_ux)) { - vr_ur = (vr_ur + 1)%rx_mod; + vr_ur = (vr_ur + 1)%cfg.rx_mod; log->debug("Entering Reassemble from timeout id=%d\n", timeout_id); reassemble_rx_sdus(); log->debug("Finished reassemble from timeout id=%d\n", timeout_id); @@ -237,7 +224,7 @@ void rlc_um::timer_expired(uint32_t timeout_id) mac_timers->get(reordering_timeout_id)->stop(); if(RX_MOD_BASE(vr_uh) > RX_MOD_BASE(vr_ur)) { - mac_timers->get(reordering_timeout_id)->set(this, t_reordering); + mac_timers->get(reordering_timeout_id)->set(this, cfg.t_reordering); mac_timers->get(reordering_timeout_id)->run(); vr_ux = vr_uh; } @@ -274,7 +261,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) header.fi = RLC_FI_FIELD_START_AND_END_ALIGNED; header.sn = vt_us; header.N_li = 0; - header.sn_size = tx_sn_field_length; + header.sn_size = cfg.tx_sn_field_length; uint32_t to_move = 0; uint32_t last_li = 0; @@ -347,7 +334,7 @@ int rlc_um::build_data_pdu(uint8_t *payload, uint32_t nof_bytes) // Set SN header.sn = vt_us; - vt_us = (vt_us + 1)%tx_mod; + vt_us = (vt_us + 1)%cfg.tx_mod; // Add header and TX log->debug("%s packing PDU with length %d\n", rrc->get_rb_name(lcid).c_str(), pdu->N_bytes); @@ -365,12 +352,12 @@ void rlc_um::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes) { std::map::iterator it; rlc_umd_pdu_header_t header; - rlc_um_read_data_pdu_header(payload, nof_bytes, rx_sn_field_length, &header); + rlc_um_read_data_pdu_header(payload, nof_bytes, cfg.rx_sn_field_length, &header); log->info_hex(payload, nof_bytes, "RX %s Rx data PDU SN: %d", rrc->get_rb_name(lcid).c_str(), header.sn); - if(RX_MOD_BASE(header.sn) >= RX_MOD_BASE(vr_uh-rx_window_size) && + if(RX_MOD_BASE(header.sn) >= RX_MOD_BASE(vr_uh-cfg.rx_window_size) && RX_MOD_BASE(header.sn) < RX_MOD_BASE(vr_ur)) { log->info("%s SN: %d outside rx window [%d:%d] - discarding\n", @@ -403,7 +390,7 @@ void rlc_um::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes) // Update vr_uh if(!inside_reordering_window(header.sn)) - vr_uh = (header.sn + 1)%rx_mod; + vr_uh = (header.sn + 1)%cfg.rx_mod; // Reassemble and deliver SDUs, while updating vr_ur log->debug("Entering Reassemble from received PDU\n"); @@ -423,7 +410,7 @@ void rlc_um::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes) { if(RX_MOD_BASE(vr_uh) > RX_MOD_BASE(vr_ur)) { - mac_timers->get(reordering_timeout_id)->set(this, t_reordering); + mac_timers->get(reordering_timeout_id)->set(this, cfg.t_reordering); mac_timers->get(reordering_timeout_id)->run(); vr_ux = vr_uh; } @@ -452,7 +439,7 @@ void rlc_um::reassemble_rx_sdus() rx_sdu->N_bytes += len; rx_window[vr_ur].buf->msg += len; rx_window[vr_ur].buf->N_bytes -= len; - if((pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) || (vr_ur != ((vr_ur_in_rx_sdu+1)%rx_mod))) { + if((pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) || (vr_ur != ((vr_ur_in_rx_sdu+1)%cfg.rx_mod))) { log->warning("Dropping remainder of lost PDU (lower edge middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)\n", vr_ur, vr_ur_in_rx_sdu); rx_sdu->reset(); } else { @@ -489,7 +476,7 @@ void rlc_um::reassemble_rx_sdus() rx_window.erase(vr_ur); } - vr_ur = (vr_ur + 1)%rx_mod; + vr_ur = (vr_ur + 1)%cfg.rx_mod; } @@ -502,11 +489,11 @@ void rlc_um::reassemble_rx_sdus() int len = rx_window[vr_ur].header.li[i]; memcpy(&rx_sdu->msg[rx_sdu->N_bytes], rx_window[vr_ur].buf->msg, len); log->debug("Concatenating %d bytes in to current length %d. rx_window remaining bytes=%d, vr_ur_in_rx_sdu=%d, vr_ur=%d, rx_mod=%d, last_mod=%d\n", - len, rx_sdu->N_bytes, rx_window[vr_ur].buf->N_bytes, vr_ur_in_rx_sdu, vr_ur, rx_mod, (vr_ur_in_rx_sdu+1)%rx_mod); + len, rx_sdu->N_bytes, rx_window[vr_ur].buf->N_bytes, vr_ur_in_rx_sdu, vr_ur, cfg.rx_mod, (vr_ur_in_rx_sdu+1)%cfg.rx_mod); rx_sdu->N_bytes += len; rx_window[vr_ur].buf->msg += len; rx_window[vr_ur].buf->N_bytes -= len; - if((pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) || (vr_ur != ((vr_ur_in_rx_sdu+1)%rx_mod))) { + if((pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) || (vr_ur != ((vr_ur_in_rx_sdu+1)%cfg.rx_mod))) { log->warning("Dropping remainder of lost PDU (update vr_ur middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)\n", vr_ur, vr_ur_in_rx_sdu); rx_sdu->reset(); } else { @@ -542,13 +529,13 @@ void rlc_um::reassemble_rx_sdus() pool->deallocate(rx_window[vr_ur].buf); rx_window.erase(vr_ur); - vr_ur = (vr_ur + 1)%rx_mod; + vr_ur = (vr_ur + 1)%cfg.rx_mod; } } bool rlc_um::inside_reordering_window(uint16_t sn) { - if(RX_MOD_BASE(sn) >= RX_MOD_BASE(vr_uh-rx_window_size) && + if(RX_MOD_BASE(sn) >= RX_MOD_BASE(vr_uh-cfg.rx_window_size) && RX_MOD_BASE(sn) < RX_MOD_BASE(vr_uh)) { return true; diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index 261a66548..c7ab2aa74 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -102,6 +102,7 @@ void basic_test() cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4; cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25; cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4; + cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5; rlc1.configure(&cnfg); rlc2.configure(&cnfg); @@ -181,6 +182,7 @@ void concat_test() cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4; cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25; cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4; + cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5; rlc1.configure(&cnfg); rlc2.configure(&cnfg); @@ -245,6 +247,7 @@ void segment_test() cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4; cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25; cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4; + cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5; rlc1.configure(&cnfg); rlc2.configure(&cnfg); @@ -327,6 +330,7 @@ void retx_test() cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4; cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25; cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4; + cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5; rlc1.configure(&cnfg); rlc2.configure(&cnfg); @@ -423,6 +427,7 @@ void resegment_test_1() cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4; cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25; cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4; + cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5; rlc1.configure(&cnfg); rlc2.configure(&cnfg); @@ -532,6 +537,7 @@ void resegment_test_2() cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4; cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25; cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4; + cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5; rlc1.configure(&cnfg); rlc2.configure(&cnfg); @@ -638,6 +644,7 @@ void resegment_test_3() cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4; cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25; cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4; + cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5; rlc1.configure(&cnfg); rlc2.configure(&cnfg); @@ -740,6 +747,7 @@ void resegment_test_4() cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4; cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25; cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4; + cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5; rlc1.configure(&cnfg); rlc2.configure(&cnfg); @@ -842,6 +850,7 @@ void resegment_test_5() cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4; cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25; cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4; + cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5; rlc1.configure(&cnfg); rlc2.configure(&cnfg); @@ -943,6 +952,7 @@ void resegment_test_6() cnfg.ul_am_rlc.max_retx_thresh = LIBLTE_RRC_MAX_RETX_THRESHOLD_T4; cnfg.ul_am_rlc.poll_byte = LIBLTE_RRC_POLL_BYTE_KB25; cnfg.ul_am_rlc.poll_pdu = LIBLTE_RRC_POLL_PDU_P4; + cnfg.ul_am_rlc.t_poll_retx = LIBLTE_RRC_T_POLL_RETRANSMIT_MS5; rlc1.configure(&cnfg); rlc2.configure(&cnfg); diff --git a/srsenb/hdr/upper/rlc.h b/srsenb/hdr/upper/rlc.h index d0c165d73..abbf99516 100644 --- a/srsenb/hdr/upper/rlc.h +++ b/srsenb/hdr/upper/rlc.h @@ -50,7 +50,7 @@ public: void add_user(uint16_t rnti); void rem_user(uint16_t rnti); void add_bearer(uint16_t rnti, uint32_t lcid); - void add_bearer(uint16_t rnti, uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg); + void add_bearer(uint16_t rnti, uint32_t lcid, srslte::srslte_rlc_config_t cnfg); // rlc_interface_pdcp void write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu); diff --git a/srsenb/src/upper/rlc.cc b/srsenb/src/upper/rlc.cc index e826e7f34..758a3b5b3 100644 --- a/srsenb/src/upper/rlc.cc +++ b/srsenb/src/upper/rlc.cc @@ -98,7 +98,7 @@ void rlc::add_bearer(uint16_t rnti, uint32_t lcid) } } -void rlc::add_bearer(uint16_t rnti, uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT* cnfg) +void rlc::add_bearer(uint16_t rnti, uint32_t lcid, srslte::srslte_rlc_config_t cnfg) { if (users.count(rnti)) { users[rnti].rlc->add_bearer(lcid, cnfg); diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 0d0bf636c..40826ae51 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1341,7 +1341,7 @@ void rrc::add_srb(LIBLTE_RRC_SRB_TO_ADD_MOD_STRUCT *srb_cnfg) { rlc->add_bearer(srb_cnfg->srb_id); }else{ - rlc->add_bearer(srb_cnfg->srb_id, &srb_cnfg->rlc_explicit_cnfg); + rlc->add_bearer(srb_cnfg->srb_id, srslte_rlc_config_t(&srb_cnfg->rlc_explicit_cnfg)); } } @@ -1409,7 +1409,7 @@ void rrc::add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg) // TODO: setup PDCP security (using k_up_enc) // Setup RLC - rlc->add_bearer(lcid, &drb_cnfg->rlc_cnfg); + rlc->add_bearer(lcid, srslte_rlc_config_t(&drb_cnfg->rlc_cnfg)); // Setup MAC uint8_t log_chan_group = 0; From 80c0d0e6946d84e5effe8f60a542bc0b3dbed9c1 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 4 Jul 2017 16:54:51 +0200 Subject: [PATCH 17/19] fix printf's --- srsue/src/upper/rrc.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 40826ae51..8bb327b9d 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -119,7 +119,7 @@ void rrc::set_ue_category(int category) void rrc::write_sdu(uint32_t lcid, byte_buffer_t *sdu) { - rrc_log->info_hex(sdu->msg, sdu->N_bytes, "RX %s SDU", bearers.at(lcid)); + rrc_log->info_hex(sdu->msg, sdu->N_bytes, "RX %s SDU", bearers.at(lcid).c_str()); switch(state) { @@ -230,7 +230,7 @@ bool rrc::have_drb() void rrc::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { - rrc_log->info_hex(pdu->msg, pdu->N_bytes, "TX %s PDU", bearers.at(lcid)); + rrc_log->info_hex(pdu->msg, pdu->N_bytes, "TX %s PDU", bearers.at(lcid).c_str()); rrc_log->info("TX PDU Stack latency: %ld us\n", pdu->get_latency_us()); switch(lcid) @@ -796,7 +796,7 @@ void rrc::parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu) liblte_rrc_unpack_dl_dcch_msg((LIBLTE_BIT_MSG_STRUCT*)&bit_buf, &dl_dcch_msg); rrc_log->info("%s - Received %s\n", - bearers.at(lcid), + bearers.at(lcid).c_str(), liblte_rrc_dl_dcch_msg_type_text[dl_dcch_msg.msg_type]); // Reset and reuse pdu buffer if possible @@ -1376,7 +1376,7 @@ void rrc::add_srb(LIBLTE_RRC_SRB_TO_ADD_MOD_STRUCT *srb_cnfg) } srbs[srb_cnfg->srb_id] = *srb_cnfg; - rrc_log->info("Added radio bearer %s\n", bearers.at(srb_cnfg->srb_id)); + rrc_log->info("Added radio bearer %s\n", bearers.at(srb_cnfg->srb_id).c_str()); } void rrc::add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg) @@ -1437,7 +1437,7 @@ void rrc::add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg) drbs[lcid] = *drb_cnfg; drb_up = true; - rrc_log->info("Added radio bearer %s\n", bearers.at(lcid)); + rrc_log->info("Added radio bearer %s\n", bearers.at(lcid).c_str()); } void rrc::release_drb(uint8_t lcid) From 803077880932dcd2b158adb5465ad9389ba64609 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 6 Jul 2017 16:42:16 +0200 Subject: [PATCH 18/19] fix PDCP initialization in eNB --- lib/include/srslte/common/interfaces_common.h | 10 +++--- .../srslte/interfaces/enb_interfaces.h | 3 +- lib/src/upper/pdcp.cc | 8 ++++- lib/src/upper/rlc.cc | 7 ++--- lib/src/upper/rlc_tm.cc | 2 +- lib/src/upper/rlc_um.cc | 6 ++-- srsenb/hdr/upper/pdcp.h | 2 +- srsenb/src/upper/pdcp.cc | 9 +----- srsenb/src/upper/rrc.cc | 31 +++++++++++++++---- 9 files changed, 49 insertions(+), 29 deletions(-) diff --git a/lib/include/srslte/common/interfaces_common.h b/lib/include/srslte/common/interfaces_common.h index 5ef45cf54..44b1c5338 100644 --- a/lib/include/srslte/common/interfaces_common.h +++ b/lib/include/srslte/common/interfaces_common.h @@ -29,20 +29,22 @@ #include "srslte/common/timers.h" #include "srslte/common/security.h" +#include "srslte/asn1/liblte_rrc.h" + namespace srslte { class srslte_pdcp_config_t { public: - srslte_pdcp_config_t(bool is_control_ = false) - :direction(SECURITY_DIRECTION_UPLINK) + srslte_pdcp_config_t(bool is_control_ = false, bool is_data_ = false, uint8_t direction_ = SECURITY_DIRECTION_UPLINK) + :direction(direction_) ,is_control(is_control_) - ,is_data(false) + ,is_data(is_data_) ,do_security(false) ,sn_len(12) {} - u_int8_t direction; + uint8_t direction; bool is_control; bool is_data; bool do_security; diff --git a/lib/include/srslte/interfaces/enb_interfaces.h b/lib/include/srslte/interfaces/enb_interfaces.h index 5ba0213c1..ed2478896 100644 --- a/lib/include/srslte/interfaces/enb_interfaces.h +++ b/lib/include/srslte/interfaces/enb_interfaces.h @@ -28,6 +28,7 @@ #include "srslte/common/common.h" #include "srslte/common/security.h" +#include "srslte/common/interfaces_common.h" #include "srslte/interfaces/sched_interface.h" #include "srslte/upper/rlc_interface.h" #include "srslte/asn1/liblte_rrc.h" @@ -175,7 +176,7 @@ public: virtual void add_user(uint16_t rnti) = 0; virtual void rem_user(uint16_t rnti) = 0; virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; - virtual void add_bearer(uint16_t rnti, uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg=NULL) = 0; + virtual void add_bearer(uint16_t rnti, uint32_t lcid, srslte::srslte_pdcp_config_t cnfg) = 0; virtual void config_security(uint16_t rnti, uint32_t lcid, uint8_t *k_rrc_enc_, diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index f28eac974..7b4af6aad 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -41,7 +41,13 @@ void pdcp::init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_ lcid = lcid_; direction = direction_; - pdcp_array[0].init(rlc, rrc, gw, pdcp_log, lcid, direction); + // Default config + srslte_pdcp_config_t cnfg; + cnfg.is_control = false; + cnfg.is_data = false; + cnfg.direction = direction_; + + pdcp_array[0].init(rlc, rrc, gw, pdcp_log, lcid, cnfg); } void pdcp::stop() diff --git a/lib/src/upper/rlc.cc b/lib/src/upper/rlc.cc index 378b539b9..9a7b50448 100644 --- a/lib/src/upper/rlc.cc +++ b/lib/src/upper/rlc.cc @@ -193,9 +193,8 @@ void rlc::write_pdu_pcch(uint8_t *payload, uint32_t nof_bytes) *******************************************************************************/ void rlc::add_bearer(uint32_t lcid) { - // No config provided - use defaults for lcid - if(default_lcid == lcid || (default_lcid+1) == lcid) - { + // No config provided - use defaults for SRB1 and SRB2 + if(lcid < 3) { if (!rlc_array[lcid].active()) { LIBLTE_RRC_RLC_CONFIG_STRUCT cnfg; cnfg.rlc_mode = LIBLTE_RRC_RLC_MODE_AM; @@ -210,7 +209,7 @@ void rlc::add_bearer(uint32_t lcid) rlc_log->warning("Bearer %s already configured. Reconfiguration not supported\n", get_rb_name(lcid).c_str()); } }else{ - rlc_log->error("Radio bearer %s does not support default RLC configuration.", + rlc_log->error("Radio bearer %s does not support default RLC configuration.\n", get_rb_name(lcid).c_str()); } } diff --git a/lib/src/upper/rlc_tm.cc b/lib/src/upper/rlc_tm.cc index 9b7cd8f00..e3bef0a99 100644 --- a/lib/src/upper/rlc_tm.cc +++ b/lib/src/upper/rlc_tm.cc @@ -113,7 +113,7 @@ int rlc_tm::read_pdu(uint8_t *payload, uint32_t nof_bytes) return pdu_size; } -void rlc_tm:: write_pdu(uint8_t *payload, uint32_t nof_bytes) +void rlc_tm::write_pdu(uint8_t *payload, uint32_t nof_bytes) { byte_buffer_t *buf = pool_allocate; memcpy(buf->msg, payload, nof_bytes); diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 133bca9a8..3d6bb9553 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -75,18 +75,18 @@ void rlc_um::configure(srslte_rlc_config_t cnfg_) log->info("%s configured in %s mode: " "t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits\n", rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode], - cfg.t_reordering, cfg.rx_sn_field_length, cfg.tx_sn_field_length); + cfg.t_reordering, rlc_umd_sn_size_num[cfg.rx_sn_field_length], rlc_umd_sn_size_num[cfg.rx_sn_field_length]); break; case LIBLTE_RRC_RLC_MODE_UM_UNI_UL: log->info("%s configured in %s mode: tx_sn_field_length=%u bits\n", rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode], - cfg.tx_sn_field_length); + rlc_umd_sn_size_num[cfg.rx_sn_field_length]); break; case LIBLTE_RRC_RLC_MODE_UM_UNI_DL: log->info("%s configured in %s mode: " "t_reordering=%d ms, rx_sn_field_length=%u bits\n", rrc->get_rb_name(lcid).c_str(), liblte_rrc_rlc_mode_text[cnfg_.rlc_mode], - cfg.t_reordering, cfg.rx_sn_field_length); + cfg.t_reordering, rlc_umd_sn_size_num[cfg.rx_sn_field_length]); break; default: log->error("RLC configuration mode not recognized\n"); diff --git a/srsenb/hdr/upper/pdcp.h b/srsenb/hdr/upper/pdcp.h index 1d047db3e..228490312 100644 --- a/srsenb/hdr/upper/pdcp.h +++ b/srsenb/hdr/upper/pdcp.h @@ -51,7 +51,7 @@ public: void add_user(uint16_t rnti); void rem_user(uint16_t rnti); void write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu); - void add_bearer(uint16_t rnti, uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg=NULL); + void add_bearer(uint16_t rnti, uint32_t lcid, srslte::srslte_pdcp_config_t cnfg); void config_security(uint16_t rnti, uint32_t lcid, uint8_t *k_rrc_enc_, diff --git a/srsenb/src/upper/pdcp.cc b/srsenb/src/upper/pdcp.cc index ee65ae9e8..027f04909 100644 --- a/srsenb/src/upper/pdcp.cc +++ b/srsenb/src/upper/pdcp.cc @@ -73,20 +73,13 @@ void pdcp::rem_user(uint16_t rnti) } } -void pdcp::add_bearer(uint16_t rnti, uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT* cnfg_) +void pdcp::add_bearer(uint16_t rnti, uint32_t lcid, srslte::srslte_pdcp_config_t cfg) { if (users.count(rnti)) { - srslte::srslte_pdcp_config_t cfg; - if(cnfg_->rlc_um_pdcp_sn_size_present) { - if(LIBLTE_RRC_PDCP_SN_SIZE_7_BITS == cnfg_->rlc_um_pdcp_sn_size) { - cfg.sn_len = 7; - } - } users[rnti].pdcp->add_bearer(lcid, cfg); } } - void pdcp::reset(uint16_t rnti) { if (users.count(rnti)) { diff --git a/srsenb/src/upper/rrc.cc b/srsenb/src/upper/rrc.cc index 3bdd46c70..331efdbd5 100644 --- a/srsenb/src/upper/rrc.cc +++ b/srsenb/src/upper/rrc.cc @@ -1154,9 +1154,14 @@ void rrc::ue::send_connection_setup(bool is_setup) // Configure MAC parent->mac->ue_cfg(rnti, &sched_cfg); - // Configure SRB1 in RLC and PDCP + // Configure SRB1 in RLC parent->rlc->add_bearer(rnti, 1); - parent->pdcp->add_bearer(rnti, 1); + + // Configure SRB1 in PDCP + srslte::srslte_pdcp_config_t pdcp_cnfg; + pdcp_cnfg.is_control = true; + pdcp_cnfg.direction = SECURITY_DIRECTION_DOWNLINK; + parent->pdcp->add_bearer(rnti, 1, pdcp_cnfg); // Configure PHY layer parent->phy->set_config_dedicated(rnti, phy_cfg); @@ -1168,7 +1173,6 @@ void rrc::ue::send_connection_setup(bool is_setup) rr_cfg->sps_cnfg_present = false; send_dl_ccch(&dl_ccch_msg); - } @@ -1312,12 +1316,27 @@ void rrc::ue::send_connection_reconf(srslte::byte_buffer_t *pdu) // Configure SRB2 in RLC and PDCP parent->rlc->add_bearer(rnti, 2); - parent->pdcp->add_bearer(rnti, 2); - + + // Configure SRB2 in PDCP + srslte::srslte_pdcp_config_t pdcp_cnfg; + pdcp_cnfg.direction = SECURITY_DIRECTION_DOWNLINK; + pdcp_cnfg.is_control = true; + pdcp_cnfg.is_data = false; + parent->pdcp->add_bearer(rnti, 2, pdcp_cnfg); + // Configure DRB1 in RLC parent->rlc->add_bearer(rnti, 3, &conn_reconf->rr_cnfg_ded.drb_to_add_mod_list[0].rlc_cnfg); + // Configure DRB1 in PDCP - parent->pdcp->add_bearer(rnti, 3, &conn_reconf->rr_cnfg_ded.drb_to_add_mod_list[0].pdcp_cnfg); + pdcp_cnfg.is_control = false; + pdcp_cnfg.is_data = true; + if (conn_reconf->rr_cnfg_ded.drb_to_add_mod_list[0].pdcp_cnfg.rlc_um_pdcp_sn_size_present) { + if(LIBLTE_RRC_PDCP_SN_SIZE_7_BITS == conn_reconf->rr_cnfg_ded.drb_to_add_mod_list[0].pdcp_cnfg.rlc_um_pdcp_sn_size) { + pdcp_cnfg.sn_len = 7; + } + } + parent->pdcp->add_bearer(rnti, 3, pdcp_cnfg); + // DRB1 has already been configured in GTPU through bearer setup // Add NAS Attach accept From 1e3b5f553ee62bb80233154820f4c851fc2a923e Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 6 Jul 2017 18:34:00 +0200 Subject: [PATCH 19/19] fix printf argument --- lib/src/upper/pdcp.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index 7b4af6aad..5f4afbd62 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -81,7 +81,7 @@ void pdcp::add_bearer(uint32_t lcid, srslte_pdcp_config_t cfg) pdcp_array[lcid].init(rlc, rrc, gw, pdcp_log, lcid, cfg); pdcp_log->info("Added bearer %s\n", rrc->get_rb_name(lcid).c_str()); } else { - pdcp_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rrc->get_rb_name(lcid)); + pdcp_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rrc->get_rb_name(lcid).c_str()); } }