diff --git a/srsapps/common/include/srsapps/common/mac_interface.h b/srsapps/common/include/srsapps/common/mac_interface.h index 440c380b0..0abb9da71 100644 --- a/srsapps/common/include/srsapps/common/mac_interface.h +++ b/srsapps/common/include/srsapps/common/mac_interface.h @@ -53,9 +53,12 @@ public: uint32_t pid; uint32_t tti; bool ndi; - uint32_t tbs; + uint32_t n_bytes; uint32_t rv; uint16_t rnti; + bool is_from_rar; + bool is_sps_release; + srslte_rnti_type_t rnti_type; srslte_phy_grant_t phy_grant; } mac_grant_t; @@ -65,6 +68,9 @@ public: uint16_t rnti; bool generate_ack; bool default_ack; + // If non-null, called after tb_decoded_ok to determine if ack needs to be sent + bool (*generate_ack_callback)(void*); + void *generate_ack_callback_arg; uint8_t *payload_ptr; srslte_softbuffer_rx_t *softbuffer; srslte_phy_grant_t phy_grant; @@ -97,7 +103,7 @@ public: virtual void tb_decoded_ok(uint32_t harq_pid) = 0; /* Indicate successfull decoding of BCH TB through PBCH */ - virtual void bch_decoded_ok(uint8_t *payload) = 0; + virtual void bch_decoded_ok(uint8_t *payload, uint32_t len) = 0; /* Function called every start of a subframe (TTI). Warning, this function is called * from a high priority thread and should terminate asap @@ -113,7 +119,9 @@ public: /* RLC configures a logical channel */ virtual void setup_lcid(uint32_t lcid, uint32_t lcg, uint32_t priority, int PBR_x_tti, uint32_t BSD) = 0; - + + virtual uint32_t get_current_tti() = 0; + virtual void reconfiguration() = 0; virtual void reset() = 0; }; @@ -126,13 +134,17 @@ public: /* MAC calls RLC to get buffer state for a logical channel. This function should return quickly */ virtual uint32_t get_buffer_state(uint32_t lcid) = 0; - /* MAC calls RLC to get RLC segment of nof_bytes length. Segmentation happens in this function. RLC PDU is stored in payload. */ - virtual void read_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) = 0; + /* MAC calls RLC to get RLC segment of nof_bytes length. Segmentation happens in this function. RLC PDU is stored in + * payload. */ + virtual uint32_t read_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) = 0; - /* MAC calls RLC to push an RLC PDU. This function is called from an independent MAC thread. PDU gets placed into the PDCP buffer and higher layer thread gets notified - when the last segment is received + /* MAC calls RLC to push an RLC PDU. This function is called from an independent MAC thread. PDU gets placed into the + * PDCP buffer and higher layer thread gets notified + * when the last segment is received */ virtual void write_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) = 0; + virtual void write_pdu_bcch_bch(uint8_t *payload, uint32_t nof_bytes) = 0; + virtual void write_pdu_bcch_dlsch(uint8_t *payload, uint32_t nof_bytes) = 0; }; @@ -145,6 +157,9 @@ public: SPS_DL_SCHED_INTERVAL, SPS_DL_NOF_PROC, + RNTI_TEMP, + RNTI_C, + BCCH_SI_WINDOW_ST, BCCH_SI_WINDOW_LEN, diff --git a/srsapps/common/include/srsapps/common/phy_interface.h b/srsapps/common/include/srsapps/common/phy_interface.h index b3a6c031e..5ab41e042 100644 --- a/srsapps/common/include/srsapps/common/phy_interface.h +++ b/srsapps/common/include/srsapps/common/phy_interface.h @@ -133,23 +133,12 @@ public: virtual void sync_start() = 0; virtual void sync_stop() = 0; - /* Functions to initialize and transmit PRACH in the next opportunity. - * This function returns at the start of the rar reception window, ie the transmission - * TTI + rar_start - */ - typedef struct { - uint32_t preamble_idx; - bool allowed_subframe_enabled; - uint32_t allowed_subframe; - float target_power_dbm; - uint16_t rar_rnti; - uint32_t rar_start; - uint32_t rar_window; - } prach_cfg_t; - virtual void prach_send(prach_cfg_t *cfg) = 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; diff --git a/srsapps/common/include/srsapps/common/tti_sync.h b/srsapps/common/include/srsapps/common/tti_sync.h new file mode 100644 index 000000000..7a45939ea --- /dev/null +++ b/srsapps/common/include/srsapps/common/tti_sync.h @@ -0,0 +1,80 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 The srsLTE Developers. See the + * COPYRIGHT file at the top-level directory of this distribution. + * + * \section LICENSE + * + * This file is part of the srsLTE library. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + + + + +#include + + +#ifndef TTISYNC_H +#define TTISYNC_H + + +namespace srslte { +namespace ue { + + /* Interface used for PHY-MAC synchronization (producer-consumer model). + * The consumer waits while its counter is lower than the producer counter. + * The PHY is the consumer. The MAC is the producer. + */ +class tti_sync +{ + public: + tti_sync(uint32_t modulus_) + { + modulus = modulus_; + increment = 1; + init_counters(0); + } + virtual void increase() = 0; + virtual void resync() = 0; + virtual uint32_t wait() = 0; + virtual void set_producer_cntr(uint32_t) = 0; + uint32_t get_producer_cntr() { return producer_cntr; } + uint32_t get_consumer_cntr() { return consumer_cntr; } + void set_increment(uint32_t increment_) { + increment = increment_; + } + protected: + void increase_producer() { producer_cntr = (producer_cntr + increment)%modulus; } + void increase_consumer() { consumer_cntr = (consumer_cntr + increment)%modulus; } + bool wait_condition() { return producer_cntr == consumer_cntr; } + void init_counters(uint32_t val) + { + consumer_cntr = val; + producer_cntr = val; + } + uint32_t increment; + uint32_t modulus; + uint32_t producer_cntr; + uint32_t consumer_cntr; +}; +} +} + +#endif diff --git a/srsapps/ue/mac/src/dl_sps.cc b/srsapps/common/include/srsapps/common/tti_sync_cv.h similarity index 63% rename from srsapps/ue/mac/src/dl_sps.cc rename to srsapps/common/include/srsapps/common/tti_sync_cv.h index b3356336e..a4026f42e 100644 --- a/srsapps/ue/mac/src/dl_sps.cc +++ b/srsapps/common/include/srsapps/common/tti_sync_cv.h @@ -25,24 +25,37 @@ * */ -#include "srsapps/ue/mac/dl_sps.h" + + +#include +#include "srsapps/common/tti_sync.h" + + +#ifndef TTISYNC_CV_H +#define TTISYNC_CV_H + namespace srslte { - namespace ue { +namespace ue { + + /* Implements tti_sync interface with condition variables. + */ + +class tti_sync_cv : public tti_sync +{ + public: + tti_sync_cv(uint32_t modulus = 10240); + ~tti_sync_cv(); + void increase(); + uint32_t wait(); + void resync(); + void set_producer_cntr(uint32_t producer_cntr); + + private: + pthread_cond_t cond; + pthread_mutex_t mutex; +}; +} +} - dl_sched_grant* dl_sps::get_pending_grant(uint32_t tti) - { - return NULL; - } - void dl_sps::reset(uint32_t tti, dl_sched_grant* grant) - { - - } - void dl_sps::clear() - { - - } - - - } -} \ No newline at end of file +#endif diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/demux.h b/srsapps/ue/mac/include/srsapps/ue/mac/demux.h index 50e4a3368..6febad7d8 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/demux.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/demux.h @@ -28,12 +28,12 @@ #include "srsapps/ue/phy/phy.h" +#include "srsapps/common/mac_interface.h" #include "srsapps/common/log.h" -#include "srsapps/ue/mac/mac_io.h" +#include "srsapps/common/qbuff.h" #include "srsapps/common/timers.h" #include "srsapps/ue/mac/mac_params.h" #include "srsapps/ue/mac/pdu.h" -#include "srsapps/ue/mac/sdu_handler.h" #ifndef DEMUX_H #define DEMUX_H @@ -47,13 +47,15 @@ class demux { public: demux(); - void init(phy* phy_h_, log* log_h_, mac_io* mac_io_h_, timers* timers_db_); + void init(phy_interface* phy_h_, rlc_interface_mac *rlc, log* log_h_, timers* timers_db_); - void add_sdu_handler(sdu_handler *handler); + void process_pdus(); + uint8_t* request_buffer(uint32_t len); + + void release_pdu(uint8_t *buff, uint32_t nof_bytes); + void release_pdu_bcch(uint8_t *buff, uint32_t nof_bytes); + void release_pdu_temp_crnti(uint8_t *buff, uint32_t nof_bytes); - void push_pdu(uint8_t *mac_pdu, uint32_t nof_bits); - void push_pdu_bcch(uint8_t *mac_pdu, uint32_t nof_bits); - void push_pdu_temp_crnti(uint8_t *mac_pdu, uint32_t nof_bits); bool is_temp_crnti_pending(); bool is_contention_resolution_id_pending(); void demultiplex_pending_pdu(); @@ -62,24 +64,38 @@ public: uint64_t get_contention_resolution_id(); private: + const static int NOF_PDU_Q = 3; // prevents threads from being locked + const static int MAX_PDU_LEN = 128*1024; + sch_pdu mac_msg; sch_pdu pending_mac_msg; - void process_pdu(sch_pdu *pdu); + void process_pdu(uint8_t *pdu, uint32_t nof_bytes); + void process_sch_pdu(sch_pdu *pdu); bool process_ce(sch_subh *subheader); - - // Mutex for exclusive access - pthread_mutex_t mutex; + bool find_unused_queue(uint8_t *idx); + bool find_nonempty_queue(uint8_t *idx); + void push_buffer(uint8_t *buff, uint32_t nof_bytes); uint64_t contention_resolution_id; bool pending_temp_rnti; bool has_pending_contention_resolution_id; + + typedef struct { + uint8_t idx; + uint8_t dummy[15]; // FIXME: This it to keep 128-bit alignment + } buff_header_t; - phy *phy_h; - log *log_h; - mac_io *mac_io_h; - timers *timers_db; - sdu_handler *sdu_handler_; + // Mutex for exclusive access + pthread_mutex_t mutex; + pthread_cond_t cvar; + qbuff pdu_q[NOF_PDU_Q]; + bool used_q[NOF_PDU_Q]; + + phy_interface *phy_h; + log *log_h; + timers *timers_db; + rlc_interface_mac *rlc; }; } } diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/dl_harq.h b/srsapps/ue/mac/include/srsapps/ue/mac/dl_harq.h index 0d6e28b98..542ca1730 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/dl_harq.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/dl_harq.h @@ -33,6 +33,7 @@ #include "srsapps/ue/mac/mac_params.h" #include "srsapps/common/timers.h" #include "srsapps/ue/mac/demux.h" +#include "srsapps/ue/mac/dl_sps.h" #include "srsapps/ue/mac/mac_pcap.h" #ifndef DLHARQ_H @@ -43,8 +44,6 @@ namespace srslte { namespace ue { -typedef _Complex float cf_t; - class dl_harq_entity { public: @@ -53,49 +52,56 @@ public: const static uint32_t HARQ_BCCH_PID = NOF_HARQ_PROC; dl_harq_entity(); - bool init(srslte_cell_t cell, uint32_t max_payload_len, srslte::log *log_h_, timers *timers_, demux *demux_unit); - bool is_sps(uint32_t pid); - void set_harq_info(uint32_t pid, dl_sched_grant *grant); - void receive_data(uint32_t tti, uint32_t pid, dl_buffer *dl_buffer, phy *phy_h); + bool init(log *log_h_, timers *timers_, demux *demux_unit); + + + /***************** PHY->MAC 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_ok(uint32_t harq_pid); + + void reset(); - bool is_ack_pending_resolution(); - void send_pending_ack_contention_resolution(); void start_pcap(mac_pcap* pcap); + private: class dl_harq_process { public: dl_harq_process(); - bool init(srslte_cell_t cell, uint32_t max_payload_len, dl_harq_entity *parent); - void set_harq_info(dl_sched_grant *grant); - void receive_data(uint32_t tti, dl_buffer *dl_buffer, phy *phy_h); + bool init(uint32_t pid, dl_harq_entity *parent); void reset(); - // Called after the contention resolution is terminated to send pending ACKs, if any - void send_pending_ack_contention_resolution(); - uint32_t pid; + bool is_sps(); + bool 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); + void tb_decoded_ok(); + private: bool is_initiated; dl_harq_entity *harq_entity; - uint8_t *payload; - uint32_t max_payload_len; - dl_sched_grant cur_grant; - dl_sched_grant pending_ack_grant; - ul_buffer *pending_ul_buffer; - bool pending_ack; - srslte::log *log_h; + log *log_h; + + uint32_t pid; + uint8_t *payload_buffer_ptr; + bool ack; + + mac_interface_phy::mac_grant_t cur_grant; + srslte_softbuffer_rx_t softbuffer; - srslte_softbuffer_rx_t softbuffer; - bool ack; }; + static bool generate_ack_callback(void *arg); + + uint32_t get_harq_sps_pid(uint32_t tti); - dl_harq_process proc[NOF_HARQ_PROC+1]; + dl_sps dl_sps_assig; + + dl_harq_process proc[NOF_HARQ_PROC+1]; timers *timers_db; demux *demux_unit; - srslte::log *log_h; - int pending_ack_pid; + log *log_h; mac_pcap *pcap; + uint16_t last_temporal_crnti; }; } diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/dl_sps.h b/srsapps/ue/mac/include/srsapps/ue/mac/dl_sps.h index c2e2d3c3a..3b865aeaa 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/dl_sps.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/dl_sps.h @@ -41,15 +41,15 @@ namespace srslte { namespace ue { -typedef _Complex float cf_t; - class dl_sps { public: - void clear(); - void reset(uint32_t tti, dl_sched_grant *grant); - dl_sched_grant *get_pending_grant(uint32_t tti); + void clear() {} + void reset() {} + bool get_pending_grant(uint32_t tti, mac_interface_phy::mac_grant_t *grant) { + return false; + } private: }; diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/mac.h b/srsapps/ue/mac/include/srsapps/ue/mac/mac.h index dde4879ee..52772c825 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/mac.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/mac.h @@ -25,29 +25,22 @@ * */ - - -#include - #include "srsapps/common/log.h" #include "srsapps/ue/phy/phy.h" #include "srsapps/ue/mac/mac_params.h" #include "srsapps/ue/mac/dl_harq.h" #include "srsapps/ue/mac/ul_harq.h" -#include "srsapps/ue/mac/dl_sps.h" -#include "srsapps/ue/mac/ul_sps.h" #include "srsapps/common/timers.h" -#include "srsapps/ue/mac/mac_io.h" #include "srsapps/ue/mac/proc_ra.h" #include "srsapps/ue/mac/proc_sr.h" #include "srsapps/ue/mac/proc_bsr.h" #include "srsapps/ue/mac/proc_phr.h" #include "srsapps/ue/mac/mux.h" #include "srsapps/ue/mac/demux.h" -#include "srsapps/ue/mac/sdu_handler.h" #include "srsapps/ue/mac/mac_pcap.h" -#include "srsapps/common/trace.h" #include "srsapps/common/mac_interface.h" +#include "srsapps/common/tti_sync_cv.h" +#include "srsapps/common/threads.h" #ifndef UEMAC_H @@ -56,95 +49,68 @@ namespace srslte { namespace ue { -typedef _Complex float cf_t; - -class mac : public timer_callback, mac_interface_phy, mac_interface_rlc +class mac : public thread, timer_callback, mac_interface_phy, mac_interface_rlc, mac_interface_params { public: - mac() : timers_db((uint32_t) NOF_MAC_TIMERS), tr_exec_total(1024*10), tr_exec_dl(1024*10), tr_exec_ul(1024*10) {started=false; pcap = NULL; } - bool init(phy *phy_h, tti_sync *ttisync, log *log_h); + mac(); + bool init(phy_interface *phy, rlc_interface_mac *rlc, log *log_h); void stop(); - int get_tti(); - void main_radio_loop(); // called after thread creation - void add_sdu_handler(sdu_handler *handler); + /******** Interface from PHY (PHY -> MAC) ****************/ + /* see mac_interface.h for comments */ + void new_grant_ul(mac_grant_t grant, uint8_t *payload_ptr, tb_action_ul_t *action); + void new_grant_ul_ack(mac_grant_t grant, uint8_t *payload_ptr, bool ack, tb_action_ul_t *action); + void harq_recv(uint32_t tti, bool ack, tb_action_ul_t *action); + void new_grant_dl(mac_grant_t grant, tb_action_dl_t *action); + void tb_decoded_ok(uint32_t harq_pid); + void bch_decoded_ok(uint8_t *payload, uint32_t len); + void tti_clock(uint32_t tti); + - bool send_sdu(uint32_t lcid, uint8_t *sdu_payload, uint32_t nbytes); - bool send_ccch_sdu(uint8_t *sdu_payload, uint32_t nbytes); - bool send_dtch0_sdu(uint8_t *sdu_payload, uint32_t nbytes); // SRB0 - bool send_dcch0_sdu(uint8_t *sdu_payload, uint32_t nbytes); // DRB0 - - int recv_sdu(uint32_t lcid, uint8_t *sdu_payload, uint32_t nbytes); - int recv_bcch_sdu(uint8_t *sdu_payload, uint32_t buffer_len_nbytes); - int recv_ccch_sdu(uint8_t *sdu_payload, uint32_t buffer_len_nbytes); - int recv_dtch0_sdu(uint8_t *sdu_payload, uint32_t buffer_len_nbytes); // SRB0 - int recv_dcch0_sdu(uint8_t *sdu_payload, uint32_t buffer_len_nbytes); // DRB0 - + /******** Interface from RLC (RLC -> MAC) ****************/ void setup_lcid(uint32_t lcid, uint32_t lcg, uint32_t priority, int PBR_x_tti, uint32_t BSD); - - void set_param(mac_params::mac_param_t param, int64_t value); - int64_t get_param(mac_params::mac_param_t param); - void reconfiguration(); void reset(); - - void start_trace(); - void write_trace(std::string filename); + + /******** MAC parameters ****************/ + void set_param(mac_interface_params::mac_param_t param, int64_t value); + int64_t get_param(mac_interface_params::mac_param_t param); void timer_expired(uint32_t timer_id); void start_pcap(mac_pcap* pcap); - + + uint32_t get_current_tti(); + + enum { - HARQ_RTT = 0, + HARQ_RTT, TIME_ALIGNMENT, CONTENTION_TIMER, BSR_TIMER_PERIODIC, BSR_TIMER_RETX, NOF_MAC_TIMERS } mac_timers_t; - - class tti_thread { - public: - bool init(mac *parent, tti_sync_cv *ttysync); - void run(); - void run_tti(uint32_t tti); - void stop(); - private: - bool started; - log *log_h; - mac *parent; - tti_sync_cv *sync; - pthread_t thread; - }; - - static const int NOF_TTI_THREADS = 2; private: + void run_thread(); + void search_si_rnti(); - - // TTI processing threads - tti_thread tti_threads[NOF_TTI_THREADS]; - tti_sync_cv tti_threads_sync[NOF_TTI_THREADS]; - pthread_mutex_t tti_threads_sync_tx[NOF_TTI_THREADS]; - bool is_first_tx; + + static const int MAC_THREAD_PRIO = 5; // Interaction with PHY - tti_sync *ttisync; - phy *phy_h; - log *log_h; - - /* Logical channel (lch) IO */ - mac_io mac_io_lch; - + tti_sync_cv ttisync; + phy_interface *phy_h; + rlc_interface_mac *rlc_h; + log *log_h; mac_params params_db; - pthread_t mac_thread; - static void* mac_thread_fnc(void*); - int tti; + uint32_t tti; bool started; bool is_synchronized; uint16_t last_temporal_crnti; + uint16_t phy_rnti; /* Multiplexing/Demultiplexing Units */ mux mux_unit; @@ -154,46 +120,22 @@ private: dl_harq_entity dl_harq; ul_harq_entity ul_harq; - /* DL/UL Semi-Persistent Sched */ - dl_sps dl_sps_assig; - ul_sps ul_sps_assig; - uint32_t get_harq_sps_pid(uint32_t tti); - + int si_window_start, si_window_length; + /* MAC Uplink-related Procedures */ ra_proc ra_procedure; sr_proc sr_procedure; bsr_proc bsr_procedure; phr_proc phr_procedure; - - /* Other procedures */ - void process_dl_grants(uint32_t tti); - bool process_ul_grants(uint32_t tti); - void receive_pch(uint32_t tti); /* Functions for MAC Timers */ timers timers_db; - uint16_t phy_rnti; void setup_timers(); void timeAlignmentTimerExpire(); // pointer to MAC PCAP object mac_pcap* pcap; - // Variables for Execution time Trace - trace tr_exec_total; - trace tr_exec_dl; - trace tr_exec_ul; - struct timeval tr_time_total[3]; - struct timeval tr_time_ul[3]; - struct timeval tr_time_dl[3]; - bool tr_enabled; - bool is_first_of_burst; - void tr_log_start(uint32_t tti); - void tr_log_end(uint32_t tti); - void tr_log_dl(uint32_t tti); - void tr_log_ul(uint32_t tti); - void pregen_phy(uint16_t phy_rnti); - }; } diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/mac_io.h b/srsapps/ue/mac/include/srsapps/ue/mac/mac_io.h deleted file mode 100644 index 57b95b5e9..000000000 --- a/srsapps/ue/mac/include/srsapps/ue/mac/mac_io.h +++ /dev/null @@ -1,112 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - - -#include -#include "srsapps/common/qbuff.h" - -#ifndef MACIO_H -#define MACIO_H - -/* Manages all MAC buffers including: - * - communication with higher layers through logical channels - * - communication between logical channels buffers and Dissassembly/Assembly unit - * - communication between Dissassembly/Assembly unit and Msg3 buffer - * - * For logical channels, IN means higher layers to MAC. OUT means MAC to higher layers. - * - * See queue.h for instructions on how to manage buffers - */ - -namespace srslte { -namespace ue { - - class mac_io - { - public: - - // list of logical channels - // Keep this order to match LoCH id with RB - typedef enum { - // Downlink (UE MAC -> UE RRC) - MAC_LCH_CCCH_DL = 0, // SRB0 - MAC_LCH_DCCH0_DL, // SRB1 - MAC_LCH_DCCH1_DL, // SRB2 - MAC_LCH_DTCH0_DL, // DRB0 - MAC_LCH_DTCH1_DL, // DRB1 - MAC_LCH_DTCH2_DL, // DRB2 - MAC_LCH_BCCH_DL, // N/A - MAC_LCH_PCCH_DL, // N/A - - // Uplink (UE RLC -> UE MAC) - MAC_LCH_CCCH_UL, // SRB0 - MAC_LCH_DCCH0_UL, // SRB1 - MAC_LCH_DCCH1_UL, // SRB2 - MAC_LCH_DTCH0_UL, // DRB0 - MAC_LCH_DTCH1_UL, // DRB1 - MAC_LCH_DTCH2_UL, // DRB2 - - MAC_NOF_QUEUES - } mac_lch_t; - - const static int NOF_DL_LCH = MAC_LCH_PCCH_DL - MAC_LCH_CCCH_DL; - const static int NOF_UL_LCH = MAC_LCH_DTCH2_UL - MAC_LCH_CCCH_UL; - - const static int DEFAULT_MSG_SZ = 8*1024; // 8 Kbytes - const static int DEFAULT_NOF_MESSAGES = 64; - - - qbuff* get(mac_lch_t ch) { - return get((uint32_t) ch); - } - - qbuff* get(int32_t lchid) { - if (lchid < MAC_NOF_QUEUES) { - return &queues[lchid]; - } else { - return NULL; - } - } - - // Move packets between queues with only 1 memcpy - void move(mac_lch_t src, mac_lch_t dst) { - get(src)->move_to(get(dst)); - } - - mac_io() { - for (int i=0;i +#include "srsapps/common/qbuff.h" #include "srsapps/common/log.h" -#include "srsapps/ue/mac/mac_io.h" +#include "srsapps/common/mac_interface.h" #include "srsapps/ue/mac/mac_params.h" #include "srsapps/ue/mac/pdu.h" #include "srsapps/ue/mac/proc_bsr.h" @@ -47,17 +48,15 @@ class mux public: mux(); void reset(); - void init(log *log_h, mac_io *mac_io_h, bsr_proc *bsr_procedure); + void init(rlc_interface_mac *rlc, log *log_h, bsr_proc *bsr_procedure); bool is_pending_ccch_sdu(); bool is_pending_any_sdu(); bool is_pending_sdu(uint32_t lcid); - uint8_t* pdu_pop(uint32_t pdu_sz); - bool pdu_move_to_msg3(uint32_t pdu_sz); - void pdu_release(); + bool pdu_get(uint8_t *payload, uint32_t pdu_sz); - uint8_t* msg3_pop(uint32_t pdu_sz); + bool msg3_get(uint8_t *payload, uint32_t pdu_sz); void msg3_flush(); void msg3_transmitted(); bool msg3_is_transmitted(); @@ -67,34 +66,33 @@ public: void set_priority(uint32_t lcid, uint32_t priority, int PBR_x_tti, uint32_t BSD); private: - bool assemble_pdu(uint32_t pdu_sz); - bool allocate_sdu(uint32_t lcid, sch_pdu *pdu); - bool allocate_sdu(uint32_t lcid, sch_pdu *pdu, bool *is_first); - bool allocate_sdu(uint32_t lcid, sch_pdu *pdu, uint32_t *sdu_sz, bool *is_first); + bool pdu_move_to_msg3(uint32_t pdu_sz); + bool allocate_sdu(uint32_t lcid, sch_pdu *pdu); + bool allocate_sdu(uint32_t lcid, sch_pdu *pdu, bool *is_first); + bool allocate_sdu(uint32_t lcid, sch_pdu *pdu, int max_sdu_sz, uint32_t *sdu_sz, bool *is_first); - int64_t Bj[mac_io::NOF_UL_LCH]; - int PBR[mac_io::NOF_UL_LCH]; // -1 sets to infinity - uint32_t BSD[mac_io::NOF_UL_LCH]; - uint32_t priority[mac_io::NOF_UL_LCH]; - uint32_t priority_sorted[mac_io::NOF_UL_LCH]; - uint32_t lchid_sorted[mac_io::NOF_UL_LCH]; - uint32_t nof_tx_pkts[mac_io::NOF_UL_LCH]; + const static int NOF_UL_LCH = 10; + + int64_t Bj[NOF_UL_LCH]; + int PBR[NOF_UL_LCH]; // -1 sets to infinity + uint32_t BSD[NOF_UL_LCH]; + uint32_t priority[NOF_UL_LCH]; + uint32_t priority_sorted[NOF_UL_LCH]; + uint32_t lchid_sorted[NOF_UL_LCH]; // Mutex for exclusive access pthread_mutex_t mutex; - log *log_h; - mac_io *mac_io_h; - bsr_proc *bsr_procedure; - uint16_t pending_crnti_ce; + log *log_h; + rlc_interface_mac *rlc; + bsr_proc *bsr_procedure; + uint16_t pending_crnti_ce; /* Msg3 Buffer */ static const uint32_t MSG3_BUFF_SZ = 128; qbuff msg3_buff; /* PDU Buffer */ - static const uint32_t PDU_BUFF_SZ = 128*1024; - qbuff pdu_buff; sch_pdu pdu_msg; bool msg3_has_been_transmitted; diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/pdu.h b/srsapps/ue/mac/include/srsapps/ue/mac/pdu.h index 7ec65e8e2..ec9dcfb32 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/pdu.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/pdu.h @@ -28,6 +28,7 @@ #include #include "srsapps/common/log.h" +#include "srsapps/common/mac_interface.h" #include #include @@ -139,7 +140,7 @@ public: return pdu_is_ul; } - virtual bool write_packet(uint8_t *ptr) = 0; + virtual bool write_packet(uint8_t *ptr, rlc_interface_mac *rlc) = 0; protected: std::vector subheaders; @@ -156,11 +157,11 @@ class subh { public: - virtual bool read_subheader(uint8_t** ptr) = 0; - virtual void read_payload(uint8_t **ptr) = 0; - virtual void write_subheader(uint8_t** ptr, bool is_last) = 0; - virtual void write_payload(uint8_t **ptr) = 0; - virtual void fprint(FILE *stream) = 0; + virtual bool read_subheader(uint8_t** ptr) = 0; + virtual void read_payload(uint8_t **ptr) = 0; + virtual void write_subheader(uint8_t** ptr, bool is_last) = 0; + virtual void write_payload(uint8_t **ptr, rlc_interface_mac *rlc) = 0; + virtual void fprint(FILE *stream) = 0; pdu* parent; @@ -207,9 +208,9 @@ public: // Writing functions void write_subheader(uint8_t** ptr, bool is_last); - void write_payload(uint8_t **ptr); - bool set_sdu(uint32_t lcid, uint8_t *ptr, uint32_t nof_bytes); - bool set_sdu(uint32_t lcid, uint8_t *ptr, uint32_t nof_bytes, bool is_first); + void write_payload(uint8_t **ptr, rlc_interface_mac *rlc); + bool set_sdu(uint32_t lcid, uint32_t nof_bytes); + bool set_sdu(uint32_t lcid, uint32_t nof_bytes, bool is_first); bool set_c_rnti(uint16_t crnti); bool set_bsr(uint32_t buff_size[4], sch_subh::cetype format, bool update_size); bool set_con_res_id(uint64_t con_res_id); @@ -225,9 +226,9 @@ private: static const int MAX_CE_PAYLOAD_LEN = 8; uint32_t lcid; uint32_t nof_bytes; - uint8_t* sdu_payload_ptr; + uint8_t* payload; + uint8_t w_payload_ce[8]; bool F_bit; - uint8_t ce_payload[MAX_CE_PAYLOAD_LEN*8]; uint32_t sizeof_ce(uint32_t lcid, bool is_ul); uint8_t buff_size_table(uint32_t buffer_size); }; @@ -239,7 +240,7 @@ public: sch_pdu(uint32_t max_rars) : pdu(max_rars) {} void parse_packet(uint8_t *ptr); - bool write_packet(uint8_t *ptr); + bool write_packet(uint8_t *ptr, rlc_interface_mac *rlc); bool has_space_ce(uint32_t nbytes); bool has_space_sdu(uint32_t nbytes); bool has_space_sdu(uint32_t nbytes, bool is_first); @@ -249,7 +250,7 @@ public: bool update_space_ce(uint32_t nbytes); bool update_space_sdu(uint32_t nbytes); bool update_space_sdu(uint32_t nbytes, bool is_first); - void fprint(FILE *stream); + void fprint(FILE *stream); }; @@ -269,7 +270,7 @@ public: // Writing functoins void write_subheader(uint8_t** ptr, bool is_last); - void write_payload(uint8_t** ptr); + void write_payload(uint8_t** ptr, rlc_interface_mac *rlc); void set_rapid(uint32_t rapid); void set_ta_cmd(uint32_t ta); void set_temp_crnti(uint16_t temp_rnti); @@ -295,7 +296,7 @@ public: bool has_backoff(); uint8_t get_backoff(); - bool write_packet(uint8_t* ptr); + bool write_packet(uint8_t* ptr, rlc_interface_mac *rlc); void fprint(FILE *stream); private: diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/proc_bsr.h b/srsapps/ue/mac/include/srsapps/ue/mac/proc_bsr.h index 9b39b84f5..2faf35201 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/proc_bsr.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/proc_bsr.h @@ -31,8 +31,8 @@ #include "srsapps/common/log.h" #include "srsapps/ue/mac/proc.h" +#include "srsapps/common/mac_interface.h" #include "srsapps/ue/mac/mac_params.h" -#include "srsapps/ue/mac/mac_io.h" #include "srsapps/common/timers.h" #ifndef PROCBSR_H @@ -47,7 +47,7 @@ class bsr_proc : public proc, timer_callback { public: bsr_proc(); - void init(log *log_h, timers *timers_db, mac_params *params_db, mac_io *mac_io_h); + void init(rlc_interface_mac *rlc, log *log_h, mac_params *params_db, timers *timers_db); void step(uint32_t tti); void reset(); void setup_lcg(uint32_t lcid, uint32_t new_lcg); @@ -74,9 +74,9 @@ private: bool reset_sr; mac_params *params_db; - mac_io *mac_io_h; timers *timers_db; log *log_h; + rlc_interface_mac *rlc; bool initiated; const static int MAX_LCID = 20; int lcg[MAX_LCID]; diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/proc_ra.h b/srsapps/ue/mac/include/srsapps/ue/mac/proc_ra.h index 3095e75aa..fa0046467 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/proc_ra.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/proc_ra.h @@ -52,8 +52,7 @@ class ra_proc : public proc,timer_callback { public: ra_proc() : rar_pdu_msg(20) {pcap = NULL;}; - bool init(mac_params *params_db, phy *phy_h, log *log_h, timers *timers_db, - mux *mux_unit, demux *demux_unit); + bool init(phy_interface *phy_h, log *log_h, mac_params *params_db, timers *timers_db, mux *mux_unit, demux *demux_unit); void reset(); void start_pdcch_order(); void start_rlc_order(); @@ -67,15 +66,18 @@ class ra_proc : public proc,timer_callback void pdcch_to_crnti(bool is_ul_grant); void timer_expired(uint32_t timer_id); + void new_grant_dl(mac_interface_phy::mac_grant_t grant, mac_interface_phy::tb_action_dl_t* action); + void tb_decoded_ok(); + void* run_prach_thread(); void start_pcap(mac_pcap* pcap); private: void process_timeadv_cmd(uint32_t ta_cmd); void step_initialization(); - void step_initialization_wait(); void step_resource_selection(); void step_preamble_transmission(); + void step_pdcch_setup(); void step_response_reception(); void step_response_error(); void step_backoff_wait(); @@ -107,7 +109,6 @@ private: int preambleIndex; // Internal variables - uint32_t tti; uint32_t preambleTransmissionCounter; uint32_t backoff_param_ms; uint32_t sel_maskIndex; @@ -116,14 +117,15 @@ private: uint32_t backoff_inteval; int received_target_power_dbm; uint32_t ra_rnti; - uint8_t payload[256]; // 56 bits is often enough + + srslte_softbuffer_rx_t softbuffer_rar; enum { IDLE = 0, INITIALIZATION, // Section 5.1.1 - INITIALIZATION_WAIT, RESOURCE_SELECTION, // Section 5.1.2 PREAMBLE_TRANSMISSION, // Section 5.1.3 + PDCCH_SETUP, RESPONSE_RECEPTION, // Section 5.1.4 RESPONSE_ERROR, BACKOFF_WAIT, @@ -139,21 +141,17 @@ private: bool first_rar_received; void read_params(); - phy *phy_h; - log *log_h; - mac_params *params_db; - timers *timers_db; - mux *mux_unit; - demux *demux_unit; - mac_pcap *pcap; - - pthread_t pt_init_prach; - pthread_cond_t cond; - pthread_mutex_t mutex; - bool start_prach_init; - + phy_interface *phy_h; + log *log_h; + mac_params *params_db; + timers *timers_db; + mux *mux_unit; + demux *demux_unit; + mac_pcap *pcap; + uint64_t transmitted_contention_id; uint16_t transmitted_crnti; + enum { PDCCH_CRNTI_NOT_RECEIVED = 0, PDCCH_CRNTI_UL_GRANT, @@ -165,6 +163,8 @@ private: RLC_ORDER, MAC_ORDER } start_mode; + uint32_t rar_grant_nbytes; + uint32_t rar_grant_tti; }; } } diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/proc_sr.h b/srsapps/ue/mac/include/srsapps/ue/mac/proc_sr.h index 5ea43cff5..e3987d1fc 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/proc_sr.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/proc_sr.h @@ -45,20 +45,22 @@ class sr_proc : public proc { public: sr_proc(); - void init(log *log_h, mac_params *params_db, phy *phy_h); + void init(phy_interface *phy_h, log *log_h, mac_params *params_db); void step(uint32_t tti); void reset(); void start(); bool need_random_access(); + private: - uint32_t sr_counter; - uint32_t dsr_transmax; - bool is_pending_sr; - mac_params *params_db; - phy *phy_h; - log *log_h; - bool initiated; - bool do_ra; + uint32_t sr_counter; + uint32_t dsr_transmax; + bool is_pending_sr; + mac_params *params_db; + + phy_interface *phy_h; + log *log_h; + bool initiated; + bool do_ra; }; } } diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/ul_harq.h b/srsapps/ue/mac/include/srsapps/ue/mac/ul_harq.h index 9fea74b5a..dac665ad0 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/ul_harq.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/ul_harq.h @@ -25,13 +25,11 @@ * */ - - - -#include "srsapps/ue/phy/phy.h" +#include "srsapps/common/mac_interface.h" #include "srsapps/common/log.h" #include "srsapps/ue/mac/mac_params.h" #include "srsapps/ue/mac/mux.h" +#include "srsapps/ue/mac/ul_sps.h" #include "srsapps/ue/mac/mac_pcap.h" #include "srsapps/common/timers.h" @@ -43,8 +41,6 @@ namespace srslte { namespace ue { -typedef _Complex float cf_t; - class ul_harq_entity { public: @@ -52,56 +48,73 @@ public: const static uint32_t NOF_HARQ_PROC = 8; static uint32_t pidof(uint32_t tti); - ul_harq_entity() { pcap = NULL; } - bool init(srslte_cell_t cell, mac_params *params_db, log *log_h, timers* timers_, mux *mux_unit); - + ul_harq_entity() { pcap = NULL; } + bool init(log *log_h, mac_params *params_db, timers* timers_, mux *mux_unit); void reset(); void reset_ndi(); - bool is_sps(uint32_t pid); - void run_tti(uint32_t tti, ul_sched_grant *grant, phy *phy_); - void run_tti(uint32_t tti, phy *phy_); + void start_pcap(mac_pcap* pcap); + + /***************** PHY->MAC interface for UL processes **************************/ + void new_grant_ul(mac_interface_phy::mac_grant_t grant, uint8_t *payload_ptr, + mac_interface_phy::tb_action_ul_t *action); + void new_grant_ul_ack(mac_interface_phy::mac_grant_t grant, uint8_t *payload_ptr, 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); + + private: - + class ul_harq_process { public: ul_harq_process(); - bool init(srslte_cell_t cell, ul_harq_entity *parent); + bool init(uint32_t pid, ul_harq_entity *parent); void reset(); void reset_ndi(); - - void generate_retx(uint32_t tti_tx, ul_buffer *ul); - void generate_retx(uint32_t tti_tx, ul_sched_grant *ul_grant, ul_buffer *ul); - void generate_new_tx(uint32_t tti_tx, uint8_t *payload, bool is_msg3, ul_sched_grant* grant, ul_buffer *ul); + + + 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::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); uint32_t get_rv(); bool has_grant(); - ul_sched_grant *get_grant(); + void set_harq_feedback(bool ack); bool get_ndi(); + bool is_sps(); uint32_t last_tx_tti(); - uint32_t pid; + uint32_t get_nof_retx(); private: + mac_interface_phy::mac_grant_t cur_grant; + + uint32_t pid; uint32_t current_tx_nb; uint32_t current_irv; bool harq_feedback; bool ndi; log *log_h; ul_harq_entity *harq_entity; - ul_sched_grant cur_grant; bool is_grant_configured; srslte_softbuffer_tx_t softbuffer; bool is_msg3; - bool is_initiated; - uint32_t tti_last_tx; + bool is_initiated; + uint32_t tti_last_tx; - void generate_tx(uint32_t tti_tx, uint8_t *pdu_payload, ul_buffer* ul); + void generate_tx(uint32_t tti_tx, mac_interface_phy::tb_action_ul_t *action); }; - - uint8_t mac_pdu_buffer[NOF_HARQ_PROC][64*1024]; + + void run_tti(uint32_t tti, mac_interface_phy::mac_grant_t *grant, uint8_t* payload_ptr, + mac_interface_phy::tb_action_ul_t* action); + void set_ack(uint32_t tti, bool ack); + + ul_sps ul_sps_assig; + timers *timers_db; mux *mux_unit; ul_harq_process proc[NOF_HARQ_PROC]; diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/ul_sps.h b/srsapps/ue/mac/include/srsapps/ue/mac/ul_sps.h index a5e707f45..eb07a28e1 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/ul_sps.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/ul_sps.h @@ -48,8 +48,8 @@ class ul_sps public: void clear() {} - void reset(uint32_t tti, sched_grant *grant) {} - ul_sched_grant *get_pending_grant(uint32_t tti) { return NULL; } + void reset(uint32_t tti) {} + bool get_pending_grant(uint32_t tti, mac_interface_phy::mac_grant_t *grant) { return false; } private: }; diff --git a/srsapps/ue/mac/src/demux.cc b/srsapps/ue/mac/src/demux.cc index 9459df282..f8de6f8d3 100644 --- a/srsapps/ue/mac/src/demux.cc +++ b/srsapps/ue/mac/src/demux.cc @@ -30,32 +30,30 @@ #include "srsapps/ue/mac/demux.h" namespace srslte { - namespace ue { +namespace ue { -demux::demux() : mac_msg(20),pending_mac_msg(20) +demux::demux() : mac_msg(20), pending_mac_msg(20) { contention_resolution_id = 0; pending_temp_rnti = false; has_pending_contention_resolution_id = false; - sdu_handler_ = NULL; - + for (int i=0;i= MAX_PDU_LEN - sizeof(buff_header_t)) { + return NULL; + } + pthread_mutex_lock(&mutex); + uint8_t idx; + while(find_unused_queue(&idx)) { + pthread_cond_wait(&cvar, &mutex); + } + if (idx > 0) { + Debug("Using queue %d for MAC PDU\n"); + } + used_q[idx] = true; + uint8_t *buff = (uint8_t*) pdu_q[idx].request(); + buff_header_t *head = (buff_header_t*) buff; + head->idx = idx; + pthread_mutex_unlock(&mutex); + + return &buff[sizeof(buff_header_t)]; +} + +void demux::push_buffer(uint8_t *buff, uint32_t nof_bytes) { + buff_header_t *head = (buff_header_t*) (buff-sizeof(buff_header_t)); + if (head->idx < NOF_PDU_Q) { + pthread_mutex_lock(&mutex); + if (nof_bytes > 0) { + if (!pdu_q[head->idx].push(nof_bytes)) { + Warning("Full queue %d when pushing MAC PDU %d bytes\n", head->idx, nof_bytes); + } + } + used_q[head->idx] = false; + pthread_cond_signal(&cvar); + pthread_mutex_unlock(&mutex); + } +} /* Demultiplexing of MAC PDU associated with SI-RNTI. The PDU passes through - * the MAC in transparent mode + * the MAC in transparent mode. + * Warning: this function sends the message to RLC now, since SI blocks do not + * require ACK feedback to be transmitted quickly. */ -void demux::push_pdu_bcch(uint8_t *mac_pdu, uint32_t nof_bits) +void demux::release_pdu_bcch(uint8_t *buff, uint32_t nof_bytes) { - mac_io_h->get(mac_io::MAC_LCH_BCCH_DL)->send(mac_pdu, nof_bits); Debug("Pushed BCCH MAC PDU in transparent mode\n"); + rlc->write_pdu_bcch_dlsch(buff, nof_bytes); + push_buffer(buff, 0); } /* Demultiplexing of MAC PDU associated with a Temporal C-RNTI. The PDU will * remain in buffer until demultiplex_pending_pdu() is called. * This features is provided to enable the Random Access Procedure to decide * wether the PDU shall pass to upper layers or not, which depends on the - * Contention Resolution result + * Contention Resolution result. + * + * Warning: this function does some processing here assuming ACK deadline is not an + * issue here because Temp C-RNTI messages have small payloads */ -void demux::push_pdu_temp_crnti(uint8_t *mac_pdu, uint32_t nof_bits) +void demux::release_pdu_temp_crnti(uint8_t *buff, uint32_t nof_bytes) { if (!pending_temp_rnti) { // Unpack DLSCH MAC PDU - pending_mac_msg.init(nof_bits/8); - pending_mac_msg.parse_packet(mac_pdu); + pending_mac_msg.init(nof_bytes); + pending_mac_msg.parse_packet(buff); //pending_mac_msg.fprint(stdout); // Look for Contention Resolution UE ID @@ -108,25 +173,43 @@ void demux::push_pdu_temp_crnti(uint8_t *mac_pdu, uint32_t nof_bits) pending_mac_msg.reset(); pending_temp_rnti = true; Debug("Saved MAC PDU with Temporal C-RNTI in buffer\n"); + push_buffer(buff, 0); } else { Warning("Error pushing PDU with Temporal C-RNTI: Another PDU is still in pending\n"); } } -/* Demultiplexing of logical channels and dissassemble of MAC CE */ -void demux::push_pdu(uint8_t *mac_pdu, uint32_t nof_bits) +/* Demultiplexing of logical channels and dissassemble of MAC CE + * This function enqueues the packet and returns quicly because ACK + * deadline is important here. + */ +void demux::release_pdu(uint8_t *buff, uint32_t nof_bytes) { - pthread_mutex_lock(&mutex); + push_buffer(buff, nof_bytes); +} +void demux::process_pdus() +{ + uint32_t len; + uint8_t idx; + while(find_nonempty_queue(&idx)) { + uint8_t *mac_pdu = (uint8_t*) pdu_q[idx].pop(&len); + if (mac_pdu) { + process_pdu(mac_pdu, len); + pdu_q[idx].release(); + } + idx++; + } +} + +void demux::process_pdu(uint8_t *mac_pdu, uint32_t nof_bytes) +{ // Unpack DLSCH MAC PDU - mac_msg.init(nof_bits/8); + mac_msg.init(nof_bytes); mac_msg.parse_packet(mac_pdu); - //mac_msg.fprint(stdout); - process_pdu(&mac_msg); + mac_msg.fprint(stdout); + process_sch_pdu(&mac_msg); Debug("Normal MAC PDU processed\n"); - - pthread_mutex_unlock(&mutex); - } void demux::discard_pending_pdu() @@ -138,40 +221,21 @@ void demux::discard_pending_pdu() void demux::demultiplex_pending_pdu() { if (pending_temp_rnti) { - process_pdu(&pending_mac_msg); + process_sch_pdu(&pending_mac_msg); discard_pending_pdu(); } else { Error("Error demultiplex pending PDU: No pending PDU\n"); } } - - -void demux::process_pdu(sch_pdu *pdu_msg) +void demux::process_sch_pdu(sch_pdu *pdu_msg) { while(pdu_msg->next()) { if (pdu_msg->get()->is_sdu()) { // Route logical channel - if (pdu_msg->get()->get_sdu_lcid() <= mac_io::MAC_LCH_DTCH2_DL) { - qbuff *dest_lch = mac_io_h->get(pdu_msg->get()->get_sdu_lcid()); - if (dest_lch) { - dest_lch->send(pdu_msg->get()->get_sdu_ptr(), pdu_msg->get()->get_sdu_nbytes()*8); - Debug("Sent MAC SDU len=%d bytes to lchid=%d\n", - pdu_msg->get()->get_sdu_nbytes(), pdu_msg->get()->get_sdu_lcid()); - if (sdu_handler_) { - sdu_handler_->notify_new_sdu(pdu_msg->get()->get_sdu_lcid()); - Debug("Notified SDU handler len=%d bytes to lchid=%d\n", - pdu_msg->get()->get_sdu_nbytes(), pdu_msg->get()->get_sdu_lcid()); - } - - } else { - Error("Getting destination channel LCID=%d\n", pdu_msg->get()->get_sdu_lcid()); - } - } else { - Warning("Received SDU for unsupported LCID=%d\n", pdu_msg->get()->get_sdu_lcid()); - } - // Process MAC Control Element + rlc->write_pdu(pdu_msg->get()->get_sdu_lcid(), pdu_msg->get()->get_sdu_ptr(), pdu_msg->get()->get_sdu_nbytes()); } else { + // Process MAC Control Element if (!process_ce(pdu_msg->get())) { Warning("Received Subheader with invalid or unkonwn LCID\n"); } @@ -179,7 +243,6 @@ void demux::process_pdu(sch_pdu *pdu_msg) } } - bool demux::process_ce(sch_subh *subh) { switch(subh->ce_type()) { case sch_subh::CON_RES_ID: diff --git a/srsapps/ue/mac/src/dl_harq.cc b/srsapps/ue/mac/src/dl_harq.cc index f84e0f586..5c0f27399 100644 --- a/srsapps/ue/mac/src/dl_harq.cc +++ b/srsapps/ue/mac/src/dl_harq.cc @@ -26,7 +26,6 @@ */ #include "srsapps/ue/phy/phy.h" -#include "srsapps/ue/phy/dl_sched_grant.h" #include "srsapps/ue/mac/mac.h" #include "srsapps/ue/mac/dl_harq.h" @@ -43,19 +42,15 @@ namespace srslte { dl_harq_entity::dl_harq_entity() { - for (uint32_t i=0;i= 0; +uint32_t dl_harq_entity::get_harq_sps_pid(uint32_t tti) { + /* + uint32_t nof_proc = ((uint32_t) params_db->get_param(mac_interface_params::SPS_DL_NOF_PROC)); + return tti/params_db.get_param(mac_interface_params::SPS_DL_SCHED_INTERVAL)%nof_proc; + */ } -void dl_harq_entity::send_pending_ack_contention_resolution() +void dl_harq_entity::new_grant_dl(mac_interface_phy::mac_grant_t grant, mac_interface_phy::tb_action_dl_t* action) { - if (is_ack_pending_resolution()) { - proc[pending_ack_pid].send_pending_ack_contention_resolution(); - pending_ack_pid = -1; + + // If PDCCH for C-RNTI and RA procedure in Contention Resolution, notify it + if (grant.rnti_type == SRSLTE_RNTI_USER) { + Warning("Not implemented ra_procedure_crnti\n"); + //ra_procedure.pdcch_to_crnti(false); + } + 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(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_ok(uint32_t harq_pid) +{ + proc[harq_pid%NOF_HARQ_PROC].tb_decoded_ok(); +} + +bool dl_harq_entity::generate_ack_callback(void *arg) +{ + demux *demux_unit = (demux*) arg; + return demux_unit->is_contention_resolution_id_pending(); +} + + + /*********************************************************** * * HARQ PROCESS * *********************************************************/ -dl_harq_entity::dl_harq_process::dl_harq_process() : cur_grant(0),pending_ack_grant(0) { +dl_harq_entity::dl_harq_process::dl_harq_process() { is_initiated = false; ack = false; - bzero(&cur_grant, sizeof(srslte::ue::dl_sched_grant)); - payload = NULL; - max_payload_len = 0; + bzero(&cur_grant, sizeof(mac_interface_phy::mac_grant_t)); } void dl_harq_entity::dl_harq_process::reset() { ack = false; - bzero(&cur_grant, sizeof(srslte::ue::dl_sched_grant)); + payload_buffer_ptr = NULL; + bzero(&cur_grant, sizeof(mac_interface_phy::mac_grant_t)); if (is_initiated) { srslte_softbuffer_rx_reset(&softbuffer); } } -void dl_harq_entity::dl_harq_process::send_pending_ack_contention_resolution() -{ - if (pending_ul_buffer) { - pending_ul_buffer->generate_ack(pending_ack, &pending_ack_grant); - } +bool dl_harq_entity::dl_harq_process::init(uint32_t pid_, dl_harq_entity *parent) { + if (srslte_softbuffer_rx_init(&softbuffer, 100)) { + 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; + } } -void dl_harq_entity::dl_harq_process::receive_data(uint32_t tti, srslte::ue::dl_buffer *dl_buffer, phy *phy_h) +bool dl_harq_entity::dl_harq_process::is_sps() { - pending_ul_buffer = NULL; + return false; +} + +bool dl_harq_entity::dl_harq_process::is_new_transmission(mac_interface_phy::mac_grant_t grant) { + bool is_new_transmission; - if (payload) { - if (cur_grant.get_tbs() <= max_payload_len) { - - // If data has not yet been successfully decoded - if (ack == false) { - - // Combine the received data and attempt to decode it - if (dl_buffer->decode_data(&cur_grant, &softbuffer, payload)) { - ack = true; - } else { - ack = false; - } - - Info("DL PID %d: TBS=%d, RV=%d, MCS=%d, crc=%s\n", pid, cur_grant.get_tbs(), cur_grant.get_rv(), cur_grant.get_mcs(), ack?"OK":"NOK"); - - if (pid == HARQ_BCCH_PID) { - if (ack) { - Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (BCCH)\n", cur_grant.get_tbs()/8); - harq_entity->demux_unit->push_pdu_bcch(payload, cur_grant.get_tbs()); - } - if (harq_entity->pcap) { - harq_entity->pcap->write_dl_sirnti(payload, cur_grant.get_tbs()/8, ack, tti); - } - } else { - if (ack) { - if (cur_grant.is_temp_rnti()) { - Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (Temporal C-RNTI)\n", - cur_grant.get_tbs()/8); - harq_entity->demux_unit->push_pdu_temp_crnti(payload, cur_grant.get_tbs()); - } else { - Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit\n", cur_grant.get_tbs()/8); - harq_entity->demux_unit->push_pdu(payload, cur_grant.get_tbs()); - } - } - if (harq_entity->pcap) { - harq_entity->pcap->write_dl_crnti(payload, cur_grant.get_tbs()/8, cur_grant.get_rnti(), ack, tti); - } - } - } 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"); - } else { - if (cur_grant.is_temp_rnti()) { - // Postpone ACK after contention resolution is resolved - pending_ack = ack; - pending_ul_buffer = phy_h->get_ul_buffer(tti+4); - harq_entity->pending_ack_pid = pid; - memcpy(&pending_ack_grant, &cur_grant, sizeof(dl_sched_grant)); - Debug("ACK pending contention resolution\n"); - } else { - Debug("Generating ACK\n"); - // Generate ACK - srslte::ue::ul_buffer *ul_buffer = phy_h->get_ul_buffer(tti+4); - ul_buffer->generate_ack(ack, &cur_grant); - } - } - } else { - fprintf(stderr, "Error with DL grant. TBS (%d) exceeds payload buffer length (%d)\n", cur_grant.get_tbs(), max_payload_len); - } - } -} -// Implement 5.3.2.2 -void dl_harq_entity::dl_harq_process::set_harq_info(srslte::ue::dl_sched_grant* new_grant) { - bool is_new_transmission = false; - bool is_new_tb = true; - if (srslte_tti_interval(new_grant->get_tti(), cur_grant.get_tti()) <= 8 && - new_grant->get_tbs() == cur_grant.get_tbs()) - { + if (srslte_tti_interval(grant.tti, cur_grant.tti) <= 8 && grant.n_bytes == cur_grant.n_bytes) { is_new_tb = false; } - if ((new_grant->get_ndi() != cur_grant.get_ndi() && !is_new_tb) || // NDI toggled for same TB - is_new_tb || // is new TB - (pid == HARQ_BCCH_PID && new_grant->get_rv() == 0)) // Broadcast PID and 1st TX (RV=0) + 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 Info for new transmission\n"); } else { if (!is_new_tb) { - Info("old_tbs=%d, new_tbs=%d, old_tti=%d new_tti=%d\n", cur_grant.get_tbs(), new_grant->get_tbs(), - cur_grant.get_tti(), new_grant->get_tti()); + Info("old_tbs=%d, new_tbs=%d, old_tti=%d new_tti=%d\n", cur_grant.n_bytes, grant.n_bytes, cur_grant.tti, grant.tti); } is_new_transmission = false; Debug("Set HARQ Info for retransmission\n"); } - Info("DL PID %d: %s RV=%d, NDI=%d, LastNDI=%d, DCI %s\n", pid, is_new_transmission?"new TX":"reTX", new_grant->get_rv(), - new_grant->get_ndi(), cur_grant.get_ndi(), new_grant->get_dciformat_string()); + Info("DL PID %d: %s RV=%d, NDI=%d, LastNDI=%d\n", pid, is_new_transmission?"new TX":"reTX", grant.rv, + grant.ndi, cur_grant.ndi); - if (is_new_transmission) { + 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) +{ + + if (is_new_transmission(grant)) { ack = false; srslte_softbuffer_rx_reset(&softbuffer); } - if (new_grant->get_tbs() <= max_payload_len) { - memcpy(&cur_grant, new_grant, sizeof(srslte::ue::dl_sched_grant)); + + // Save grant + memcpy(&cur_grant, &grant, sizeof(mac_interface_phy::mac_grant_t)); + action->default_ack = ack; + action->generate_ack = true; + + // If data has not yet been successfully decoded + if (ack == false) { + + // Instruct the PHY To combine the received data and attempt to decode it + action->decode_enabled = true; + action->rv = cur_grant.rv; + action->rnti = cur_grant.rnti; + action->softbuffer = &softbuffer; + payload_buffer_ptr = harq_entity->demux_unit->request_buffer(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; + } + memcpy(&action->phy_grant, &cur_grant.phy_grant, sizeof(mac_interface_phy::mac_grant_t)); + + Info("DL PID %d: TBS=%d, RV=%d, crc=%s\n", pid, cur_grant.n_bytes, cur_grant.rv, ack?"OK":"NOK"); + } else { - Error("Error with DL grant. TBS (%d) exceeds payload buffer length (%d)\n", new_grant->get_tbs(), max_payload_len); + 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; + + if (pid == HARQ_BCCH_PID) { + // Compute RV + uint32_t k; + if (grant.tti%10 == 5) { // This is SIB1, k is different + k = (grant.tti/20)%4; + } else { + k = (grant.tti/10)%4; + } + action->rv = ((uint32_t) ceilf((float)1.5*k))%4; + } + } else { + if (cur_grant.rnti_type == SRSLTE_RNTI_TEMP) { + // 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 dl_harq_entity::dl_harq_process::tb_decoded_ok() +{ + 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); + } + if (ack) { + Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (BCCH)\n", cur_grant.n_bytes); + harq_entity->demux_unit->release_pdu_bcch(payload_buffer_ptr, cur_grant.n_bytes); + } + } 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->release_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->release_pdu(payload_buffer_ptr, cur_grant.n_bytes); + } + } } } -bool dl_harq_entity::dl_harq_process::init(srslte_cell_t cell, uint32_t max_payload_len_, dl_harq_entity *parent) { - max_payload_len = max_payload_len_; - if (srslte_softbuffer_rx_init(&softbuffer, cell)) { - Error("Error initiating soft buffer\n"); - return false; - } else { - is_initiated = true; - harq_entity = parent; - log_h = harq_entity->log_h; - payload = (uint8_t*) srslte_vec_malloc(sizeof(uint8_t) * max_payload_len); - return payload?true:false; - } -} + } diff --git a/srsapps/ue/mac/src/mac.cc b/srsapps/ue/mac/src/mac.cc index 0c929e3a9..212d57376 100644 --- a/srsapps/ue/mac/src/mac.cc +++ b/srsapps/ue/mac/src/mac.cc @@ -30,49 +30,43 @@ #include #include -#include "srsapps/common/threads.h" -#include "srsapps/ue/phy/phy.h" #include "srsapps/common/log.h" #include "srsapps/ue/mac/mac.h" -#include "srsapps/ue/mac/mac_params.h" #include "srsapps/ue/mac/pcap.h" namespace srslte { namespace ue { - +mac::mac() : ttisync(10240), timers_db((uint32_t) NOF_MAC_TIMERS) +{ + started = false; + pcap = NULL; + si_window_start = -1; + si_window_length = -1; +} -bool mac::init(phy *phy_h_, tti_sync* ttisync_, log* log_h_) +bool mac::init(phy_interface *phy, rlc_interface_mac *rlc, log *log_h_) { started = false; - ttisync = ttisync_; - phy_h = phy_h_; + phy_h = phy; + rlc_h = rlc; log_h = log_h_; tti = 0; is_synchronized = false; last_temporal_crnti = 0; phy_rnti = 0; - is_first_tx = true; - bsr_procedure.init(log_h, &timers_db, ¶ms_db, &mac_io_lch); - mux_unit.init(log_h, &mac_io_lch, &bsr_procedure); - demux_unit.init(phy_h, log_h, &mac_io_lch, &timers_db); - ra_procedure.init(¶ms_db, phy_h, log_h, &timers_db, &mux_unit, &demux_unit); - sr_procedure.init(log_h, ¶ms_db, phy_h); - is_first_of_burst = true; + bsr_procedure.init( rlc_h, log_h, ¶ms_db, &timers_db); + mux_unit.init ( rlc_h, log_h, &bsr_procedure); + demux_unit.init (phy_h, rlc_h, log_h, &timers_db); + ra_procedure.init (phy_h, log_h, ¶ms_db, &timers_db, &mux_unit, &demux_unit); + sr_procedure.init (phy_h, log_h, ¶ms_db); + ul_harq.init ( log_h, ¶ms_db, &timers_db, &mux_unit); + dl_harq.init ( log_h, &timers_db, &demux_unit); + reset(); - for (int i=0;ipdcch_dl_search_reset(); + phy_h->pdcch_ul_search_reset(); + + params_db.set_param(mac_interface_params::BCCH_SI_WINDOW_ST, -1); + params_db.set_param(mac_interface_params::BCCH_SI_WINDOW_LEN, -1); } -void* mac::mac_thread_fnc(void *arg) { - srslte::ue::mac* mac = static_cast(arg); - mac->main_radio_loop(); - return NULL; -} - -void mac::main_radio_loop() { +void mac::run_thread() { setup_timers(); + + Info("Waiting PHY to synchronize with cell\n"); + phy_h->sync_start(); + while(!phy_h->get_current_tti()) { + usleep(50000); + } + + ttisync.set_producer_cntr(phy_h->get_current_tti()); + while(started) { - if (!is_synchronized) { - srslte_cell_t cell; - uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; - - if (phy_h->decode_mib_best(&cell, bch_payload)) { - - // Print MIB - srslte_cell_fprint(stdout, &cell, phy_h->get_current_tti()/10); - if (pcap) { - pcap->write_dl_bch(bch_payload, SRSLTE_BCH_PAYLOAD_LEN/8, true, phy_h->get_current_tti()); - } - - // Init HARQ for this cell - Info("Init UL/DL HARQ\n"); - ul_harq.init(cell, ¶ms_db, log_h, &timers_db, &mux_unit); - dl_harq.init(cell, 1024*1024, log_h, &timers_db, &demux_unit); - - // Set the current PHY cell to the detected cell - Info("Setting up PHY for cell_id=%d\n", cell.id); - if (phy_h->set_cell(cell)) { - Info("Starting RX streaming\n"); - if (phy_h->start_rxtx()) { - log_h->step(ttisync->wait()); + /* Warning: Here order of invocation of procedures is important!! */ + tti = ttisync.wait(); - Info("Receiver synchronized\n"); - - // Send MIB to RRC - mac_io_lch.get(mac_io::MAC_LCH_BCCH_DL)->send(bch_payload, SRSLTE_BCH_PAYLOAD_LEN); - - ttisync->resync(); - Info("Wait for AGC, CFO estimation, etc. \n"); - for (int i=0;i<1000;i++) { - tti = ttisync->wait(); - } - for (int i=0;iwait(); - tr_log_start(tti); - log_h->step(tti); - - // Step all procedures - bsr_procedure.step(tti); - - // Check if BSR procedure need to start SR - - if (bsr_procedure.need_to_send_sr()) { - Debug("Starting SR procedure by BSR request, PHY TTI=%d\n", phy_h->get_current_tti()); - sr_procedure.start(); - } - if (bsr_procedure.need_to_reset_sr()) { - Debug("Resetting SR procedure by BSR request\n"); - sr_procedure.reset(); - } - sr_procedure.step(tti); - - // Check SR if we need to start RA - if (sr_procedure.need_random_access()) { - Warning("Starting RA procedure by MAC order is DISABLED\n"); - //ra_procedure.start_mac_order(); - } - - ra_procedure.step(tti); - //phr_procedure.step(tti); - - timers_db.step_all(); + log_h->step(tti); - // Trigger execution of corresponding TTI processor thread - //printf("triggering tti=%d\n", tti); - tti_threads_sync[tti%NOF_TTI_THREADS].increase(); - //tti_threads[0].run_tti(tti); - + // Step all procedures + bsr_procedure.step(tti); + + // Check if BSR procedure need to start SR + + if (bsr_procedure.need_to_send_sr()) { + Debug("Starting SR procedure by BSR request, PHY TTI=%d\n", phy_h->get_current_tti()); + sr_procedure.start(); } + if (bsr_procedure.need_to_reset_sr()) { + Debug("Resetting SR procedure by BSR request\n"); + sr_procedure.reset(); + } + sr_procedure.step(tti); + + // Check SR if we need to start RA + if (sr_procedure.need_random_access()) { + Warning("Starting RA procedure by MAC order is DISABLED\n"); + //ra_procedure.start_mac_order(); + } + + ra_procedure.step(tti); + //phr_procedure.step(tti); + + timers_db.step_all(); + + search_si_rnti(); + + demux_unit.process_pdus(); } } - -struct phy_crnti { - phy *phy_ptr; - log *log_h; - uint16_t crnti; -}; - -void *pregen_phy_thread(void *arg) { - struct phy_crnti *a = (struct phy_crnti*) arg; - a->log_h->info("Setting PHY RNTI=%d\n", a->crnti); - a->phy_ptr->set_crnti(a->crnti); - a->phy_ptr->pregen_signals(); - a->log_h->info("Done Setting PHY RNTI\n"); - free(a); - return NULL; +void mac::search_si_rnti() +{ + // Reset PDCCH search + if (si_window_length >= 0 && si_window_start >= 0) { + if (tti >= si_window_start + si_window_length) { + phy_h->pdcch_dl_search_reset(); + } + } + + // Setup PDCCH search + int _si_window_start = params_db.get_param(mac_interface_params::BCCH_SI_WINDOW_ST); + int _si_window_length = params_db.get_param(mac_interface_params::BCCH_SI_WINDOW_LEN); + + if (_si_window_length > 0 && _si_window_start >= 0) { + si_window_length = _si_window_length; + si_window_start = _si_window_start; + Debug("Searching for DL grant for SI-RNTI window_st=%d, window_len=%d\n", si_window_start, si_window_length); + phy_h->pdcch_dl_search(SRSLTE_RNTI_SI, 0xffff, si_window_start, si_window_length); + params_db.set_param(mac_interface_params::BCCH_SI_WINDOW_ST, -1); + params_db.set_param(mac_interface_params::BCCH_SI_WINDOW_LEN, -1); + } } -void mac::pregen_phy(uint16_t phy_rnti) +void mac::tti_clock(uint32_t tti) { - pthread_t rnti_thread; - struct phy_crnti *arg = (struct phy_crnti*) malloc(sizeof(struct phy_crnti)); - arg->crnti = phy_rnti; - arg->phy_ptr = phy_h; - arg->log_h = log_h; - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_attr_setschedpolicy(&attr, SCHED_OTHER); - if (pthread_create(&rnti_thread, &attr, pregen_phy_thread, arg)) { - perror("pthread_create"); + ttisync.increase(); +} + +void mac::bch_decoded_ok(uint8_t* payload, uint32_t len) +{ + // Send MIB to RRC + rlc_h->write_pdu_bcch_bch(payload, len); + + if (pcap) { + pcap->write_dl_bch(payload, len, true, phy_h->get_current_tti()); } } -void mac::add_sdu_handler(sdu_handler *handler) { - demux_unit.add_sdu_handler(handler); +void mac::harq_recv(uint32_t tti, bool ack, mac_interface_phy::tb_action_ul_t* action) +{ + ul_harq.harq_recv(tti, ack, action); } +void mac::new_grant_dl(mac_interface_phy::mac_grant_t grant, mac_interface_phy::tb_action_dl_t* action) +{ + if (grant.rnti_type == SRSLTE_RNTI_RAR) { + ra_procedure.new_grant_dl(grant, action); + } else { + dl_harq.new_grant_dl(grant, action); + } +} + +uint32_t mac::get_current_tti() +{ + return phy_h->get_current_tti(); +} + +void mac::new_grant_ul(mac_interface_phy::mac_grant_t grant, uint8_t* payload_ptr, + mac_interface_phy::tb_action_ul_t* action) +{ + ul_harq.new_grant_ul(grant, payload_ptr, action); +} + +void mac::new_grant_ul_ack(mac_interface_phy::mac_grant_t grant, uint8_t* payload_ptr, bool ack, + mac_interface_phy::tb_action_ul_t* action) +{ + ul_harq.new_grant_ul_ack(grant, payload_ptr, ack, action); +} + +void mac::tb_decoded_ok(uint32_t harq_pid) +{ + if (ra_procedure.in_progress()) { + ra_procedure.tb_decoded_ok(); + } else { + dl_harq.tb_decoded_ok(harq_pid); + } +} + + void mac::setup_timers() { - if (params_db.get_param(mac_params::TIMER_TIMEALIGN) > 0) { - timers_db.get(TIME_ALIGNMENT)->set(this, params_db.get_param(mac_params::TIMER_TIMEALIGN)); + if (params_db.get_param(mac_interface_params::TIMER_TIMEALIGN) > 0) { + timers_db.get(TIME_ALIGNMENT)->set(this, params_db.get_param(mac_interface_params::TIMER_TIMEALIGN)); } } -static sched_grant::rnti_type_t rnti_type(int rnti_param_id) { - switch(rnti_param_id) { - case mac_params::RNTI_C: - return sched_grant::RNTI_TYPE_CRNTI; - case mac_params::RNTI_TEMP: - return sched_grant::RNTI_TYPE_TEMP; - case mac_params::RNTI_SPS: - return sched_grant::RNTI_TYPE_SPS; - case mac_params::RNTI_RA: - return sched_grant::RNTI_TYPE_RA; - } -} - -uint32_t mac::get_harq_sps_pid(uint32_t tti) { - uint32_t nof_proc = ((uint32_t) params_db.get_param(mac_params::SPS_DL_NOF_PROC)); - return tti/params_db.get_param(mac_params::SPS_DL_SCHED_INTERVAL)%nof_proc; - -} void mac::timer_expired(uint32_t timer_id) { @@ -364,366 +266,32 @@ void mac::timer_expired(uint32_t timer_id) } /* Function called on expiry of TimeAlignmentTimer */ -void mac::timeAlignmentTimerExpire() { +void mac::timeAlignmentTimerExpire() +{ dl_harq.reset(); ul_harq.reset(); - dl_sps_assig.clear(); - ul_sps_assig.clear(); } -// Receive PCH when requested as defined in Section 5.5 -void mac::receive_pch(uint32_t tti) { - if (params_db.get_param(mac_params::PCCH_RECEIVE)) { - dl_buffer *dl_buffer = phy_h->get_dl_buffer(tti); - dl_sched_grant pch_grant(sched_grant::RNTI_TYPE_PRNTI, SRSLTE_PRNTI); - if (dl_buffer->get_dl_grant(&pch_grant)) { - qbuff *pcch_buff = mac_io_lch.get(mac_io::MAC_LCH_PCCH_DL); - uint8_t *ptr = (uint8_t*) pcch_buff->request(); - if (ptr && pch_grant.get_tbs() <= mac_io_lch.DEFAULT_MSG_SZ) { - if (dl_buffer->decode_data(&pch_grant, ptr)) { - pcch_buff->release(); - } else { - Warning("Error decoding PCH\n"); - } - } else { - Error("Error getting pointer from PCCH buffer\n"); - } - } else { - Debug("No P-RNTI grant found while looking for PCH messages\n"); - } - } -} - -/* This function controls DL Grant Assignment as specified in Section 5.3.1 in 36.321 - * and issues commands to DL harq operation - */ -void mac::process_dl_grants(uint32_t tti) { - // Get DL buffer for this TTI - dl_buffer *dl_buffer = phy_h->get_dl_buffer(tti); - - // 5.3.1 DL Assignment reception - for (int i = mac_params::RNTI_C;i<=mac_params::RNTI_RA;i++) { - // Check C-RNTI, SPS-RNTI and Temporal RNTI - if (params_db.get_param(i) != 0) { - dl_sched_grant ue_grant(rnti_type(i), params_db.get_param(i)); - if (dl_buffer->get_dl_grant(&ue_grant)) { - // If PDCCH for C-RNTI and RA procedure in Contention Resolution, notify it - if (ra_procedure.is_contention_resolution() && i == mac_params::RNTI_C) { - ra_procedure.pdcch_to_crnti(false); - } - if (i != mac_params::RNTI_SPS) { - uint32_t harq_pid = ue_grant.get_harq_process(); - if (i == mac_params::RNTI_TEMP && last_temporal_crnti != params_db.get_param(i)) { - ue_grant.set_ndi(true); - Info("Set NDI=1 for Temp-RNTI DL grant\n"); - last_temporal_crnti = params_db.get_param(i); - } - if (i == mac_params::RNTI_C && dl_harq.is_sps(harq_pid)) { - ue_grant.set_ndi(true); - Info("Set NDI=1 for C-RNTI DL grant\n"); - } - dl_harq.set_harq_info(harq_pid, &ue_grant); - dl_harq.receive_data(tti, harq_pid, dl_buffer, phy_h); - } else { - /* This is for SPS scheduling */ - uint32_t harq_pid = get_harq_sps_pid(tti); - if (ue_grant.get_ndi()) { - ue_grant.set_ndi(false); - dl_harq.set_harq_info(harq_pid, &ue_grant); - dl_harq.receive_data(tti, harq_pid, dl_buffer, phy_h); - } else { - if (ue_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 { - dl_sps_assig.reset(tti, &ue_grant); - ue_grant.set_ndi(true); - dl_harq.set_harq_info(harq_pid, &ue_grant); - } - } - } - } - } - } - /* Process configured DL assingments (SPS) */ - dl_sched_grant *sps_grant = dl_sps_assig.get_pending_grant(tti); - if (sps_grant != NULL) { - Info("Processing SPS grant\n"); - uint32_t harq_pid = get_harq_sps_pid(tti); - sps_grant->set_ndi(true); - dl_harq.set_harq_info(harq_pid, sps_grant); - dl_harq.receive_data(tti, harq_pid, dl_buffer, phy_h); - } - - /* Process SI-RNTI */ - uint32_t si_window_start = params_db.get_param(mac_params::BCCH_SI_WINDOW_ST); - uint32_t si_window_length = params_db.get_param(mac_params::BCCH_SI_WINDOW_LEN); - - if (tti >= si_window_start && tti < (si_window_start + si_window_length)) { - // Exclude subf 5 and sfn%2==0 unless it's a SIB1 message (window_length=1) (This is defined in 36.331 Sec 5.2.3) - if (!(phy_h->tti_to_subf(si_window_length) != 1 && - phy_h->tti_to_subf(si_window_start) == 5 && (phy_h->tti_to_SFN(tti)%2) == 0)) - { - Debug("Searching for DL grant for SI-RNTI window_st=%d, window_len=%d\n", si_window_start, si_window_length); - dl_sched_grant si_grant(sched_grant::RNTI_TYPE_SIRNTI, SRSLTE_SIRNTI); - if (dl_buffer->get_dl_grant(&si_grant)) { - uint32_t k; - if (phy_h->tti_to_subf(si_window_start) == 5) { // This is SIB1, k is different - k = (phy_h->tti_to_SFN(tti)/2)%4; - } else { - k = phy_h->tti_to_subf(tti)%4; - } - si_grant.set_rv(((uint32_t) ceilf((float)1.5*k))%4); - Info("DL grant found, sending to HARQ with RV: %d\n", si_grant.get_rv()); - dl_harq.set_harq_info(dl_harq_entity::HARQ_BCCH_PID, &si_grant); - dl_harq.receive_data(tti, dl_harq_entity::HARQ_BCCH_PID, dl_buffer, phy_h); - params_db.set_param(mac_params::BCCH_SI_WINDOW_ST, 0); - params_db.set_param(mac_params::BCCH_SI_WINDOW_LEN, 0); - } - } - - } -} - -/* UL Grant reception and processin as defined in Section 5.4.1 in 36.321 */ -bool mac::process_ul_grants(uint32_t tti) { - // Get DL buffer for this TTI to look for DCI grants - dl_buffer *dl_buffer = phy_h->get_dl_buffer(tti); - - //if (timers_db.get(TIME_ALIGNMENT)->is_running()) { - if (1) { - for (int i = mac_params::RNTI_C;i<=mac_params::RNTI_TEMP;i++) { - // Check C-RNTI, SPS-RNTI and Temporal C-RNTI - if (params_db.get_param(i) != 0) { - ul_sched_grant ul_grant(rnti_type(i), params_db.get_param(i)); - if (dl_buffer->get_ul_grant(&ul_grant)) { - if (ul_grant.is_from_rar()) { - dl_buffer->discard_pending_rar_grant(); - } - if (ra_procedure.is_contention_resolution() && i == mac_params::RNTI_C) { - ra_procedure.pdcch_to_crnti(true); - } - if (i == mac_params::RNTI_C || i == mac_params::RNTI_TEMP || ra_procedure.is_running()) { - if (i == mac_params::RNTI_C && ul_harq.is_sps(tti)) { - ul_grant.set_ndi(true); - } - ul_harq.run_tti(tti, &ul_grant, phy_h); - return true; - } - else if (i == mac_params::RNTI_SPS) { - if (ul_grant.get_ndi()) { - ul_grant.set_ndi(false); - ul_harq.run_tti(tti, &ul_grant, phy_h); - } else { - if (ul_grant.is_sps_release()) { - ul_sps_assig.clear(); - } else { - ul_sps_assig.reset(tti, &ul_grant); - ul_grant.set_ndi(true); - ul_harq.run_tti(tti, &ul_grant, phy_h); - return true; - } - } - } - } - } - } - /* Process configured UL assingments (SPS) */ - ul_sched_grant *sps_grant = ul_sps_assig.get_pending_grant(tti); - if (sps_grant != NULL) { - sps_grant->set_ndi(true); - ul_harq.run_tti(tti, sps_grant, phy_h); - return true; - } - } - ul_harq.run_tti(tti, phy_h); - return false; -} - - -int mac::recv_sdu(uint32_t lcid, uint8_t* sdu_payload, uint32_t nbytes) -{ - if (lcid <= mac_io::MAC_LCH_PCCH_DL) { - return mac_io_lch.get(lcid)->recv(sdu_payload, nbytes); - } else { - Error("Receiving SDU: Invalid lcid=%d\n", lcid); - return -1; - } -} - -int mac::recv_bcch_sdu(uint8_t* sdu_payload, uint32_t buffer_len_nbytes) -{ - return mac_io_lch.get(mac_io::MAC_LCH_BCCH_DL)->recv(sdu_payload, buffer_len_nbytes); -} - -int mac::recv_ccch_sdu(uint8_t* sdu_payload, uint32_t buffer_len_nbytes) -{ - return mac_io_lch.get(mac_io::MAC_LCH_CCCH_DL)->recv(sdu_payload, buffer_len_nbytes); -} - -int mac::recv_dtch0_sdu(uint8_t* sdu_payload, uint32_t buffer_len_nbytes) -{ - return mac_io_lch.get(mac_io::MAC_LCH_DTCH0_DL)->recv(sdu_payload, buffer_len_nbytes); -} - -int mac::recv_dcch0_sdu(uint8_t* sdu_payload, uint32_t buffer_len_nbytes) -{ - return mac_io_lch.get(mac_io::MAC_LCH_DCCH0_DL)->recv(sdu_payload, buffer_len_nbytes); -} - - -bool mac::send_sdu(uint32_t lcid, uint8_t* sdu_payload, uint32_t nbytes) -{ - lcid += mac_io::MAC_LCH_CCCH_UL; - if (lcid <= mac_io::MAC_LCH_DTCH2_UL) { - return mac_io_lch.get(lcid)->send(sdu_payload, nbytes); - } else { - Error("Receiving SDU: Invalid lcid=%d\n", lcid); - return -1; - } -} - -bool mac::send_ccch_sdu(uint8_t* sdu_payload, uint32_t nbytes) -{ - return mac_io_lch.get(mac_io::MAC_LCH_CCCH_UL)->send(sdu_payload, nbytes); -} - -bool mac::send_dtch0_sdu(uint8_t* sdu_payload, uint32_t nbytes) -{ - return mac_io_lch.get(mac_io::MAC_LCH_DTCH0_UL)->send(sdu_payload, nbytes); -} - -bool mac::send_dcch0_sdu(uint8_t* sdu_payload, uint32_t nbytes) -{ - return mac_io_lch.get(mac_io::MAC_LCH_DCCH0_UL)->send(sdu_payload, nbytes); -} - -void mac::set_param(mac_params::mac_param_t param, int64_t value) +void mac::set_param(mac_interface_params::mac_param_t param, int64_t value) { params_db.set_param((uint32_t) param, value); } -int64_t mac::get_param(mac_params::mac_param_t param) +int64_t mac::get_param(mac_interface_params::mac_param_t param) { return params_db.get_param((uint32_t) param); } void mac::setup_lcid(uint32_t lcid, uint32_t lcg, uint32_t priority, int PBR_x_tti, uint32_t BSD) { - Info("Logical Channel Setup: LCID=%d, LCG=%d, priority=%d, PBR=%d, BSd=%d\n", lcid, lcg, priority, PBR_x_tti, BSD); + Info("Logical Channel Setup: LCID=%d, LCG=%d, priority=%d, PBR=%d, BSd=%d\n", + lcid, lcg, priority, PBR_x_tti, BSD); mux_unit.set_priority(lcid, priority, PBR_x_tti, BSD); bsr_procedure.setup_lcg(lcid, lcg); bsr_procedure.set_priority(lcid, priority); } - -void* tti_thread_runner(void *arg) { - mac::tti_thread* x = (mac::tti_thread*) arg; - x->run(); - return NULL; -} - -bool mac::tti_thread::init(mac* parent_, tti_sync_cv *sync_) -{ - parent = parent_; - log_h = parent->log_h; - sync = sync_; - - started = threads_new_rt(&thread, tti_thread_runner, this); - return started; -} - -void mac::tti_thread::stop() -{ - started = false; - pthread_join(thread, NULL); -} - -void mac::tti_thread::run() -{ - while(started) { - uint32_t tti = sync->wait(); - - if (parent->is_synchronized) { - run_tti((tti+1)%10240); - } - } -} - -void mac::tti_thread::run_tti(uint32_t tti) { - //printf("running tti=%d\n", tti); - // Receive PCH, if requested - parent->receive_pch(tti); - - // Process DL grants always - parent->process_dl_grants(tti); - - // Send pending HARQ ACK, if any, and contention resolution is resolved - if (parent->dl_harq.is_ack_pending_resolution()) { - parent->ra_procedure.step(tti); - if (parent->ra_procedure.is_successful() || parent->ra_procedure.is_response_error()) { - Info("Sending pending ACK for contention resolution PHY TTI: %d\n", parent->phy_h->get_current_tti()); - parent->dl_harq.send_pending_ack_contention_resolution(); - } - } - - // Process UL grants if RA procedure is done or in contention resolution - if (parent->ra_procedure.is_contention_resolution() || parent->ra_procedure.is_successful()) { - parent->process_ul_grants(tti); - } - - // If ACK/SR was pending but there was no PUSCH transmission, transmit now through PUCCH - ul_buffer *ul_buffer = parent->phy_h->get_ul_buffer(tti+4); - - // Generate scheduling request if we have to - if (parent->phy_h->sr_is_ready_to_send(tti+4)) { - ul_buffer->generate_sr(); - } - - // If the packet was not generated by an UL grant, means it's PUCCH or SRS. Generate now the signal - if (!ul_buffer->is_released() && (ul_buffer->uci_ready() || ul_buffer->srs_is_ready_to_send())) { - ul_buffer->generate_data(); - } - - // Wait for previous TTI to be transmitted - if (!parent->is_first_tx) { - pthread_mutex_lock(&parent->tti_threads_sync_tx[tti%parent->NOF_TTI_THREADS]); - } - parent->is_first_tx = false; - - // Send now to the radio - if (ul_buffer->is_released()) { - ul_buffer->send(); - ul_buffer->ready(); - parent->is_first_of_burst = false; - } else { - if (!parent->is_first_of_burst) { - ul_buffer->send_end_of_burst(); - parent->is_first_of_burst = true; - } - } - - // Allow next TTI to be transmitted - pthread_mutex_unlock(&parent->tti_threads_sync_tx[(tti+1)%parent->NOF_TTI_THREADS]); - - // Check if there is pending CCCH SDU in Multiplexing Unit - if (parent->mux_unit.is_pending_ccch_sdu()) { - // Start RA procedure - if (!parent->ra_procedure.in_progress() && !parent->ra_procedure.is_successful()) { - parent->ra_procedure.start_rlc_order(); - } - } - if (parent->ra_procedure.is_successful() && - parent->phy_rnti != parent->params_db.get_param(mac_params::RNTI_C) && - parent->params_db.get_param(mac_params::RNTI_C) > 0 && - parent->phy_h->get_param(srslte::ue::phy_params::SRS_IS_CONFIGURED) == 1) - { - parent->phy_rnti = parent->params_db.get_param(mac_params::RNTI_C); - parent->pregen_phy(parent->phy_rnti); - } -} } } + + diff --git a/srsapps/ue/mac/src/mac_pcap.cc b/srsapps/ue/mac/src/mac_pcap.cc index c9539a804..585cca804 100644 --- a/srsapps/ue/mac/src/mac_pcap.cc +++ b/srsapps/ue/mac/src/mac_pcap.cc @@ -55,23 +55,18 @@ void mac_pcap::pack_and_write(uint8_t* pdu, uint32_t pdu_len_bytes, uint32_t reT uint16_t crnti, uint8_t direction, uint8_t rnti_type) { if (enable_write) { - if (pdu_len_bytes < max_pdu_len) { - MAC_Context_Info_t context = - { - FDD_RADIO, direction, rnti_type, - crnti, /* RNTI */ - ue_id, /* UEId */ - reTX, /* Retx */ - crc_ok, /* CRC Stsatus (i.e. OK) */ - tti/10, /* Sysframe number */ - tti%10 /* Subframe number */ - }; - if (pdu) { - srslte_bit_unpack_vector(pdu, pdu_pcap_tmp, pdu_len_bytes*8); - MAC_LTE_PCAP_WritePDU(pcap_file, &context, pdu_pcap_tmp, pdu_len_bytes); - } - } else { - fprintf(stderr, "MAC PCAP: PDU len %d exceeds maximum allowed length (%d bytes)\n", pdu_len_bytes, max_pdu_len); + MAC_Context_Info_t context = + { + FDD_RADIO, direction, rnti_type, + crnti, /* RNTI */ + ue_id, /* UEId */ + reTX, /* Retx */ + crc_ok, /* CRC Stsatus (i.e. OK) */ + tti/10, /* Sysframe number */ + tti%10 /* Subframe number */ + }; + if (pdu) { + MAC_LTE_PCAP_WritePDU(pcap_file, &context, pdu, pdu_len_bytes); } } } diff --git a/srsapps/ue/mac/src/mux.cc b/srsapps/ue/mac/src/mux.cc index e6935682e..d126b0630 100644 --- a/srsapps/ue/mac/src/mux.cc +++ b/srsapps/ue/mac/src/mux.cc @@ -32,18 +32,14 @@ namespace srslte { namespace ue { -#define IO_IDX(lch) (lch + mac_io::MAC_LCH_CCCH_UL) -#define UL_IDX(lch) (lch - mac_io::MAC_LCH_CCCH_UL) - mux::mux() : pdu_msg(20) { - msg3_buff.init(mac::NOF_TTI_THREADS, MSG3_BUFF_SZ); - pdu_buff.init(mac::NOF_TTI_THREADS, PDU_BUFF_SZ); - bzero(nof_tx_pkts, sizeof(uint32_t) * mac_io::NOF_UL_LCH); + msg3_buff.init(1, MSG3_BUFF_SZ); + pthread_mutex_init(&mutex, NULL); msg3_has_been_transmitted = false; - for (int i=0;iget(i)->isempty()) { + for (int i=0;iget_buffer_state(i)) { return true; } } @@ -82,30 +78,27 @@ bool mux::is_pending_any_sdu() } bool mux::is_pending_sdu(uint32_t lch_id) { - lch_id += (uint32_t) mac_io::MAC_LCH_CCCH_UL; - if (lch_id < mac_io::MAC_NOF_QUEUES) { - return !mac_io_h->get(lch_id)->isempty(); - } + return rlc->get_buffer_state(lch_id)>0; } void mux::set_priority(uint32_t lch_id, uint32_t set_priority, int set_PBR, uint32_t set_BSD) { pthread_mutex_lock(&mutex); - if (lch_id < mac_io::NOF_UL_LCH) { + if (lch_id < NOF_UL_LCH) { priority[lch_id] = set_priority; PBR[lch_id] = set_PBR; BSD[lch_id] = set_BSD; // Insert priority in sorted idx array int new_index = 0; - while(set_priority > priority_sorted[new_index] && new_index < mac_io::NOF_UL_LCH) { + while(set_priority > priority_sorted[new_index] && new_index < NOF_UL_LCH) { new_index++; } int old_index = 0; - while(lch_id != lchid_sorted[old_index] && new_index < mac_io::NOF_UL_LCH) { + while(lch_id != lchid_sorted[old_index] && new_index < NOF_UL_LCH) { old_index++; } - if (new_index == mac_io::NOF_UL_LCH) { + if (new_index == NOF_UL_LCH) { Error("Can't find LchID=%d in sorted list\n", lch_id); return; } @@ -122,56 +115,6 @@ void mux::set_priority(uint32_t lch_id, uint32_t set_priority, int set_PBR, uint } -void mux::pdu_release() -{ - pdu_buff.release(); - pthread_mutex_unlock(&mutex); -} - -bool mux::pdu_move_to_msg3(uint32_t pdu_sz) -{ - if (pdu_buff.isempty()) { - if (assemble_pdu(pdu_sz)) { - if (pdu_buff.pending_data() < MSG3_BUFF_SZ) { - pdu_buff.move_to(&msg3_buff); - return true; - } else { - pdu_buff.release(); - Error("Assembled PDU size exceeds Msg3 buffer size\n"); - return false; - } - } else { - Error("Assembling PDU\n"); - return false; - } - } else { - Error("Generating PDU: PDU pending in buffer for transmission\n"); - return false; - } -} - -// Multiplexing and logical channel priorization as defined in Section 5.4.3 -uint8_t* mux::pdu_pop(uint32_t pdu_sz) -{ - // Acquire mutex. Will be released after a call to pdu_release - pthread_mutex_lock(&mutex); - - if (pdu_buff.isempty()) { - if (assemble_pdu(pdu_sz)) { - return (uint8_t*) pdu_buff.pop(); - } else { - return NULL; - } - } else { - Error("Generating PDU: PDU pending in buffer for transmission\n"); - return NULL; - } -} - -void mux::append_crnti_ce_next_tx(uint16_t crnti) { - pending_crnti_ce = crnti; -} - sch_subh::cetype bsr_format_convert(bsr_proc::bsr_format_t format) { switch(format) { case bsr_proc::LONG_BSR: @@ -179,24 +122,21 @@ sch_subh::cetype bsr_format_convert(bsr_proc::bsr_format_t format) { case bsr_proc::SHORT_BSR: return sch_subh::SHORT_BSR; case bsr_proc::TRUNC_BSR: - return sch_subh::TRUNC_BSR; - + return sch_subh::TRUNC_BSR; } } -int pkt_num=0; -bool mux::assemble_pdu(uint32_t pdu_sz_nbits) { - uint8_t *buff = (uint8_t*) pdu_buff.request(); - if (!buff) { - Error("Assembling PDU: Buffer is not available\n"); - return false; - } - - // Make sure pdu_sz is byte-aligned - pdu_sz_nbits = 8*(pdu_sz_nbits/8); - + +int pkt_num = 0; + +// Multiplexing and logical channel priorization as defined in Section 5.4.3 +bool mux::pdu_get(uint8_t *payload, uint32_t pdu_sz) +{ + + pthread_mutex_lock(&mutex); + // Update Bj - for (int i=0;i= 0) { Bj[i] += PBR[i]; @@ -207,16 +147,14 @@ bool mux::assemble_pdu(uint32_t pdu_sz_nbits) { } // Logical Channel Procedure - - uint32_t sdu_sz = 0; - - pdu_msg.init(pdu_sz_nbits/8, true); + + pdu_msg.init(pdu_sz, true); // MAC control element for C-RNTI or data from UL-CCCH bool is_first = true; - if (!allocate_sdu(UL_IDX(mac_io::MAC_LCH_CCCH_UL), &pdu_msg, &is_first)) { + if (!allocate_sdu(0, &pdu_msg, &is_first)) { if (pending_crnti_ce) { - if (pdu_msg.new_subh()) { + if (pdu_msg.new_subh()) {http://moodycamel.com/blog/2014/detailed-design-of-a-lock-free-queue pdu_msg.next(); if (!pdu_msg.get()->set_c_rnti(pending_crnti_ce)) { Warning("Pending C-RNTI CE could not be inserted in MAC PDU\n"); @@ -250,29 +188,25 @@ bool mux::assemble_pdu(uint32_t pdu_sz_nbits) { // data from any Logical Channel, except data from UL-CCCH; // first only those with positive Bj - for (int i=0;i 0 || PBR[i] < 0) && res) { - res = allocate_sdu(lchid_sorted[i], &pdu_msg, &sdu_sz, &is_first); - if (res && PBR[i] >= 0) { - Bj[i] -= sdu_sz; + uint32_t sdu_sz = 0; + for (int i=0;i 0 || PBR[lcid] < 0) && res) { + res = allocate_sdu(lcid, &pdu_msg, Bj[lcid], &sdu_sz, &is_first); + if (res && PBR[lcid] >= 0) { + Bj[lcid] -= sdu_sz; + } } } } // If resources remain, allocate regardless of their Bj value - for (int i=0;i 0) { - mac_io_h->get(IO_IDX(i))->release(); - nof_tx_pkts[i]--; - } - } - bool send_bsr = bsr_procedure->generate_bsr_on_ul_grant(pdu_msg.rem_size(), &bsr); // Insert Padding BSR if not inserted Regular/Periodic BSR if (!bsr_payload_sz && send_bsr) { @@ -287,55 +221,58 @@ bool mux::assemble_pdu(uint32_t pdu_sz_nbits) { bsr_subh->set_bsr(bsr.buff_size, bsr_format_convert(bsr.format), bsr_payload_sz?false:true); } - Debug("Assembled MAC PDU msg size %d/%d bytes\n", pdu_msg.size(), pdu_sz_nbits/8); - //pdu_msg.fprint(stdout); + Debug("Assembled MAC PDU msg size %d/%d bytes\n", pdu_msg.size(), pdu_sz); + + pthread_mutex_unlock(&mutex); /* Generate MAC PDU and save to buffer */ - if (pdu_msg.write_packet(buff)) { - pdu_buff.push(pdu_sz_nbits); - } else { + if (!pdu_msg.write_packet(payload, rlc)) { Error("Writing PDU message to packet\n"); return false; - } - return true; + } else { + return true; + } } +void mux::append_crnti_ce_next_tx(uint16_t crnti) { + pending_crnti_ce = crnti; +} + + bool mux::allocate_sdu(uint32_t lcid, sch_pdu *pdu_msg) { - return allocate_sdu(lcid, pdu_msg, NULL, NULL); + return allocate_sdu(lcid, pdu_msg, -1, NULL, NULL); } bool mux::allocate_sdu(uint32_t lcid, sch_pdu *pdu_msg, bool *is_first) { - return allocate_sdu(lcid, pdu_msg, NULL, is_first); + return allocate_sdu(lcid, pdu_msg, -1, NULL, is_first); } -bool mux::allocate_sdu(uint32_t lcid, sch_pdu *pdu_msg, uint32_t *sdu_sz, bool *is_first) +bool mux::allocate_sdu(uint32_t lcid, sch_pdu *pdu_msg, int max_sdu_sz, uint32_t *sdu_sz, bool *is_first) { // Get n-th pending SDU pointer and length - uint32_t buff_len = 0; - uint8_t *buff_ptr = (uint8_t*) mac_io_h->get(mac_io::MAC_LCH_CCCH_UL + lcid)->pop(&buff_len, nof_tx_pkts[lcid]); + uint32_t sdu_len = rlc->get_buffer_state(lcid); - uint32_t nbytes = (buff_len-1)/8 + 1; - - if (buff_ptr && buff_len > 0) { // there is pending SDU to allocate - if (sdu_sz) { - *sdu_sz = buff_len; + if (sdu_len > 0) { // there is pending SDU to allocate + if (sdu_len > max_sdu_sz && max_sdu_sz >= 0) { + sdu_len = max_sdu_sz; + } + if (sdu_len > pdu_msg->rem_size() - pdu_msg->size_plus_header_sdu(sdu_len)) { + sdu_len = pdu_msg->rem_size() - pdu_msg->size_plus_header_sdu(sdu_len); } if (pdu_msg->new_subh()) { // there is space for a new subheader pdu_msg->next(); - if (pdu_msg->get()->set_sdu(lcid, buff_ptr, nbytes, is_first?*is_first:false)) { // new SDU could be added + if (pdu_msg->get()->set_sdu(lcid, sdu_len, is_first?*is_first:false)) { // new SDU could be added if (is_first) { *is_first = false; } - Info("Allocated SDU lcid=%d nbytes=%d\n", lcid, nbytes); - // Increase number of pop'ed packets from queue - nof_tx_pkts[lcid]++; + if (sdu_sz) { + *sdu_sz = sdu_len; + } + Info("Allocated SDU lcid=%d nbytes=%d\n", lcid, sdu_len); return true; } else { - if (pdu_msg->rem_size() > 10) { - Info("Could not allocate SDU in current grant. SDU length: %d bytes. Grant space: %d bytes\n", nbytes, - pdu_msg->rem_size()); - } + Error("Could not add SDU rem_size=%d, sdu_len=%d\n", pdu_msg->rem_size(), sdu_len); pdu_msg->del_subh(); } } @@ -343,8 +280,6 @@ bool mux::allocate_sdu(uint32_t lcid, sch_pdu *pdu_msg, uint32_t *sdu_sz, bool * return false; } - - void mux::msg3_flush() { msg3_buff.flush(); @@ -361,23 +296,37 @@ bool mux::msg3_is_transmitted() return msg3_has_been_transmitted; } -/* Returns a pointer to the Msg3 buffer */ -uint8_t* mux::msg3_pop(uint32_t TB_size) + +bool mux::pdu_move_to_msg3(uint32_t pdu_sz) { - uint32_t len; - uint8_t *msg3 = (uint8_t*) msg3_buff.pop(&len); + uint8_t *msg3 = (uint8_t*) msg3_buff.request(); if (msg3) { - if (len < TB_size) { - // Pad with zeros without exceeding maximum buffer size - if (TB_size <= MSG3_BUFF_SZ) { - bzero(&msg3[len], (TB_size-len)*sizeof(uint8_t)); - } else { - Error("Requested TB size from Msg3 buffer exceeds buffer size (%d>%d)\n", TB_size, MSG3_BUFF_SZ); - return NULL; - } - } + if (pdu_get(msg3, pdu_sz)) { + msg3_buff.push(pdu_sz); + return true; + } else { + Error("Assembling PDU\n"); + } + } else { + Error("Generating PDU: PDU pending in buffer for transmission\n"); + } + return false; +} + +/* Returns a pointer to the Msg3 buffer */ +bool mux::msg3_get(uint8_t *payload, uint32_t pdu_sz) +{ + if (pdu_move_to_msg3(pdu_sz)) { + uint8_t *msg3 = (uint8_t*) msg3_buff.pop(); + if (msg3) { + memcpy(payload, msg3, sizeof(uint8_t)*pdu_sz); + msg3_buff.release(); + return true; + } else { + Error("Generating Msg3\n"); + } } - return msg3; + return false; } diff --git a/srsapps/ue/mac/src/pdu.cc b/srsapps/ue/mac/src/pdu.cc index e8fd2d97d..4adb5f16a 100644 --- a/srsapps/ue/mac/src/pdu.cc +++ b/srsapps/ue/mac/src/pdu.cc @@ -104,7 +104,7 @@ void sch_pdu::parse_packet(uint8_t *ptr) } // Section 6.1.2 -bool sch_pdu::write_packet(uint8_t* ptr) +bool sch_pdu::write_packet(uint8_t* ptr, rlc_interface_mac *rlc) { uint8_t *init_ptr = ptr; bool last_is_padding = false; @@ -159,16 +159,16 @@ bool sch_pdu::write_packet(uint8_t* ptr) // Write payloads in the same order for (int i=0;ihas_space_ce(ce_size) || !update_size) { - uint8_t *ptr = ce_payload; if (format==LONG_BSR) { - bzero(ce_payload, 3*8*sizeof(uint8_t)); - for (int i=0;i<4;i++) { - srslte_bit_pack(buff_size_table(buff_size[i]), &ptr, 6); - } + w_payload_ce[0] = (buff_size_table(buff_size[0])&0x3f) << 2 | (buff_size_table(buff_size[1])&0xc0)>>6; + w_payload_ce[1] = (buff_size_table(buff_size[1])&0xf) << 4 | (buff_size_table(buff_size[2])&0xf0)>>4; + w_payload_ce[2] = (buff_size_table(buff_size[2])&0x3) << 6 | (buff_size_table(buff_size[3])&0x3f); } else { - bzero(ce_payload, 8*sizeof(uint8_t)); - srslte_bit_pack(nonzero_lcg, &ptr, 2); - srslte_bit_pack(buff_size_table(buff_size[nonzero_lcg]), &ptr, 6); + w_payload_ce[0] = (nonzero_lcg&0x3)<<6 | buff_size_table(buff_size[nonzero_lcg])&0x3f; } lcid = format; if (update_size) { @@ -377,11 +380,9 @@ bool sch_subh::set_bsr(uint32_t buff_size[4], sch_subh::cetype format, bool upda bool sch_subh::set_c_rnti(uint16_t crnti) { if (((sch_pdu*)parent)->has_space_ce(2)) { - - *((uint16_t*) ce_payload) = crnti; + w_payload_ce[0] = (uint8_t) (crnti&0xff00)>>8; + w_payload_ce[1] = (uint8_t) (crnti&0x00ff); lcid = C_RNTI; - uint8_t *ptr = ce_payload; - srslte_bit_pack(crnti, &ptr, 16); ((sch_pdu*)parent)->update_space_ce(2); return true; } else { @@ -391,8 +392,12 @@ bool sch_subh::set_c_rnti(uint16_t crnti) bool sch_subh::set_con_res_id(uint64_t con_res_id) { if (((sch_pdu*)parent)->has_space_ce(6)) { - uint8_t *ptr = ce_payload; - srslte_bit_pack_l(con_res_id, &ptr, 48); + w_payload_ce[0] = (uint8_t) ((con_res_id&0xff0000000000)>>48); + w_payload_ce[1] = (uint8_t) ((con_res_id&0x00ff00000000)>>32); + w_payload_ce[2] = (uint8_t) ((con_res_id&0x0000ff000000)>>24); + w_payload_ce[3] = (uint8_t) ((con_res_id&0x000000ff0000)>>16); + w_payload_ce[4] = (uint8_t) ((con_res_id&0x00000000ff00)>>8); + w_payload_ce[5] = (uint8_t) ((con_res_id&0x0000000000ff)); lcid = CON_RES_ID; ((sch_pdu*)parent)->update_space_ce(6); return true; @@ -403,9 +408,7 @@ bool sch_subh::set_con_res_id(uint64_t con_res_id) bool sch_subh::set_phd(uint8_t phd) { if (((sch_pdu*)parent)->has_space_ce(1)) { - uint8_t *ptr = ce_payload; - srslte_bit_pack(0, &ptr, 2); - srslte_bit_pack(phd, &ptr, 6); + w_payload_ce[0] = phd&0x3f; lcid = PHD_REPORT; ((sch_pdu*)parent)->update_space_ce(1); return true; @@ -414,31 +417,29 @@ bool sch_subh::set_phd(uint8_t phd) } } -bool sch_subh::set_sdu(uint32_t lcid_, uint8_t* ptr, uint32_t nof_bytes_) +bool sch_subh::set_ta_cmd(uint8_t ta_cmd) { - return set_sdu(lcid_, ptr, nof_bytes_, false); -} - -bool sch_subh::set_sdu(uint32_t lcid_, uint8_t* ptr, uint32_t nof_bytes_, bool is_first) -{ - if (((sch_pdu*)parent)->has_space_sdu(nof_bytes_, is_first)) { - sdu_payload_ptr = ptr; - nof_bytes = nof_bytes_; - lcid = lcid_; - ((sch_pdu*)parent)->update_space_sdu(nof_bytes_, is_first); + if (((sch_pdu*)parent)->has_space_ce(1)) { + w_payload_ce[0] = ta_cmd&0x3f; + lcid = TA_CMD; + ((sch_pdu*)parent)->update_space_ce(1); return true; } else { return false; } } -bool sch_subh::set_ta_cmd(uint8_t ta_cmd) + +bool sch_subh::set_sdu(uint32_t lcid_, uint32_t nof_bytes_) { - if (((sch_pdu*)parent)->has_space_ce(1)) { - uint8_t *ptr = ce_payload; - srslte_bit_pack(0, &ptr, 2); - srslte_bit_pack(ta_cmd, &ptr, 6); - lcid = TA_CMD; - ((sch_pdu*)parent)->update_space_ce(1); + return set_sdu(lcid_, nof_bytes_, false); +} + +bool sch_subh::set_sdu(uint32_t lcid_, uint32_t nof_bytes_, bool is_first) +{ + if (((sch_pdu*)parent)->has_space_sdu(nof_bytes_, is_first)) { + nof_bytes = nof_bytes_; + lcid = lcid_; + ((sch_pdu*)parent)->update_space_sdu(nof_bytes_, is_first); return true; } else { return false; @@ -449,44 +450,47 @@ void sch_subh::write_subheader(uint8_t** ptr, bool is_last) { if (is_sdu()) { // MAC SDU: R/R/E/LCID/F/L subheader - srslte_bit_pack(0, ptr, 2); // R, R - srslte_bit_pack(is_last?0:1, ptr, 1); // E - srslte_bit_pack(lcid, ptr, 5); // LCID + *(*ptr + 0) = (uint8_t) is_last<<5 | (lcid & 0x1f); // 2nd and 3rd octet if (!is_last) { - srslte_bit_pack(F_bit?1:0, ptr, 1); // F - srslte_bit_pack(nof_bytes, ptr, nof_bytes<128?7:15); // L + if (nof_bytes >= 128) { + *(*ptr + 1) = (uint8_t) 1<<7 | ((nof_bytes & 0x7f00) >> 8); + *(*ptr + 2) = (uint8_t) (nof_bytes & 0xff); + } else { + *(*ptr + 1) = (uint8_t) (nof_bytes & 0x7f); + } } } else { // MAC CE: R/R/E/LCID MAC Subheader - srslte_bit_pack(0, ptr, 2); // R, R - srslte_bit_pack(is_last?0:1, ptr, 1); // E - srslte_bit_pack(lcid, ptr, 5); // LCID + *(*ptr + 0) = (uint8_t) is_last<<5 | (lcid & 0x1f); } } -void sch_subh::write_payload(uint8_t** ptr) + +void sch_subh::write_payload(uint8_t** ptr, rlc_interface_mac *rlc) { - uint8_t *src; if (is_sdu()) { - src = sdu_payload_ptr; + // Read data from RLC interface + rlc->read_pdu(lcid, *ptr, nof_bytes); } else { nof_bytes = sizeof_ce(lcid, parent->is_ul()); - src = ce_payload; + memcpy(*ptr, w_payload_ce, nof_bytes*sizeof(uint8_t)); } - memcpy(*ptr, src, nof_bytes*8*sizeof(uint8_t)); - *ptr += nof_bytes*8; + *ptr += nof_bytes; } + bool sch_subh::read_subheader(uint8_t** ptr) { // Skip R - *ptr += 2; - bool e_bit = srslte_bit_unpack(ptr, 1)?true:false; - lcid = srslte_bit_unpack(ptr, 5); + bool e_bit = (bool) *(*ptr + 0) & 0x20; + lcid = (uint8_t) *(*ptr + 0) & 0x1f; if (is_sdu()) { if (e_bit) { - F_bit = srslte_bit_unpack(ptr, 1)?true:false; - nof_bytes = srslte_bit_unpack(ptr, F_bit?15:7); + F_bit = (bool) *(*ptr + 1) & 0x80; + nof_bytes = (uint32_t)*(*ptr + 1) & 0x7f; + if (F_bit) { + nof_bytes = nof_bytes<<8 | (uint32_t) *(*ptr + 2) & 0xff; + } } else { nof_bytes = 0; F_bit = 0; @@ -498,16 +502,34 @@ bool sch_subh::read_subheader(uint8_t** ptr) } void sch_subh::read_payload(uint8_t** ptr) { - if (is_sdu()) { - sdu_payload_ptr = *ptr; - } else { - memcpy(ce_payload, *ptr, 8*nof_bytes*sizeof(uint8_t)); - } - *ptr += nof_bytes*8; + payload = *ptr; + *ptr += nof_bytes; } +// Table 6.1.3.1-1 Buffer size levels for BSR +uint32_t btable[61] = { + 10, 12, 14, 17, 19, 22, 26, 31, 36, 42, 49, 57, 67, 78, 91, 107, 125, 146, 171, 200, 234, 274, 321, 376, 440, 515, 603, 706, 826, 967, 1132, + 1326, 1552, 1817, 2127, 2490, 2915, 3413, 3995, 4667, 5476, 6411, 7505, 8787, 10287, 12043, 14099, 16507, 19325, 22624, 26487, 31009, 36304, + 42502, 49759, 58255, 68201, 79846, 93479, 109439, 128125}; + +uint8_t sch_subh::buff_size_table(uint32_t buffer_size) { + if (buffer_size == 0) { + return 0; + } else if (buffer_size > 150000) { + return 63; + } else { + for (int i=0;i<61;i++) { + if (buffer_size < btable[i]) { + return 1+i; + } + } + return 62; + } +} + + @@ -552,15 +574,12 @@ void rar_pdu::set_backoff(uint8_t bi) } // Section 6.1.5 -bool rar_pdu::write_packet(uint8_t* ptr) +bool rar_pdu::write_packet(uint8_t* ptr, rlc_interface_mac *rlc) { // Write Backoff Indicator, if any if (has_backoff_indicator) { if (nof_subheaders > 0) { - srslte_bit_pack(1, &ptr, 1); // E - srslte_bit_pack(0, &ptr, 1); // T - srslte_bit_pack(0, &ptr, 2); // R, R - srslte_bit_pack(backoff_indicator, &ptr, 4); + *(ptr) = 1<<7 | backoff_indicator&0xf; } } // Write RAR subheaders @@ -569,10 +588,10 @@ bool rar_pdu::write_packet(uint8_t* ptr) } // Write payload for (int i=0;i>4; + *(*ptr + 1) = (uint8_t) (ta&0xf) <<4 | grant[0]<<3 | grant[1] << 2 | grant[2] << 1 | grant[3]; + uint8_t *x = &grant[4]; + *(*ptr + 2) = (uint8_t) srslte_bit_unpack(&x, 8); + *(*ptr + 3) = (uint8_t) srslte_bit_unpack(&x, 8); + *(*ptr + 4) = (uint8_t) ((temp_rnti&0xff00) >> 8); + *(*ptr + 5) = (uint8_t) (temp_rnti&0x00ff); } + void rar_subh::read_payload(uint8_t** ptr) { - *ptr += 1; // R - ta = srslte_bit_unpack(ptr, 11); // Timing Adv Cmd - memcpy(grant, *ptr, 20*sizeof(uint8_t)); // UL Grant - *ptr += 20; - temp_rnti = srslte_bit_unpack(ptr, 16); // Temp C-RNTI + ta = *(*ptr + 0)&0x7f << 4 | (*(*ptr + 1)&0xf0)>>4; + grant[0] = *(*ptr + 1)&0x8; + grant[1] = *(*ptr + 1)&0x4; + grant[2] = *(*ptr + 1)&0x2; + grant[3] = *(*ptr + 1)&0x1; + uint8_t *x = &grant[4]; + srslte_bit_pack(*(*ptr+2), &x, 8); + srslte_bit_pack(*(*ptr+3), &x, 8); + temp_rnti = *(*ptr + 4)<<8 | *(*ptr + 5); } + bool rar_subh::read_subheader(uint8_t** ptr) { - bool e_bit = srslte_bit_unpack(ptr, 1); // E - bool type = srslte_bit_unpack(ptr, 1); // T + bool e_bit = *(*ptr + 0) & 0x80; + bool type = *(*ptr + 0) & 0x40; if (type) { - preamble = srslte_bit_unpack(ptr, 6); // RAPID + preamble = *(*ptr + 0) & 0x3f; } else { - // Read Backoff - *ptr += 2; // R, R - ((rar_pdu*)parent)->set_backoff((uint8_t) srslte_bit_unpack(ptr, 4)); + ((rar_pdu*)parent)->set_backoff(*(*ptr + 0) & 0xf); } return e_bit; } - -// Table 6.1.3.1-1 Buffer size levels for BSR -uint32_t btable[61] = { - 10, 12, 14, 17, 19, 22, 26, 31, 36, 42, 49, 57, 67, 78, 91, 107, 125, 146, 171, 200, 234, 274, 321, 376, 440, 515, 603, 706, 826, 967, 1132, - 1326, 1552, 1817, 2127, 2490, 2915, 3413, 3995, 4667, 5476, 6411, 7505, 8787, 10287, 12043, 14099, 16507, 19325, 22624, 26487, 31009, 36304, - 42502, 49759, 58255, 68201, 79846, 93479, 109439, 128125}; - -uint8_t sch_subh::buff_size_table(uint32_t buffer_size) { - if (buffer_size == 0) { - return 0; - } else if (buffer_size > 150000) { - return 63; - } else { - for (int i=0;i<61;i++) { - if (buffer_size < btable[i]) { - return 1+i; - } - } - return 62; - } -} - } } diff --git a/srsapps/ue/mac/src/proc_bsr.cc b/srsapps/ue/mac/src/proc_bsr.cc index 6e2700bcd..db79eb7b4 100644 --- a/srsapps/ue/mac/src/proc_bsr.cc +++ b/srsapps/ue/mac/src/proc_bsr.cc @@ -26,7 +26,6 @@ */ #include "srsapps/ue/mac/proc_bsr.h" -#include "srsapps/ue/mac/mac_params.h" #include "srsapps/ue/mac/mac.h" #include "srsapps/ue/mac/mux.h" @@ -48,11 +47,11 @@ bsr_proc::bsr_proc() triggered_bsr_type=NONE; } -void bsr_proc::init(log* log_h_, timers *timers_db_, mac_params* params_db_, mac_io *mac_io_h_) +void bsr_proc::init(rlc_interface_mac *rlc_, log* log_h_, mac_params* params_db_, timers *timers_db_) { log_h = log_h_; + rlc = rlc_; params_db = params_db_; - mac_io_h = mac_io_h_; timers_db = timers_db_; initiated = true; } @@ -85,12 +84,12 @@ void bsr_proc::timer_expired(uint32_t timer_id) { bool bsr_proc::check_highest_channel() { int pending_data_lcid = -1; - for (int i=0;i= 0) { - if (!mac_io_h->get(i+mac_io::MAC_LCH_CCCH_UL)->isempty()) { + if (rlc->get_buffer_state(i) > 0) { pending_data_lcid = i; - for (int j=0;jget(j+mac_io::MAC_LCH_CCCH_UL)->isempty()) { + for (int j=0;jget_buffer_state(j) > 0) { if (priorities[j] > priorities[i]) { pending_data_lcid = -1; } @@ -101,7 +100,7 @@ bool bsr_proc::check_highest_channel() { } if (pending_data_lcid >= 0) { // If there is new data available for this logical channel - uint32_t nbytes = mac_io_h->get(pending_data_lcid+mac_io::MAC_LCH_CCCH_UL)->pending_data()/8; + uint32_t nbytes = rlc->get_buffer_state(pending_data_lcid); if (nbytes > last_pending_data[pending_data_lcid]) { if (triggered_bsr_type != REGULAR) { @@ -119,16 +118,16 @@ bool bsr_proc::check_single_channel() { uint32_t pending_data_lcid = 0; uint32_t nof_nonzero_lcid = 0; - for (int i=0;i= 0) { - if (!mac_io_h->get(i+mac_io::MAC_LCH_CCCH_UL)->isempty()) { + if (rlc->get_buffer_state(i) > 0) { pending_data_lcid = i; nof_nonzero_lcid++; } } } if (nof_nonzero_lcid == 1) { - uint32_t nbytes = mac_io_h->get(pending_data_lcid+mac_io::MAC_LCH_CCCH_UL)->pending_data()/8; + uint32_t nbytes = rlc->get_buffer_state(pending_data_lcid); // If there is new data available for this logical channel if (nbytes > last_pending_data[pending_data_lcid]) { triggered_bsr_type = REGULAR; @@ -140,8 +139,8 @@ bool bsr_proc::check_single_channel() { } void bsr_proc::update_pending_data() { - for (int i=0;iNOF_UL_LCH;i++) { - last_pending_data[i] = mac_io_h->get(i+mac_io::MAC_LCH_CCCH_UL)->pending_data()/8; + for (int i=0;iget_buffer_state(i); } } @@ -149,9 +148,9 @@ bool bsr_proc::generate_bsr(bsr_t *bsr, uint32_t nof_padding_bytes) { bool ret = false; uint32_t nof_lcg=0; bzero(bsr, sizeof(bsr_t)); - for (int i=0;iNOF_UL_LCH;i++) { + for (int i=0;i= 0) { - uint32_t n = mac_io_h->get(i+mac_io::MAC_LCH_CCCH_UL)->pending_data()/8; + uint32_t n = rlc->get_buffer_state(i); bsr->buff_size[lcg[i]] += n; if (n > 0) { nof_lcg++; @@ -196,16 +195,16 @@ void bsr_proc::step(uint32_t tti) } if (!timer_periodic) { - if (params_db->get_param(mac_params::BSR_TIMER_PERIODIC)) { + if (params_db->get_param(mac_interface_params::BSR_TIMER_PERIODIC)) { timer_periodic = true; - timers_db->get(mac::BSR_TIMER_PERIODIC)->set(this, params_db->get_param(mac_params::BSR_TIMER_PERIODIC)); + timers_db->get(mac::BSR_TIMER_PERIODIC)->set(this, params_db->get_param(mac_interface_params::BSR_TIMER_PERIODIC)); } } if (!timer_retx) { - if (params_db->get_param(mac_params::BSR_TIMER_RETX)) { + if (params_db->get_param(mac_interface_params::BSR_TIMER_RETX)) { timer_retx = true; - timers_db->get(mac::BSR_TIMER_RETX)->set(this, params_db->get_param(mac_params::BSR_TIMER_RETX)); + timers_db->get(mac::BSR_TIMER_RETX)->set(this, params_db->get_param(mac_interface_params::BSR_TIMER_RETX)); } } @@ -222,8 +221,8 @@ void bsr_proc::step(uint32_t tti) if ((tti - last_print)%10240 > 40) { char str[128]; bzero(str, 128); - for (int i=0;iget(i+mac_io::MAC_LCH_CCCH_UL)->pending_data()/8, last_pending_data[i]); + for (int i=0;iget_buffer_state(i), last_pending_data[i]); } Info("QUEUE status: %s\n", str); last_print = tti; @@ -257,15 +256,10 @@ uint32_t bsr_proc::need_to_send_bsr_on_ul_grant(uint32_t grant_size) { uint32_t bsr_sz = 0; if (triggered_bsr_type == PERIODIC || triggered_bsr_type == REGULAR) { - uint32_t total_data = 0; /* Check if grant + MAC SDU headers is enough to accomodate all pending data */ - for (int i=0;iNOF_UL_LCH && total_data < grant_size;i++) { - uint32_t idx = 0; - uint32_t sdu_len = 0; - while(mac_io_h->get(i+mac_io::MAC_LCH_CCCH_UL)->pop(&sdu_len, idx) && total_data < grant_size) { - idx++; - total_data += sch_pdu::size_plus_header_sdu(sdu_len/8); - } + uint32_t total_data = 0; + for (int i=0;iget_buffer_state(i)); } total_data--; // Because last SDU has no size header diff --git a/srsapps/ue/mac/src/proc_ra.cc b/srsapps/ue/mac/src/proc_ra.cc index b2f849275..19759db6c 100644 --- a/srsapps/ue/mac/src/proc_ra.cc +++ b/srsapps/ue/mac/src/proc_ra.cc @@ -30,8 +30,6 @@ #include #include -#include "srsapps/ue/mac/mac_params.h" -#include "srsapps/ue/mac/mac_io.h" #include "srsapps/ue/mac/proc_ra.h" #include "srsapps/ue/mac/mac.h" #include "srsapps/ue/mac/mux.h" @@ -47,26 +45,7 @@ uint32_t backoff_table[16] = {0, 10, 20, 30, 40, 60, 80, 120, 160, 240, 320, 480 // Table 7.6-1: DELTA_PREAMBLE values. int delta_preamble_db_table[5] = {0, 0, -3, -3, 8}; - -void* init_prach_thread(void *arg) { - ra_proc* ra = (ra_proc*) arg; - return ra->run_prach_thread(); -} - -void* ra_proc::run_prach_thread() { - pthread_mutex_lock(&mutex); - while(!start_prach_init) { - pthread_cond_wait(&cond, &mutex); - } - pthread_mutex_unlock(&mutex); - if (phy_h->init_prach()) { - return (void*) 0; - } else { - return (void*) -1; - } - -} -bool ra_proc::init(mac_params* params_db_, phy* phy_h_, srslte::log* log_h_, srslte::timers* timers_db_, +bool ra_proc::init(phy_interface* phy_h_, log* log_h_, mac_params* params_db_, timers* timers_db_, mux* mux_unit_, demux* demux_unit_) { phy_h = phy_h_; @@ -75,12 +54,8 @@ bool ra_proc::init(mac_params* params_db_, phy* phy_h_, srslte::log* log_h_, srs timers_db = timers_db_; mux_unit = mux_unit_; demux_unit= demux_unit_; - start_prach_init = false; - if (pthread_create(&pt_init_prach, NULL, init_prach_thread, this)) { - perror("pthread_create"); - } - pthread_mutex_init(&mutex, NULL); - pthread_cond_init(&cond, NULL); + srslte_softbuffer_rx_init(&softbuffer_rar, 10); + reset(); } @@ -96,32 +71,32 @@ void ra_proc::start_pcap(mac_pcap* pcap_) void ra_proc::read_params() { // Read initialization parameters - configIndex = params_db->get_param(mac_params::RA_CONFIGINDEX); - preambleIndex = params_db->get_param(mac_params::RA_PREAMBLEINDEX); - maskIndex = params_db->get_param(mac_params::RA_MASKINDEX); - nof_preambles = params_db->get_param(mac_params::RA_NOFPREAMBLES); + configIndex = params_db->get_param(mac_interface_params::RA_CONFIGINDEX); + preambleIndex = params_db->get_param(mac_interface_params::RA_PREAMBLEINDEX); + maskIndex = params_db->get_param(mac_interface_params::RA_MASKINDEX); + nof_preambles = params_db->get_param(mac_interface_params::RA_NOFPREAMBLES); if (!nof_preambles || nof_preambles > 64) { nof_preambles = 64; } - nof_groupA_preambles = params_db->get_param(mac_params::RA_NOFGROUPAPREAMBLES); + nof_groupA_preambles = params_db->get_param(mac_interface_params::RA_NOFGROUPAPREAMBLES); if (!nof_groupA_preambles) { - nof_groupA_preambles = nof_preambles; + nof_groupA_preambles = nof_preambles; } if (nof_groupA_preambles > nof_preambles) { - nof_groupA_preambles = nof_preambles; + nof_groupA_preambles = nof_preambles; } nof_groupB_preambles = nof_preambles - nof_groupA_preambles; if (nof_groupB_preambles) { - messagePowerOffsetGroupB = params_db->get_param(mac_params::RA_MESSAGEPOWEROFFSETB); - messageSizeGroupA = params_db->get_param(mac_params::RA_MESSAGESIZEA); - Pcmax = params_db->get_param(mac_params::RA_PCMAX); - deltaPreambleMsg3 = params_db->get_param(mac_params::RA_DELTAPREAMBLEMSG3); + messagePowerOffsetGroupB= params_db->get_param(mac_interface_params::RA_MESSAGEPOWEROFFSETB); + messageSizeGroupA = params_db->get_param(mac_interface_params::RA_MESSAGESIZEA); + Pcmax = params_db->get_param(mac_interface_params::RA_PCMAX); + deltaPreambleMsg3 = params_db->get_param(mac_interface_params::RA_DELTAPREAMBLEMSG3); } - responseWindowSize = params_db->get_param(mac_params::RA_RESPONSEWINDOW); - powerRampingStep = params_db->get_param(mac_params::RA_POWERRAMPINGSTEP); - preambleTransMax = params_db->get_param(mac_params::RA_PREAMBLETRANSMAX); - iniReceivedTargetPower = params_db->get_param(mac_params::RA_INITRECEIVEDPOWER); - contentionResolutionTimer = params_db->get_param(mac_params::RA_CONTENTIONTIMER); + responseWindowSize = params_db->get_param(mac_interface_params::RA_RESPONSEWINDOW); + powerRampingStep = params_db->get_param(mac_interface_params::RA_POWERRAMPINGSTEP); + preambleTransMax = params_db->get_param(mac_interface_params::RA_PREAMBLETRANSMAX); + iniReceivedTargetPower = params_db->get_param(mac_interface_params::RA_INITRECEIVEDPOWER); + contentionResolutionTimer = params_db->get_param(mac_interface_params::RA_CONTENTIONTIMER); delta_preamble_db = delta_preamble_db_table[configIndex%5]; @@ -154,9 +129,9 @@ bool ra_proc::is_error() { const char* state_str[11] = {"Idle", "RA Initializat.: ", - "RA Initial.Wait: ", "RA ResSelection: ", "RA PreambleTx : ", + "RA PDCCH setup : ", "RA PreambleRx : ", "RA ResponseErr : ", "RA BackoffWait : ", @@ -199,28 +174,9 @@ void ra_proc::step_initialization() { mux_unit->msg3_flush(); backoff_param_ms = 0; - // Instruct phy prach init thread to start initialization - pthread_mutex_lock(&mutex); - start_prach_init = true; - pthread_cond_signal(&cond); - pthread_mutex_unlock(&mutex); - state = INITIALIZATION_WAIT; - -} - -void ra_proc::step_initialization_wait() { - int n = pthread_kill(pt_init_prach, 0); - if (n) { - void *status; - pthread_join(pt_init_prach, &status); - if (status) { - rError("Initializing PRACH on PHY\n"); - state = RA_PROBLEM; - } else { - rInfo("PRACH init OK\n"); - state = RESOURCE_SELECTION; - } - } + // Instruct phy to configure PRACH + phy_h->configure_prach_params(); + state = RESOURCE_SELECTION; } void ra_proc::step_resource_selection() { @@ -249,7 +205,8 @@ void ra_proc::step_resource_selection() { sel_maskIndex = 0; } - rInfo("Selected preambleIndex=%d maskIndex=%d nof_GroupApreambles=%d\n", sel_preamble, sel_maskIndex,nof_groupA_preambles); + rInfo("Selected preambleIndex=%d maskIndex=%d nof_GroupApreambles=%d\n", + sel_preamble, sel_maskIndex,nof_groupA_preambles); state = PREAMBLE_TRANSMISSION; } @@ -258,116 +215,111 @@ void ra_proc::step_preamble_transmission() { delta_preamble_db + (preambleTransmissionCounter-1)*powerRampingStep; - phy_h->send_prach(sel_preamble, sel_maskIndex - 1, received_target_power_dbm); + phy_h->prach_send(sel_preamble, sel_maskIndex - 1, received_target_power_dbm); rInfo("Selected received_target_power_dbm=%d dBm\n", received_target_power_dbm); - state = RESPONSE_RECEPTION; + state = PDCCH_SETUP; +} + +void ra_proc::step_pdcch_setup() { + int ra_tti = phy_h->prach_tx_tti(); + if (ra_tti > 0) { + ra_rnti = 1+ra_tti%10; + phy_h->pdcch_dl_search(SRSLTE_RNTI_RAR, ra_rnti, ra_tti+3, responseWindowSize); + state = RESPONSE_RECEPTION; + } +} + +void ra_proc::new_grant_dl(mac_interface_phy::mac_grant_t grant, mac_interface_phy::tb_action_dl_t* action) +{ + if (grant.n_bytes < MAX_RAR_PDU_LEN) { + rInfo("DL grant found RA-RNTI=%d\n", ra_rnti); + action->decode_enabled = true; + action->default_ack = false; + action->generate_ack = false; + action->payload_ptr = rar_pdu_buffer; + action->rnti = grant.rnti; + memcpy(&action->phy_grant, &grant.phy_grant, sizeof(srslte_phy_grant_t)); + action->rv = grant.rv; + action->softbuffer = &softbuffer_rar; + rar_grant_nbytes = grant.n_bytes; + rar_grant_tti = grant.tti; + if (action->rv == 0) { + srslte_softbuffer_rx_reset(&softbuffer_rar); + } + } else { + rError("Received RAR grant exceeds buffer length (%d>%d)\n", grant.n_bytes, MAX_RAR_PDU_LEN); + action->decode_enabled = false; + state = RESPONSE_ERROR; + } +} + +void ra_proc::tb_decoded_ok() { + if (pcap) { + pcap->write_dl_crnti(rar_pdu_buffer, rar_grant_nbytes, ra_rnti, true, rar_grant_tti); + } + + rDebug("RAR decoded successfully TBS=%d\n", rar_grant_nbytes); + + rar_pdu_msg.init(rar_grant_nbytes); + rar_pdu_msg.parse_packet(rar_pdu_buffer); + + // Set Backoff parameter + if (rar_pdu_msg.has_backoff()) { + backoff_param_ms = backoff_table[rar_pdu_msg.get_backoff()%16]; + } else { + backoff_param_ms = 0; + } + + while(rar_pdu_msg.next()) { + if (rar_pdu_msg.get()->get_rapid() == sel_preamble) { + rInfo("Received RAPID=%d\n", sel_preamble); + + process_timeadv_cmd(rar_pdu_msg.get()->get_ta_cmd()); + + // FIXME: Indicate received target power + //phy_h->set_target_power_rar(iniReceivedTargetPower, (preambleTransmissionCounter-1)*powerRampingStep); + + uint8_t grant[rar_subh::RAR_GRANT_LEN]; + rar_pdu_msg.get()->get_sched_grant(grant); + + phy_h->set_rar_grant(rar_grant_tti, grant); + + if (preambleIndex > 0) { + // Preamble selected by Network + state = COMPLETION; + } else { + // Preamble selected by UE MAC + params_db->set_param(mac_interface_params::RNTI_TEMP, rar_pdu_msg.get()->get_temp_crnti()); + if (first_rar_received) { + first_rar_received = false; + + // Save transmitted C-RNTI (if any) + transmitted_crnti = params_db->get_param(mac_interface_params::RNTI_C); + + // Save transmitted UE contention id, as defined by higher layers + transmitted_contention_id = params_db->get_param(mac_interface_params::CONTENTION_ID); + params_db->set_param(mac_interface_params::CONTENTION_ID, 0); + + // If we have a C-RNTI, tell Mux unit to append C-RNTI CE if no CCCH SDU transmission + if (transmitted_crnti) { + mux_unit->append_crnti_ce_next_tx(transmitted_crnti); + } + } + rDebug("Going to Contention Resolution state\n"); + state = CONTENTION_RESOLUTION; + + // Start contention resolution timer + timers_db->get(mac::CONTENTION_TIMER)->reset(); + timers_db->get(mac::CONTENTION_TIMER)->run(); + } + } else { + rDebug("Found RAR for preamble %d\n", rar_pdu_msg.get()->get_rapid()); + } + } } void ra_proc::step_response_reception() { - int ra_tti = phy_h->get_prach_transmitted_tti(); - if (ra_tti > 0) { - - ra_rnti = 1+ra_tti%10; // f_id=0 for FDD - dl_sched_grant rar_grant(ra_rnti); - uint32_t interval_ra = srslte_tti_interval(tti, ra_tti); - - // Try to decode RAR only within the RA response window - if (interval_ra >= 3 && interval_ra <= 3+responseWindowSize) { - - // Get DL grant for RA-RNTI - dl_buffer *dl_buffer = phy_h->get_dl_buffer(tti); - if (dl_buffer->get_dl_grant(&rar_grant)) - { - rInfo("DL grant found RA-RNTI=%d\n", ra_rnti); - if (rar_grant.get_tbs() > MAX_RAR_PDU_LEN) { - rError("RAR PDU exceeds local RAR PDU buffer (%d>%d)\n", rar_grant.get_tbs(), MAX_RAR_PDU_LEN); - state = RESPONSE_ERROR; - return; - } - - // Decode packet - dl_buffer->reset_softbuffer(); - bool ack = dl_buffer->decode_data(&rar_grant, rar_pdu_buffer); - if (pcap) { - pcap->write_dl_crnti(payload, rar_grant.get_tbs()/8, ra_rnti, ack, tti); - } - - if (ack) { - rDebug("RAR decoded successfully TBS=%d\n", rar_grant.get_tbs()); - - rar_pdu_msg.init(rar_grant.get_tbs()/8); - rar_pdu_msg.parse_packet(rar_pdu_buffer); - - // Set Backoff parameter - if (rar_pdu_msg.has_backoff()) { - backoff_param_ms = backoff_table[rar_pdu_msg.get_backoff()%16]; - } else { - backoff_param_ms = 0; - } - - while(rar_pdu_msg.next()) { - if (rar_pdu_msg.get()->get_rapid() == sel_preamble) { - rInfo("Received RAPID=%d\n", sel_preamble); - - process_timeadv_cmd(rar_pdu_msg.get()->get_ta_cmd()); - - // FIXME: Indicate received target power - //phy_h->set_target_power_rar(iniReceivedTargetPower, (preambleTransmissionCounter-1)*powerRampingStep); - - // Indicate grant to PHY layer. RAR grants have 6 sf delay (4 is the default delay) - uint8_t grant[rar_subh::RAR_GRANT_LEN]; - rar_pdu_msg.get()->get_sched_grant(grant); - phy_h->get_dl_buffer(tti+2)->set_rar_grant(grant); - - if (preambleIndex > 0) { - // Preamble selected by Network - state = COMPLETION; - } else { - // Preamble selected by UE MAC - params_db->set_param(mac_params::RNTI_TEMP, rar_pdu_msg.get()->get_temp_crnti()); - if (first_rar_received) { - first_rar_received = false; - - // Save transmitted C-RNTI (if any) - transmitted_crnti = params_db->get_param(mac_params::RNTI_C); - - // Save transmitted UE contention id, as defined by higher layers - transmitted_contention_id = params_db->get_param(mac_params::CONTENTION_ID); - params_db->set_param(mac_params::CONTENTION_ID, 0); - - // If we have a C-RNTI, tell Mux unit to append C-RNTI CE if no CCCH SDU transmission - if (transmitted_crnti) { - mux_unit->append_crnti_ce_next_tx(transmitted_crnti); - } - - // Get TransportBlock size for the grant - ul_sched_grant msg3_grant(sched_grant::RNTI_TYPE_TEMP, rar_pdu_msg.get()->get_temp_crnti()); - phy_h->get_dl_buffer(tti+2)->get_ul_grant(&msg3_grant); - - // Move MAC PDU from Multiplexing and assembly unit to Msg3 - rInfo("Generating Msg3 for TBS=%d\n", msg3_grant.get_tbs()); - mux_unit->pdu_move_to_msg3(msg3_grant.get_tbs()); // 56 is the minimum grant provided - } - rDebug("Going to Contention Resolution state\n"); - state = CONTENTION_RESOLUTION; - - // Start contention resolution timer - timers_db->get(mac::CONTENTION_TIMER)->reset(); - timers_db->get(mac::CONTENTION_TIMER)->run(); - } - } else { - rDebug("Found RAR for preamble %d\n", rar_pdu_msg.get()->get_rapid()); - } - } - } - } - srslte_verbose = SRSLTE_VERBOSE_NONE; - } - if (interval_ra > 3+responseWindowSize && interval_ra < 10000) { - rInfo("Timeout while trying to receive RAR\n"); - state = RESPONSE_ERROR; - } - } + // do nothing. Processing done in tb_decoded_ok() } void ra_proc::step_response_error() { @@ -377,7 +329,7 @@ void ra_proc::step_response_error() { rError("Maximum number of transmissions reached (%d)\n", preambleTransMax); state = RA_PROBLEM; } else { - backoff_interval_start = tti; + backoff_interval_start = phy_h->get_current_tti(); if (backoff_param_ms) { backoff_inteval = rand()%backoff_param_ms; } else { @@ -394,7 +346,7 @@ void ra_proc::step_response_error() { } void ra_proc::step_backoff_wait() { - if (srslte_tti_interval(tti, backoff_interval_start) >= backoff_inteval) { + if (srslte_tti_interval(phy_h->get_current_tti(), backoff_interval_start) >= backoff_inteval) { state = RESOURCE_SELECTION; } } @@ -411,7 +363,7 @@ void ra_proc::step_contention_resolution() { start_mode == PDCCH_ORDER) { timers_db->get(mac::CONTENTION_TIMER)->stop(); - params_db->set_param(mac_params::RNTI_TEMP, 0); + params_db->set_param(mac_interface_params::RNTI_TEMP, 0); state = COMPLETION; } pdcch_to_crnti_received = PDCCH_CRNTI_NOT_RECEIVED; @@ -428,7 +380,7 @@ void ra_proc::step_contention_resolution() { if (transmitted_contention_id == rx_contention_id) { rDebug("MAC PDU Contention Resolution ID matches the one transmitted in CCCH SDU\n"); // UE Contention Resolution ID included in MAC CE matches the CCCH SDU transmitted in Msg3 - params_db->set_param(mac_params::RNTI_C, params_db->get_param(mac_params::RNTI_TEMP)); + params_db->set_param(mac_interface_params::RNTI_C, params_db->get_param(mac_interface_params::RNTI_TEMP)); // finish the disassembly and demultiplexing of the MAC PDU demux_unit->demultiplex_pending_pdu(); state = COMPLETION; @@ -441,7 +393,7 @@ void ra_proc::step_contention_resolution() { // FIXME: Need to flush Msg3 HARQ buffer. Why? state = RESPONSE_ERROR; } - params_db->set_param(mac_params::RNTI_TEMP, 0); + params_db->set_param(mac_interface_params::RNTI_TEMP, 0); } } } else { @@ -451,15 +403,14 @@ void ra_proc::step_contention_resolution() { } void ra_proc::step_completition() { - params_db->set_param(mac_params::RA_PREAMBLEINDEX, 0); - params_db->set_param(mac_params::RA_MASKINDEX, 0); + params_db->set_param(mac_interface_params::RA_PREAMBLEINDEX, 0); + params_db->set_param(mac_interface_params::RA_MASKINDEX, 0); mux_unit->msg3_flush(); msg3_transmitted = false; } void ra_proc::step(uint32_t tti_) { - tti = tti_; if (is_running()) { switch(state) { case IDLE: @@ -467,15 +418,15 @@ void ra_proc::step(uint32_t tti_) case INITIALIZATION: step_initialization(); break; - case INITIALIZATION_WAIT: - step_initialization_wait(); - break; case RESOURCE_SELECTION: step_resource_selection(); break; case PREAMBLE_TRANSMISSION: step_preamble_transmission(); break; + case PDCCH_SETUP: + step_pdcch_setup(); + break; case RESPONSE_RECEPTION: step_response_reception(); break; @@ -529,7 +480,7 @@ void ra_proc::start_rlc_order() void ra_proc::timer_expired(uint32_t timer_id) { rInfo("Contention Resolution Timer expired. Going to Response Error\n"); - params_db->set_param(mac_params::RNTI_TEMP, 0); + params_db->set_param(mac_interface_params::RNTI_TEMP, 0); state = RESPONSE_ERROR; } diff --git a/srsapps/ue/mac/src/proc_sr.cc b/srsapps/ue/mac/src/proc_sr.cc index f0140e957..8ec35e6c5 100644 --- a/srsapps/ue/mac/src/proc_sr.cc +++ b/srsapps/ue/mac/src/proc_sr.cc @@ -36,7 +36,7 @@ sr_proc::sr_proc() { initiated = false; } -void sr_proc::init(log* log_h_, mac_params* params_db_, phy* phy_h_) +void sr_proc::init(phy_interface* phy_h_, log* log_h_, mac_params* params_db_) { log_h = log_h_; params_db = params_db_; @@ -48,20 +48,19 @@ void sr_proc::init(log* log_h_, mac_params* params_db_, phy* phy_h_) void sr_proc::reset() { is_pending_sr = false; - phy_h->send_sr(false); } void sr_proc::step(uint32_t tti) { if (initiated) { if (is_pending_sr) { - if (params_db->get_param(mac_params::SR_PUCCH_CONFIGURED)) { + if (params_db->get_param(mac_interface_params::SR_PUCCH_CONFIGURED)) { if (sr_counter < dsr_transmax) { int last_tx_tti = phy_h->sr_last_tx_tti(); if (last_tx_tti >= 0 && last_tx_tti + 4 < tti) { sr_counter++; Info("SR signalling PHY. sr_counter=%d, PHY TTI=%d\n", sr_counter, phy_h->get_current_tti()); - phy_h->send_sr(true); + phy_h->sr_send(); } } else { do_ra = true; @@ -93,7 +92,7 @@ void sr_proc::start() sr_counter = 0; is_pending_sr = true; } - dsr_transmax = params_db->get_param(mac_params::SR_TRANS_MAX); + dsr_transmax = params_db->get_param(mac_interface_params::SR_TRANS_MAX); Info("SR starting dsrTransMax=%d. sr_counter=%d\n", dsr_transmax, sr_counter); } } diff --git a/srsapps/ue/mac/src/ul_harq.cc b/srsapps/ue/mac/src/ul_harq.cc index 3d8bf69ad..c2deaa43f 100644 --- a/srsapps/ue/mac/src/ul_harq.cc +++ b/srsapps/ue/mac/src/ul_harq.cc @@ -25,10 +25,7 @@ * */ -#include "srsapps/ue/phy/phy.h" #include "srsapps/common/log.h" - -#include "srsapps/ue/mac/mac_params.h" #include "srsapps/ue/mac/mac.h" #include "srsapps/ue/mac/ul_harq.h" @@ -41,16 +38,15 @@ namespace srslte { * *********************************************************/ -bool ul_harq_entity::init(srslte_cell_t cell, mac_params *params_db_, log *log_h_, timers *timers_db_, mux *mux_unit_) { +bool ul_harq_entity::init(log *log_h_, mac_params *params_db_, timers *timers_db_, mux *mux_unit_) { log_h = log_h_; mux_unit = mux_unit_; params_db = params_db_; timers_db = timers_db_; for (uint32_t i=0;iget_dl_buffer(tti)->decode_ack(proc[pid_harq].get_grant())); + proc[pid_harq].set_harq_feedback(ack); } +} +void ul_harq_entity::harq_recv(uint32_t tti, bool ack, mac_interface_phy::tb_action_ul_t* action) +{ + set_ack(tti, ack); + run_tti(tti, NULL, NULL, action); +} + +// Implements Section 5.4.1 +void ul_harq_entity::new_grant_ul(mac_interface_phy::mac_grant_t grant, uint8_t* payload_ptr, + 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, payload_ptr, 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, payload_ptr, action); + } else { + Info("Not implemented\n"); + } + } +} + +void ul_harq_entity::new_grant_ul_ack(mac_interface_phy::mac_grant_t grant, uint8_t* payload_ptr, bool ack, + mac_interface_phy::tb_action_ul_t* action) +{ + set_ack(grant.tti, ack); + new_grant_ul(grant, payload_ptr, action); +} + + + +// Implements Section 5.4.2.1 +// Called with UL grant +void ul_harq_entity::run_tti(uint32_t tti, mac_interface_phy::mac_grant_t *grant, uint8_t* payload_ptr, + mac_interface_phy::tb_action_ul_t* action) +{ + + uint32_t tti_tx = (tti+4)%10240; + uint32_t pid = pidof(tti_tx); + + // Receive and route HARQ feedbacks if (grant) { - if ((!grant->is_temp_rnti() && grant->get_ndi() != proc[pid].get_ndi()) || - (grant->is_crnti() && !proc[pid].has_grant()) || - grant->is_from_rar()) + if ((!grant->rnti_type == SRSLTE_RNTI_TEMP && grant->ndi != proc[pid].get_ndi()) || + (grant->rnti_type == SRSLTE_RNTI_USER && !proc[pid].has_grant()) || + grant->is_from_rar) { // New transmission - uint8_t* msg3_ptr = (uint8_t*) mux_unit->msg3_pop(grant->get_tbs()); // Uplink grant in a RAR - if (grant->is_from_rar()) { - if (msg3_ptr) { - proc[pid].generate_new_tx(tti_tx, msg3_ptr, true, grant, phy_h->get_ul_buffer(tti_tx)); - mux_unit->msg3_transmitted(); + if (grant->is_from_rar) { + if (mux_unit->msg3_get(payload_ptr, grant->n_bytes)) { + proc[pid].generate_new_tx(tti_tx, true, grant, action); } else { Warning("UL RAR grant available but no Msg3 on buffer\n"); } @@ -118,26 +147,24 @@ void ul_harq_entity::run_tti(uint32_t tti, ul_sched_grant *grant, phy *phy_h) // Normal UL grant } else { // Request a MAC PDU from the Multiplexing & Assemble Unit - uint8_t* mac_pdu = mux_unit->pdu_pop(grant->get_tbs()); - if (mac_pdu) { - // FIXME: This is inefficient. too many memcopies - memcpy(mac_pdu_buffer[pid], mac_pdu, grant->get_tbs()*sizeof(uint8_t)); - mux_unit->pdu_release(); - proc[pid].generate_new_tx(tti_tx, mac_pdu_buffer[pid], false, grant, phy_h->get_ul_buffer(tti_tx)); + if (mux_unit->pdu_get(payload_ptr, grant->n_bytes)) { + proc[pid].generate_new_tx(tti_tx, false, grant, action); } else { - mux_unit->pdu_release(); Warning("Uplink grant but no MAC PDU in Multiplex Unit buffer\n"); } } } else { // Adaptive Re-TX - proc[pid].generate_retx(tti_tx, grant, phy_h->get_ul_buffer(tti_tx)); + proc[pid].generate_retx(tti_tx, grant, action); } } else if (proc[pid].has_grant()) { // Non-Adaptive Re-Tx - proc[pid].generate_retx(tti_tx, phy_h->get_ul_buffer(tti_tx)); + proc[pid].generate_retx(tti_tx, action); } - + if (pcap) { + pcap->write_ul_crnti(payload_ptr, grant->n_bytes, grant->rnti, proc[pid].get_nof_retx(), tti_tx); + } + } @@ -151,30 +178,34 @@ void ul_harq_entity::run_tti(uint32_t tti, ul_sched_grant *grant, phy *phy_h) static int rv_of_irv[4] = {0, 2, 3, 1}; static int irv_of_rv[4] = {0, 3, 1, 2}; -ul_harq_entity::ul_harq_process::ul_harq_process() : cur_grant(0) { +ul_harq_entity::ul_harq_process::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(ul_sched_grant)); + bzero(&cur_grant, sizeof(mac_interface_phy::mac_grant_t)); } + void ul_harq_entity::ul_harq_process::reset() { current_tx_nb = 0; current_irv = 0; tti_last_tx = 0; is_grant_configured = false; - bzero(&cur_grant, sizeof(ul_sched_grant)); if (is_initiated) { srslte_softbuffer_tx_reset(&softbuffer); } + bzero(&cur_grant, sizeof(mac_interface_phy::mac_grant_t)); } + bool ul_harq_entity::ul_harq_process::has_grant() { return is_grant_configured; } + void ul_harq_entity::ul_harq_process::reset_ndi() { ndi = false; } + bool ul_harq_entity::ul_harq_process::get_ndi() { return ndi; @@ -185,11 +216,6 @@ uint32_t ul_harq_entity::ul_harq_process::get_rv() return rv_of_irv[current_irv%4]; } -ul_sched_grant* ul_harq_entity::ul_harq_process::get_grant() -{ - return &cur_grant; -} - void ul_harq_entity::ul_harq_process::set_harq_feedback(bool ack) { harq_feedback = ack; // UL packet successfully delivered @@ -201,39 +227,42 @@ void ul_harq_entity::ul_harq_process::set_harq_feedback(bool ack) { } } -bool ul_harq_entity::ul_harq_process::init(srslte_cell_t cell, ul_harq_entity *parent) { - if (srslte_softbuffer_tx_init(&softbuffer, cell)) { +bool ul_harq_entity::ul_harq_process::init(uint32_t pid_, ul_harq_entity* parent) { + if (srslte_softbuffer_tx_init(&softbuffer, 100)) { fprintf(stderr, "Error initiating soft buffer\n"); return false; } else { is_initiated = true; harq_entity = parent; log_h = harq_entity->log_h; + pid = pid_; return true; } } -void ul_harq_entity::ul_harq_process::generate_retx(uint32_t tti_tx, ul_buffer* ul) +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, ul); + 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, ul_sched_grant* grant, ul_buffer* ul) +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) { current_tx_nb++; if (grant) { // HARQ entity requests an adaptive transmission - memcpy(&cur_grant, grant, sizeof(ul_sched_grant)); - current_irv = irv_of_rv[grant->get_rv()%4]; + current_irv = irv_of_rv[grant->rv%4]; harq_feedback = false; - Info("UL PID %d: Adaptive retx=%d, RV=%d, TBS=%d, MCS=%d\n", pid, current_tx_nb, get_rv(), grant->get_tbs(), grant->get_mcs()); - generate_tx(tti_tx, NULL, ul); + Info("UL PID %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 PID %d: Non-Adaptive retx=%d, RV=%d, TBS=%d, MCS=%d\n", pid, current_tx_nb, get_rv(), cur_grant.get_tbs(), cur_grant.get_mcs()); + Info("UL PID %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, NULL, ul); + generate_tx(tti_tx, action); } } @@ -244,56 +273,69 @@ void ul_harq_entity::ul_harq_process::generate_retx(uint32_t tti_tx, ul_sched_gr } // New transmission (Section 5.4.2.2) -void ul_harq_entity::ul_harq_process::generate_new_tx(uint32_t tti_tx, uint8_t *pdu_payload, bool is_msg3_, ul_sched_grant* ul_grant, ul_buffer* ul) +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 (ul_grant && pdu_payload) { + if (grant) { srslte_softbuffer_tx_reset(&softbuffer); - memcpy(&cur_grant, ul_grant, sizeof(ul_sched_grant)); + 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 PID %d: New TX%s, RV=%d, TBS=%d, MCS=%d, RNTI=%d\n", pid, is_msg3?" for Msg3":"", get_rv(), cur_grant.get_tbs(), - cur_grant.get_mcs(), cur_grant.get_rnti()); - generate_tx(tti_tx, pdu_payload, ul); + Info("UL PID %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, uint8_t *pdu_payload, ul_buffer* ul) +void ul_harq_entity::ul_harq_process::generate_tx(uint32_t tti_tx, mac_interface_phy::tb_action_ul_t *action) { - cur_grant.set_rv(get_rv()); - ul->set_current_tx_nb(current_tx_nb); - ul->generate_data(&cur_grant, &softbuffer, pdu_payload); - - if (harq_entity->pcap) { - harq_entity->pcap->write_ul_crnti(pdu_payload, cur_grant.get_tbs()/8, cur_grant.get_rnti(), current_tx_nb, tti_tx); - } + action->current_tx_nb = current_tx_nb; + action->expect_ack = true; + action->rnti = is_msg3?harq_entity->params_db->get_param(mac_interface_params::RNTI_TEMP):cur_grant.rnti; + action->rv = get_rv(); + action->softbuffer = &softbuffer; + action->tx_enabled = true; + memcpy(&action->phy_grant, &cur_grant.phy_grant, sizeof(srslte_phy_grant_t)); current_irv = (current_irv+1)%4; tti_last_tx = tti_tx; if (is_msg3) { - if (current_tx_nb == harq_entity->params_db->get_param(mac_params::HARQ_MAXMSG3TX)) { + if (current_tx_nb == harq_entity->params_db->get_param(mac_interface_params::HARQ_MAXMSG3TX)) { Info("UL PID %d: Maximum number of ReTX for Msg3 reached (%d). Discarting TB.\n", pid, - harq_entity->params_db->get_param(mac_params::HARQ_MAXMSG3TX)); + harq_entity->params_db->get_param(mac_interface_params::HARQ_MAXMSG3TX)); reset(); + action->expect_ack = false; } } else { - if (current_tx_nb == harq_entity->params_db->get_param(mac_params::HARQ_MAXTX)) { + if (current_tx_nb == harq_entity->params_db->get_param(mac_interface_params::HARQ_MAXTX)) { Info("UL PID %d: Maximum number of ReTX reached (%d). Discarting TB.\n", pid, - harq_entity->params_db->get_param(mac_params::HARQ_MAXTX)); + harq_entity->params_db->get_param(mac_interface_params::HARQ_MAXTX)); reset(); + action->expect_ack = false; } } } +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; +} } } \ No newline at end of file diff --git a/srsapps/ue/mac/test/mac_test.cc b/srsapps/ue/mac/test/mac_test.cc index 8dede5467..42aa455d7 100644 --- a/srsapps/ue/mac/test/mac_test.cc +++ b/srsapps/ue/mac/test/mac_test.cc @@ -32,7 +32,7 @@ #include "liblte_rrc.h" #include "srsapps/radio/radio_uhd.h" #include "srsapps/ue/phy/phy.h" -#include "srsapps/common/tti_sync_cv.h" +#include "srsapps/common/mac_interface.h" #include "srsapps/common/log_stdout.h" #include "srsapps/ue/mac/mac.h" #include "srsapps/ue/mac/mac_pcap.h" @@ -116,26 +116,26 @@ uint32_t sib_start_tti(uint32_t tti, uint32_t period, uint32_t x) { void setup_mac_phy_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, srslte::ue::mac *mac, srslte::ue::phy *phy) { // RACH-CONFIGCOMMON if (sib2->rr_config_common_sib.rach_cnfg.preambles_group_a_cnfg.present) { - mac->set_param(srslte::ue::mac_params::RA_NOFGROUPAPREAMBLES, + mac->set_param(srslte::ue::mac_interface_params::RA_NOFGROUPAPREAMBLES, liblte_rrc_message_size_group_a_num[sib2->rr_config_common_sib.rach_cnfg.preambles_group_a_cnfg.size_of_ra]); - mac->set_param(srslte::ue::mac_params::RA_MESSAGESIZEA, + mac->set_param(srslte::ue::mac_interface_params::RA_MESSAGESIZEA, liblte_rrc_message_size_group_a_num[sib2->rr_config_common_sib.rach_cnfg.preambles_group_a_cnfg.msg_size]); - mac->set_param(srslte::ue::mac_params::RA_MESSAGEPOWEROFFSETB, + mac->set_param(srslte::ue::mac_interface_params::RA_MESSAGEPOWEROFFSETB, liblte_rrc_message_power_offset_group_b_num[sib2->rr_config_common_sib.rach_cnfg.preambles_group_a_cnfg.msg_pwr_offset_group_b]); } - mac->set_param(srslte::ue::mac_params::RA_NOFPREAMBLES, + mac->set_param(srslte::ue::mac_interface_params::RA_NOFPREAMBLES, liblte_rrc_number_of_ra_preambles_num[sib2->rr_config_common_sib.rach_cnfg.num_ra_preambles]); - mac->set_param(srslte::ue::mac_params::RA_POWERRAMPINGSTEP, + mac->set_param(srslte::ue::mac_interface_params::RA_POWERRAMPINGSTEP, liblte_rrc_power_ramping_step_num[sib2->rr_config_common_sib.rach_cnfg.pwr_ramping_step]); - mac->set_param(srslte::ue::mac_params::RA_INITRECEIVEDPOWER, + mac->set_param(srslte::ue::mac_interface_params::RA_INITRECEIVEDPOWER, liblte_rrc_preamble_initial_received_target_power_num[sib2->rr_config_common_sib.rach_cnfg.preamble_init_rx_target_pwr]); - mac->set_param(srslte::ue::mac_params::RA_PREAMBLETRANSMAX, + mac->set_param(srslte::ue::mac_interface_params::RA_PREAMBLETRANSMAX, liblte_rrc_preamble_trans_max_num[sib2->rr_config_common_sib.rach_cnfg.preamble_trans_max]); - mac->set_param(srslte::ue::mac_params::RA_RESPONSEWINDOW, + mac->set_param(srslte::ue::mac_interface_params::RA_RESPONSEWINDOW, liblte_rrc_ra_response_window_size_num[sib2->rr_config_common_sib.rach_cnfg.ra_resp_win_size]); - mac->set_param(srslte::ue::mac_params::RA_CONTENTIONTIMER, + mac->set_param(srslte::ue::mac_interface_params::RA_CONTENTIONTIMER, liblte_rrc_mac_contention_resolution_timer_num[sib2->rr_config_common_sib.rach_cnfg.mac_con_res_timer]); - mac->set_param(srslte::ue::mac_params::HARQ_MAXMSG3TX, + mac->set_param(srslte::ue::mac_interface_params::HARQ_MAXMSG3TX, sib2->rr_config_common_sib.rach_cnfg.max_harq_msg3_tx); printf("Set RACH ConfigCommon: NofPreambles=%d, ResponseWindow=%d, ContentionResolutionTimer=%d ms, MaxTrials=%d\n", @@ -145,28 +145,28 @@ void setup_mac_phy_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, srslte::u liblte_rrc_preamble_trans_max_num[sib2->rr_config_common_sib.rach_cnfg.preamble_trans_max]); // PDSCH ConfigCommon - mac->set_param(srslte::ue::mac_params::PDSCH_RSPOWER, + mac->set_param(srslte::ue::mac_interface_params::PDSCH_RSPOWER, sib2->rr_config_common_sib.pdsch_cnfg.rs_power); - mac->set_param(srslte::ue::mac_params::PDSCH_PB, + mac->set_param(srslte::ue::mac_interface_params::PDSCH_PB, sib2->rr_config_common_sib.pdsch_cnfg.p_b); // PUSCH ConfigCommon - phy->set_param(srslte::ue::phy_params::PUSCH_BETA, 10); - phy->set_param(srslte::ue::phy_params::PUSCH_EN_64QAM, + phy->set_param(srslte::ue::phy_interface_params::PUSCH_BETA, 10); + phy->set_param(srslte::ue::phy_interface_params::PUSCH_EN_64QAM, sib2->rr_config_common_sib.pusch_cnfg.enable_64_qam); - phy->set_param(srslte::ue::phy_params::PUSCH_HOPPING_OFFSET, + phy->set_param(srslte::ue::phy_interface_params::PUSCH_HOPPING_OFFSET, sib2->rr_config_common_sib.pusch_cnfg.pusch_hopping_offset); - phy->set_param(srslte::ue::phy_params::PUSCH_HOPPING_N_SB, + phy->set_param(srslte::ue::phy_interface_params::PUSCH_HOPPING_N_SB, sib2->rr_config_common_sib.pusch_cnfg.n_sb); - phy->set_param(srslte::ue::phy_params::PUSCH_HOPPING_INTRA_SF, + phy->set_param(srslte::ue::phy_interface_params::PUSCH_HOPPING_INTRA_SF, sib2->rr_config_common_sib.pusch_cnfg.hopping_mode == LIBLTE_RRC_HOPPING_MODE_INTRA_AND_INTER_SUBFRAME?1:0); - phy->set_param(srslte::ue::phy_params::DMRS_GROUP_HOPPING_EN, + phy->set_param(srslte::ue::phy_interface_params::DMRS_GROUP_HOPPING_EN, sib2->rr_config_common_sib.pusch_cnfg.ul_rs.group_hopping_enabled?1:0); - phy->set_param(srslte::ue::phy_params::DMRS_SEQUENCE_HOPPING_EN, + phy->set_param(srslte::ue::phy_interface_params::DMRS_SEQUENCE_HOPPING_EN, sib2->rr_config_common_sib.pusch_cnfg.ul_rs.sequence_hopping_enabled?1:0); - phy->set_param(srslte::ue::phy_params::PUSCH_RS_CYCLIC_SHIFT, + phy->set_param(srslte::ue::phy_interface_params::PUSCH_RS_CYCLIC_SHIFT, sib2->rr_config_common_sib.pusch_cnfg.ul_rs.cyclic_shift); - phy->set_param(srslte::ue::phy_params::PUSCH_RS_GROUP_ASSIGNMENT, + phy->set_param(srslte::ue::phy_interface_params::PUSCH_RS_GROUP_ASSIGNMENT, sib2->rr_config_common_sib.pusch_cnfg.ul_rs.group_assignment_pusch); printf("Set PUSCH ConfigCommon: HopOffset=%d, RSGroup=%d, RSNcs=%d, N_sb=%d\n", @@ -176,14 +176,14 @@ void setup_mac_phy_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, srslte::u sib2->rr_config_common_sib.pusch_cnfg.n_sb); // PUCCH ConfigCommon - phy->set_param(srslte::ue::phy_params::PUCCH_BETA, 10); - phy->set_param(srslte::ue::phy_params::PUCCH_DELTA_SHIFT, + phy->set_param(srslte::ue::phy_interface_params::PUCCH_BETA, 10); + phy->set_param(srslte::ue::phy_interface_params::PUCCH_DELTA_SHIFT, liblte_rrc_delta_pucch_shift_num[sib2->rr_config_common_sib.pucch_cnfg.delta_pucch_shift]); - phy->set_param(srslte::ue::phy_params::PUCCH_CYCLIC_SHIFT, + phy->set_param(srslte::ue::phy_interface_params::PUCCH_CYCLIC_SHIFT, sib2->rr_config_common_sib.pucch_cnfg.n_cs_an); - phy->set_param(srslte::ue::phy_params::PUCCH_N_PUCCH_1, + phy->set_param(srslte::ue::phy_interface_params::PUCCH_N_PUCCH_1, sib2->rr_config_common_sib.pucch_cnfg.n1_pucch_an); - phy->set_param(srslte::ue::phy_params::PUCCH_N_RB_2, + phy->set_param(srslte::ue::phy_interface_params::PUCCH_N_RB_2, sib2->rr_config_common_sib.pucch_cnfg.n_rb_cqi); printf("Set PUCCH ConfigCommon: DeltaShift=%d, CyclicShift=%d, N1=%d, NRB=%d\n", liblte_rrc_delta_pucch_shift_num[sib2->rr_config_common_sib.pucch_cnfg.delta_pucch_shift], @@ -193,15 +193,15 @@ void setup_mac_phy_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, srslte::u // PRACH Configcommon - phy->set_param(srslte::ue::phy_params::PRACH_ROOT_SEQ_IDX, + phy->set_param(srslte::ue::phy_interface_params::PRACH_ROOT_SEQ_IDX, sib2->rr_config_common_sib.prach_cnfg.root_sequence_index); - phy->set_param(srslte::ue::phy_params::PRACH_HIGH_SPEED_FLAG, + phy->set_param(srslte::ue::phy_interface_params::PRACH_HIGH_SPEED_FLAG, sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.high_speed_flag?1:0); - phy->set_param(srslte::ue::phy_params::PRACH_FREQ_OFFSET, + phy->set_param(srslte::ue::phy_interface_params::PRACH_FREQ_OFFSET, sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.prach_freq_offset); - phy->set_param(srslte::ue::phy_params::PRACH_ZC_CONFIG, + phy->set_param(srslte::ue::phy_interface_params::PRACH_ZC_CONFIG, sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.zero_correlation_zone_config); - phy->set_param(srslte::ue::phy_params::PRACH_CONFIG_INDEX, + phy->set_param(srslte::ue::phy_interface_params::PRACH_CONFIG_INDEX, sib2->rr_config_common_sib.prach_cnfg.prach_cnfg_info.prach_config_index); printf("Set PRACH ConfigCommon: SeqIdx=%d, HS=%d, FreqOffset=%d, ZC=%d, ConfigIndex=%d\n", @@ -213,9 +213,9 @@ void setup_mac_phy_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, srslte::u // SRS ConfigCommon if (sib2->rr_config_common_sib.srs_ul_cnfg.present) { - phy->set_param(srslte::ue::phy_params::SRS_CS_BWCFG, sib2->rr_config_common_sib.srs_ul_cnfg.bw_cnfg); - phy->set_param(srslte::ue::phy_params::SRS_CS_SFCFG, sib2->rr_config_common_sib.srs_ul_cnfg.subfr_cnfg); - phy->set_param(srslte::ue::phy_params::SRS_CS_ACKNACKSIMUL, sib2->rr_config_common_sib.srs_ul_cnfg.ack_nack_simul_tx); + phy->set_param(srslte::ue::phy_interface_params::SRS_CS_BWCFG, sib2->rr_config_common_sib.srs_ul_cnfg.bw_cnfg); + phy->set_param(srslte::ue::phy_interface_params::SRS_CS_SFCFG, sib2->rr_config_common_sib.srs_ul_cnfg.subfr_cnfg); + phy->set_param(srslte::ue::phy_interface_params::SRS_CS_ACKNACKSIMUL, sib2->rr_config_common_sib.srs_ul_cnfg.ack_nack_simul_tx); } printf("Set SRS ConfigCommon: BW-Configuration=%d, SF-Configuration=%d, ACKNACK=%d\n", @@ -229,25 +229,24 @@ void process_connsetup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *msg, srslte::ue::mac // FIXME: There's an error parsing the connectionSetup message. This value is hard-coded: if (msg->rr_cnfg.phy_cnfg_ded_present) { - phy->set_param(srslte::ue::phy_params::PUCCH_N_PUCCH_SR, + phy->set_param(srslte::ue::phy_interface_params::PUCCH_N_PUCCH_SR, msg->rr_cnfg.phy_cnfg_ded.sched_request_cnfg.sr_pucch_resource_idx); - phy->set_param(srslte::ue::phy_params::SR_CONFIG_INDEX, + phy->set_param(srslte::ue::phy_interface_params::SR_CONFIG_INDEX, msg->rr_cnfg.phy_cnfg_ded.sched_request_cnfg.sr_cnfg_idx); - phy->set_param(srslte::ue::phy_params::UCI_I_OFFSET_ACK, msg->rr_cnfg.phy_cnfg_ded.pusch_cnfg_ded.beta_offset_ack_idx); - phy->set_param(srslte::ue::phy_params::UCI_I_OFFSET_CQI, msg->rr_cnfg.phy_cnfg_ded.pusch_cnfg_ded.beta_offset_cqi_idx); - phy->set_param(srslte::ue::phy_params::UCI_I_OFFSET_RI, msg->rr_cnfg.phy_cnfg_ded.pusch_cnfg_ded.beta_offset_ri_idx); + phy->set_param(srslte::ue::phy_interface_params::UCI_I_OFFSET_ACK, msg->rr_cnfg.phy_cnfg_ded.pusch_cnfg_ded.beta_offset_ack_idx); + phy->set_param(srslte::ue::phy_interface_params::UCI_I_OFFSET_CQI, msg->rr_cnfg.phy_cnfg_ded.pusch_cnfg_ded.beta_offset_cqi_idx); + phy->set_param(srslte::ue::phy_interface_params::UCI_I_OFFSET_RI, msg->rr_cnfg.phy_cnfg_ded.pusch_cnfg_ded.beta_offset_ri_idx); if (msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded_present && msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.setup_present) { - phy->set_param(srslte::ue::phy_params::SRS_UE_CS, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.cyclic_shift); - phy->set_param(srslte::ue::phy_params::SRS_UE_DURATION, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.duration); - phy->set_param(srslte::ue::phy_params::SRS_UE_NRRC, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.freq_domain_pos); - phy->set_param(srslte::ue::phy_params::SRS_UE_BW, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.srs_bandwidth); - phy->set_param(srslte::ue::phy_params::SRS_UE_CONFIGINDEX, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.srs_cnfg_idx); - phy->set_param(srslte::ue::phy_params::SRS_UE_HOP, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.srs_hopping_bandwidth); - phy->set_param(srslte::ue::phy_params::SRS_UE_CYCLICSHIFT, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.cyclic_shift); - phy->set_param(srslte::ue::phy_params::SRS_UE_TXCOMB, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.tx_comb); - phy->set_param(srslte::ue::phy_params::SRS_IS_CONFIGURED, 1); - phy->set_param(srslte::ue::phy_params::SRS_BETA, 10); + phy->set_param(srslte::ue::phy_interface_params::SRS_UE_CS, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.cyclic_shift); + phy->set_param(srslte::ue::phy_interface_params::SRS_UE_DURATION, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.duration); + phy->set_param(srslte::ue::phy_interface_params::SRS_UE_NRRC, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.freq_domain_pos); + phy->set_param(srslte::ue::phy_interface_params::SRS_UE_BW, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.srs_bandwidth); + phy->set_param(srslte::ue::phy_interface_params::SRS_UE_CONFIGINDEX, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.srs_cnfg_idx); + phy->set_param(srslte::ue::phy_interface_params::SRS_UE_HOP, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.srs_hopping_bandwidth); + phy->set_param(srslte::ue::phy_interface_params::SRS_UE_CYCLICSHIFT, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.cyclic_shift); + phy->set_param(srslte::ue::phy_interface_params::SRS_UE_TXCOMB, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.tx_comb); + phy->set_param(srslte::ue::phy_interface_params::SRS_IS_CONFIGURED, 1); } } printf("Set PHY configuration: SR-n_pucch=%d, SR-ConfigIndex=%d, SRS-ConfigIndex=%d, SRS-bw=%d, SRS-Nrcc=%d, SRS-hop=%d, SRS-Ncs=%d\n", @@ -259,15 +258,15 @@ void process_connsetup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *msg, srslte::ue::mac msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.srs_hopping_bandwidth, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.cyclic_shift); - mac->set_param(srslte::ue::mac_params::HARQ_MAXTX, + mac->set_param(srslte::ue::mac_interface_params::HARQ_MAXTX, liblte_rrc_max_harq_tx_num[msg->rr_cnfg.mac_main_cnfg.explicit_value.ulsch_cnfg.max_harq_tx]); - mac->set_param(srslte::ue::mac_params::SR_TRANS_MAX, + mac->set_param(srslte::ue::mac_interface_params::SR_TRANS_MAX, liblte_rrc_dsr_trans_max_num[msg->rr_cnfg.phy_cnfg_ded.sched_request_cnfg.dsr_trans_max]); - mac->set_param(srslte::ue::mac_params::SR_PUCCH_CONFIGURED, 1); + mac->set_param(srslte::ue::mac_interface_params::SR_PUCCH_CONFIGURED, 1); - mac->set_param(srslte::ue::mac_params::BSR_TIMER_RETX, + mac->set_param(srslte::ue::mac_interface_params::BSR_TIMER_RETX, liblte_rrc_retransmission_bsr_timer_num[msg->rr_cnfg.mac_main_cnfg.explicit_value.ulsch_cnfg.retx_bsr_timer]); - mac->set_param(srslte::ue::mac_params::BSR_TIMER_PERIODIC, + mac->set_param(srslte::ue::mac_interface_params::BSR_TIMER_PERIODIC, liblte_rrc_periodic_bsr_timer_num[msg->rr_cnfg.mac_main_cnfg.explicit_value.ulsch_cnfg.periodic_bsr_timer]); printf("Set MAC configuration: dsr-TransMAX: %d, harq-MaxReTX=%d, bsr-TimerReTX=%d, bsr-TimerPeriodic=%d\n", @@ -325,7 +324,6 @@ void sig_int_handler(int signo) if (prog_args.do_trace) { //radio_uhd.write_trace("radio"); phy.write_trace("phy"); - mac.write_trace("mac"); } if (prog_args.do_pcap) { mac_pcap.close(); @@ -334,10 +332,139 @@ void sig_int_handler(int signo) exit(0); } +class my_rlc : public srslte::ue::rlc_interface_mac { +public: + bool mib_decoded; + bool sib1_decoded; + bool sib2_decoded; + bool connsetup_decoded; + int nsegm_dcch; + uint8_t si_window_len, sib2_period; + + my_rlc() { + mib_decoded = false; + sib1_decoded = false; + sib2_decoded = false; + connsetup_decoded = false; + nsegm_dcch = 0; + si_window_len = 0; + sib2_period = 0; + } + + uint32_t get_buffer_state(uint32_t lcid) { + if (lcid == 0) { + if (sib2_decoded && !connsetup_decoded) { + return 6; + } + } else if (lcid == 1) { + if (connsetup_decoded && nsegm_dcch < 2) { + return lengths[nsegm_dcch]; + } else if (nsegm_dcch == 2) { + return 2; + } + } + return 0; + } + + uint32_t read_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) + { + if (lcid == 0) { + LIBLTE_RRC_UL_CCCH_MSG_STRUCT ul_ccch_msg; + // Prepare ConnectionRequest packet + ul_ccch_msg.msg_type = LIBLTE_RRC_UL_CCCH_MSG_TYPE_RRC_CON_REQ; + ul_ccch_msg.msg.rrc_con_req.ue_id_type = LIBLTE_RRC_CON_REQ_UE_ID_TYPE_RANDOM_VALUE; + ul_ccch_msg.msg.rrc_con_req.ue_id.random = 1000; + ul_ccch_msg.msg.rrc_con_req.cause = LIBLTE_RRC_CON_REQ_EST_CAUSE_MO_SIGNALLING; + liblte_rrc_pack_ul_ccch_msg(&ul_ccch_msg, &bit_msg); + + uint64_t uecri=0; + uint8_t *ue_cri_ptr = (uint8_t*) &uecri; + uint32_t nbytes = bit_msg.N_bits/8; + uint8_t *ptr = bit_msg.msg; + for (int i=0;i 0) { + if (dlsch_msg.sibs[0].sib_type == LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1) { + si_window_len = liblte_rrc_si_window_length_num[dlsch_msg.sibs[0].sib.sib1.si_window_length]; + sib2_period = liblte_rrc_si_periodicity_num[dlsch_msg.sibs[0].sib.sib1.sched_info[0].si_periodicity]; + printf("SIB1 received %d bytes, CellID=%d, si_window=%d, sib2_period=%d\n", + nof_bytes, dlsch_msg.sibs[0].sib.sib1.cell_id&0xfff, si_window_len, sib2_period); + sib1_decoded = true; + } else if (dlsch_msg.sibs[0].sib_type == LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2) { + + printf("SIB2 received %d bytes\n", nof_bytes); + setup_mac_phy_sib2(&dlsch_msg.sibs[0].sib.sib2, &mac, &phy); + sib2_decoded = true; + } + } + } + +private: + LIBLTE_BIT_MSG_STRUCT bit_msg; + LIBLTE_BYTE_MSG_STRUCT byte_msg; +}; + int main(int argc, char *argv[]) { - srslte::ue::tti_sync_cv ttisync(10240); srslte::log_stdout mac_log("MAC"), phy_log("PHY"); parse_args(&prog_args, argc, argv); @@ -358,7 +485,6 @@ int main(int argc, char *argv[]) signal(SIGINT, sig_int_handler); //radio_uhd.start_trace(); phy.start_trace(); - mac.start_trace(); } if (prog_args.do_pcap) { @@ -374,144 +500,32 @@ int main(int argc, char *argv[]) radio_uhd.init(); radio_uhd.set_rx_gain(prog_args.uhd_rx_gain); radio_uhd.set_tx_gain(prog_args.uhd_tx_gain); - phy.init(&radio_uhd, &ttisync, &phy_log); + phy.init(&radio_uhd, &mac, &phy_log); } else { radio_uhd.init_agc(); radio_uhd.set_tx_rx_gain_offset(0); - phy.init_agc(&radio_uhd, &ttisync, &phy_log); + phy.init_agc(&radio_uhd, &mac, &phy_log); } // Init MAC - mac.init(&phy, &ttisync, &mac_log); + mac.init(&phy, &my_rlc, &mac_log); // Set RX freq radio_uhd.set_rx_freq(prog_args.uhd_rx_freq); radio_uhd.set_tx_freq(prog_args.uhd_tx_freq); - LIBLTE_BIT_MSG_STRUCT bit_msg; - LIBLTE_RRC_MIB_STRUCT bch_msg; - LIBLTE_RRC_BCCH_DLSCH_MSG_STRUCT dlsch_msg; - LIBLTE_RRC_UL_CCCH_MSG_STRUCT ul_ccch_msg; - LIBLTE_RRC_DL_CCCH_MSG_STRUCT dl_ccch_msg; - - uint32_t si_window_len, sib2_period; - int tti; - enum {START, SIB1, SIB2, CONNECT, SETUPCOMPLETE, IDLE} state = START; - int n; - while(1) { - switch(state) { - case START: - n = mac.recv_bcch_sdu(bit_msg.msg, LIBLTE_MAX_MSG_SIZE); - if (n > 0) { - bit_msg.N_bits = n; - liblte_rrc_unpack_bcch_bch_msg(&bit_msg, &bch_msg); - printf("MIB received %d bytes, BW=%s\n", n, liblte_rrc_dl_bandwidth_text[bch_msg.dl_bw]); - state = SIB1; - } - break; - case SIB1: - n = mac.recv_bcch_sdu(bit_msg.msg, LIBLTE_MAX_MSG_SIZE); - if (n > 0) { - bit_msg.N_bits = n; - liblte_rrc_unpack_bcch_dlsch_msg(&bit_msg, &dlsch_msg); - si_window_len = liblte_rrc_si_window_length_num[dlsch_msg.sibs[0].sib.sib1.si_window_length]; - sib2_period = liblte_rrc_si_periodicity_num[dlsch_msg.sibs[0].sib.sib1.sched_info[0].si_periodicity]; - printf("SIB1 received %d bytes, CellID=%d, si_window=%d, sib2_period=%d\n", - n/8, dlsch_msg.sibs[0].sib.sib1.cell_id&0xfff, si_window_len, sib2_period); - state = SIB2; - } else { - tti = mac.get_tti(); - mac.set_param(srslte::ue::mac_params::BCCH_SI_WINDOW_ST, sib_start_tti(tti, 2, 5)); - mac.set_param(srslte::ue::mac_params::BCCH_SI_WINDOW_LEN, 1); - } - break; - case SIB2: - n = mac.recv_bcch_sdu(bit_msg.msg, LIBLTE_MAX_MSG_SIZE); - if (n > 0) { - // Process SIB2 - bit_msg.N_bits = n; - liblte_rrc_unpack_bcch_dlsch_msg(&bit_msg, &dlsch_msg); - printf("SIB2 received %d bytes\n", n/8); - setup_mac_phy_sib2(&dlsch_msg.sibs[0].sib.sib2, &mac, &phy); - - // Prepare ConnectionRequest packet - ul_ccch_msg.msg_type = LIBLTE_RRC_UL_CCCH_MSG_TYPE_RRC_CON_REQ; - ul_ccch_msg.msg.rrc_con_req.ue_id_type = LIBLTE_RRC_CON_REQ_UE_ID_TYPE_RANDOM_VALUE; - ul_ccch_msg.msg.rrc_con_req.ue_id.random = 1000; - ul_ccch_msg.msg.rrc_con_req.cause = LIBLTE_RRC_CON_REQ_EST_CAUSE_MO_SIGNALLING; - liblte_rrc_pack_ul_ccch_msg(&ul_ccch_msg, &bit_msg); - - uint64_t uecri=0; - uint8_t *ue_cri_ptr = (uint8_t*) &uecri; - uint32_t nbytes = bit_msg.N_bits/8; - uint8_t *ptr = bit_msg.msg; - for (int i=0;i 0) { - printf("ConnSetup received %d bytes\n", n/8); - bit_msg.N_bits = n; - srslte_vec_fprint_hex(stdout, bit_msg.msg, n); - liblte_rrc_unpack_dl_ccch_msg(&bit_msg, &dl_ccch_msg); - printf("Response: %s\n", liblte_rrc_dl_ccch_msg_type_text[dl_ccch_msg.msg_type]); - switch (dl_ccch_msg.msg_type) { - case LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_SETUP: - // Process ConnectionSetup - process_connsetup(&dl_ccch_msg.msg.rrc_con_setup, &mac, &phy); - - // Generate and send ConnectionSetupComplete - for (int i=0;i<2;i++) { - printf("Sending Connection Setup Complete %d\n", i); - srslte_bit_pack_vector(setupComplete_segm[i], bit_msg.msg, lengths[i]*8); - n=mac.send_dcch0_sdu(bit_msg.msg, lengths[i]*8); - if (n < 0) { - fprintf(stderr, "Error writting to DCCH0\n"); - exit(-1); - } - } - state = SETUPCOMPLETE; - break; - case LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_REJ: - mac.set_param(srslte::ue::mac_params::RNTI_C, 0); - break; - } - // exit(0); - } - break; - case SETUPCOMPLETE: - // Wait for ConnectionSetup - n = mac.recv_dcch0_sdu(bit_msg.msg, LIBLTE_MAX_MSG_SIZE); - if (n > 0) { - printf("Received on DCCH0 %d bytes\n", n/8); - printf("Send RLC ACK\n"); - srslte_bit_pack_vector(reply, bit_msg.msg, 2*8); - n=mac.send_dcch0_sdu(bit_msg.msg, 2*8); - if (n < 0) { - fprintf(stderr, "Error writting to DCCH0\n"); - exit(-1); - } - state = IDLE; - } - break; - case IDLE: - break; + uint32_t tti; + if (my_rlc.mib_decoded) { + if (!my_rlc.sib1_decoded) { + tti = mac.get_current_tti(); + mac.set_param(srslte::ue::mac_interface_params::BCCH_SI_WINDOW_ST, sib_start_tti(tti, 2, 5)); + mac.set_param(srslte::ue::mac_interface_params::BCCH_SI_WINDOW_LEN, 1); + } else { + tti = mac.get_current_tti(); + mac.set_param(srslte::ue::mac_interface_params::BCCH_SI_WINDOW_ST, sib_start_tti(tti, my_rlc.sib2_period, 0)); + mac.set_param(srslte::ue::mac_interface_params::BCCH_SI_WINDOW_LEN, my_rlc.si_window_len); + } } - usleep(10000); } } diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/phch_common.h b/srsapps/ue/phy/include/srsapps/ue/phy/phch_common.h index 433ce5e47..e88169212 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/phch_common.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/phch_common.h @@ -73,6 +73,7 @@ namespace ue { void worker_end(uint32_t tti, bool tx_enable, cf_t *buffer, uint32_t nof_samples, srslte_timestamp_t tx_time); bool sr_enabled; + int sr_last_tx_tti; private: pthread_mutex_t tx_mutex; diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/phch_worker.h b/srsapps/ue/phy/include/srsapps/ue/phy/phch_worker.h index 9a6f14f3c..d7ac46a92 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/phch_worker.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/phch_worker.h @@ -106,6 +106,9 @@ private: uint16_t ul_rnti; uint8_t *ul_payload; + // FIXME: THIS IS TEMPORAL. Need to change srslte to accept bits for payload + uint8_t payload_bits[64*1024]; + // UL configuration parameters srslte_refsignal_srs_cfg_t srs_cfg; srslte_pucch_cfg_t pucch_cfg; diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/phy.h b/srsapps/ue/phy/include/srsapps/ue/phy/phy.h index 1377d97f3..dc2379a34 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/phy.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/phy.h @@ -71,7 +71,7 @@ public: void write_trace(std::string filename); /********** MAC INTERFACE ********************/ - /* Instructs the PHY to configure using the parameters written with set_param() */ + /* Instructs the PHY to configure using the parameters written by set_param() */ void configure_prach_params(); void configure_ul_params(); @@ -79,11 +79,13 @@ public: void sync_start(); void sync_stop(); - /* Functions to initialize and transmit PRACH in the next opportunity */ - void prach_send(prach_cfg_t *cfg); - + /* Transmits PRACH in the next opportunity */ + void prach_send(uint32_t preamble_idx, int allowed_subframe = -1, float target_power_dbm = 0.0); + int prach_tx_tti(); + /* Indicates the transmission of a SR signal in the next opportunity */ void sr_send(); + int sr_last_tx_tti(); // Time advance commands void set_timeadv_rar(uint32_t ta_cmd); diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/prach.h b/srsapps/ue/phy/include/srsapps/ue/phy/prach.h index e4aae9105..16a094a14 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/prach.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/prach.h @@ -49,10 +49,9 @@ namespace ue { void init(phy_params *params_db, log *log_h); bool init_cell(srslte_cell_t cell); void free_cell(); - bool prepare_to_send(phy_interface::prach_cfg_t* cfg); bool prepare_to_send(uint32_t preamble_idx, int allowed_subframe = -1, float target_power_dbm = -1); bool is_ready_to_send(uint32_t current_tti); - void get_rar_cfg(uint16_t* rar_rnti, uint32_t* tti_start, uint32_t* tti_end); + int tx_tti(); bool send(radio* radio_handler, float cfo, srslte_timestamp_t rx_time); @@ -66,12 +65,11 @@ namespace ue { uint32_t len; cf_t *buffer[64]; srslte_prach_t prach_obj; - uint32_t transmitted_tti; + int transmitted_tti; srslte_cell_t cell; cf_t *signal_buffer; srslte_cfo_t cfo_h; - phy_interface::prach_cfg_t prach_cfg; }; } diff --git a/srsapps/ue/phy/src/phch_recv.cc b/srsapps/ue/phy/src/phch_recv.cc index 73e7f9ca3..72eaa69b4 100644 --- a/srsapps/ue/phy/src/phch_recv.cc +++ b/srsapps/ue/phy/src/phch_recv.cc @@ -201,7 +201,7 @@ bool phch_recv::cell_search(int force_N_id_2) if (ret == 1) { srslte_pbch_mib_unpack(bch_payload, &cell, NULL); srslte_cell_fprint(stdout, &cell, 0); - mac->bch_decoded_ok(bch_payload); + mac->bch_decoded_ok(bch_payload, SRSLTE_BCH_PAYLOAD_LEN); return true; } else { Warning("Error decoding MIB: Error decoding PBCH\n"); @@ -305,16 +305,11 @@ void phch_recv::run_thread() if (prach_buffer->is_ready_to_send(tti)) { srslte_timestamp_t cur_time; radio_h->get_time(&cur_time); - Info("TX PRACH now. RX time: %d:%f, Now: %d:%f\n", rx_time.full_secs, rx_time.frac_secs, cur_time.full_secs, cur_time.frac_secs); + Info("TX PRACH now. RX time: %d:%f, Now: %d:%f\n", rx_time.full_secs, rx_time.frac_secs, + cur_time.full_secs, cur_time.frac_secs); // send prach if we have to prach_buffer->send(radio_h, cfo, tx_time); - radio_h->tx_end(); - - /* Setup DL RNTI search to look for RAR as configured by MAC */ - uint16_t rar_rnti; - uint32_t rar_start, rar_end; - prach_buffer->get_rar_cfg(&rar_rnti, &rar_start, &rar_end); - worker_com->set_dl_rnti(SRSLTE_RNTI_RAR, rar_rnti, (int) rar_start, (int) rar_end); + radio_h->tx_end(); } workers_pool->start_worker(worker); } diff --git a/srsapps/ue/phy/src/phch_worker.cc b/srsapps/ue/phy/src/phch_worker.cc index e73a0a6e5..fd3cc9d3c 100644 --- a/srsapps/ue/phy/src/phch_worker.cc +++ b/srsapps/ue/phy/src/phch_worker.cc @@ -158,6 +158,9 @@ void phch_worker::work_imp() dl_ack = decode_pdsch(&dl_action.phy_grant.dl, dl_action.payload_ptr, dl_action.softbuffer, dl_action.rv, dl_action.rnti); phy->mac->tb_decoded_ok(dl_mac_grant.pid); } + if (dl_action.generate_ack_callback) { + dl_action.generate_ack = dl_action.generate_ack_callback(dl_action.generate_ack_callback_arg); + } if (dl_action.generate_ack) { set_uci_ack(dl_ack); } @@ -273,7 +276,7 @@ bool phch_worker::decode_pdcch_dl(srslte::ue::mac_interface_phy::mac_grant_t* gr /* Fill MAC grant structure */ grant->ndi = dci_unpacked.ndi; grant->pid = dci_unpacked.harq_process; - grant->tbs = grant->phy_grant.dl.mcs.tbs; + grant->n_bytes = grant->phy_grant.dl.mcs.tbs/8; grant->tti = tti; grant->rv = dci_unpacked.rv_idx; grant->rnti = dl_rnti; @@ -299,8 +302,10 @@ bool phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload, if (ue_dl.pdsch_cfg.grant.mcs.mod > 0 && ue_dl.pdsch_cfg.grant.mcs.tbs >= 0) { if (srslte_pdsch_decode_rnti(&ue_dl.pdsch, &ue_dl.pdsch_cfg, softbuffer, ue_dl.sf_symbols, - ue_dl.ce, 0, rnti, payload) == 0) + ue_dl.ce, 0, rnti, payload_bits) == 0) { + // FIXME: TEMPORAL + srslte_bit_unpack_vector(payload_bits, payload, grant->mcs.tbs); Debug("TB decoded OK\n"); return true; } else { @@ -354,6 +359,7 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant) Error("Converting RAR message to UL grant\n"); return false; } + grant->is_from_rar = true; Info("RAR grant found for TTI=%d\n", tti); rar_cqi_request = rar_grant.cqi_request; ret = true; @@ -372,6 +378,7 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant) Error("Converting DCI message to UL grant\n"); return false; } + grant->is_from_rar = false; ret = true; Info("PDCCH: UL DCI Format0 cce_index=%d, n_data_bits=%d\n", ue_dl.last_n_cce, dci_msg.nof_bits); } @@ -379,7 +386,7 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant) if (ret) { grant->ndi = dci_unpacked.ndi; grant->pid = 0; // This is computed by MAC from TTI - grant->tbs = grant->phy_grant.ul.mcs.tbs; + grant->n_bytes = grant->phy_grant.ul.mcs.tbs/8; grant->tti = tti; grant->rnti = ul_rnti; @@ -412,6 +419,7 @@ void phch_worker::set_uci_sr() if (srslte_ue_ul_sr_send_tti(I_sr, tti+4)) { Info("SR transmission at TTI=%d\n", tti+4); uci_data.scheduling_request = true; + phy->sr_last_tx_tti = tti+4; phy->sr_enabled = false; } } @@ -457,8 +465,11 @@ void phch_worker::encode_pusch(srslte_ra_ul_grant_t *grant, uint32_t current_tx_ Error("Configuring UL grant\n"); } + // FIXME: TEMPORAL + srslte_bit_pack_vector(ul_payload, payload_bits, grant->mcs.tbs); + if (srslte_ue_ul_pusch_encode_rnti_softbuffer(&ue_ul, - ul_payload, uci_data, + payload_bits, uci_data, softbuffer, rnti, signal_buffer)) diff --git a/srsapps/ue/phy/src/phy.cc b/srsapps/ue/phy/src/phy.cc index 1f4ec65d4..4fb978e15 100644 --- a/srsapps/ue/phy/src/phy.cc +++ b/srsapps/ue/phy/src/phy.cc @@ -187,14 +187,19 @@ void phy::get_current_cell(srslte_cell_t *cell) sf_recv.get_current_cell(cell); } -void phy::prach_send(phy_interface::prach_cfg_t* cfg) +void phy::prach_send(uint32_t preamble_idx, int allowed_subframe, float target_power_dbm) { - if (!prach_buffer.prepare_to_send(cfg)) { + if (!prach_buffer.prepare_to_send(preamble_idx, allowed_subframe, target_power_dbm)) { Error("Preparing PRACH to send\n"); } } +int phy::prach_tx_tti() +{ + return prach_buffer.tx_tti(); +} + void phy::reset() { // TODO @@ -210,6 +215,11 @@ void phy::sr_send() workers_common.sr_enabled = true; } +int phy::sr_last_tx_tti() +{ + return workers_common.sr_last_tx_tti; +} + bool phy::status_is_sync() { return sf_recv.status_is_sync(); diff --git a/srsapps/ue/phy/src/prach.cc b/srsapps/ue/phy/src/prach.cc index 6419a1206..8ceafb903 100644 --- a/srsapps/ue/phy/src/prach.cc +++ b/srsapps/ue/phy/src/prach.cc @@ -95,16 +95,6 @@ bool prach::init_cell(srslte_cell_t cell_) return initiated; } -bool prach::prepare_to_send(phy_interface::prach_cfg_t* cfg) -{ - int allowed_sf = cfg->allowed_subframe_enabled?(int) cfg->allowed_subframe:-1; - bool ret = prepare_to_send(cfg->preamble_idx, allowed_sf, cfg->target_power_dbm); - if (ret) { - memcpy(&prach_cfg, cfg, sizeof(phy_interface::prach_cfg_t)); - } - return ret; -} - bool prach::prepare_to_send(uint32_t preamble_idx_, int allowed_subframe_, float target_power_dbm) { if (initiated && preamble_idx_ < 64) { @@ -137,17 +127,8 @@ bool prach::is_ready_to_send(uint32_t current_tti_) { return false; } -void prach::get_rar_cfg(uint16_t *rar_rnti, uint32_t *tti_start, uint32_t *tti_end) -{ - if (rar_rnti) { - *rar_rnti = prach_cfg.rar_rnti; - } - if (tti_start) { - *tti_start = transmitted_tti + prach_cfg.rar_start; - } - if (tti_end) { - *tti_end = transmitted_tti + prach_cfg.rar_start + prach_cfg.rar_window; - } +int prach::tx_tti() { + return transmitted_tti; } bool prach::send(radio *radio_handler, float cfo, srslte_timestamp_t tx_time) diff --git a/srsapps/ue/phy/test/ue_itf_test_prach.cc b/srsapps/ue/phy/test/ue_itf_test_prach.cc index b363271ea..a46fcc3c6 100644 --- a/srsapps/ue/phy/test/ue_itf_test_prach.cc +++ b/srsapps/ue/phy/test/ue_itf_test_prach.cc @@ -202,9 +202,26 @@ uint16_t temp_c_rnti; class testmac : public srslte::ue::mac_interface_phy { public: + + testmac() { + rar_rnti_set = false; + } + + bool rar_rnti_set; + + void tti_clock(uint32_t tti) { + if (!rar_rnti_set) { + int prach_tti = my_phy.prach_tx_tti(); + if (prach_tti > 0) { + my_phy.pdcch_dl_search(SRSLTE_RNTI_RAR, 1+prach_tti%10, prach_tti+3, 10); + rar_rnti_set = true; + } + } + } + void new_grant_ul(mac_grant_t grant, uint8_t *payload_ptr, tb_action_ul_t *action) { printf("New grant UL\n"); - srslte_bit_pack_vector((uint8_t*) conn_request_msg, payload_ptr, grant.tbs); + srslte_bit_pack_vector((uint8_t*) conn_request_msg, payload_ptr, grant.n_bytes*8); action->current_tx_nb = nof_rtx_connsetup; action->rv = rv_value[nof_rtx_connsetup%4]; action->softbuffer = &softbuffer_tx; @@ -272,7 +289,7 @@ public: temp_c_rnti = rar_msg.temp_c_rnti; - if (last_grant.tbs > 20 + SRSLTE_RAR_GRANT_LEN) { + if (last_grant.n_bytes*8 > 20 + SRSLTE_RAR_GRANT_LEN) { uint8_t rar_grant[SRSLTE_RAR_GRANT_LEN]; memcpy(rar_grant, &payload[20], sizeof(uint8_t)*SRSLTE_RAR_GRANT_LEN); my_phy.set_rar_grant(last_grant.tti, rar_grant); @@ -286,14 +303,15 @@ public: } } - void bch_decoded_ok(uint8_t *payload) { + void bch_decoded_ok(uint8_t *payload, uint32_t len) { printf("BCH decoded\n"); bch_decoded = true; srslte_cell_t cell; my_phy.get_current_cell(&cell); - srslte_softbuffer_rx_init(&softbuffer_rx, cell); - srslte_softbuffer_tx_init(&softbuffer_tx, cell); + srslte_softbuffer_rx_init(&softbuffer_rx, cell.nof_prb); + srslte_softbuffer_tx_init(&softbuffer_tx, cell.nof_prb); } + private: mac_grant_t last_grant; }; @@ -347,13 +365,7 @@ int main(int argc, char *argv[]) config_phy(); /* Instruct PHY to send PRACH and prepare it for receiving RAR */ - srslte::ue::phy_interface::prach_cfg_t prach_cfg; - prach_cfg.allowed_subframe_enabled = false; - prach_cfg.preamble_idx = preamble_idx; - prach_cfg.rar_rnti = 2; - prach_cfg.rar_start = 3; - prach_cfg.rar_window = 10; - my_phy.prach_send(&prach_cfg); + my_phy.prach_send(preamble_idx); /* go to idle and process each tti */ bool running = true; diff --git a/srsapps/ue/phy/test/ue_itf_test_sib1.cc b/srsapps/ue/phy/test/ue_itf_test_sib1.cc index 47326608c..71c1e0871 100644 --- a/srsapps/ue/phy/test/ue_itf_test_sib1.cc +++ b/srsapps/ue/phy/test/ue_itf_test_sib1.cc @@ -127,13 +127,14 @@ public: total_oks++; } - void bch_decoded_ok(uint8_t *payload) { + void bch_decoded_ok(uint8_t *payload, uint32_t len) { printf("BCH decoded\n"); bch_decoded = true; srslte_cell_t cell; my_phy.get_current_cell(&cell); - srslte_softbuffer_rx_init(&softbuffer, cell); - + srslte_softbuffer_rx_init(&softbuffer, cell.nof_prb); + } + void tti_clock(uint32_t tti) { } }; diff --git a/srslte/examples/pdsch_enodeb.c b/srslte/examples/pdsch_enodeb.c index 5d77ee9d0..a551d8e31 100644 --- a/srslte/examples/pdsch_enodeb.c +++ b/srslte/examples/pdsch_enodeb.c @@ -259,7 +259,7 @@ void base_init() { srslte_pdsch_set_rnti(&pdsch, UE_CRNTI); - if (srslte_softbuffer_tx_init(&softbuffer, cell)) { + if (srslte_softbuffer_tx_init(&softbuffer, cell.nof_prb)) { fprintf(stderr, "Error initiating soft buffer\n"); exit(-1); } diff --git a/srslte/include/srslte/fec/softbuffer.h b/srslte/include/srslte/fec/softbuffer.h index a35073746..2dedfb5d0 100644 --- a/srslte/include/srslte/fec/softbuffer.h +++ b/srslte/include/srslte/fec/softbuffer.h @@ -53,14 +53,14 @@ typedef struct SRSLTE_API { } srslte_softbuffer_tx_t; SRSLTE_API int srslte_softbuffer_rx_init(srslte_softbuffer_rx_t * q, - srslte_cell_t cell); + uint32_t nof_prb); SRSLTE_API void srslte_softbuffer_rx_reset(srslte_softbuffer_rx_t *p); SRSLTE_API void srslte_softbuffer_rx_free(srslte_softbuffer_rx_t *p); SRSLTE_API int srslte_softbuffer_tx_init(srslte_softbuffer_tx_t * q, - srslte_cell_t cell); + uint32_t nof_prb); SRSLTE_API void srslte_softbuffer_tx_reset(srslte_softbuffer_tx_t *p); diff --git a/srslte/lib/fec/src/softbuffer.c b/srslte/lib/fec/src/softbuffer.c index fad61186b..1cad3496c 100644 --- a/srslte/lib/fec/src/softbuffer.c +++ b/srslte/lib/fec/src/softbuffer.c @@ -44,7 +44,7 @@ #define MAX_PDSCH_RE(cp) (2 * SRSLTE_CP_NSYMB(cp) * 12) -int srslte_softbuffer_rx_init(srslte_softbuffer_rx_t *q, srslte_cell_t cell) { +int srslte_softbuffer_rx_init(srslte_softbuffer_rx_t *q, uint32_t nof_prb) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { @@ -52,7 +52,7 @@ int srslte_softbuffer_rx_init(srslte_softbuffer_rx_t *q, srslte_cell_t cell) { bzero(q, sizeof(srslte_softbuffer_rx_t)); - ret = srslte_ra_tbs_from_idx(26, cell.nof_prb); + ret = srslte_ra_tbs_from_idx(26, nof_prb); if (ret != SRSLTE_ERROR) { q->max_cb = (uint32_t) ret / (SRSLTE_TCOD_MAX_LEN_CB - 24) + 1; @@ -106,7 +106,7 @@ void srslte_softbuffer_rx_reset(srslte_softbuffer_rx_t *q) { -int srslte_softbuffer_tx_init(srslte_softbuffer_tx_t *q, srslte_cell_t cell) { +int srslte_softbuffer_tx_init(srslte_softbuffer_tx_t *q, uint32_t nof_prb) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { @@ -114,7 +114,7 @@ int srslte_softbuffer_tx_init(srslte_softbuffer_tx_t *q, srslte_cell_t cell) { bzero(q, sizeof(srslte_softbuffer_tx_t)); - ret = srslte_ra_tbs_from_idx(26, cell.nof_prb); + ret = srslte_ra_tbs_from_idx(26, nof_prb); if (ret != SRSLTE_ERROR) { q->max_cb = (uint32_t) ret / (SRSLTE_TCOD_MAX_LEN_CB - 24) + 1; diff --git a/srslte/lib/phch/test/dlsch_encode_test_mex.c b/srslte/lib/phch/test/dlsch_encode_test_mex.c index 60549d48f..05d55b470 100644 --- a/srslte/lib/phch/test/dlsch_encode_test_mex.c +++ b/srslte/lib/phch/test/dlsch_encode_test_mex.c @@ -91,7 +91,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mxFree(mod_str); - if (srslte_softbuffer_tx_init(&softbuffer, cell)) { + if (srslte_softbuffer_tx_init(&softbuffer, cell.nof_prb)) { mexErrMsgTxt("Error initiating DL-SCH soft buffer\n"); return; } diff --git a/srslte/lib/phch/test/pdsch_test.c b/srslte/lib/phch/test/pdsch_test.c index d580ff278..b2313aa3f 100644 --- a/srslte/lib/phch/test/pdsch_test.c +++ b/srslte/lib/phch/test/pdsch_test.c @@ -183,12 +183,12 @@ int main(int argc, char **argv) { srslte_pdsch_set_rnti(&pdsch, 1234); - if (srslte_softbuffer_tx_init(&softbuffer_tx, cell)) { + if (srslte_softbuffer_tx_init(&softbuffer_tx, cell.nof_prb)) { fprintf(stderr, "Error initiating TX soft buffer\n"); goto quit; } - if (srslte_softbuffer_rx_init(&softbuffer_rx, cell)) { + if (srslte_softbuffer_rx_init(&softbuffer_rx, cell.nof_prb)) { fprintf(stderr, "Error initiating RX soft buffer\n"); goto quit; } diff --git a/srslte/lib/phch/test/pdsch_test_mex.c b/srslte/lib/phch/test/pdsch_test_mex.c index 970a82b9a..fbabbee52 100644 --- a/srslte/lib/phch/test/pdsch_test_mex.c +++ b/srslte/lib/phch/test/pdsch_test_mex.c @@ -93,7 +93,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) } srslte_pdsch_set_rnti(&pdsch, (uint16_t) (rnti32 & 0xffff)); - if (srslte_softbuffer_rx_init(&softbuffer, cell)) { + if (srslte_softbuffer_rx_init(&softbuffer, cell.nof_prb)) { mexErrMsgTxt("Error initiating soft buffer\n"); return; } diff --git a/srslte/lib/phch/test/pusch_encode_test_mex.c b/srslte/lib/phch/test/pusch_encode_test_mex.c index 9e63a73ea..280857fc2 100644 --- a/srslte/lib/phch/test/pusch_encode_test_mex.c +++ b/srslte/lib/phch/test/pusch_encode_test_mex.c @@ -139,7 +139,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) srslte_softbuffer_tx_t softbuffer; - if (srslte_softbuffer_tx_init(&softbuffer, cell)) { + if (srslte_softbuffer_tx_init(&softbuffer, cell.nof_prb)) { mexErrMsgTxt("Error initiating soft buffer\n"); return; } diff --git a/srslte/lib/phch/test/pusch_test.c b/srslte/lib/phch/test/pusch_test.c index a9943324c..96a5e4600 100644 --- a/srslte/lib/phch/test/pusch_test.c +++ b/srslte/lib/phch/test/pusch_test.c @@ -207,7 +207,7 @@ int main(int argc, char **argv) { } gettimeofday(&t[1], NULL); - if (srslte_softbuffer_tx_init(&softbuffer, cell)) { + if (srslte_softbuffer_tx_init(&softbuffer, cell.nof_prb)) { fprintf(stderr, "Error initiating soft buffer\n"); goto quit; } diff --git a/srslte/lib/phch/test/ulsch_encode_test_mex.c b/srslte/lib/phch/test/ulsch_encode_test_mex.c index 4fc054a39..beb01e543 100644 --- a/srslte/lib/phch/test/ulsch_encode_test_mex.c +++ b/srslte/lib/phch/test/ulsch_encode_test_mex.c @@ -69,7 +69,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) cell.id=1; cell.cp=SRSLTE_CP_NORM; - if (srslte_softbuffer_tx_init(&softbuffer, cell)) { + if (srslte_softbuffer_tx_init(&softbuffer, cell.nof_prb)) { mexErrMsgTxt("Error initiating HARQ\n"); return; } diff --git a/srslte/lib/ue/src/ue_dl.c b/srslte/lib/ue/src/ue_dl.c index 51ed1cd4c..2f25aae86 100644 --- a/srslte/lib/ue/src/ue_dl.c +++ b/srslte/lib/ue/src/ue_dl.c @@ -86,7 +86,7 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q, fprintf(stderr, "Error creating PDSCH object\n"); goto clean_exit; } - if (srslte_softbuffer_rx_init(&q->softbuffer, q->cell)) { + if (srslte_softbuffer_rx_init(&q->softbuffer, q->cell.nof_prb)) { fprintf(stderr, "Error initiating soft buffer\n"); goto clean_exit; } diff --git a/srslte/lib/ue/src/ue_ul.c b/srslte/lib/ue/src/ue_ul.c index 9caf43dd8..820de4092 100644 --- a/srslte/lib/ue/src/ue_ul.c +++ b/srslte/lib/ue/src/ue_ul.c @@ -74,7 +74,7 @@ int srslte_ue_ul_init(srslte_ue_ul_t *q, fprintf(stderr, "Error creating PUSCH object\n"); goto clean_exit; } - if (srslte_softbuffer_tx_init(&q->softbuffer, q->cell)) { + if (srslte_softbuffer_tx_init(&q->softbuffer, q->cell.nof_prb)) { fprintf(stderr, "Error initiating soft buffer\n"); goto clean_exit; }