Merge branch 'next' into agpl_next

master
Codebot 4 years ago committed by Your Name
commit 887f1da10c

@ -65,11 +65,13 @@ struct cells results[1024];
float rf_gain = 70.0;
char* rf_args = "";
char* rf_dev = "";
void usage(char* prog)
{
printf("Usage: %s [agsendtvb] -b band\n", prog);
printf("\t-a RF args [Default %s]\n", rf_args);
printf("\t-d RF devicename [Default %s]\n", rf_dev);
printf("\t-g RF gain [Default %.2f dB]\n", rf_gain);
printf("\t-s earfcn_start [Default All]\n");
printf("\t-e earfcn_end [Default All]\n");
@ -88,6 +90,9 @@ void parse_args(int argc, char** argv)
case 'b':
band = (int)strtol(argv[optind], NULL, 10);
break;
case 'd':
rf_dev = argv[optind];
break;
case 's':
earfcn_start = (int)strtol(argv[optind], NULL, 10);
break;
@ -151,7 +156,8 @@ int main(int argc, char** argv)
parse_args(argc, argv);
printf("Opening RF device...\n");
if (srsran_rf_open(&rf, rf_args)) {
if (srsran_rf_open_devname(&rf, rf_dev, rf_args, 1)) {
ERROR("Error opening rf");
exit(-1);
}

@ -551,7 +551,7 @@ int main(int argc, char** argv)
system_frame_number = (mib.sfn + sfn_offset) % 1024;
cell.mode = mib.mode;
// set number of ports of base cell to that of NB-IoT cell (FIXME: read eutra-NumCRS-Ports-r13)
// set number of ports of base cell to that of NB-IoT cell (TODO: read eutra-NumCRS-Ports-r13)
cell.base.nof_ports = cell.nof_ports;
if (cell.mode == SRSRAN_NBIOT_MODE_INBAND_SAME_PCI) {

@ -374,7 +374,6 @@ srsran_ue_sync_t ue_sync;
prog_args_t prog_args;
uint32_t pkt_errors = 0, pkt_total = 0, nof_detected = 0, pmch_pkt_errors = 0, pmch_pkt_total = 0, nof_trials = 0;
double evm = 0.0;
srsran_netsink_t net_sink, net_sink_signal;
/* Useful macros for printing lines which will disappear */

@ -253,7 +253,7 @@ int main(int argc, char** argv)
if (!prog_args.input_file_name) {
printf("Opening RF device...\n");
if (srsran_rf_open_multi(&radio, prog_args.rf_args, prog_args.nof_rx_antennas)) {
if (srsran_rf_open_devname(&radio, prog_args.rf_dev, prog_args.rf_args, prog_args.nof_rx_antennas)) {
ERROR("Error opening rf");
exit(-1);
}

@ -48,7 +48,7 @@ public:
bool empty() const { return stop_ == start_; }
auto length() -> decltype(std::declval<T>() - std::declval<T>()) const { return stop_ - start_; }
auto length() const -> decltype(std::declval<T>() - std::declval<T>()) { return stop_ - start_; }
void set(T start_point, T stop_point)
{

@ -59,7 +59,7 @@ public:
{
for (mem_block_elem_t& elem : pools) {
std::unique_lock<std::mutex> lock(elem.mutex);
srsran_assert(elem.count == 0, "There are missing deallocations for stack id=%zd", elem.key);
srsran_expect(elem.count == 0, "There are missing deallocations for stack id=%zd", elem.key);
if (elem.alloc.is_init()) {
void* ptr = elem.alloc.memblock_ptr();
elem.alloc.clear();

@ -295,7 +295,7 @@ public:
using iterator = T*;
using const_iterator = const T*;
explicit bounded_array(uint32_t size_ = 0) : current_size(size_) {}
explicit bounded_array(uint32_t size_ = 0) : data_(), current_size(size_) {}
static uint32_t capacity() { return MAX_N; }
uint32_t size() const { return current_size; }
T& operator[](uint32_t idx) { return data_[idx]; }

@ -4159,7 +4159,7 @@ public:
#elif defined(__aarch64__)
#if defined(__APPLE__)
error_addr = reinterpret_cast<void *>(uctx->uc_mcontext->__ss.__pc);
#elif
#else
error_addr = reinterpret_cast<void *>(uctx->uc_mcontext.pc);
#endif
#elif defined(__mips__)

@ -80,7 +80,7 @@ private:
// Elements of Table 5.4.2.3-1 in TS 38.104
struct nr_band {
uint8_t band;
uint16_t band;
delta_f_raster_t delta_f_raster;
uint32_t ul_nref_first;
uint32_t ul_nref_step;
@ -92,12 +92,45 @@ private:
// List of NR bands for FR1 (Table 5.4.2.3-1)
// bands with more than one raster offset have multiple entries
// TODO: add remaining bands
static const uint32_t nof_nr_bands_fr1 = 7;
static const uint32_t nof_nr_bands_fr1 = 36;
static constexpr std::array<nr_band, nof_nr_bands_fr1> nr_band_table_fr1 = {{
// clang-format off
{1, KHZ_100, 384000, 20, 396000, 422000, 20, 434000},
{2, KHZ_100, 370000, 20, 382000, 386000, 20, 398000},
{3, KHZ_100, 342000, 20, 357000, 361000, 20, 376000},
{5, KHZ_100, 164800, 20, 169800, 173800, 20, 178800},
{7, KHZ_100, 500000, 20, 514000, 524000, 20, 538000},
{8, KHZ_100, 176000, 20, 183000, 185000, 20, 192000},
{12, KHZ_100, 139800, 20, 143200, 145800, 20, 149200},
{20, KHZ_100, 166400, 20, 172400, 158200, 20, 164200},
{25, KHZ_100, 370000, 20, 383000, 386000, 20, 399000},
{28, KHZ_100, 140600, 20, 149600, 151600, 20, 160600},
{34, KHZ_100, 402000, 20, 405000, 402000, 20, 405000},
{38, KHZ_100, 514000, 20, 524000, 514000, 20, 524000},
{39, KHZ_100, 376000, 20, 384000, 376000, 20, 384000},
{40, KHZ_100, 460000, 20, 480000, 460000, 20, 480000},
{41, KHZ_15, 499200, 3, 537999, 499200, 3, 537999},
{41, KHZ_30, 499200, 6, 537996, 499200, 6, 537996},
{50, KHZ_100, 286400, 20, 303400, 286400, 20, 303400},
{51, KHZ_100, 285400, 20, 286400, 285400, 20, 286400},
{66, KHZ_100, 342000, 20, 356000, 422000, 20, 440000},
{70, KHZ_100, 339000, 20, 342000, 399000, 20, 404000},
{71, KHZ_100, 132600, 20, 139600, 123400, 20, 130400},
{74, KHZ_100, 285400, 20, 294000, 295000, 20, 303600},
// n75+n76 missing
{75, KHZ_100, 0, 0, 0, 286400, 20, 303400},
{76, KHZ_100, 0, 0, 0, 285400, 20, 286400},
{77, KHZ_15, 620000, 1, 680000, 620000, 1, 680000},
{77, KHZ_30, 620000, 2, 680000, 620000, 2, 680000},
@ -105,9 +138,31 @@ private:
{78, KHZ_30, 620000, 2, 653332, 620000, 2, 653332},
{79, KHZ_15, 693334, 2, 733333, 693334, 2, 733333},
{79, KHZ_30, 693334, 2, 733332, 693334, 2, 733332}
{79, KHZ_30, 693334, 2, 733332, 693334, 2, 733332},
{80, KHZ_100, 342000, 20, 357000, 0, 0, 0},
{81, KHZ_100, 176000, 20, 183000, 0, 0, 0},
{82, KHZ_100, 166400, 20, 172400, 0, 0, 0},
{83, KHZ_100, 140600, 20, 149600, 0, 0, 0},
{84, KHZ_100, 384000, 20, 396000, 0, 0, 0},
{86, KHZ_100, 342000, 20, 356000, 0, 0, 0}
// clang-format on
}};
static const uint32_t nof_nr_bands_fr2 = 36;
static constexpr std::array<nr_band, nof_nr_bands_fr2> nr_band_table_fr2 = {{
{257, KHZ_60, 2054166, 1, 2104165, 2054166, 1, 2104165},
{257, KHZ_120, 2054167, 2, 2104165, 2054167, 20, 2104165},
{258, KHZ_60, 2016667, 1, 2070832, 2016667, 1, 2070832},
{258, KHZ_120, 2016667, 2, 2070831, 2016667, 2, 2070832},
{260, KHZ_60, 2229166, 1, 2279165, 2229166, 1, 2279165},
{260, KHZ_120, 2229167, 2, 2279165, 2229167, 2, 2279165},
{261, KHZ_60, 2070833, 1, 2084999, 2070833, 1, 2084999},
{261, KHZ_120, 2070833, 2, 2084999, 2070833, 2, 2084999}
}};
};
} // namespace srsran

@ -202,7 +202,7 @@ private:
std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - tti_start_time)
.count();
// FIXME: add averaging
// TODO: add averaging
metrics.avg_rtt_us = rtt;
}
};

@ -164,7 +164,7 @@ public:
const uint8_t* data() const { return msg; }
uint32_t size() const { return N_bytes; }
iterator begin() { return msg; }
const iterator begin() const { return msg; }
const_iterator begin() const { return msg; }
iterator end() { return msg + N_bytes; }
const_iterator end() const { return msg + N_bytes; }

@ -65,7 +65,8 @@ struct cell_cfg_t {
double dl_freq_hz;
uint32_t ul_earfcn;
double ul_freq_hz;
int target_ul_sinr_db;
int target_pucch_sinr_db;
int target_pusch_sinr_db;
uint32_t initial_dl_cqi;
bool enable_phr_handling;
std::vector<scell_cfg_t> scell_list;

@ -35,6 +35,7 @@ struct s1ap_args_t {
uint16_t mnc; // BCD-coded with 0xF filler
std::string mme_addr;
std::string gtp_bind_addr;
std::string gtp_advertise_addr;
std::string s1c_bind_addr;
std::string enb_name;
};

@ -74,9 +74,12 @@ public:
cell_cfg_sib_t sibs[MAX_SIBS];
uint32_t si_window_ms;
/* pucch configuration */
float target_pucch_ul_sinr;
/* pusch configuration */
srsran_pusch_hopping_cfg_t pusch_hopping_cfg;
float target_ul_sinr;
float target_pusch_ul_sinr;
bool enable_phr_handling;
bool enable_64qam;

@ -91,7 +91,7 @@ public:
tb_ul_t tb; // only single TB in UL
} tb_action_ul_t;
virtual int sf_indication(const uint32_t tti) = 0; ///< FIXME: rename to slot indication
virtual int sf_indication(const uint32_t tti) = 0; ///< TODO: rename to slot indication
// Query the MAC for the current RNTI to look for
struct sched_rnti_t {

@ -44,9 +44,7 @@ struct phy_args_t {
std::vector<uint32_t> dl_earfcn_list = {3400}; // vectorized version of dl_earfcn that gets populated during init
std::map<uint32_t, uint32_t> ul_earfcn_map; // Map linking DL EARFCN and UL EARFCN
std::string dl_nr_arfcn = "632628"; // comma-separated list of DL NR ARFCNs
std::vector<uint32_t> dl_nr_arfcn_list = {
632628}; // vectorized version of dl_nr_arfcn that gets populated during init
int force_N_id_2 = -1; // Cell identity within the identity group (PSS) to filter.
float dl_freq = -1.0f;
float ul_freq = -1.0f;
@ -63,7 +61,6 @@ struct phy_args_t {
uint32_t nof_lte_carriers = 1;
uint32_t nof_nr_carriers = 0;
uint32_t nr_max_nof_prb = 106;
double nr_freq_hz = 2630e6;
uint32_t nof_rx_ant = 1;
std::string equalizer_mode = "mmse";
int cqi_max = 15;

@ -289,6 +289,7 @@ typedef struct SRSRAN_API {
uint32_t pci;
uint32_t absolute_frequency_ssb;
uint32_t absolute_frequency_point_a;
uint32_t offset_to_carrier; ///< Offset between point A and the lowest subcarrier of the lowest RB
srsran_subcarrier_spacing_t scs;
uint32_t nof_prb; ///< @brief See TS 38.101-1 Table 5.3.2-1 for more details
uint32_t start;

@ -56,7 +56,7 @@ static const uint16_t NMAX = 1024;
/*!
* \brief Base 2 logarithm of maximum codeword length
*/
static const uint16_t NMAX_LOG = 10;
#define NMAX_LOG 10U
/*!
* \brief \f$log_2(EMAX)\f$

@ -237,7 +237,7 @@ typedef struct SRSRAN_API {
* @remark Implemented according TS 38.212 section 7.3.1.0 DCI size alignment
* @param[in,out] dci DCI object
* @param[in] cfg NR-DCI configuration
* @return SRSLTE_SUCCESS if the configuration is valid, SRSLTE_ERROR code otherwise
* @return SRSRAN_SUCCESS if the configuration is valid, SRSRAN_ERROR code otherwise
*/
SRSRAN_API int srsran_dci_nr_set_cfg(srsran_dci_nr_t* dci, const srsran_dci_cfg_nr_t* cfg);
@ -266,7 +266,7 @@ SRSRAN_API bool srsran_dci_nr_valid_direction(const srsran_dci_msg_nr_t* dci);
* @param q NR DCI object with precomputed DCI parameters
* @param dci DL NR DCI to pack (serialize)
* @param[out] msg Resultant packed DCI message
* @return SRSLTE_SUCCESS if provided arguments are valid, SRSLTE_ERROR code otherwise
* @return SRSRAN_SUCCESS if provided arguments are valid, SRSRAN_ERROR code otherwise
*/
SRSRAN_API int srsran_dci_nr_dl_pack(const srsran_dci_nr_t* q, const srsran_dci_dl_nr_t* dci, srsran_dci_msg_nr_t* msg);
@ -275,7 +275,7 @@ SRSRAN_API int srsran_dci_nr_dl_pack(const srsran_dci_nr_t* q, const srsran_dci_
* @param q NR DCI object with precomputed DCI parameters
* @param msg DCI message to unpack (deserialize)
* @param[out] dci Resultant unpacked DL DCI
* @return SRSLTE_SUCCESS if provided arguments are valid, SRSLTE_ERROR code otherwise
* @return SRSRAN_SUCCESS if provided arguments are valid, SRSRAN_ERROR code otherwise
*/
SRSRAN_API int srsran_dci_nr_dl_unpack(const srsran_dci_nr_t* q, srsran_dci_msg_nr_t* msg, srsran_dci_dl_nr_t* dci);
@ -284,7 +284,7 @@ SRSRAN_API int srsran_dci_nr_dl_unpack(const srsran_dci_nr_t* q, srsran_dci_msg_
* @param q NR DCI object with precomputed DCI parameters
* @param dci UL NR DCI to pack (serialize)
* @param[out] msg resultant DCI message
* @return SRSLTE_SUCCESS if provided arguments are valid, SRSLTE_ERROR code otherwise
* @return SRSRAN_SUCCESS if provided arguments are valid, SRSRAN_ERROR code otherwise
*/
SRSRAN_API int srsran_dci_nr_ul_pack(const srsran_dci_nr_t* q, const srsran_dci_ul_nr_t* dci, srsran_dci_msg_nr_t* msg);
@ -293,7 +293,7 @@ SRSRAN_API int srsran_dci_nr_ul_pack(const srsran_dci_nr_t* q, const srsran_dci_
* @param q NR DCI object with precomputed DCI parameters
* @param msg DCI message to unpack (deserialize)
* @param[out] dci Resultant unpacked UL DCI
* @return SRSLTE_SUCCESS if provided arguments are valid, SRSLTE_ERROR code otherwise
* @return SRSRAN_SUCCESS if provided arguments are valid, SRSRAN_ERROR code otherwise
*/
SRSRAN_API int srsran_dci_nr_ul_unpack(const srsran_dci_nr_t* q, srsran_dci_msg_nr_t* msg, srsran_dci_ul_nr_t* dci);

@ -88,7 +88,7 @@ SRSRAN_API int srsran_re_pattern_merge(srsran_re_pattern_list_t* list, const srs
* @brief Checks collision between a RE pattern list and a RE pattern
* @param list Provides pattern list
* @param p Provides a pattern
* @return SRSLTE_SUCCESS if no collision is detected, SRSLTE_ERROR code otherwise
* @return SRSRAN_SUCCESS if no collision is detected, SRSRAN_ERROR code otherwise
*/
SRSRAN_API int srsran_re_pattern_check_collision(const srsran_re_pattern_list_t* list, const srsran_re_pattern_t* p);

@ -66,8 +66,8 @@ public:
pdcp_entity_base(pdcp_entity_base&&) = default;
virtual ~pdcp_entity_base();
virtual bool configure(const pdcp_config_t& cnfg_) = 0;
virtual void reset() = 0;
virtual void reestablish() = 0;
virtual void reset() = 0;
virtual void reestablish() = 0;
bool is_active() { return active; }
bool is_srb() { return cfg.rb_type == PDCP_RB_IS_SRB; }
@ -115,7 +115,7 @@ public:
}
}
void config_security(as_security_config_t sec_cfg_);
void config_security(const as_security_config_t& sec_cfg_);
// GW/SDAP/RRC interface
virtual void write_sdu(unique_byte_buffer_t sdu, int sn = -1) = 0;

@ -459,7 +459,7 @@ bool make_phy_csi_report(const csi_report_cfg_s& csi_report_cfg,
return false;
}
if (srsran_csi_hl_report_cfg.type = SRSRAN_CSI_REPORT_TYPE_PERIODIC) {
if (srsran_csi_hl_report_cfg.type == SRSRAN_CSI_REPORT_TYPE_PERIODIC) {
srsran_csi_hl_report_cfg.periodic.period =
csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.type().to_number();
switch (csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.type()) {
@ -586,7 +586,7 @@ bool make_phy_csi_report(const csi_report_cfg_s& csi_report_cfg,
bool make_phy_coreset_cfg(const ctrl_res_set_s& ctrl_res_set, srsran_coreset_t* in_srsran_coreset)
{
srsran_coreset_t srsran_coreset = {};
srsran_coreset.id = ctrl_res_set.ctrl_res_set_id;
srsran_coreset.id = ctrl_res_set.ctrl_res_set_id;
switch (ctrl_res_set.precoder_granularity) {
case ctrl_res_set_s::precoder_granularity_opts::same_as_reg_bundle:
srsran_coreset.precoder_granularity = srsran_coreset_precoder_granularity_reg_bundle;
@ -949,77 +949,76 @@ bool make_phy_zp_csi_rs_resource(const asn1::rrc_nr::zp_csi_rs_res_s& zp_csi_rs_
}
zp_csi_rs_resource.resource_mapping.freq_band.nof_rb = zp_csi_rs_res.res_map.freq_band.nrof_rbs;
zp_csi_rs_resource.resource_mapping.freq_band.start_rb = zp_csi_rs_res.res_map.freq_band.start_rb;
if(zp_csi_rs_res.periodicity_and_offset_present){
switch (zp_csi_rs_res.periodicity_and_offset.type())
{
case csi_res_periodicity_and_offset_c::types_opts::options::slots4:
zp_csi_rs_resource.periodicity.period = 4;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots4();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots5:
zp_csi_rs_resource.periodicity.period = 5;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots5();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots8:
zp_csi_rs_resource.periodicity.period = 8;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots8();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots10:
zp_csi_rs_resource.periodicity.period = 10;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots10();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots16:
zp_csi_rs_resource.periodicity.period = 16;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots16();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots20:
zp_csi_rs_resource.periodicity.period = 20;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots20();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots32:
zp_csi_rs_resource.periodicity.period = 32;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots32();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots40:
zp_csi_rs_resource.periodicity.period = 40;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots40();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots64:
zp_csi_rs_resource.periodicity.period = 64;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots64();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots80:
zp_csi_rs_resource.periodicity.period = 80;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots80();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots160:
zp_csi_rs_resource.periodicity.period = 160;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots160();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots320:
zp_csi_rs_resource.periodicity.period = 320;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots320();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots640:
zp_csi_rs_resource.periodicity.period = 640;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots640();
break;
default:
asn1::log_warning("Invalid option for periodicity_and_offset %s",
zp_csi_rs_res.periodicity_and_offset.type().to_string());
return false;
if (zp_csi_rs_res.periodicity_and_offset_present) {
switch (zp_csi_rs_res.periodicity_and_offset.type()) {
case csi_res_periodicity_and_offset_c::types_opts::options::slots4:
zp_csi_rs_resource.periodicity.period = 4;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots4();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots5:
zp_csi_rs_resource.periodicity.period = 5;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots5();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots8:
zp_csi_rs_resource.periodicity.period = 8;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots8();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots10:
zp_csi_rs_resource.periodicity.period = 10;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots10();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots16:
zp_csi_rs_resource.periodicity.period = 16;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots16();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots20:
zp_csi_rs_resource.periodicity.period = 20;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots20();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots32:
zp_csi_rs_resource.periodicity.period = 32;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots32();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots40:
zp_csi_rs_resource.periodicity.period = 40;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots40();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots64:
zp_csi_rs_resource.periodicity.period = 64;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots64();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots80:
zp_csi_rs_resource.periodicity.period = 80;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots80();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots160:
zp_csi_rs_resource.periodicity.period = 160;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots160();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots320:
zp_csi_rs_resource.periodicity.period = 320;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots320();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots640:
zp_csi_rs_resource.periodicity.period = 640;
zp_csi_rs_resource.periodicity.offset = zp_csi_rs_res.periodicity_and_offset.slots640();
break;
default:
asn1::log_warning("Invalid option for periodicity_and_offset %s",
zp_csi_rs_res.periodicity_and_offset.type().to_string());
return false;
}
} else {
asn1::log_warning("Option periodicity_and_offset not present");
return false;
asn1::log_warning("Option periodicity_and_offset not present");
return false;
}
*out_zp_csi_rs_resource = zp_csi_rs_resource;
return true;
}
bool make_phy_nzp_csi_rs_resource(const asn1::rrc_nr::nzp_csi_rs_res_s& asn1_nzp_csi_rs_res,
srsran_csi_rs_nzp_resource_t* out_csi_rs_nzp_resource)
bool make_phy_nzp_csi_rs_resource(const asn1::rrc_nr::nzp_csi_rs_res_s& asn1_nzp_csi_rs_res,
srsran_csi_rs_nzp_resource_t* out_csi_rs_nzp_resource)
{
srsran_csi_rs_nzp_resource_t csi_rs_nzp_resource;
csi_rs_nzp_resource.id = asn1_nzp_csi_rs_res.nzp_csi_rs_res_id;
@ -1028,24 +1027,24 @@ bool make_phy_nzp_csi_rs_resource(const asn1::rrc_nr::nzp_csi_rs_res_s& asn1_nz
csi_rs_nzp_resource.resource_mapping.row = srsran_csi_rs_resource_mapping_row_1;
for (uint32_t i = 0; i < asn1_nzp_csi_rs_res.res_map.freq_domain_alloc.row1().length(); i++) {
csi_rs_nzp_resource.resource_mapping.frequency_domain_alloc[i] =
asn1_nzp_csi_rs_res.res_map.freq_domain_alloc.row1().get(asn1_nzp_csi_rs_res.res_map.freq_domain_alloc.row1().length() -
1 - i);
asn1_nzp_csi_rs_res.res_map.freq_domain_alloc.row1().get(
asn1_nzp_csi_rs_res.res_map.freq_domain_alloc.row1().length() - 1 - i);
}
break;
case csi_rs_res_map_s::freq_domain_alloc_c_::types_opts::options::row2:
csi_rs_nzp_resource.resource_mapping.row = srsran_csi_rs_resource_mapping_row_2;
for (uint32_t i = 0; i < asn1_nzp_csi_rs_res.res_map.freq_domain_alloc.row2().length(); i++) {
csi_rs_nzp_resource.resource_mapping.frequency_domain_alloc[i] =
asn1_nzp_csi_rs_res.res_map.freq_domain_alloc.row2().get(asn1_nzp_csi_rs_res.res_map.freq_domain_alloc.row2().length() -
1 - i);
asn1_nzp_csi_rs_res.res_map.freq_domain_alloc.row2().get(
asn1_nzp_csi_rs_res.res_map.freq_domain_alloc.row2().length() - 1 - i);
}
break;
case csi_rs_res_map_s::freq_domain_alloc_c_::types_opts::options::row4:
csi_rs_nzp_resource.resource_mapping.row = srsran_csi_rs_resource_mapping_row_4;
for (uint32_t i = 0; i < asn1_nzp_csi_rs_res.res_map.freq_domain_alloc.row4().length(); i++) {
csi_rs_nzp_resource.resource_mapping.frequency_domain_alloc[i] =
asn1_nzp_csi_rs_res.res_map.freq_domain_alloc.row4().get(asn1_nzp_csi_rs_res.res_map.freq_domain_alloc.row4().length() -
1 - i);
asn1_nzp_csi_rs_res.res_map.freq_domain_alloc.row4().get(
asn1_nzp_csi_rs_res.res_map.freq_domain_alloc.row4().length() - 1 - i);
}
break;
case csi_rs_res_map_s::freq_domain_alloc_c_::types_opts::options::other:
@ -1113,69 +1112,68 @@ bool make_phy_nzp_csi_rs_resource(const asn1::rrc_nr::nzp_csi_rs_res_s& asn1_nz
csi_rs_nzp_resource.power_control_offset_ss = asn1_nzp_csi_rs_res.pwr_ctrl_offset_ss.to_number();
}
if(asn1_nzp_csi_rs_res.periodicity_and_offset_present){
switch (asn1_nzp_csi_rs_res.periodicity_and_offset.type())
{
case csi_res_periodicity_and_offset_c::types_opts::options::slots4:
csi_rs_nzp_resource.periodicity.period = 4;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots4();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots5:
csi_rs_nzp_resource.periodicity.period = 5;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots5();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots8:
csi_rs_nzp_resource.periodicity.period = 8;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots8();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots10:
csi_rs_nzp_resource.periodicity.period = 10;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots10();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots16:
csi_rs_nzp_resource.periodicity.period = 16;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots16();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots20:
csi_rs_nzp_resource.periodicity.period = 20;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots20();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots32:
csi_rs_nzp_resource.periodicity.period = 32;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots32();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots40:
csi_rs_nzp_resource.periodicity.period = 40;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots40();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots64:
csi_rs_nzp_resource.periodicity.period = 64;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots64();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots80:
csi_rs_nzp_resource.periodicity.period = 80;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots80();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots160:
csi_rs_nzp_resource.periodicity.period = 160;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots160();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots320:
csi_rs_nzp_resource.periodicity.period = 320;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots320();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots640:
csi_rs_nzp_resource.periodicity.period = 640;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots640();
break;
default:
asn1::log_warning("Invalid option for periodicity_and_offset %s",
asn1_nzp_csi_rs_res.periodicity_and_offset.type().to_string());
return false;
if (asn1_nzp_csi_rs_res.periodicity_and_offset_present) {
switch (asn1_nzp_csi_rs_res.periodicity_and_offset.type()) {
case csi_res_periodicity_and_offset_c::types_opts::options::slots4:
csi_rs_nzp_resource.periodicity.period = 4;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots4();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots5:
csi_rs_nzp_resource.periodicity.period = 5;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots5();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots8:
csi_rs_nzp_resource.periodicity.period = 8;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots8();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots10:
csi_rs_nzp_resource.periodicity.period = 10;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots10();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots16:
csi_rs_nzp_resource.periodicity.period = 16;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots16();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots20:
csi_rs_nzp_resource.periodicity.period = 20;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots20();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots32:
csi_rs_nzp_resource.periodicity.period = 32;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots32();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots40:
csi_rs_nzp_resource.periodicity.period = 40;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots40();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots64:
csi_rs_nzp_resource.periodicity.period = 64;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots64();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots80:
csi_rs_nzp_resource.periodicity.period = 80;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots80();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots160:
csi_rs_nzp_resource.periodicity.period = 160;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots160();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots320:
csi_rs_nzp_resource.periodicity.period = 320;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots320();
break;
case csi_res_periodicity_and_offset_c::types_opts::options::slots640:
csi_rs_nzp_resource.periodicity.period = 640;
csi_rs_nzp_resource.periodicity.offset = asn1_nzp_csi_rs_res.periodicity_and_offset.slots640();
break;
default:
asn1::log_warning("Invalid option for periodicity_and_offset %s",
asn1_nzp_csi_rs_res.periodicity_and_offset.type().to_string());
return false;
}
} else {
asn1::log_warning("Option periodicity_and_offset not present");
return false;
asn1::log_warning("Option periodicity_and_offset not present");
return false;
}
csi_rs_nzp_resource.scrambling_id = asn1_nzp_csi_rs_res.scrambling_id;
@ -1193,14 +1191,12 @@ bool make_phy_carrier_cfg(const freq_info_dl_s& asn1_freq_info_dl, srsran_carrie
asn1::log_warning("Option absolute_freq_ssb not present");
return false;
}
uint32_t absolute_frequency_point_a = asn1_freq_info_dl.absolute_freq_point_a;
if (asn1_freq_info_dl.scs_specific_carrier_list.size() != 1) {
asn1::log_warning("Option absolute_freq_ssb not present");
return false;
}
uint32_t nof_prb = asn1_freq_info_dl.scs_specific_carrier_list[0].carrier_bw;
srsran_subcarrier_spacing_t scs = srsran_subcarrier_spacing_15kHz;
srsran_subcarrier_spacing_t scs = srsran_subcarrier_spacing_15kHz;
switch (asn1_freq_info_dl.scs_specific_carrier_list[0].subcarrier_spacing) {
case subcarrier_spacing_opts::options::khz15:
scs = srsran_subcarrier_spacing_15kHz;
@ -1222,8 +1218,9 @@ bool make_phy_carrier_cfg(const freq_info_dl_s& asn1_freq_info_dl, srsran_carrie
}
// As the carrier structure requires parameters from different objects, set fields separately
out_carrier_nr->absolute_frequency_ssb = absolute_frequency_ssb;
out_carrier_nr->absolute_frequency_point_a = absolute_frequency_point_a;
out_carrier_nr->nof_prb = nof_prb;
out_carrier_nr->absolute_frequency_point_a = asn1_freq_info_dl.absolute_freq_point_a;
out_carrier_nr->offset_to_carrier = asn1_freq_info_dl.scs_specific_carrier_list[0].offset_to_carrier;
out_carrier_nr->nof_prb = asn1_freq_info_dl.scs_specific_carrier_list[0].carrier_bw;
out_carrier_nr->scs = scs;
return true;
}

@ -269,7 +269,7 @@ int srsran_basic_vnf::dl_config_request(const srsenb::phy_interface_stack_nr::dl
dl_conf.header.msg_len = sizeof(dl_conf) - sizeof(basic_vnf_api::msg_header_t);
dl_conf.t1 = last_sf_indication_time; // play back the time
dl_conf.t2 = 0xaa; // FIXME: add timestamp
dl_conf.t2 = 0xaa; // TODO: add timestamp
dl_conf.tti = request.tti;
dl_conf.beam_id = request.beam_id;

@ -129,7 +129,9 @@ int open_socket(net_utils::addr_family ip_type, net_utils::socket_type socket_ty
evnts.sctp_address_event = 1;
if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts)) != 0) {
srslog::fetch_basic_logger(LOGSERVICE).error("Failed to subscribe to SCTP_SHUTDOWN event: %s", strerror(errno));
perror("Could not regiester socket to SCTP events\n");
perror("Could not register socket to SCTP events\n");
close(fd);
return -1;
}
/*
@ -143,6 +145,7 @@ int open_socket(net_utils::addr_family ip_type, net_utils::socket_type socket_ty
rto_opts.srto_assoc_id = 0;
if (getsockopt(fd, SOL_SCTP, SCTP_RTOINFO, &rto_opts, &rto_sz) < 0) {
printf("Error getting RTO_INFO sockopts\n");
close(fd);
return -1;
}
@ -158,6 +161,7 @@ int open_socket(net_utils::addr_family ip_type, net_utils::socket_type socket_ty
if (setsockopt(fd, SOL_SCTP, SCTP_RTOINFO, &rto_opts, rto_sz) < 0) {
perror("Error setting RTO_INFO sockopts\n");
close(fd);
return -1;
}
@ -166,6 +170,8 @@ int open_socket(net_utils::addr_family ip_type, net_utils::socket_type socket_ty
socklen_t init_sz = sizeof(sctp_initmsg);
if (getsockopt(fd, SOL_SCTP, SCTP_INITMSG, &init_opts, &init_sz) < 0) {
printf("Error getting sockopts\n");
close(fd);
return -1;
}
init_opts.sinit_max_attempts = 3;
@ -177,6 +183,7 @@ int open_socket(net_utils::addr_family ip_type, net_utils::socket_type socket_ty
init_opts.sinit_max_init_timeo);
if (setsockopt(fd, SOL_SCTP, SCTP_INITMSG, &init_opts, init_sz) < 0) {
perror("Error setting SCTP_INITMSG sockopts\n");
close(fd);
return -1;
}
}

@ -27,6 +27,8 @@ int bands_test_nr()
srsran::srsran_band_helper bands;
TESTASSERT(bands.nr_arfcn_to_freq(632628) == 3489.42e6);
TESTASSERT(bands.nr_arfcn_to_freq(633928) == 3508.92e6); // default refPointA
TESTASSERT(bands.nr_arfcn_to_freq(634240) == 3513.6e6); // default ARFCN with freq divisible by 11.52 MHz
const uint32_t max_valid_nr_arfcn = 3279165;

@ -474,24 +474,42 @@ static void interpolate_pilots(srsran_chest_dl_t* q,
(fidx_offset) ? 1 : 2);
}
} else {
if (cfg->estimator_alg == SRSRAN_ESTIMATOR_ALG_AVERAGE && nsymbols > 1) {
fidx_offset = q->cell.id % 3;
srsran_interp_linear_offset(
&q->srsran_interp_lin_3, pilot_estimates, ce, fidx_offset, SRSRAN_NRE / 4 - fidx_offset);
if (cfg->estimator_alg == SRSRAN_ESTIMATOR_ALG_AVERAGE) {
if (nsymbols > 1) {
fidx_offset = q->cell.id % 3;
srsran_interp_linear_offset(
&q->srsran_interp_lin_3, pilot_estimates, ce, fidx_offset, SRSRAN_NRE / 4 - fidx_offset);
} else {
fidx_offset = srsran_refsignal_cs_fidx(q->cell, l, port_id, 0);
srsran_interp_linear_offset(&q->srsran_interp_lin,
&pilot_estimates[2 * q->cell.nof_prb * l],
ce,
fidx_offset,
SRSRAN_NRE / 2 - fidx_offset);
}
} else {
fidx_offset = srsran_refsignal_cs_fidx(q->cell, l, port_id, 0);
srsran_interp_linear_offset(
&q->srsran_interp_lin,
&pilot_estimates[2 * q->cell.nof_prb * l],
&ce[srsran_refsignal_cs_nsymbol(l, q->cell.cp, port_id) * q->cell.nof_prb * SRSRAN_NRE],
fidx_offset,
SRSRAN_NRE / 2 - fidx_offset);
if (nsymbols < 2) {
fidx_offset = srsran_refsignal_cs_fidx(q->cell, l, port_id, 0);
srsran_interp_linear_offset(&q->srsran_interp_lin,
&pilot_estimates[2 * q->cell.nof_prb * l],
ce,
fidx_offset,
SRSRAN_NRE / 2 - fidx_offset);
} else {
fidx_offset = srsran_refsignal_cs_fidx(q->cell, l, port_id, 0);
srsran_interp_linear_offset(
&q->srsran_interp_lin,
&pilot_estimates[2 * q->cell.nof_prb * l],
&ce[srsran_refsignal_cs_nsymbol(l, q->cell.cp, port_id) * q->cell.nof_prb * SRSRAN_NRE],
fidx_offset,
SRSRAN_NRE / 2 - fidx_offset);
}
}
}
}
/* Now interpolate in the time domain between symbols */
if (sf->sf_type == SRSRAN_SF_NORM && (cfg->estimator_alg == SRSRAN_ESTIMATOR_ALG_AVERAGE || nsymbols < 3)) {
if (sf->sf_type == SRSRAN_SF_NORM && (cfg->estimator_alg == SRSRAN_ESTIMATOR_ALG_AVERAGE || nsymbols < 2)) {
// If we average per subframe, just copy the estimates in the time domain
for (uint32_t l = 1; l < 2 * SRSRAN_CP_NSYMB(q->cell.cp); l++) {
memcpy(&ce[l * SRSRAN_NRE * q->cell.nof_prb], ce, sizeof(cf_t) * SRSRAN_NRE * q->cell.nof_prb);
@ -504,7 +522,7 @@ static void interpolate_pilots(srsran_chest_dl_t* q,
srsran_interp_linear_vector2(&q->srsran_interp_linvec, &cesymb(6), &cesymb(10), &cesymb(10), &cesymb(11), 4, 1);
} else {
if (SRSRAN_CP_ISNORM(q->cell.cp)) {
if (port_id <= 2) {
if (port_id < 2) {
srsran_interp_linear_vector(&q->srsran_interp_linvec, &cesymb(0), &cesymb(4), &cesymb(1), 4, 3);
srsran_interp_linear_vector(&q->srsran_interp_linvec, &cesymb(4), &cesymb(7), &cesymb(5), 3, 2);
if (nsymbols == 4) {
@ -521,7 +539,7 @@ static void interpolate_pilots(srsran_chest_dl_t* q,
srsran_interp_linear_vector(&q->srsran_interp_linvec, &cesymb(1), &cesymb(8), &cesymb(9), 7, 5);
}
} else {
if (port_id <= 2) {
if (port_id < 2) {
// TODO: TDD and extended cyclic prefix
srsran_interp_linear_vector(&q->srsran_interp_linvec, &cesymb(0), &cesymb(3), &cesymb(1), 3, 2);
srsran_interp_linear_vector(&q->srsran_interp_linvec, &cesymb(3), &cesymb(6), &cesymb(4), 3, 2);

@ -27,13 +27,14 @@
#include <stdlib.h>
static srsran_carrier_nr_t carrier = {
1, // pci
0, // absolute_frequency_ssb
0, // absolute_frequency_point_a
srsran_subcarrier_spacing_15kHz, // scs
50, // nof_prb
0, // start
1 // max_mimo_layers
1, // pci
0, // absolute_frequency_ssb
0, // absolute_frequency_point_a
0, // offset_to_carrier
srsran_subcarrier_spacing_15kHz, // scs
50, // nof_prb
0, // start
1 // max_mimo_layers
};
static float snr_dB = 20.0;

@ -29,15 +29,15 @@
#include <strings.h>
#include <unistd.h>
static srsran_carrier_nr_t carrier = {
1, // pci
0, // absolute_frequency_ssb
0, // absolute_frequency_point_a
srsran_subcarrier_spacing_15kHz, // scs
50, // nof_prb
0, // start
1 // max_mimo_layers
1, // pci
0, // absolute_frequency_ssb
0, // absolute_frequency_point_a
0, // offset_to_carrier
srsran_subcarrier_spacing_15kHz, // scs
50, // nof_prb
0, // start
1 // max_mimo_layers
};
typedef struct {

@ -244,11 +244,27 @@ int srsran_enb_ul_get_pucch(srsran_enb_ul_t* q,
// If we are looking for SR and ACK at the same time and ret=0, means there is no SR.
// try again to decode ACK only
if (cfg->uci_cfg.is_scheduling_request_tti && srsran_uci_cfg_total_ack(&cfg->uci_cfg) && !res->detected) {
if (cfg->uci_cfg.is_scheduling_request_tti && srsran_uci_cfg_total_ack(&cfg->uci_cfg)) {
// Disable SR
cfg->uci_cfg.is_scheduling_request_tti = false;
if (get_pucch(q, ul_sf, cfg, res)) {
// Init PUCCH result without SR
srsran_pucch_res_t res_no_sr = {};
// Actual decode without SR
if (get_pucch(q, ul_sf, cfg, &res_no_sr)) {
return SRSRAN_ERROR;
}
// Override PUCCH result if PUCCH without SR was detected, and
// - no PUCCH with SR was detected; or
// - PUCCH without SR has better correlation
if (res_no_sr.detected && (!res->detected || res_no_sr.correlation > res->correlation)) {
*res = res_no_sr;
} else {
// If the PUCCH decode result is not overridden, flag SR
cfg->uci_cfg.is_scheduling_request_tti = true;
}
}
return SRSRAN_SUCCESS;

@ -93,7 +93,7 @@ void* create_ldpc_dec_c(uint8_t bgN, uint8_t bgM, uint16_t ls, float scaling_fct
uint16_t liftN = bgN * ls;
uint16_t hrrN = (bgK + 4) * ls;
if ((vp = malloc(sizeof(struct ldpc_regs_c))) == NULL) {
if ((vp = SRSRAN_MEM_ALLOC(struct ldpc_regs_c, 1)) == NULL) {
return NULL;
}
@ -177,13 +177,13 @@ int init_ldpc_dec_c(void* p, const int8_t* llrs, uint16_t ls)
return -1;
}
bzero(vp->soft_bits, skip * sizeof(int8_t));
srsran_vec_i8_zero(vp->soft_bits, skip);
for (i = skip; i < vp->liftN; i++) {
vp->soft_bits[i] = llrs[i - skip];
}
bzero(vp->check_to_var, (vp->hrrN + vp->ls) * vp->bgM * sizeof(int8_t));
bzero(vp->var_to_check, (vp->hrrN + vp->ls) * sizeof(int8_t));
srsran_vec_i8_zero(vp->check_to_var, (vp->hrrN + vp->ls) * (uint32_t)vp->bgM);
srsran_vec_i8_zero(vp->var_to_check, vp->hrrN + vp->ls);
return 0;
}
@ -258,7 +258,7 @@ int update_ldpc_check_to_var_c(void* p,
vp->prod_v2c[index] *= (vp->var_to_check[i_v2c] >= 0) ? 1 : -1;
}
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
int8_t* this_check_to_var = vp->check_to_var + i_layer * (vp->hrrN + vp->ls);
@ -277,7 +277,7 @@ int update_ldpc_check_to_var_c(void* p,
this_check_to_var[i_v2c] *= vp->prod_v2c[index] * ((vp->var_to_check[i_v2c] >= 0) ? 1 : -1);
}
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
return 0;
@ -314,7 +314,7 @@ int update_ldpc_soft_bits_c(void* p, int i_layer, const int8_t (*these_var_indic
}
vp->soft_bits[i_bit] = (int8_t)tmp;
}
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
return 0;

@ -56,8 +56,8 @@
* \brief Represents a node of the base factor graph.
*/
typedef union bg_node_t {
int8_t c[SRSRAN_AVX2_B_SIZE]; /*!< Each base node may contain up to \ref SRSRAN_AVX2_B_SIZE lifted nodes. */
__m256i v; /*!< All the lifted nodes of the current base node as a 256-bit line. */
int8_t* c; /*!< Each base node may contain up to \ref SRSRAN_AVX2_B_SIZE lifted nodes. */
__m256i* v; /*!< All the lifted nodes of the current base node as a 256-bit line. */
} bg_node_t;
/*!
@ -72,10 +72,10 @@ static const int8_t infinity7 = (1U << 6U) - 1;
struct ldpc_regs_c_avx2 {
__m256i scaling_fctr; /*!< \brief Scaling factor for the normalized min-sum decoding algorithm. */
bg_node_t* soft_bits; /*!< \brief A-posteriori log-likelihood ratios. */
__m256i* check_to_var; /*!< \brief Check-to-variable messages. */
__m256i* var_to_check; /*!< \brief Variable-to-check messages. */
__m256i* rotated_v2c; /*!< \brief To store a rotated version of the variable-to-check messages. */
bg_node_t soft_bits; /*!< \brief A-posteriori log-likelihood ratios. */
__m256i* check_to_var; /*!< \brief Check-to-variable messages. */
__m256i* var_to_check; /*!< \brief Variable-to-check messages. */
__m256i* rotated_v2c; /*!< \brief To store a rotated version of the variable-to-check messages. */
uint16_t ls; /*!< \brief Lifting size. */
uint8_t hrr; /*!< \brief Number of variable nodes in the high-rate region (before lifting). */
@ -154,33 +154,28 @@ void* create_ldpc_dec_c_avx2(uint8_t bgN, uint8_t bgM, uint16_t ls, float scalin
uint8_t bgK = bgN - bgM;
uint16_t hrr = bgK + 4;
if ((vp = srsran_vec_malloc(sizeof(struct ldpc_regs_c_avx2))) == NULL) {
if ((vp = SRSRAN_MEM_ALLOC(struct ldpc_regs_c_avx2, 1)) == NULL) {
return NULL;
}
SRSRAN_MEM_ZERO(vp, struct ldpc_regs_c_avx2, 1);
if ((vp->soft_bits = srsran_vec_malloc(bgN * sizeof(bg_node_t))) == NULL) {
free(vp);
if ((vp->soft_bits.v = SRSRAN_MEM_ALLOC(__m256i, bgN)) == NULL) {
delete_ldpc_dec_c_avx2(vp);
return NULL;
}
if ((vp->check_to_var = srsran_vec_malloc((hrr + 1) * bgM * sizeof(__m256i))) == NULL) {
free(vp->soft_bits);
free(vp);
if ((vp->check_to_var = SRSRAN_MEM_ALLOC(__m256i, (hrr + 1) * (uint32_t)bgM)) == NULL) {
delete_ldpc_dec_c_avx2(vp);
return NULL;
}
if ((vp->var_to_check = srsran_vec_malloc((hrr + 1) * sizeof(__m256i))) == NULL) {
free(vp->check_to_var);
free(vp->soft_bits);
free(vp);
if ((vp->var_to_check = SRSRAN_MEM_ALLOC(__m256i, hrr + 1)) == NULL) {
delete_ldpc_dec_c_avx2(vp);
return NULL;
}
if ((vp->rotated_v2c = srsran_vec_malloc((hrr + 1) * sizeof(__m256i))) == NULL) {
free(vp->var_to_check);
free(vp->check_to_var);
free(vp->soft_bits);
free(vp);
if ((vp->rotated_v2c = SRSRAN_MEM_ALLOC(__m256i, hrr + 1)) == NULL) {
delete_ldpc_dec_c_avx2(vp);
return NULL;
}
@ -199,13 +194,22 @@ void delete_ldpc_dec_c_avx2(void* p)
{
struct ldpc_regs_c_avx2* vp = p;
if (vp != NULL) {
if (vp == NULL) {
return;
}
if (vp->rotated_v2c) {
free(vp->rotated_v2c);
}
if (vp->var_to_check) {
free(vp->var_to_check);
}
if (vp->check_to_var) {
free(vp->check_to_var);
free(vp->soft_bits);
free(vp);
}
if (vp->soft_bits.v) {
free(vp->soft_bits.v);
}
free(vp);
}
int init_ldpc_dec_c_avx2(void* p, const int8_t* llrs, uint16_t ls)
@ -219,17 +223,17 @@ int init_ldpc_dec_c_avx2(void* p, const int8_t* llrs, uint16_t ls)
}
// the first 2 x LS bits of the codeword are not sent
vp->soft_bits[0].v = _mm256_set1_epi8(0);
vp->soft_bits[1].v = _mm256_set1_epi8(0);
vp->soft_bits.v[0] = _mm256_set1_epi8(0);
vp->soft_bits.v[1] = _mm256_set1_epi8(0);
for (i = 2; i < vp->bgN; i++) {
for (j = 0; j < ls; j++) {
vp->soft_bits[i].c[j] = llrs[(i - 2) * ls + j];
vp->soft_bits.c[i * SRSRAN_AVX2_B_SIZE + j] = llrs[(i - 2) * ls + j];
}
bzero(&(vp->soft_bits[i].c[ls]), (SRSRAN_AVX2_B_SIZE - ls) * sizeof(int8_t));
SRSRAN_MEM_ZERO(&(vp->soft_bits.c[i * SRSRAN_AVX2_B_SIZE + ls]), int8_t, SRSRAN_AVX2_B_SIZE - ls);
}
bzero(vp->check_to_var, (vp->hrr + 1) * vp->bgM * sizeof(__m256i));
bzero(vp->var_to_check, (vp->hrr + 1) * sizeof(__m256i));
SRSRAN_MEM_ZERO(vp->check_to_var, __m256i, (vp->hrr + 1) * (uint32_t)vp->bgM);
SRSRAN_MEM_ZERO(vp->var_to_check, __m256i, vp->hrr + 1);
return 0;
}
@ -244,15 +248,12 @@ int update_ldpc_var_to_check_c_avx2(void* p, int i_layer)
__m256i* this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1);
// Update the high-rate region.
inner_var_to_check_c_avx2(&(vp->soft_bits[0].v), this_check_to_var, vp->var_to_check, infinity7, vp->hrr);
inner_var_to_check_c_avx2(vp->soft_bits.v, this_check_to_var, vp->var_to_check, infinity7, vp->hrr);
if (i_layer >= 4) {
// Update the extension region.
inner_var_to_check_c_avx2(&(vp->soft_bits[0].v) + vp->hrr + i_layer - 4,
this_check_to_var + vp->hrr,
vp->var_to_check + vp->hrr,
infinity7,
1);
inner_var_to_check_c_avx2(
vp->soft_bits.v + vp->hrr + i_layer - 4, this_check_to_var + vp->hrr, vp->var_to_check + vp->hrr, infinity7, 1);
}
return 0;
@ -313,7 +314,7 @@ int update_ldpc_check_to_var_c_avx2(void* p,
mask_min_epi8 = _mm256_cmpgt_epi8(mins_v2c_epi8, this_abs_v2c_epi8);
mins_v2c_epi8 = _mm256_blendv_epi8(mins_v2c_epi8, help_min_epi8, mask_min_epi8);
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
__m256i* this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1);
@ -342,7 +343,7 @@ int update_ldpc_check_to_var_c_avx2(void* p,
this_check_to_var[i_v2c_base] = rotate_node_left(this_c2v_epi8, shift, vp->ls);
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
return 0;
@ -375,9 +376,9 @@ int update_ldpc_soft_bits_c_avx2(void* p, int i_layer, const int8_t (*these_var_
// tmp = (tmp < -infty7) : -infty8 ? tmp
mask_epi8 = _mm256_cmpgt_epi8(neg_infty7_epi8, tmp_epi8);
vp->soft_bits[current_var_index].v = _mm256_blendv_epi8(tmp_epi8, neg_infty8_epi8, mask_epi8);
vp->soft_bits.v[current_var_index] = _mm256_blendv_epi8(tmp_epi8, neg_infty8_epi8, mask_epi8);
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
return 0;
@ -395,7 +396,7 @@ int extract_ldpc_message_c_avx2(void* p, uint8_t* message, uint16_t liftK)
for (int i = 0; i < liftK / vp->ls; i++) {
for (j = 0; j < vp->ls; j++) {
message[i * vp->ls + j] = (vp->soft_bits[i].c[j] < 0);
message[i * vp->ls + j] = (vp->soft_bits.c[i * SRSRAN_AVX2_B_SIZE + j] < 0);
}
}

@ -56,8 +56,8 @@
* \brief Represents a node of the base factor graph.
*/
typedef union bg_node_t {
int8_t c[SRSRAN_AVX2_B_SIZE]; /*!< Each base node may contain up to \ref SRSRAN_AVX2_B_SIZE lifted nodes. */
__m256i v; /*!< All the lifted nodes of the current base node as a 256-bit line. */
int8_t* c; /*!< Each base node may contain up to \ref SRSRAN_AVX2_B_SIZE lifted nodes. */
__m256i* v; /*!< All the lifted nodes of the current base node as a 256-bit line. */
} bg_node_t;
/*!
@ -72,11 +72,11 @@ static const int8_t infinity7 = (1U << 6U) - 1;
struct ldpc_regs_c_avx2_flood {
__m256i scaling_fctr; /*!< \brief Scaling factor for the normalized min-sum decoding algorithm. */
bg_node_t* soft_bits; /*!< \brief A-posteriori log-likelihood ratios. */
__m256i* llrs; /*!< \brief A-priori log-likelihood ratios. */
__m256i* check_to_var; /*!< \brief Check-to-variable messages. */
__m256i* var_to_check; /*!< \brief Variable-to-check messages. */
__m256i* rotated_v2c; /*!< \brief To store a rotated version of the variable-to-check messages. */
bg_node_t soft_bits; /*!< \brief A-posteriori log-likelihood ratios. */
__m256i* llrs; /*!< \brief A-priori log-likelihood ratios. */
__m256i* check_to_var; /*!< \brief Check-to-variable messages. */
__m256i* var_to_check; /*!< \brief Variable-to-check messages. */
__m256i* rotated_v2c; /*!< \brief To store a rotated version of the variable-to-check messages. */
uint16_t ls; /*!< \brief Lifting size. */
uint8_t hrr; /*!< \brief Number of variable nodes in the high-rate region (before lifting). */
@ -155,42 +155,34 @@ void* create_ldpc_dec_c_avx2_flood(uint8_t bgN, uint8_t bgM, uint16_t ls, float
uint8_t bgK = bgN - bgM;
uint16_t hrr = bgK + 4;
if ((vp = srsran_vec_malloc(sizeof(struct ldpc_regs_c_avx2_flood))) == NULL) {
if ((vp = SRSRAN_MEM_ALLOC(struct ldpc_regs_c_avx2_flood, 1)) == NULL) {
return NULL;
}
SRSRAN_MEM_ZERO(vp, struct ldpc_regs_c_avx2_flood, 1);
if ((vp->llrs = srsran_vec_malloc(bgN * sizeof(__m256i))) == NULL) {
free(vp);
if ((vp->llrs = SRSRAN_MEM_ALLOC(__m256i, bgN)) == NULL) {
delete_ldpc_dec_c_avx2_flood(vp);
return NULL;
}
if ((vp->soft_bits = srsran_vec_malloc(bgN * sizeof(bg_node_t))) == NULL) {
free(vp->llrs);
free(vp);
if ((vp->soft_bits.v = SRSRAN_MEM_ALLOC(__m256i, bgN)) == NULL) {
delete_ldpc_dec_c_avx2_flood(vp);
return NULL;
}
if ((vp->check_to_var = srsran_vec_malloc((hrr + 1) * bgM * sizeof(__m256i))) == NULL) {
free(vp->soft_bits);
free(vp->llrs);
free(vp);
uint32_t sz = (uint32_t)(hrr + 1) * (uint32_t)bgM;
if ((vp->check_to_var = SRSRAN_MEM_ALLOC(__m256i, sz)) == NULL) {
delete_ldpc_dec_c_avx2_flood(vp);
return NULL;
}
if ((vp->var_to_check = srsran_vec_malloc((hrr + 1) * bgM * sizeof(__m256i))) == NULL) {
free(vp->check_to_var);
free(vp->soft_bits);
free(vp->llrs);
free(vp);
if ((vp->var_to_check = SRSRAN_MEM_ALLOC(__m256i, sz)) == NULL) {
delete_ldpc_dec_c_avx2_flood(vp);
return NULL;
}
if ((vp->rotated_v2c = srsran_vec_malloc((hrr + 1) * sizeof(__m256i))) == NULL) {
free(vp->var_to_check);
free(vp->check_to_var);
free(vp->soft_bits);
free(vp->llrs);
free(vp);
if ((vp->rotated_v2c = SRSRAN_MEM_ALLOC(__m256i, hrr + 1)) == NULL) {
delete_ldpc_dec_c_avx2_flood(vp);
return NULL;
}
@ -209,14 +201,25 @@ void delete_ldpc_dec_c_avx2_flood(void* p)
{
struct ldpc_regs_c_avx2_flood* vp = p;
if (vp != NULL) {
if (vp == NULL) {
return;
}
if (vp->rotated_v2c) {
free(vp->rotated_v2c);
}
if (vp->var_to_check) {
free(vp->var_to_check);
}
if (vp->check_to_var) {
free(vp->check_to_var);
free(vp->soft_bits);
}
if (vp->soft_bits.v) {
free(vp->soft_bits.v);
}
if (vp->llrs) {
free(vp->llrs);
free(vp);
}
free(vp);
}
int init_ldpc_dec_c_avx2_flood(void* p, const int8_t* llrs, uint16_t ls)
@ -230,20 +233,20 @@ int init_ldpc_dec_c_avx2_flood(void* p, const int8_t* llrs, uint16_t ls)
}
// the first 2 x LS bits of the codeword are not sent
vp->soft_bits[0].v = _mm256_set1_epi8(0);
vp->soft_bits[1].v = _mm256_set1_epi8(0);
vp->soft_bits.v[0] = _mm256_set1_epi8(0);
vp->soft_bits.v[1] = _mm256_set1_epi8(0);
vp->llrs[0] = _mm256_set1_epi8(0);
vp->llrs[1] = _mm256_set1_epi8(0);
for (i = 2; i < vp->bgN; i++) {
for (j = 0; j < ls; j++) {
vp->soft_bits[i].c[j] = llrs[(i - 2) * ls + j];
vp->soft_bits.c[i * SRSRAN_AVX2_B_SIZE + j] = llrs[(i - 2) * ls + j];
}
bzero(&(vp->soft_bits[i].c[ls]), (SRSRAN_AVX2_B_SIZE - ls) * sizeof(int8_t));
vp->llrs[i] = vp->soft_bits[i].v;
srsran_vec_i8_zero(&(vp->soft_bits.c[i * SRSRAN_AVX2_B_SIZE + ls]), SRSRAN_AVX2_B_SIZE - ls);
vp->llrs[i] = vp->soft_bits.v[i];
}
bzero(vp->check_to_var, (vp->hrr + 1) * vp->bgM * sizeof(__m256i));
bzero(vp->var_to_check, (vp->hrr + 1) * vp->bgM * sizeof(__m256i));
SRSRAN_MEM_ZERO(vp->check_to_var, __m256i, (vp->hrr + 1) * (uint32_t)vp->bgM);
SRSRAN_MEM_ZERO(vp->var_to_check, __m256i, (vp->hrr + 1) * (uint32_t)vp->bgM);
return 0;
}
@ -259,11 +262,11 @@ int update_ldpc_var_to_check_c_avx2_flood(void* p, int i_layer)
__m256i* this_var_to_check = vp->var_to_check + i_layer * (vp->hrr + 1);
// Update the high-rate region.
inner_var_to_check_c_avx2(&(vp->soft_bits[0].v), this_check_to_var, this_var_to_check, infinity7, vp->hrr);
inner_var_to_check_c_avx2(&(vp->soft_bits.v[0]), this_check_to_var, this_var_to_check, infinity7, vp->hrr);
if (i_layer >= 4) {
// Update the extension region.
inner_var_to_check_c_avx2(&(vp->soft_bits[0].v) + vp->hrr + i_layer - 4,
inner_var_to_check_c_avx2(&(vp->soft_bits.v[0]) + vp->hrr + i_layer - 4,
this_check_to_var + vp->hrr,
this_var_to_check + vp->hrr,
infinity7,
@ -328,7 +331,7 @@ int update_ldpc_check_to_var_c_avx2_flood(void* p,
mask_min_epi8 = _mm256_cmpgt_epi8(mins_v2c_epi8, this_abs_v2c_epi8);
mins_v2c_epi8 = _mm256_blendv_epi8(mins_v2c_epi8, help_min_epi8, mask_min_epi8);
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
__m256i* this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1);
@ -357,7 +360,7 @@ int update_ldpc_check_to_var_c_avx2_flood(void* p,
this_check_to_var[i_v2c_base] = rotate_node_left(this_c2v_epi8, shift, vp->ls);
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
return 0;
@ -381,7 +384,7 @@ int update_ldpc_soft_bits_c_avx2_flood(void* p, const int8_t (*these_var_indices
__m256i mask_epi8;
for (i = 0; i < vp->bgN; i++) {
vp->soft_bits[i].v = vp->llrs[i];
vp->soft_bits.v[i] = vp->llrs[i];
}
for (i_layer = 0; i_layer < vp->bgM; i_layer++) {
@ -391,7 +394,7 @@ int update_ldpc_soft_bits_c_avx2_flood(void* p, const int8_t (*these_var_indices
for (i = 0; (current_var_index != -1) && (i < MAX_CNCT); i++) {
i_bit_tmp_base = (current_var_index <= vp->hrr) ? current_var_index : vp->hrr;
tmp_epi8 = _mm256_adds_epi8(this_check_to_var[i_bit_tmp_base], vp->soft_bits[current_var_index].v);
tmp_epi8 = _mm256_adds_epi8(this_check_to_var[i_bit_tmp_base], vp->soft_bits.v[current_var_index]);
// tmp = (tmp > infty7) : infty8 ? tmp
mask_epi8 = _mm256_cmpgt_epi8(tmp_epi8, infty7_epi8);
@ -399,7 +402,7 @@ int update_ldpc_soft_bits_c_avx2_flood(void* p, const int8_t (*these_var_indices
// tmp = (tmp < -infty7) : -infty8 ? tmp
mask_epi8 = _mm256_cmpgt_epi8(neg_infty7_epi8, tmp_epi8);
vp->soft_bits[current_var_index].v = _mm256_blendv_epi8(tmp_epi8, neg_infty8_epi8, mask_epi8);
vp->soft_bits.v[current_var_index] = _mm256_blendv_epi8(tmp_epi8, neg_infty8_epi8, mask_epi8);
current_var_index = these_var_indices[i_layer][i + 1];
}
@ -420,7 +423,7 @@ int extract_ldpc_message_c_avx2_flood(void* p, uint8_t* message, uint16_t liftK)
for (int i = 0; i < liftK / vp->ls; i++) {
for (j = 0; j < vp->ls; j++) {
message[i * vp->ls + j] = (vp->soft_bits[i].c[j] < 0);
message[i * vp->ls + j] = (vp->soft_bits.c[i * SRSRAN_AVX2_B_SIZE + j] < 0);
}
}

@ -368,7 +368,7 @@ int update_ldpc_check_to_var_c_avx2long(void* p,
vp->mins_v2c_epi8[j] = _mm256_blendv_epi8(vp->mins_v2c_epi8[j], help_min_epi8, mask_min_epi8);
}
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
__m256i* this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1) * vp->n_subnodes;
@ -403,7 +403,7 @@ int update_ldpc_check_to_var_c_avx2long(void* p,
// rotating right LS - shift positions is the same as rotating left shift positions
rotate_node_right(vp->this_c2v_epi8, this_check_to_var + i_v2c_base, vp->ls - shift, vp->ls, vp->n_subnodes);
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
return 0;
@ -445,7 +445,7 @@ int update_ldpc_soft_bits_c_avx2long(void* p, int i_layer, const int8_t (*these_
vp->soft_bits[current_var_index_subnode + j].v = _mm256_blendv_epi8(tmp_epi8, neg_infty8_epi8, mask_epi8);
}
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
return 0;

@ -137,107 +137,63 @@ void* create_ldpc_dec_c_avx2long_flood(uint8_t bgN, uint8_t bgM, uint16_t ls, fl
uint8_t bgK = bgN - bgM;
uint16_t hrr = bgK + 4;
if ((vp = srsran_vec_malloc(sizeof(struct ldpc_regs_c_avx2long_flood))) == NULL) {
if ((vp = SRSRAN_MEM_ALLOC(struct ldpc_regs_c_avx2long_flood, 1)) == NULL) {
return NULL;
}
SRSRAN_MEM_ZERO(vp, struct ldpc_regs_c_avx2long_flood, 1);
// compute number of subnodes
int left_out = ls % SRSRAN_AVX2_B_SIZE;
int n_subnodes = ls / SRSRAN_AVX2_B_SIZE + (left_out > 0);
if ((vp->llrs = srsran_vec_malloc(bgN * n_subnodes * sizeof(__m256i))) == NULL) {
free(vp);
if ((vp->llrs = SRSRAN_MEM_ALLOC(__m256i, bgN * n_subnodes)) == NULL) {
delete_ldpc_dec_c_avx2long_flood(vp);
return NULL;
}
if ((vp->soft_bits = srsran_vec_malloc(bgN * n_subnodes * sizeof(bg_node_t))) == NULL) {
free(vp->llrs);
free(vp);
if ((vp->soft_bits = SRSRAN_MEM_ALLOC(bg_node_t, bgN * n_subnodes)) == NULL) {
delete_ldpc_dec_c_avx2long_flood(vp);
return NULL;
}
if ((vp->check_to_var = srsran_vec_malloc((hrr + 1) * bgM * n_subnodes * sizeof(__m256i))) == NULL) {
free(vp->soft_bits);
free(vp->llrs);
free(vp);
if ((vp->check_to_var = SRSRAN_MEM_ALLOC(__m256i, (hrr + 1) * (uint32_t)bgM * n_subnodes)) == NULL) {
delete_ldpc_dec_c_avx2long_flood(vp);
return NULL;
}
if ((vp->var_to_check_to_free = srsran_vec_malloc(((hrr + 1) * bgM * n_subnodes + 2) * sizeof(__m256i))) == NULL) {
free(vp->check_to_var);
free(vp->soft_bits);
free(vp->llrs);
free(vp);
if ((vp->var_to_check_to_free = SRSRAN_MEM_ALLOC(__m256i, (hrr + 1) * (uint32_t)bgM * n_subnodes + 2)) == NULL) {
delete_ldpc_dec_c_avx2long_flood(vp);
return NULL;
}
vp->var_to_check = &vp->var_to_check_to_free[1];
if ((vp->minp_v2c_epi8 = srsran_vec_malloc(n_subnodes * sizeof(__m256i))) == NULL) {
free(vp->var_to_check_to_free);
free(vp->check_to_var);
free(vp->soft_bits);
free(vp->llrs);
free(vp);
if ((vp->minp_v2c_epi8 = SRSRAN_MEM_ALLOC(__m256i, n_subnodes)) == NULL) {
delete_ldpc_dec_c_avx2long_flood(vp);
return NULL;
}
if ((vp->mins_v2c_epi8 = srsran_vec_malloc(n_subnodes * sizeof(__m256i))) == NULL) {
free(vp->minp_v2c_epi8);
free(vp->var_to_check_to_free);
free(vp->check_to_var);
free(vp->soft_bits);
free(vp->llrs);
free(vp);
if ((vp->mins_v2c_epi8 = SRSRAN_MEM_ALLOC(__m256i, n_subnodes)) == NULL) {
delete_ldpc_dec_c_avx2long_flood(vp);
return NULL;
}
if ((vp->prod_v2c_epi8 = srsran_vec_malloc(n_subnodes * sizeof(__m256i))) == NULL) {
free(vp->mins_v2c_epi8);
free(vp->minp_v2c_epi8);
free(vp->var_to_check_to_free);
free(vp->check_to_var);
free(vp->soft_bits);
free(vp->llrs);
free(vp);
if ((vp->prod_v2c_epi8 = SRSRAN_MEM_ALLOC(__m256i, n_subnodes)) == NULL) {
delete_ldpc_dec_c_avx2long_flood(vp);
return NULL;
}
if ((vp->min_ix_epi8 = srsran_vec_malloc(n_subnodes * sizeof(__m256i))) == NULL) {
free(vp->prod_v2c_epi8);
free(vp->mins_v2c_epi8);
free(vp->minp_v2c_epi8);
free(vp->var_to_check_to_free);
free(vp->check_to_var);
free(vp->soft_bits);
free(vp->llrs);
free(vp);
if ((vp->min_ix_epi8 = SRSRAN_MEM_ALLOC(__m256i, n_subnodes)) == NULL) {
delete_ldpc_dec_c_avx2long_flood(vp);
return NULL;
}
if ((vp->rotated_v2c = srsran_vec_malloc((hrr + 1) * n_subnodes * sizeof(__m256i))) == NULL) {
free(vp->min_ix_epi8);
free(vp->prod_v2c_epi8);
free(vp->mins_v2c_epi8);
free(vp->minp_v2c_epi8);
free(vp->var_to_check_to_free);
free(vp->check_to_var);
free(vp->soft_bits);
free(vp->llrs);
free(vp);
if ((vp->rotated_v2c = SRSRAN_MEM_ALLOC(__m256i, (hrr + 1) * (uint32_t)n_subnodes)) == NULL) {
delete_ldpc_dec_c_avx2long_flood(vp);
return NULL;
}
if ((vp->this_c2v_epi8_to_free = srsran_vec_malloc((n_subnodes + 2) * sizeof(__m256i))) == NULL) {
free(vp->rotated_v2c);
free(vp->min_ix_epi8);
free(vp->prod_v2c_epi8);
free(vp->mins_v2c_epi8);
free(vp->minp_v2c_epi8);
free(vp->var_to_check_to_free);
free(vp->check_to_var);
free(vp->soft_bits);
free(vp->llrs);
free(vp);
if ((vp->this_c2v_epi8_to_free = SRSRAN_MEM_ALLOC(__m256i, n_subnodes + 2)) == NULL) {
delete_ldpc_dec_c_avx2long_flood(vp);
return NULL;
}
vp->this_c2v_epi8 = &vp->this_c2v_epi8_to_free[1];
@ -259,19 +215,40 @@ void delete_ldpc_dec_c_avx2long_flood(void* p)
{
struct ldpc_regs_c_avx2long_flood* vp = p;
if (vp != NULL) {
if (vp == NULL) {
return;
}
if (vp->this_c2v_epi8_to_free) {
free(vp->this_c2v_epi8_to_free);
}
if (vp->rotated_v2c) {
free(vp->rotated_v2c);
}
if (vp->min_ix_epi8) {
free(vp->min_ix_epi8);
}
if (vp->prod_v2c_epi8) {
free(vp->prod_v2c_epi8);
}
if (vp->mins_v2c_epi8) {
free(vp->mins_v2c_epi8);
}
if (vp->minp_v2c_epi8) {
free(vp->minp_v2c_epi8);
}
if (vp->var_to_check_to_free) {
free(vp->var_to_check_to_free);
}
if (vp->check_to_var) {
free(vp->check_to_var);
}
if (vp->soft_bits) {
free(vp->soft_bits);
}
if (vp->llrs) {
free(vp->llrs);
free(vp);
}
free(vp);
}
int init_ldpc_dec_c_avx2long_flood(void* p, const int8_t* llrs, uint16_t ls)
@ -302,8 +279,8 @@ int init_ldpc_dec_c_avx2long_flood(void* p, const int8_t* llrs, uint16_t ls)
bzero((int8_t*)(vp->llrs + i * vp->n_subnodes + j - 1) + k, (SRSRAN_AVX2_B_SIZE - k) * sizeof(int8_t));
}
bzero(vp->check_to_var, (vp->hrr + 1) * vp->bgM * vp->n_subnodes * sizeof(__m256i));
bzero(vp->var_to_check, (vp->hrr + 1) * vp->bgM * vp->n_subnodes * sizeof(__m256i));
SRSRAN_MEM_ZERO(vp->check_to_var, __m256i, (vp->hrr + 1) * (uint32_t)vp->bgM * (uint32_t)vp->n_subnodes);
SRSRAN_MEM_ZERO(vp->var_to_check, __m256i, (vp->hrr + 1) * (uint32_t)vp->bgM * (uint32_t)vp->n_subnodes);
return 0;
}
@ -396,7 +373,7 @@ int update_ldpc_check_to_var_c_avx2long_flood(void* p,
vp->mins_v2c_epi8[j] = _mm256_blendv_epi8(vp->mins_v2c_epi8[j], help_min_epi8, mask_min_epi8);
}
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
__m256i* this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1) * vp->n_subnodes;
@ -428,7 +405,7 @@ int update_ldpc_check_to_var_c_avx2long_flood(void* p,
// rotating right LS - shift positions is the same as rotating left shift positions
rotate_node_right(vp->this_c2v_epi8, this_check_to_var + i_v2c_base, vp->ls - shift, vp->ls, vp->n_subnodes);
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
return 0;

@ -324,7 +324,7 @@ int update_ldpc_check_to_var_c_avx512(void* p,
mask_min_epi8 = _mm512_cmpgt_epi8_mask(mins_v2c_epi8, this_abs_v2c_epi8);
mins_v2c_epi8 = _mm512_mask_blend_epi8(mask_min_epi8, mins_v2c_epi8, help_min_epi8);
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
__m512i* this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1);
@ -356,7 +356,7 @@ int update_ldpc_check_to_var_c_avx512(void* p,
// rotating right LS - shift positions is the same as rotating left shift positions
rotate_node_right((uint8_t*)vp->this_c2v_epi8, this_check_to_var + i_v2c_base, (vp->ls - shift) % vp->ls, vp->ls);
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
return 0;
@ -390,7 +390,7 @@ int update_ldpc_soft_bits_c_avx512(void* p, int i_layer, const int8_t (*these_va
vp->soft_bits.v[current_var_index] = _mm512_mask_blend_epi8(mask_epi8, tmp_epi8, _mm512_neg_infty8_epi8);
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
return 0;

@ -391,7 +391,7 @@ int update_ldpc_check_to_var_c_avx512long(void* p,
vp->mins_v2c_epi8[j] = _mm512_mask_blend_epi8(mask_min_epi8, vp->mins_v2c_epi8[j], help_min_epi8);
}
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
__m512i* this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1) * vp->n_subnodes;
@ -426,7 +426,7 @@ int update_ldpc_check_to_var_c_avx512long(void* p,
// rotating right LS - shift positions is the same as rotating left shift positions
rotate_node_right((uint8_t*)vp->this_c2v_epi8, this_check_to_var + i_v2c_base, (vp->ls - shift) % vp->ls, vp->ls);
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
return 0;
@ -469,7 +469,7 @@ int update_ldpc_soft_bits_c_avx512long(void* p, int i_layer, const int8_t (*thes
_mm512_mask_blend_epi8(mask_epi8, tmp_epi8, _mm512_neg_infty8_epi8);
}
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
return 0;

@ -302,8 +302,8 @@ int init_ldpc_dec_c_avx512long_flood(void* p, const int8_t* llrs, uint16_t ls)
bzero((int8_t*)(vp->llrs + i * vp->n_subnodes + j - 1) + k, (SRSRAN_AVX512_B_SIZE - k) * sizeof(int8_t));
}
bzero(vp->check_to_var, (vp->hrr + 1) * vp->bgM * vp->n_subnodes * sizeof(__m512i));
bzero(vp->var_to_check, (vp->hrr + 1) * vp->bgM * vp->n_subnodes * sizeof(__m512i));
SRSRAN_MEM_ZERO(vp->check_to_var, __m512i, (vp->hrr + 1) * (uint32_t)vp->bgM * (uint32_t)vp->n_subnodes);
SRSRAN_MEM_ZERO(vp->var_to_check, __m512i, (vp->hrr + 1) * (uint32_t)vp->bgM * (uint32_t)vp->n_subnodes);
return 0;
}
@ -393,7 +393,7 @@ int update_ldpc_check_to_var_c_avx512long_flood(void* p,
vp->mins_v2c_epi8[j] = _mm512_mask_blend_epi8(mask_min_epi8, vp->mins_v2c_epi8[j], help_min_epi8);
}
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
__m512i* this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1) * vp->n_subnodes;
@ -427,7 +427,7 @@ int update_ldpc_check_to_var_c_avx512long_flood(void* p,
// rotating right LS - shift positions is the same as rotating left shift positions
rotate_node_right((uint8_t*)vp->this_c2v_epi8, this_check_to_var + i_v2c_base, (vp->ls - shift) % vp->ls, vp->ls);
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
return 0;

@ -190,15 +190,15 @@ int init_ldpc_dec_c_flood(void* p, const int8_t* llrs, uint16_t ls)
return -1;
}
bzero(vp->llrs, skip * sizeof(int8_t));
bzero(vp->soft_bits, skip * sizeof(int8_t));
srsran_vec_i8_zero(vp->llrs, skip);
srsran_vec_i8_zero(vp->soft_bits, skip);
for (i = skip; i < vp->liftN; i++) {
vp->llrs[i] = llrs[i - skip];
vp->soft_bits[i] = llrs[i - skip];
}
bzero(vp->check_to_var, (vp->hrrN + vp->ls) * vp->bgM * sizeof(int8_t));
bzero(vp->var_to_check, (vp->hrrN + vp->ls) * vp->bgM * sizeof(int8_t));
srsran_vec_i8_zero(vp->check_to_var, (vp->hrrN + vp->ls) * (uint32_t)vp->bgM);
srsran_vec_i8_zero(vp->var_to_check, (vp->hrrN + vp->ls) * (uint32_t)vp->bgM);
return 0;
}
@ -276,7 +276,7 @@ int update_ldpc_check_to_var_c_flood(void* p,
vp->prod_v2c[index] *= (this_var_to_check[i_v2c] >= 0) ? 1 : -1;
}
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
int8_t* this_check_to_var = vp->check_to_var + i_layer * (vp->hrrN + vp->ls);
@ -295,7 +295,7 @@ int update_ldpc_check_to_var_c_flood(void* p,
this_check_to_var[i_v2c] *= vp->prod_v2c[index] * ((this_var_to_check[i_v2c] >= 0) ? 1 : -1);
}
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
return 0;

@ -156,8 +156,8 @@ int init_ldpc_dec_f(void* p, const float* llrs, uint16_t ls)
vp->soft_bits[i] = llrs[i - skip];
}
bzero(vp->check_to_var, (vp->hrrN + vp->ls) * vp->bgM * sizeof(float));
bzero(vp->var_to_check, (vp->hrrN + vp->ls) * sizeof(float));
srsran_vec_f_zero(vp->check_to_var, (vp->hrrN + vp->ls) * (uint32_t)vp->bgM);
srsran_vec_f_zero(vp->var_to_check, vp->hrrN + vp->ls);
return 0;
}
@ -232,7 +232,7 @@ int update_ldpc_check_to_var_f(void* p,
vp->prod_v2c[index] *= (vp->var_to_check[i_v2c] >= 0) ? 1 : -1;
}
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
float* this_check_to_var = vp->check_to_var + i_layer * (vp->hrrN + vp->ls);
@ -251,7 +251,7 @@ int update_ldpc_check_to_var_f(void* p,
this_check_to_var[i_v2c] *= (float)vp->prod_v2c[index] * ((vp->var_to_check[i_v2c] >= 0) ? 1.F : -1.F);
}
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
return 0;
@ -280,7 +280,7 @@ int update_ldpc_soft_bits_f(void* p, int i_layer, const int8_t (*these_var_indic
vp->soft_bits[i_bit] = this_check_to_var[i_bit_tmp] + this_var_to_check[i_bit_tmp];
}
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
return 0;

@ -177,13 +177,13 @@ int init_ldpc_dec_s(void* p, const int16_t* llrs, uint16_t ls)
return -1;
}
bzero(vp->soft_bits, skip * sizeof(int16_t));
srsran_vec_i16_zero(vp->soft_bits, skip);
for (i = skip; i < vp->liftN; i++) {
vp->soft_bits[i] = llrs[i - skip];
}
bzero(vp->check_to_var, (vp->hrrN + vp->ls) * vp->bgM * sizeof(int16_t));
bzero(vp->var_to_check, (vp->hrrN + vp->ls) * sizeof(int16_t));
srsran_vec_i16_zero(vp->check_to_var, (vp->hrrN + vp->ls) * (uint32_t)vp->bgM);
srsran_vec_i16_zero(vp->var_to_check, vp->hrrN + vp->ls);
return 0;
}
@ -258,7 +258,7 @@ int update_ldpc_check_to_var_s(void* p,
vp->prod_v2c[index] *= (vp->var_to_check[i_v2c] >= 0) ? 1 : -1;
}
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
int16_t* this_check_to_var = vp->check_to_var + i_layer * (vp->hrrN + vp->ls);
@ -277,7 +277,7 @@ int update_ldpc_check_to_var_s(void* p,
this_check_to_var[i_v2c] *= vp->prod_v2c[index] * ((vp->var_to_check[i_v2c] >= 0) ? 1 : -1);
}
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
return 0;
@ -315,7 +315,7 @@ int update_ldpc_soft_bits_s(void* p, int i_layer, const int8_t (*these_var_indic
}
vp->soft_bits[i_bit] = (int16_t)tmp;
}
current_var_index = (*these_var_indices)[i + 1];
current_var_index = (*these_var_indices)[(i + 1) % MAX_CNCT];
}
return 0;

@ -145,7 +145,7 @@ int load_avx2long(void* p, const uint8_t* input, const uint8_t msg_len, const ui
ini = ini + node_size;
}
bzero(vp->codeword + msg_len * vp->n_subnodes, (cdwd_len - msg_len) * vp->n_subnodes * sizeof(__m256i));
SRSRAN_MEM_ZERO(vp->codeword + msg_len * vp->n_subnodes, bg_node_t, (cdwd_len - msg_len) * (uint32_t)vp->n_subnodes);
return 0;
}
@ -212,8 +212,8 @@ void preprocess_systematic_bits_avx2long(srsran_ldpc_encoder_t* q)
int N = q->bgN;
int K = q->bgK;
int M = q->bgM;
int ls = q->ls;
uint32_t M = q->bgM;
uint16_t* pcm = q->pcm;
int k = 0;
@ -223,7 +223,7 @@ void preprocess_systematic_bits_avx2long(srsran_ldpc_encoder_t* q)
__m256i tmp_epi8;
bzero(vp->aux, M * vp->n_subnodes * sizeof(__m256i));
SRSRAN_MEM_ZERO(vp->aux, __m256i, M * vp->n_subnodes);
// split the input message into K chunks of ls bits each and, for all chunks
for (k = 0; k < K; k++) {

@ -134,6 +134,12 @@ static int init_rm(srsran_ldpc_rm_t* p,
return -1;
}
// Protect zero modulo
if (mod_order == 0) {
ERROR("Invalid modulation order");
return -1;
}
// check out_len is multiple of mod_order
if ((E % mod_order) != 0) { // N can only be a multiple of either BASEN[0] or BASEN[1], but not both
ERROR("Wrong RM codeword length (E) = %d. It must be a multiple of modulation order = %d", E, mod_order);

@ -651,11 +651,23 @@ int main(int argc, char** argv)
void print_decoder(char* title, int n_batches, int n_errors, double elapsed_time)
{
double wer = NAN;
if (n_batches != 0 && batch_size != 0) {
wer = (double)n_errors / n_batches / batch_size;
}
printf("\n**** %s ****", title);
printf("\nEstimated word error rate:\n %e (%d errors)\n", (double)n_errors / n_batches / batch_size, n_errors);
printf("\nEstimated word error rate:\n %e (%d errors)\n", wer, n_errors);
double w_rate = NAN;
double k_rate = NAN;
double n_rate = NAN;
if (elapsed_time != 0) {
w_rate = n_batches * batch_size / elapsed_time;
k_rate = n_batches * batch_size * finalK / elapsed_time;
n_rate = n_batches * batch_size * finalN / elapsed_time;
}
printf("Estimated throughput decoder:\n %e word/s\n %e bit/s (information)\n %e bit/s (encoded)\n",
n_batches * batch_size / elapsed_time,
n_batches * batch_size * finalK / elapsed_time,
n_batches * batch_size * finalN / elapsed_time);
w_rate,
k_rate,
n_rate);
}

@ -104,7 +104,7 @@ void get_examples(uint8_t* messages, //
sprintf(cstr, "ls%dcwds", lift_size);
do {
do {
tmp[0] = fgetc(ex_file);
tmp[0] = (char)fgetc(ex_file);
} while (tmp[0] != 'l');
fscanf(ex_file, "%[^\n]", tmp + 1);
fgetc(ex_file); // discard newline

@ -91,7 +91,7 @@ void srsran_polar_chanalloc_rx(const uint8_t* output_decoder,
uint16_t i_o = 0;
uint16_t iPC = 0;
uint16_t iK = 0;
for (uint16_t iKPC = 0; iKPC < K + nPC; iKPC++) {
for (uint16_t iKPC = 0; iKPC < K + (uint16_t)nPC; iKPC++) {
i_o = K_set[iKPC]; // includes parity bits
if (i_o == PC_set[iPC]) { // skip
iPC = iPC + 1;

@ -34,6 +34,7 @@
#include "polar_decoder_ssc_c_avx2.h"
#include "../utils_avx2.h"
#include "polar_decoder_vector_avx2.h"
#include "srsran/phy/fec/polar/polar_code.h"
#include "srsran/phy/fec/polar/polar_encoder.h"
#include "srsran/phy/utils/vector.h"
@ -51,13 +52,13 @@ struct StateAVX2 {
* \brief Describes an SSC polar decoder (8-bit version).
*/
struct pSSC_c_avx2 {
int8_t** llr0; /*!< \brief Pointers to the upper half of LLRs values at all stages. */
int8_t** llr1; /*!< \brief Pointers to the lower half of LLRs values at all stages. */
uint8_t* est_bit; /*!< \brief Pointers to the temporary estimated bits. */
struct Params* param; /*!< \brief Pointer to a Params structure. */
struct StateAVX2* state; /*!< \brief Pointer to a State. */
void* tmp_node_type; /*!< \brief Pointer to a Tmp_node_type. */
srsran_polar_encoder_t* enc; /*!< \brief Pointer to a srsran_polar_encoder_t. */
int8_t* llr0[NMAX_LOG + 1]; /*!< \brief Pointers to the upper half of LLRs values at all stages. */
int8_t* llr1[NMAX_LOG + 1]; /*!< \brief Pointers to the lower half of LLRs values at all stages. */
uint8_t* est_bit; /*!< \brief Pointers to the temporary estimated bits. */
struct Params* param; /*!< \brief Pointer to a Params structure. */
struct StateAVX2* state; /*!< \brief Pointer to a State. */
void* tmp_node_type; /*!< \brief Pointer to a Tmp_node_type. */
srsran_polar_encoder_t* enc; /*!< \brief Pointer to a srsran_polar_encoder_t. */
void (*f)(const int8_t* x, const int8_t* y, int8_t* z, const uint16_t len); /*!< \brief Pointer to the function-f. */
void (*g)(const uint8_t* b,
const int8_t* x,
@ -109,12 +110,6 @@ void delete_polar_decoder_ssc_c_avx2(void* p)
if (pp->llr0[0]) {
free(pp->llr0[0]); // remove LLR buffer.
}
if (pp->llr0) {
free(pp->llr0);
}
if (pp->llr1) {
free(pp->llr1);
}
if (pp->param) {
if (pp->param->node_type[0]) {
free(pp->param->node_type[0]);
@ -200,10 +195,6 @@ void* create_polar_decoder_ssc_c_avx2(const uint8_t nMax)
pp->est_bit = srsran_vec_u8_malloc(est_bit_size); // every 32 chars are aligned
// allocate memory for LLR pointers.
pp->llr0 = malloc((nMax + 1) * sizeof(int8_t*));
pp->llr1 = malloc((nMax + 1) * sizeof(int8_t*));
// LLR MEMORY NOT ALIGNED FOR LLR_BUFFERS_SIZE < SRSRAN_SIMB_LLR_ALIGNED
// We do not align the memory at lower stages, as if done, after each function f and function g
@ -312,7 +303,6 @@ int init_polar_decoder_ssc_c_avx2(void* p,
int polar_decoder_ssc_c_avx2(void* p, uint8_t* data_decoded)
{
if (p == NULL) {
return -1;
}
@ -331,7 +321,6 @@ int polar_decoder_ssc_c_avx2(void* p, uint8_t* data_decoded)
static void simplified_node(struct pSSC_c_avx2* p)
{
struct pSSC_c_avx2* pp = p;
pp->state->stage--; // to child node.
@ -345,7 +334,6 @@ static void simplified_node(struct pSSC_c_avx2* p)
uint16_t stage_half_size = 0;
switch (pp->param->node_type[stage][bit_pos]) {
case RATE_1:
pp->hard_bit(pp->llr0[stage], pp->est_bit + pp->state->bit_pos, stage_size);

@ -129,7 +129,6 @@ static inline void srsran_vec_polar_encoder_32_avx2(const uint8_t* x, uint8_t* z
*/
static inline void srsran_vec_xor_bbb_avx2(const uint8_t* x, const uint8_t* y, uint8_t* z, uint16_t len)
{
for (int i = 0; i < len; i += SRSRAN_AVX2_B_SIZE) {
__m256i simd_x = _mm256_loadu_si256((__m256i*)&x[i]);
__m256i simd_y = _mm256_loadu_si256((__m256i*)&y[i]);
@ -142,19 +141,18 @@ static inline void srsran_vec_xor_bbb_avx2(const uint8_t* x, const uint8_t* y, u
int polar_encoder_encode_avx2(void* p, const uint8_t* input, uint8_t* output, const uint8_t code_size_log)
{
struct pAVX2* q = p;
if (q == NULL) {
return -1;
}
uint8_t* tmp = q->tmp;
uint8_t* x = NULL;
uint8_t* y = NULL;
uint8_t* z = NULL;
if (q == NULL) {
return -1;
}
// load data
uint32_t code_size = 1U << code_size_log;

@ -51,6 +51,16 @@ void srsran_polar_code_sets_free(srsran_polar_sets_t* c)
}
}
#define SAFE_READ(PTR, SIZE, N, FILE) \
do { \
size_t nbytes = SIZE * N; \
if (nbytes != fread(PTR, SIZE, N, FILE)) { \
perror("read"); \
fclose(FILE); \
exit(1); \
} \
} while (false)
int srsran_polar_code_sets_read(srsran_polar_sets_t* c,
const uint16_t message_size,
const uint8_t code_size_log,
@ -109,10 +119,10 @@ int srsran_polar_code_sets_read(srsran_polar_sets_t* c,
exit(1);
}
fread(c->info_set, sizeof(uint16_t), c->info_set_size, fptr);
fread(c->message_set, sizeof(uint16_t), c->message_set_size, fptr);
fread(c->parity_set, sizeof(uint16_t), c->parity_set_size, fptr);
fread(c->frozen_set, sizeof(uint16_t), c->frozen_set_size, fptr);
SAFE_READ(c->info_set, sizeof(uint16_t), c->info_set_size, fptr);
SAFE_READ(c->message_set, sizeof(uint16_t), c->message_set_size, fptr);
SAFE_READ(c->parity_set, sizeof(uint16_t), c->parity_set_size, fptr);
SAFE_READ(c->frozen_set, sizeof(uint16_t), c->frozen_set_size, fptr);
fclose(fptr);
return 0;

@ -70,7 +70,11 @@ int main(int argc, char** argv)
uint32_t st = 0, end = 187;
if (long_cb) {
st = srsran_cbsegm_cbindex(long_cb);
int n = srsran_cbsegm_cbindex(long_cb);
if (n < SRSRAN_SUCCESS) {
return SRSRAN_ERROR;
}
st = (uint32_t)n;
end = st;
}

@ -120,7 +120,6 @@ int main(int argc, char** argv)
short* llr_s;
uint8_t* llr_c;
uint8_t * data_tx, *data_rx, *data_rx_bytes, *symbols;
uint32_t i, j;
float var[SNR_POINTS];
uint32_t snr_points;
uint32_t errors = 0;
@ -140,7 +139,11 @@ int main(int argc, char** argv)
if (test_known_data) {
frame_length = KNOWN_DATA_LEN;
} else {
frame_length = srsran_cbsegm_cbsize(srsran_cbsegm_cbindex(frame_length));
int n = srsran_cbsegm_cbsize(srsran_cbsegm_cbindex(frame_length));
if (n < SRSRAN_SUCCESS) {
return SRSRAN_ERROR;
}
frame_length = (uint32_t)n;
}
coded_length = 3 * (frame_length) + SRSRAN_TCOD_TOTALTAIL;
@ -209,7 +212,7 @@ int main(int argc, char** argv)
ebno_inc = (SNR_MAX - SNR_MIN) / SNR_POINTS;
if (ebno_db == 100.0) {
snr_points = SNR_POINTS;
for (i = 0; i < snr_points; i++) {
for (uint32_t i = 0; i < snr_points; i++) {
ebno_db = SNR_MIN + i * ebno_inc;
esno_db = ebno_db + srsran_convert_power_to_dB(1.0f / 3.0f);
var[i] = srsran_convert_dB_to_amplitude(-esno_db);
@ -219,13 +222,13 @@ int main(int argc, char** argv)
var[0] = srsran_convert_dB_to_amplitude(-esno_db);
snr_points = 1;
}
for (i = 0; i < snr_points; i++) {
for (uint32_t i = 0; i < snr_points; i++) {
mean_usec = 0;
errors = 0;
frame_cnt = 0;
while (frame_cnt < nof_frames) {
/* generate data_tx */
for (j = 0; j < frame_length; j++) {
for (uint32_t j = 0; j < frame_length; j++) {
if (test_known_data) {
data_tx[j] = known_data[j];
} else {
@ -235,19 +238,19 @@ int main(int argc, char** argv)
/* coded BER */
if (test_known_data) {
for (j = 0; j < coded_length; j++) {
for (uint32_t j = 0; j < coded_length; j++) {
symbols[j] = known_data_encoded[j];
}
} else {
srsran_tcod_encode(&tcod, data_tx, symbols, frame_length);
}
for (j = 0; j < coded_length; j++) {
for (uint32_t j = 0; j < coded_length; j++) {
llr[j] = symbols[j] ? 1 : -1;
}
srsran_ch_awgn_f(llr, llr, var[i], coded_length);
for (j = 0; j < coded_length; j++) {
for (uint32_t j = 0; j < coded_length; j++) {
llr_s[j] = (int16_t)(100 * llr[j]);
}

@ -461,7 +461,7 @@ static void tdec_iteration_8(srsran_tdec_t* h, int8_t* input)
if (h->dec_type == SRSRAN_TDEC_AUTO) {
h->current_llr_type = SRSRAN_TDEC_8;
h->current_dec = tdec_sb_idx_8(h->current_long_cb);
h->current_inter_idx = interleaver_idx(h->nof_blocks8[h->current_dec]);
h->current_inter_idx = interleaver_idx(h->nof_blocks8[h->current_dec % SRSRAN_TDEC_NOF_AUTO_MODES_8]);
// If long_cb is not multiple of any 8-bit decoder, use a 16-bit decoder and do type conversion
if (h->current_dec >= 10) {

@ -54,42 +54,43 @@ inline static uint8x16_t v_load_s8(int i15,
#define int8x16_to_8x8x2(v) ((int8x8x2_t){{vget_low_s8(v), vget_high_s8(v)}})
inline static void vshuff_s32_even(int32x4_t a, int imm, int32x4_t* res)
{
*res = vsetq_lane_s32(vgetq_lane_s32((a), ((imm) >> 2) & 0x3), *res, 1);
*res = vsetq_lane_s32(vgetq_lane_s32((a), ((imm) >> 6) & 0x3), *res, 3);
}
inline static void vshuff_s32_odd(int32x4_t a, int imm, int32x4_t* res)
{
*res = vsetq_lane_s32(vgetq_lane_s32((a), (imm)&0x3), *res, 0);
*res = vsetq_lane_s32(vgetq_lane_s32((a), ((imm) >> 4) & 0x3), *res, 2);
}
inline static void vshuff_s32_idx(int32x4_t a, int imm, int32x4_t* res, int idx)
{
*res = vsetq_lane_s32(vgetq_lane_s32((a), ((imm) >> idx * 2) & 0x3), *res, idx);
}
inline static void vshuff_s16_idx(int16x8_t a, int imm, int16x8_t* res, int idx)
{
*res = vsetq_lane_s16(vgetq_lane_s16((a), ((imm) >> (idx * 4)) & 0xF), *res, idx);
}
inline static void vshuff_s16_even(int16x8_t a, int imm, int16x8_t* res)
{
*res = vsetq_lane_s16(vgetq_lane_s16((a), ((imm) >> 4) & 0xF), *res, 1);
*res = vsetq_lane_s16(vgetq_lane_s16((a), ((imm) >> 12) & 0xF), *res, 3);
*res = vsetq_lane_s16(vgetq_lane_s16((a), ((imm) >> 20) & 0xF), *res, 5);
*res = vsetq_lane_s16(vgetq_lane_s16((a), ((imm) >> 28) & 0xF), *res, 7);
}
inline static void vshuff_s16_odd(int16x8_t a, int imm, int16x8_t* res)
{
*res = vsetq_lane_s16(vgetq_lane_s16((a), ((imm)) & 0xF), *res, 0);
*res = vsetq_lane_s16(vgetq_lane_s16((a), ((imm) >> 8) & 0xF), *res, 2);
*res = vsetq_lane_s16(vgetq_lane_s16((a), ((imm) >> 16) & 0xF), *res, 4);
*res = vsetq_lane_s16(vgetq_lane_s16((a), ((imm) >> 24) & 0xF), *res, 6);
}
#define vshuff_s32_even(a, imm, res) \
do { \
*res = vsetq_lane_s32(vgetq_lane_s32((a), ((imm) >> 2) & 0x3), *res, 1); \
*res = vsetq_lane_s32(vgetq_lane_s32((a), ((imm) >> 6) & 0x3), *res, 3); \
} while (0)
#define vshuff_s32_odd(a, imm, res) \
do { \
*res = vsetq_lane_s32(vgetq_lane_s32((a), (imm)&0x3), *res, 0); \
*res = vsetq_lane_s32(vgetq_lane_s32((a), ((imm) >> 4) & 0x3), *res, 2); \
} while (0)
#define vshuff_s32_idx(a, imm, res, idx) \
do { \
*res = vsetq_lane_s32(vgetq_lane_s32((a), ((imm) >> idx * 2) & 0x3), *res, idx); \
} while (0)
#define vshuff_s16_idx(a, imm, res, idx) \
do { \
*res = vsetq_lane_s16(vgetq_lane_s16((a), ((imm) >> (idx * 4)) & 0xF), *res, idx); \
} while (0)
#define vshuff_s16_even(a, imm, res) \
do { \
*res = vsetq_lane_s16(vgetq_lane_s16((a), ((imm) >> 4) & 0xF), *res, 1); \
*res = vsetq_lane_s16(vgetq_lane_s16((a), ((imm) >> 12) & 0xF), *res, 3); \
*res = vsetq_lane_s16(vgetq_lane_s16((a), ((imm) >> 20) & 0xF), *res, 5); \
*res = vsetq_lane_s16(vgetq_lane_s16((a), ((imm) >> 28) & 0xF), *res, 7); \
} while (0)
#define vshuff_s16_odd(a, imm, res) \
do { \
*res = vsetq_lane_s16(vgetq_lane_s16((a), ((imm)) & 0xF), *res, 0); \
*res = vsetq_lane_s16(vgetq_lane_s16((a), ((imm) >> 8) & 0xF), *res, 2); \
*res = vsetq_lane_s16(vgetq_lane_s16((a), ((imm) >> 16) & 0xF), *res, 4); \
*res = vsetq_lane_s16(vgetq_lane_s16((a), ((imm) >> 24) & 0xF), *res, 6); \
} while (0)
#endif

@ -283,12 +283,13 @@ int srsran_npdcch_decode_msg(srsran_npdcch_t* q,
} else {
DEBUG("Skipping DCI: nCCE=%d, L=%d, msg_len=%d, mean=%f", location->ncce, location->L, nof_bits, mean);
}
q->num_decoded_symbols = num_decoded_symbols;
ret = SRSRAN_SUCCESS;
} else {
fprintf(stderr, "Invalid parameters, location=%d,%d\n", location->ncce, location->L);
}
q->num_decoded_symbols = num_decoded_symbols;
return ret;
}

@ -194,8 +194,13 @@ int srsran_pdcch_nr_init_tx(srsran_pdcch_nr_t* q, const srsran_pdcch_nr_args_t*
}
q->is_tx = true;
srsran_polar_encoder_type_t encoder_type =
(args->disable_simd) ? SRSRAN_POLAR_ENCODER_PIPELINED : SRSRAN_POLAR_ENCODER_AVX2;
srsran_polar_encoder_type_t encoder_type = SRSRAN_POLAR_ENCODER_PIPELINED;
#ifdef LV_HAVE_AVX2
if (!args->disable_simd) {
encoder_type = SRSRAN_POLAR_ENCODER_AVX2;
}
#endif // LV_HAVE_AVX2
if (srsran_polar_encoder_init(&q->encoder, encoder_type, NMAX_LOG) < SRSRAN_SUCCESS) {
return SRSRAN_ERROR;
@ -214,8 +219,13 @@ int srsran_pdcch_nr_init_rx(srsran_pdcch_nr_t* q, const srsran_pdcch_nr_args_t*
return SRSRAN_ERROR;
}
srsran_polar_decoder_type_t decoder_type =
(args->disable_simd) ? SRSRAN_POLAR_DECODER_SSC_C : SRSRAN_POLAR_DECODER_SSC_C_AVX2;
srsran_polar_decoder_type_t decoder_type = SRSRAN_POLAR_DECODER_SSC_C;
#ifdef LV_HAVE_AVX2
if (!args->disable_simd) {
decoder_type = SRSRAN_POLAR_DECODER_SSC_C_AVX2;
}
#endif // LV_HAVE_AVX2
if (srsran_polar_decoder_init(&q->decoder, decoder_type, NMAX_LOG) < SRSRAN_SUCCESS) {
return SRSRAN_ERROR;
@ -334,9 +344,9 @@ static uint32_t pdcch_nr_cp(const srsran_pdcch_nr_t* q,
static uint32_t pdcch_nr_c_init(const srsran_pdcch_nr_t* q, const srsran_dci_msg_nr_t* dci_msg)
{
uint32_t n_id = (dci_msg->ctx.ss_type == srsran_search_space_type_ue && q->coreset.dmrs_scrambling_id_present)
? q->coreset.dmrs_scrambling_id
: q->carrier.pci;
uint32_t n_id = (dci_msg->ctx.ss_type == srsran_search_space_type_ue && q->coreset.dmrs_scrambling_id_present)
? q->coreset.dmrs_scrambling_id
: q->carrier.pci;
uint32_t n_rnti = (dci_msg->ctx.ss_type == srsran_search_space_type_ue && q->coreset.dmrs_scrambling_id_present)
? dci_msg->ctx.rnti
: 0U;

@ -591,8 +591,6 @@ static uint32_t pdsch_nr_grant_info(const srsran_pdsch_nr_t* q,
if (res != NULL) {
if (grant->tb[i].enabled && !isnan(res->evm[i])) {
len = srsran_print_check(str, str_len, len, "evm=%.2f ", res->evm[i]);
if (i < SRSRAN_MAX_CODEWORDS - 1) {
}
}
}
}

@ -1027,8 +1027,6 @@ static uint32_t pusch_nr_grant_info(const srsran_pusch_nr_t* q,
if (res != NULL) {
if (grant->tb[i].enabled && !isnan(res->evm[i])) {
len = srsran_print_check(str, str_len, len, "evm=%.2f ", res->evm[i]);
if (i < SRSRAN_MAX_CODEWORDS - 1) {
}
}
}
}

@ -28,6 +28,7 @@ static srsran_carrier_nr_t carrier = {
1, // pci
0, // absolute_frequency_ssb
0, // absolute_frequency_point_a
0, // offset_to_carrier
srsran_subcarrier_spacing_15kHz, // scs
50, // nof_prb
0, // start

@ -30,16 +30,16 @@
#include <math.h>
static srsran_carrier_nr_t carrier = {
1, // pci
0, // absolute_frequency_ssb
0, // absolute_frequency_point_a
srsran_subcarrier_spacing_15kHz, // scs
SRSRAN_MAX_PRB_NR, // nof_prb
0, // start
1 // max_mimo_layers
1, // pci
0, // absolute_frequency_ssb
0, // absolute_frequency_point_a
0, // offset_to_carrier
srsran_subcarrier_spacing_15kHz, // scs
SRSRAN_MAX_PRB_NR, // nof_prb
0, // start
1 // max_mimo_layers
};
static uint32_t n_prb = 0; // Set to 0 for steering
static uint32_t mcs = 30; // Set to 30 for steering
static srsran_sch_cfg_nr_t pdsch_cfg = {};

@ -35,6 +35,7 @@ static srsran_carrier_nr_t carrier = {
1, // pci
0, // absolute_frequency_ssb
0, // absolute_frequency_point_a
0, // offset_to_carrier
srsran_subcarrier_spacing_15kHz, // scs
6, // nof_prb
0, // start

@ -29,13 +29,14 @@
#include <getopt.h>
static srsran_carrier_nr_t carrier = {
1, // pci
0, // absolute_frequency_ssb
0, // absolute_frequency_point_a
srsran_subcarrier_spacing_15kHz, // scs
SRSRAN_MAX_PRB_NR, // nof_prb
0, // start
1 // max_mimo_layers
1, // pci
0, // absolute_frequency_ssb
0, // absolute_frequency_point_a
0, // offset_to_carrier
srsran_subcarrier_spacing_15kHz, // scs
SRSRAN_MAX_PRB_NR, // nof_prb
0, // start
1 // max_mimo_layers
};
static uint32_t n_prb = 0; // Set to 0 for steering

@ -28,13 +28,14 @@
#include <srsran/phy/utils/random.h>
static srsran_carrier_nr_t carrier = {
1, // pci
0, // absolute_frequency_ssb
0, // absolute_frequency_point_a
srsran_subcarrier_spacing_15kHz, // scs
SRSRAN_MAX_PRB_NR, // nof_prb
0, // start
1 // max_mimo_layers
1, // pci
0, // absolute_frequency_ssb
0, // absolute_frequency_point_a
0, // offset_to_carrier
srsran_subcarrier_spacing_15kHz, // scs
SRSRAN_MAX_PRB_NR, // nof_prb
0, // start
1 // max_mimo_layers
};
static uint32_t n_prb = 0; // Set to 0 for steering

@ -1070,13 +1070,13 @@ int srsran_uci_nr_encode_pusch_ack(srsran_uci_nr_t* q,
const srsran_uci_value_nr_t* value,
uint8_t* o)
{
int A = cfg->o_ack;
// Check inputs
if (q == NULL || cfg == NULL || value == NULL || o == NULL) {
return SRSRAN_ERROR_INVALID_INPUTS;
}
int A = cfg->o_ack;
// 6.3.2.1 UCI bit sequence generation
// 6.3.2.1.1 HARQ-ACK
bool has_csi_part2 = srsran_csi_has_part2(cfg->csi, cfg->nof_csi);

@ -296,26 +296,16 @@ int rf_soapy_open_multi(char* args, void** h, uint32_t num_requested_channels)
SoapySDRKwargsList_clear(soapy_args, length);
return SRSRAN_ERROR;
}
char* devname = DEVNAME_NONE;
// Print connected devices
for (size_t i = 0; i < length; i++) {
printf("Soapy has found device #%d: ", (int)i);
for (size_t j = 0; j < soapy_args[i].size; j++) {
printf("%s=%s, ", soapy_args[i].keys[j], soapy_args[i].vals[j]);
if (!strcmp(soapy_args[i].keys[j], "name") && !strcmp(soapy_args[i].vals[j], "LimeSDR-USB")) {
devname = DEVNAME_LIME;
} else if (!strcmp(soapy_args[i].keys[j], "name") && !strcmp(soapy_args[i].vals[j], "LimeSDR Mini")) {
devname = DEVNAME_LIME_MINI;
}
}
printf("\n");
}
// With the Lime we are better off using LTE sample rates
if (strcmp(devname, "Lime") && srsran_symbol_size_is_standard() == false) {
printf("\033[0;31mConsider using LTE sample rates for better RF performance.\nEither compile with "
"\'-DUSE_LTE_RATES=True\' or start srsENB or srsUE with \'--expert.lte_sample_rates=true\'\033[0m\n");
}
// Select Soapy device by id
int dev_id = 0;
if (args != NULL) {
@ -338,6 +328,14 @@ int rf_soapy_open_multi(char* args, void** h, uint32_t num_requested_channels)
dev_id = SRSRAN_MIN(dev_id, length - 1);
printf("Selecting Soapy device: %d\n", dev_id);
// With the Lime we are better off using LTE sample rates
const char* devname = SoapySDRKwargs_get(&soapy_args[dev_id], "name");
if (devname != NULL && strstr(devname, "Lime") != NULL && srsran_symbol_size_is_standard() == false) {
printf("\033[0;31mDetected LimeSDR. Consider using LTE rates for better RF performance.\nEither compile with "
"\'-DUSE_LTE_RATES=True\' or start srsENB/srsUE with \'--expert.lte_sample_rates=true\'\033[0m\n");
}
// Now make the device
SoapySDRDevice* sdr = SoapySDRDevice_make(&(soapy_args[dev_id]));
if (sdr == NULL) {
printf("Failed to create Soapy object\n");
@ -352,7 +350,7 @@ int rf_soapy_open_multi(char* args, void** h, uint32_t num_requested_channels)
handler->device = sdr;
handler->tx_stream_active = false;
handler->rx_stream_active = false;
handler->devname = devname;
handler->devname = DEVNAME_SOAPY;
// create stream args from device args
SoapySDRKwargs stream_args = {};

@ -26,9 +26,7 @@
#include "srsran/phy/rf/rf.h"
#include <stdbool.h>
#include <stdint.h>
#define DEVNAME_NONE "none"
#define DEVNAME_LIME "lime"
#define DEVNAME_LIME_MINI "lime_mini"
#define DEVNAME_SOAPY "soapy"
SRSRAN_API int rf_soapy_open(char* args, void** handler);

@ -46,22 +46,25 @@
* - BURST: A burst has started
* - END_OF_BURST: An underflow, overflow or late has been detected, the next transmission shall be aborted and an end
* of burst will be send in the next transmission;
* - WAIT_EOB_ACK: Waits for either an end of burst ACK event or a transmission after EOB_ACK_TIMEOUT_S the
* Late/Underflow occurred.
* - START_BURST: The next transmission will be flagged as start of burst.
*
* +-------+ L/O/U detected +--------------+ EoB Sent +-------------+
* | Burst |--------------->| End-of-burst |------------->| Start burst |<--- Initial state
* +-------+ | +--------------+ ^ +-------------+
* ^ | | |
* | | Burst ACK | |
* | +-------------------------------------+ |
* | |
* | Start of burst is transmitted |
* +----------------------------------------------------------+
* +-------+ L/O/U detected +--------------+ EoB Sent +--------------+ EOB ACK Rx +-------------+
* | Burst |--------------->| End-of-burst |------------>| Wait EOB ACK |------------>| Start burst |<-- Initial state
* +-------+ +--------------+ +--------------+ +-------------+
* ^ | |
* | | New Transmission | New Transmission
* | | (TS timed out) |
* | | |
* | Start of burst is transmitted | |
* +---------------------------------------------------------+----------------------------+
*/
typedef enum {
RF_UHD_IMP_TX_STATE_START_BURST = 0,
RF_UHD_IMP_TX_STATE_BURST,
RF_UHD_IMP_TX_STATE_END_OF_BURST,
RF_UHD_IMP_TX_STATE_WAIT_EOB_ACK ///< Wait for enb-of-burst ACK
} rf_uhd_imp_underflow_state_t;
/**
@ -77,6 +80,11 @@ const std::set<std::string> RF_UHD_IMP_PROHIBITED_STREAM_REMAKE = {DEVNAME_X300,
DEVNAME_E3X0,
DEVNAME_B200};
/**
* List of devices that do NOT support end of burst flushing
*/
const std::set<std::string> RF_UHD_IMP_PROHIBITED_EOB_FLUSH = {DEVNAME_X300, DEVNAME_N300};
/**
* List of devices that do NOT require/support to restart streaming after rate changes/timeouts
*/
@ -119,6 +127,11 @@ static const std::chrono::milliseconds RF_UHD_IMP_ASYNCH_MSG_SLEEP_MS = std::chr
*/
static const uint32_t RF_UHD_IMP_MAX_RX_TRIALS = 100;
/**
* Timeout for end of burst ack.
*/
static const double RF_UHD_IMP_WAIT_EOB_ACK_TIMEOUT_S = 2.0;
struct rf_uhd_handler_t {
size_t id;
@ -139,6 +152,7 @@ struct rf_uhd_handler_t {
srsran_rf_error_handler_t uhd_error_handler = nullptr;
void* uhd_error_handler_arg = nullptr;
rf_uhd_imp_underflow_state_t tx_state = RF_UHD_IMP_TX_STATE_START_BURST;
uhd::time_spec_t eob_ack_timeout = {}; //< Set when a Underflow/Late happens
double current_master_clock = 0.0;
@ -250,8 +264,10 @@ static void log_rx_error(rf_uhd_handler_t* h)
#if HAVE_ASYNC_THREAD
static void* async_thread(void* h)
{
rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h;
uhd::async_metadata_t md;
rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h;
uhd::async_metadata_t md = {};
uhd::time_spec_t last_underflow_ts = {};
uhd::time_spec_t last_late_ts = {};
while (handler->async_thread_running) {
std::unique_lock<std::mutex> lock(handler->async_mutex);
@ -273,12 +289,20 @@ static void* async_thread(void* h)
const uhd::async_metadata_t::event_code_t& event_code = md.event_code;
if (event_code == uhd::async_metadata_t::EVENT_CODE_UNDERFLOW ||
event_code == uhd::async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET) {
log_underflow(handler);
if (md.time_spec != last_underflow_ts) {
last_underflow_ts = md.time_spec;
handler->eob_ack_timeout = md.time_spec + RF_UHD_IMP_WAIT_EOB_ACK_TIMEOUT_S;
log_underflow(handler);
}
} else if (event_code == uhd::async_metadata_t::EVENT_CODE_TIME_ERROR) {
log_late(handler, false);
if (md.time_spec != last_late_ts) {
last_late_ts = md.time_spec;
handler->eob_ack_timeout = md.time_spec + RF_UHD_IMP_WAIT_EOB_ACK_TIMEOUT_S;
log_late(handler, false);
}
} else if (event_code == uhd::async_metadata_t::EVENT_CODE_BURST_ACK) {
// Makes sure next block will be start of burst
if (handler->tx_state == RF_UHD_IMP_TX_STATE_BURST) {
if (handler->tx_state == RF_UHD_IMP_TX_STATE_WAIT_EOB_ACK) {
handler->tx_state = RF_UHD_IMP_TX_STATE_START_BURST;
}
} else {
@ -979,8 +1003,8 @@ static inline int rf_uhd_imp_end_burst(rf_uhd_handler_t* handler)
return SRSRAN_ERROR;
}
// Update TX state
handler->tx_state = RF_UHD_IMP_TX_STATE_START_BURST;
// Update TX state to wait for end of burst ACK
handler->tx_state = RF_UHD_IMP_TX_STATE_WAIT_EOB_ACK;
return SRSRAN_SUCCESS;
}
@ -1296,7 +1320,7 @@ int rf_uhd_recv_with_time_multi(void* h,
}
// Receive stream in multiple blocks
while (rxd_samples_total < nsamples && trials < RF_UHD_IMP_MAX_RX_TRIALS) {
while (rxd_samples_total < nsamples and trials < RF_UHD_IMP_MAX_RX_TRIALS) {
void* buffs_ptr[SRSRAN_MAX_CHANNELS] = {};
for (uint32_t i = 0; i < handler->nof_rx_channels; i++) {
cf_t* data_c = (cf_t*)data[i];
@ -1389,36 +1413,14 @@ int rf_uhd_send_timed_multi(void* h,
std::unique_lock<std::mutex> lock(handler->tx_mutex);
uhd::tx_metadata_t md;
void* buffs_ptr[SRSRAN_MAX_CHANNELS] = {};
size_t txd_samples = 0;
int n = 0;
int n = 0; //< Counts transmitted samples
// Check Tx stream has been created
if (not handler->uhd->is_tx_ready()) {
return SRSRAN_ERROR;
}
// Run Underflow recovery state machine
switch (handler->tx_state) {
case RF_UHD_IMP_TX_STATE_BURST:
// Normal case, do nothing
break;
case RF_UHD_IMP_TX_STATE_END_OF_BURST:
// Send end of burst and ignore transmission
if (rf_uhd_imp_end_burst(handler) != SRSRAN_SUCCESS) {
return SRSRAN_ERROR;
}
// Flush receiver
rf_uhd_flush_buffer(h);
return SRSRAN_ERROR;
case RF_UHD_IMP_TX_STATE_START_BURST:
// Set tart of burst to false if recovering from the Underflow
is_start_of_burst = true;
handler->tx_state = RF_UHD_IMP_TX_STATE_BURST;
break;
}
// Set Tx timestamp
if (not has_time_spec) {
// If it the beginning of a burst, set timestamp
if (is_start_of_burst) {
@ -1450,15 +1452,40 @@ int rf_uhd_send_timed_multi(void* h,
do {
size_t tx_samples = handler->tx_nof_samples;
// Set start of burst. Time spec only for the first packet in the burst
md.start_of_burst = is_start_of_burst;
// If an Underflow or a Late has been detected, end the burst immediately
if (handler->tx_state == RF_UHD_IMP_TX_STATE_END_OF_BURST) {
// Send end of burst and ignore transmission
if (rf_uhd_imp_end_burst(handler) != SRSRAN_SUCCESS) {
return SRSRAN_ERROR;
}
// Flush receiver only if allowed
if (RF_UHD_IMP_PROHIBITED_EOB_FLUSH.count(handler->devname) == 0) {
rf_uhd_flush_buffer(h);
}
return SRSRAN_ERROR;
}
// If the state is waiting for EOB ACK and the metadata of the current packet has passed the timeout, then start the
// burst
if (handler->tx_state == RF_UHD_IMP_TX_STATE_WAIT_EOB_ACK and md.time_spec >= handler->eob_ack_timeout) {
Info("Tx while waiting for EOB, timed out... " << md.time_spec.get_real_secs()
<< " >= " << handler->eob_ack_timeout.get_real_secs()
<< ". Starting new burst...");
handler->tx_state = RF_UHD_IMP_TX_STATE_START_BURST;
}
// Set start of burst, ignore function argument and set the flag based on the current Tx state
md.start_of_burst = (handler->tx_state == RF_UHD_IMP_TX_STATE_START_BURST);
// some devices don't like timestamps in each call
// Time spec only for the first packet in the burst, some devices are not capable of handling like timestamps for
// each baseband packet
if (RF_UHD_IMP_TIMESPEC_AT_BURST_START_ONLY.count(handler->devname) == 0) {
md.has_time_spec = is_start_of_burst or has_time_spec;
md.has_time_spec = md.start_of_burst or has_time_spec;
} else {
// only set time for start
md.has_time_spec = is_start_of_burst and has_time_spec;
md.has_time_spec = md.start_of_burst and has_time_spec;
}
// middle packets are never end of burst, last one as defined
@ -1469,20 +1496,35 @@ int rf_uhd_send_timed_multi(void* h,
md.end_of_burst = is_end_of_burst;
}
// Update data pointers
for (int i = 0; i < SRSRAN_MAX_CHANNELS; i++) {
void* buff = (void*)&data_c[i][n];
buffs_ptr[i] = buff;
}
if (handler->uhd->send(buffs_ptr, tx_samples, md, RF_UHD_IMP_TRX_TIMEOUT_S, txd_samples) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
size_t txd_samples = tx_samples; //< Stores the number of transmitted samples in this packet
// Skip baseband packet transmission if it is waiting for the enb of burst ACK
if (handler->tx_state != RF_UHD_IMP_TX_STATE_WAIT_EOB_ACK) {
// Actual transmission
if (handler->uhd->send(buffs_ptr, tx_samples, md, RF_UHD_IMP_TRX_TIMEOUT_S, txd_samples) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSRAN_ERROR;
}
// Tx state is now in burst
if (md.start_of_burst) {
handler->tx_state = RF_UHD_IMP_TX_STATE_BURST;
}
} else {
Debug("Tx while waiting for EOB, aborting block... " << md.time_spec.get_real_secs() << " < "
<< handler->eob_ack_timeout.get_real_secs());
}
// Next packets are not start of burst
is_start_of_burst = false;
// Increase the metadata transmit time
md.time_spec += txd_samples / handler->tx_rate;
// Increase number of transmitted samples
n += txd_samples;
} while (n < nsamples);

@ -32,7 +32,7 @@ pdcp_entity_base::pdcp_entity_base(task_sched_handle task_sched_, srslog::basic_
pdcp_entity_base::~pdcp_entity_base() {}
void pdcp_entity_base::config_security(as_security_config_t sec_cfg_)
void pdcp_entity_base::config_security(const as_security_config_t& sec_cfg_)
{
sec_cfg = sec_cfg_;

@ -148,7 +148,7 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu)
// Extract RCVD_SN from header
uint32_t rcvd_sn = read_data_header(pdu);
discard_data_header(pdu); // FIXME Check wheather the header is part of integrity check.
discard_data_header(pdu); // TODO: Check wheather the header is part of integrity check.
// Extract MAC
uint8_t mac[4];

@ -469,7 +469,7 @@ int make_phy_sr_resource_test()
sched_request_res_cfg.periodicity_and_offset_present = true;
sched_request_res_cfg.periodicity_and_offset.set_sl40();
sched_request_res_cfg.periodicity_and_offset.sl40() = 8;
sched_request_res_cfg.res_present = true;
sched_request_res_cfg.res_present = true;
sched_request_res_cfg.res = 16;
srsran_pucch_nr_sr_resource_t srsran_pucch_nr_sr_resource;
@ -551,30 +551,30 @@ int make_phy_pusch_scaling_test()
uci_on_pusch.scaling = uci_on_pusch_s::scaling_opts::f1;
float scaling;
TESTASSERT(make_phy_pusch_scaling(uci_on_pusch, &scaling) == true);
TESTASSERT(scaling = 1.0);
TESTASSERT(scaling == 1.0);
return SRSRAN_SUCCESS;
}
int make_phy_zp_csi_rs_resource_test()
{
srsran_csi_rs_zp_resource_t zp_csi_rs_resource0 = {};
// Item 0
// ZP-CSI-RS-Resource
// zp-CSI-RS-ResourceId: 0
// resourceMapping
// frequencyDomainAllocation: row4 (2)
// row4: 80 [bit length 3, 5 LSB pad bits, 100. ....
// decimal value 4]
// nrofPorts: p4 (2)
// firstOFDMSymbolInTimeDomain: 8
// cdm-Type: fd-CDM2 (1)
// density: one (1)
// one: NULL
// freqBand
// startingRB: 0
// nrofRBs: 52
// periodicityAndOffset: slots80 (9)
// slots80: 1
// Item 0
// ZP-CSI-RS-Resource
// zp-CSI-RS-ResourceId: 0
// resourceMapping
// frequencyDomainAllocation: row4 (2)
// row4: 80 [bit length 3, 5 LSB pad bits, 100. ....
// decimal value 4]
// nrofPorts: p4 (2)
// firstOFDMSymbolInTimeDomain: 8
// cdm-Type: fd-CDM2 (1)
// density: one (1)
// one: NULL
// freqBand
// startingRB: 0
// nrofRBs: 52
// periodicityAndOffset: slots80 (9)
// slots80: 1
asn1::rrc_nr::zp_csi_rs_res_s zp_csi_rs_res0;
zp_csi_rs_res0.res_map.freq_domain_alloc.set_row4();
@ -583,9 +583,9 @@ int make_phy_zp_csi_rs_resource_test()
zp_csi_rs_res0.res_map.first_ofdm_symbol_in_time_domain = 8;
zp_csi_rs_res0.res_map.cdm_type = csi_rs_res_map_s::cdm_type_opts::options::fd_cdm2;
zp_csi_rs_res0.res_map.density.set_one();
zp_csi_rs_res0.res_map.freq_band.start_rb = 0;
zp_csi_rs_res0.res_map.freq_band.nrof_rbs = 52;
zp_csi_rs_res0.periodicity_and_offset_present = true;
zp_csi_rs_res0.res_map.freq_band.start_rb = 0;
zp_csi_rs_res0.res_map.freq_band.nrof_rbs = 52;
zp_csi_rs_res0.periodicity_and_offset_present = true;
zp_csi_rs_res0.periodicity_and_offset.set_slots80() = 1;
TESTASSERT(make_phy_zp_csi_rs_resource(zp_csi_rs_res0, &zp_csi_rs_resource0) == true);
@ -632,7 +632,7 @@ int make_phy_nzp_csi_rs_resource_test()
nzp_csi_rs_res.nzp_csi_rs_res_id = 0;
nzp_csi_rs_res.res_map.freq_domain_alloc.set_row2();
nzp_csi_rs_res.res_map.freq_domain_alloc.row2().from_string("100000000000");
nzp_csi_rs_res.res_map.nrof_ports = csi_rs_res_map_s::nrof_ports_opts::options::p1;
nzp_csi_rs_res.res_map.nrof_ports = csi_rs_res_map_s::nrof_ports_opts::options::p1;
nzp_csi_rs_res.res_map.first_ofdm_symbol_in_time_domain = 4;
nzp_csi_rs_res.res_map.cdm_type = csi_rs_res_map_s::cdm_type_opts::options::no_cdm;
nzp_csi_rs_res.res_map.density.set_one();
@ -644,7 +644,7 @@ int make_phy_nzp_csi_rs_resource_test()
nzp_csi_rs_res.scrambling_id = 0;
nzp_csi_rs_res.periodicity_and_offset_present = true;
nzp_csi_rs_res.periodicity_and_offset.set_slots80() = 1;
srsran_csi_rs_nzp_resource_t nzp_resource_0;
TESTASSERT(make_phy_nzp_csi_rs_resource(nzp_csi_rs_res, &nzp_resource_0) == true);

@ -32,13 +32,15 @@ struct rx_thread_tester {
std::thread t;
rx_thread_tester() :
task_queue(task_sched.make_task_queue()), t([this]() {
task_queue(task_sched.make_task_queue()),
t([this]() {
stop_token.store(false);
while (not stop_token.load(std::memory_order_relaxed)) {
task_sched.run_pending_tasks();
std::this_thread::sleep_for(std::chrono::microseconds(100));
}
})
}),
stop_token(false)
{}
~rx_thread_tester()
{

@ -29,13 +29,14 @@
#include <getopt.h>
static srsran_carrier_nr_t carrier = {
501, // pci
0, // absolute_frequency_ssb
0, // absolute_frequency_point_a
srsran_subcarrier_spacing_15kHz, // scs
52, // nof_prb
0, // start
1 // max_mimo_layers
501, // pci
0, // absolute_frequency_ssb
0, // absolute_frequency_point_a
0, // offset_to_carrier
srsran_subcarrier_spacing_15kHz, // scs
52, // nof_prb
0, // start
1 // max_mimo_layers
};
static uint32_t n_prb = 0; // Set to 0 for steering
@ -275,7 +276,6 @@ int main(int argc, char** argv)
if (srsran_ue_dl_nr_set_carrier(&ue_dl, &carrier)) {
ERROR("Error setting SCH NR carrier");
goto clean_exit;
goto clean_exit;
}
srsran_dci_cfg_nr_t dci_cfg = {};

@ -5,15 +5,16 @@
#####################################################################
# eNB configuration
#
# enb_id: 20-bit eNB identifier.
# mcc: Mobile Country Code
# mnc: Mobile Network Code
# mme_addr: IP address of MME for S1 connnection
# gtp_bind_addr: Local IP address to bind for GTP connection
# s1c_bind_addr: Local IP address to bind for S1AP connection
# n_prb: Number of Physical Resource Blocks (6,15,25,50,75,100)
# tm: Transmission mode 1-4 (TM1 default)
# nof_ports: Number of Tx ports (1 port default, set to 2 for TM2/3/4)
# enb_id: 20-bit eNB identifier.
# mcc: Mobile Country Code
# mnc: Mobile Network Code
# mme_addr: IP address of MME for S1 connnection
# gtp_bind_addr: Local IP address to bind for GTP connection
# gtp_advertise_addr: IP address of eNB to advertise for DL GTP-U Traffic
# s1c_bind_addr: Local IP address to bind for S1AP connection
# n_prb: Number of Physical Resource Blocks (6,15,25,50,75,100)
# tm: Transmission mode 1-4 (TM1 default)
# nof_ports: Number of Tx ports (1 port default, set to 2 for TM2/3/4)
#
#####################################################################
[enb]

@ -43,7 +43,8 @@ class stack_interface_phy_lte;
class prach_worker : srsran::thread
{
public:
prach_worker(uint32_t cc_idx_, srslog::basic_logger& logger) : buffer_pool(8), thread("PRACH_WORKER"), logger(logger)
prach_worker(uint32_t cc_idx_, srslog::basic_logger& logger) :
buffer_pool(8), thread("PRACH_WORKER"), logger(logger), running(false)
{
cc_idx = cc_idx_;
}

@ -44,15 +44,23 @@ public:
static constexpr uint32_t PUSCH_CODE = 0, PUCCH_CODE = 1;
static constexpr int PHR_NEG_NOF_PRB = 1;
explicit tpc(uint32_t cell_nof_prb, float target_snr_dB_ = -1.0, bool phr_handling_flag_ = false) :
explicit tpc(uint32_t cell_nof_prb,
float target_pucch_snr_dB_ = -1.0,
float target_pusch_sn_dB_ = -1.0,
bool phr_handling_flag_ = false) :
nof_prb(cell_nof_prb),
target_snr_dB(target_snr_dB_),
snr_estim_list({ul_ch_snr_estim{target_snr_dB_}, ul_ch_snr_estim{target_snr_dB_}}),
target_pucch_snr_dB(target_pucch_snr_dB_),
target_pusch_snr_dB(target_pusch_sn_dB_),
snr_estim_list({ul_ch_snr_estim{target_pusch_snr_dB}, ul_ch_snr_estim{target_pucch_snr_dB}}),
phr_handling_flag(phr_handling_flag_)
{
max_prbs_cached = nof_prb;
}
void set_cfg(float target_snr_dB_) { target_snr_dB = target_snr_dB_; }
void set_cfg(float target_pusch_snr_dB_, float target_pucch_snr_dB_)
{
target_pucch_snr_dB = target_pucch_snr_dB_;
target_pusch_snr_dB = target_pusch_snr_dB_;
}
void set_snr(float snr, uint32_t ul_ch_code)
{
@ -81,7 +89,9 @@ public:
void new_tti()
{
for (auto& ch_snr : snr_estim_list) {
for (size_t chidx = 0; chidx < 2; ++chidx) {
float target_snr_dB = chidx == PUSCH_CODE ? target_pusch_snr_dB : target_pucch_snr_dB;
auto& ch_snr = snr_estim_list[chidx];
if (target_snr_dB < 0) {
ch_snr.pending_delta = 0;
continue;
@ -139,7 +149,8 @@ private:
}
uint8_t enconde_tpc(uint32_t cc)
{
auto& ch_snr = snr_estim_list[cc];
float target_snr_dB = cc == PUSCH_CODE ? target_pusch_snr_dB : target_pucch_snr_dB;
auto& ch_snr = snr_estim_list[cc];
assert(ch_snr.pending_delta == 0); // ensure called once per {cc,tti}
if (target_snr_dB < 0) {
// undefined target SINR case. Increase Tx power once per PHR, considering the number of allocable PRBs remains
@ -167,7 +178,7 @@ private:
}
uint32_t nof_prb;
float target_snr_dB;
float target_pucch_snr_dB, target_pusch_snr_dB;
bool phr_handling_flag;
// PHR-related variables

@ -124,9 +124,9 @@ private:
std::map<uint32_t, user_interface> users;
rlc_interface_pdcp* rlc;
rrc_interface_pdcp* rrc;
gtpu_interface_pdcp* gtpu;
rlc_interface_pdcp* rlc = nullptr;
rrc_interface_pdcp* rrc = nullptr;
gtpu_interface_pdcp* gtpu = nullptr;
srsran::task_sched_handle task_sched;
srslog::basic_logger& logger;
};

@ -48,7 +48,7 @@ class rlc : public rlc_interface_mac, public rlc_interface_rrc, public rlc_inter
public:
explicit rlc(srslog::basic_logger& logger) : logger(logger) {}
void
init(pdcp_interface_rlc* pdcp_, rrc_interface_rlc* rrc_, mac_interface_rlc* mac_, srsran::timer_handler* timers_);
init(pdcp_interface_rlc* pdcp_, rrc_interface_rlc* rrc_, mac_interface_rlc* mac_, srsran::timer_handler* timers_);
void stop();
void get_metrics(rlc_metrics_t& m, const uint32_t nof_tti);
@ -104,11 +104,11 @@ private:
std::map<uint32_t, user_interface> users;
std::vector<mch_service_t> mch_services;
mac_interface_rlc* mac;
pdcp_interface_rlc* pdcp;
rrc_interface_rlc* rrc;
mac_interface_rlc* mac = nullptr;
pdcp_interface_rlc* pdcp = nullptr;
rrc_interface_rlc* rrc = nullptr;
srslog::basic_logger& logger;
srsran::timer_handler* timers;
srsran::timer_handler* timers = nullptr;
};
} // namespace srsenb

@ -288,7 +288,7 @@ private:
srsran::unique_timer ts1_reloc_overall; ///< TS1_{RELOCOverall}
// Procedure state
s1ap_proc_id_t current_state;
s1ap_proc_id_t current_state = s1ap_proc_id_t::nulltype;
erab_id_list updated_erabs;
srsran::bounded_vector<asn1::s1ap::erab_item_s, ASN1_S1AP_MAXNOOF_ERABS> failed_cfg_erabs;

@ -62,7 +62,9 @@ cell_list =
//ul_earfcn = 21400;
ho_active = false;
//meas_gap_period = 0; // 0 (inactive), 40 or 80
//allowed_meas_bw = 6;
// target_pusch_sinr = -1;
// target_pucch_sinr = -1;
// allowed_meas_bw = 6;
// CA cells
scell_list = (

@ -758,7 +758,8 @@ static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root)
cell_cfg.root_seq_idx, cellroot, "root_seq_idx", rrc_cfg->sibs[1].sib2().rr_cfg_common.prach_cfg.root_seq_idx);
parse_default_field(cell_cfg.initial_dl_cqi, cellroot, "initial_dl_cqi", 5u);
parse_default_field(cell_cfg.meas_cfg.meas_gap_period, cellroot, "meas_gap_period", 0u);
HANDLEPARSERCODE(parse_default_field(cell_cfg.target_ul_sinr_db, cellroot, "target_ul_sinr", -1));
HANDLEPARSERCODE(parse_default_field(cell_cfg.target_pusch_sinr_db, cellroot, "target_pusch_sinr", -1));
HANDLEPARSERCODE(parse_default_field(cell_cfg.target_pucch_sinr_db, cellroot, "target_pucch_sinr", -1));
HANDLEPARSERCODE(parse_default_field(cell_cfg.enable_phr_handling, cellroot, "enable_phr_handling", false));
parse_default_field(cell_cfg.meas_cfg.allowed_meas_bw, cellroot, "allowed_meas_bw", 6u);
srsran_assert(srsran::is_lte_cell_nof_prb(cell_cfg.meas_cfg.allowed_meas_bw), "Invalid measurement Bandwidth");

@ -73,18 +73,19 @@ void parse_args(all_args_t* args, int argc, char* argv[])
bpo::options_description common("Configuration options");
common.add_options()
("enb.stack", bpo::value<string>(&args->stack.type)->default_value("lte"), "Type of the upper stack [lte, nr]")
("enb.enb_id", bpo::value<string>(&enb_id)->default_value("0x0"), "eNodeB ID")
("enb.name", bpo::value<string>(&args->stack.s1ap.enb_name)->default_value("srsenb01"), "eNodeB Name")
("enb.mcc", bpo::value<string>(&mcc)->default_value("001"), "Mobile Country Code")
("enb.mnc", bpo::value<string>(&mnc)->default_value("01"), "Mobile Network Code")
("enb.mme_addr", bpo::value<string>(&args->stack.s1ap.mme_addr)->default_value("127.0.0.1"),"IP address of MME for S1 connection")
("enb.gtp_bind_addr", bpo::value<string>(&args->stack.s1ap.gtp_bind_addr)->default_value("192.168.3.1"), "Local IP address to bind for GTP connection")
("enb.s1c_bind_addr", bpo::value<string>(&args->stack.s1ap.s1c_bind_addr)->default_value("192.168.3.1"), "Local IP address to bind for S1AP connection")
("enb.n_prb", bpo::value<uint32_t>(&args->enb.n_prb)->default_value(25), "Number of PRB")
("enb.nof_ports", bpo::value<uint32_t>(&args->enb.nof_ports)->default_value(1), "Number of ports")
("enb.tm", bpo::value<uint32_t>(&args->enb.transmission_mode)->default_value(1), "Transmission mode (1-8)")
("enb.p_a", bpo::value<float>(&args->enb.p_a)->default_value(0.0f), "Power allocation rho_a (-6, -4.77, -3, -1.77, 0, 1, 2, 3)")
("enb.stack", bpo::value<string>(&args->stack.type)->default_value("lte"), "Type of the upper stack [lte, nr]")
("enb.enb_id", bpo::value<string>(&enb_id)->default_value("0x0"), "eNodeB ID")
("enb.name", bpo::value<string>(&args->stack.s1ap.enb_name)->default_value("srsenb01"), "eNodeB Name")
("enb.mcc", bpo::value<string>(&mcc)->default_value("001"), "Mobile Country Code")
("enb.mnc", bpo::value<string>(&mnc)->default_value("01"), "Mobile Network Code")
("enb.mme_addr", bpo::value<string>(&args->stack.s1ap.mme_addr)->default_value("127.0.0.1"),"IP address of MME for S1 connection")
("enb.gtp_bind_addr", bpo::value<string>(&args->stack.s1ap.gtp_bind_addr)->default_value("192.168.3.1"), "Local IP address to bind for GTP connection")
("enb.gtp_advertise_addr", bpo::value<string>(&args->stack.s1ap.gtp_advertise_addr)->default_value(""), "IP address of eNB to advertise for DL GTP-U Traffic")
("enb.s1c_bind_addr", bpo::value<string>(&args->stack.s1ap.s1c_bind_addr)->default_value("192.168.3.1"), "Local IP address to bind for S1AP connection")
("enb.n_prb", bpo::value<uint32_t>(&args->enb.n_prb)->default_value(25), "Number of PRB")
("enb.nof_ports", bpo::value<uint32_t>(&args->enb.nof_ports)->default_value(1), "Number of ports")
("enb.tm", bpo::value<uint32_t>(&args->enb.transmission_mode)->default_value(1), "Transmission mode (1-8)")
("enb.p_a", bpo::value<float>(&args->enb.p_a)->default_value(0.0f), "Power allocation rho_a (-6, -4.77, -3, -1.77, 0, 1, 2, 3)")
("enb_files.sib_config", bpo::value<string>(&args->enb_files.sib_config)->default_value("sib.conf"), "SIB configuration files")
("enb_files.rr_config", bpo::value<string>(&args->enb_files.rr_config)->default_value("rr.conf"), "RR configuration files")

@ -139,8 +139,12 @@ int phy::init(const phy_args_t& args,
parse_common_config(cfg);
// Add workers to workers pool and start threads
lte_workers.init(args, &workers_common, log_sink, WORKERS_THREAD_PRIO);
nr_workers.init(args, &workers_common, log_sink, WORKERS_THREAD_PRIO);
if (not cfg.phy_cell_cfg.empty()) {
lte_workers.init(args, &workers_common, log_sink, WORKERS_THREAD_PRIO);
}
if (not cfg.phy_cell_cfg_nr.empty()) {
nr_workers.init(args, &workers_common, log_sink, WORKERS_THREAD_PRIO);
}
// For each carrier, initialise PRACH worker
for (uint32_t cc = 0; cc < cfg.phy_cell_cfg.size(); cc++) {

@ -43,7 +43,7 @@ using namespace std;
namespace srsenb {
txrx::txrx(srslog::basic_logger& logger) : thread("TXRX"), logger(logger)
txrx::txrx(srslog::basic_logger& logger) : thread("TXRX"), logger(logger), running(false)
{
/* Do nothing */
}

@ -36,7 +36,10 @@ sched_ue_cell::sched_ue_cell(uint16_t rnti_, const sched_cell_params_t& cell_cfg
cell_cfg(&cell_cfg_),
dci_locations(generate_cce_location_table(rnti_, cell_cfg_)),
harq_ent(SCHED_MAX_HARQ_PROC, SCHED_MAX_HARQ_PROC),
tpc_fsm(cell_cfg->nof_prb(), cell_cfg->cfg.target_ul_sinr, cell_cfg->cfg.enable_phr_handling),
tpc_fsm(cell_cfg->nof_prb(),
cell_cfg->cfg.target_pucch_ul_sinr,
cell_cfg->cfg.target_pusch_ul_sinr,
cell_cfg->cfg.enable_phr_handling),
fixed_mcs_dl(cell_cfg_.sched_cfg->pdsch_mcs),
fixed_mcs_ul(cell_cfg_.sched_cfg->pusch_mcs),
current_tti(current_tti_),

@ -733,16 +733,17 @@ void rrc::config_mac()
item.si_window_ms = cfg.sib1.si_win_len.to_number();
item.prach_rar_window =
cfg.sibs[1].sib2().rr_cfg_common.rach_cfg_common.ra_supervision_info.ra_resp_win_size.to_number();
item.prach_freq_offset = cfg.sibs[1].sib2().rr_cfg_common.prach_cfg.prach_cfg_info.prach_freq_offset;
item.maxharq_msg3tx = cfg.sibs[1].sib2().rr_cfg_common.rach_cfg_common.max_harq_msg3_tx;
item.enable_64qam = cfg.sibs[1].sib2().rr_cfg_common.pusch_cfg_common.pusch_cfg_basic.enable64_qam;
item.initial_dl_cqi = cfg.cell_list[ccidx].initial_dl_cqi;
item.target_ul_sinr = cfg.cell_list[ccidx].target_ul_sinr_db;
item.enable_phr_handling = cfg.cell_list[ccidx].enable_phr_handling;
item.delta_pucch_shift = cfg.sibs[1].sib2().rr_cfg_common.pucch_cfg_common.delta_pucch_shift.to_number();
item.ncs_an = cfg.sibs[1].sib2().rr_cfg_common.pucch_cfg_common.ncs_an;
item.n1pucch_an = cfg.sibs[1].sib2().rr_cfg_common.pucch_cfg_common.n1_pucch_an;
item.nrb_cqi = cfg.sibs[1].sib2().rr_cfg_common.pucch_cfg_common.nrb_cqi;
item.prach_freq_offset = cfg.sibs[1].sib2().rr_cfg_common.prach_cfg.prach_cfg_info.prach_freq_offset;
item.maxharq_msg3tx = cfg.sibs[1].sib2().rr_cfg_common.rach_cfg_common.max_harq_msg3_tx;
item.enable_64qam = cfg.sibs[1].sib2().rr_cfg_common.pusch_cfg_common.pusch_cfg_basic.enable64_qam;
item.initial_dl_cqi = cfg.cell_list[ccidx].initial_dl_cqi;
item.target_pucch_ul_sinr = cfg.cell_list[ccidx].target_pucch_sinr_db;
item.target_pusch_ul_sinr = cfg.cell_list[ccidx].target_pusch_sinr_db;
item.enable_phr_handling = cfg.cell_list[ccidx].enable_phr_handling;
item.delta_pucch_shift = cfg.sibs[1].sib2().rr_cfg_common.pucch_cfg_common.delta_pucch_shift.to_number();
item.ncs_an = cfg.sibs[1].sib2().rr_cfg_common.pucch_cfg_common.ncs_an;
item.n1pucch_an = cfg.sibs[1].sib2().rr_cfg_common.pucch_cfg_common.n1_pucch_an;
item.nrb_cqi = cfg.sibs[1].sib2().rr_cfg_common.pucch_cfg_common.nrb_cqi;
item.nrb_pucch = SRSRAN_MAX(cfg.sr_cfg.nof_prb, cfg.cqi_cfg.nof_prb);
logger.info("Allocating %d PRBs for PUCCH", item.nrb_pucch);

@ -45,7 +45,7 @@ int rrc_nr::init(const rrc_nr_cfg_t& cfg_,
gtpu = gtpu_;
ngap = ngap_;
// FIXME: overwriting because we are not passing config right now
// TODO: overwriting because we are not passing config right now
cfg = update_default_cfg(cfg_);
// config logging
@ -167,7 +167,7 @@ rrc_nr_cfg_t rrc_nr::update_default_cfg(const rrc_nr_cfg_t& current)
cfg_default.nof_sibs = 1;
sib2_s& sib2 = cfg_default.sibs[0].set_sib2();
sib2.cell_resel_info_common.q_hyst.value = sib2_s::cell_resel_info_common_s_::q_hyst_opts::db5;
// FIXME: Fill SIB2 values
// TODO: Fill SIB2 values
// set loglevel
cfg_default.log_level = "debug";

@ -395,8 +395,10 @@ void rrc::ue::handle_rrc_con_req(rrc_conn_request_s* msg)
for (auto& user : parent->users) {
if (user.first != rnti && user.second->has_tmsi && user.second->mmec == mmec && user.second->m_tmsi == m_tmsi) {
parent->logger.info("RRC connection request: UE context already exists. M-TMSI=%d", m_tmsi);
parent->s1ap->user_release(rnti, asn1::s1ap::cause_radio_network_opts::radio_conn_with_ue_lost);
parent->rem_user_thread(user.first);
if (parent->s1ap->user_release(rnti, asn1::s1ap::cause_radio_network_opts::radio_conn_with_ue_lost)) {
// Do not wait for MME response
parent->rem_user_thread(user.first);
}
break;
}
}

@ -768,8 +768,7 @@ bool gtpu::send_end_marker(uint32_t teidin)
servaddr.sin_addr.s_addr = htonl(tx_tun->spgw_addr);
servaddr.sin_port = htons(GTPU_PORT);
sendto(fd, pdu->msg, pdu->N_bytes, MSG_EOR, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in));
return true;
return sendto(fd, pdu->msg, pdu->N_bytes, MSG_EOR, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in)) > 0;
}
/****************************************************************************

@ -427,7 +427,7 @@ bool s1ap::user_release(uint16_t rnti, asn1::s1ap::cause_radio_network_e cause_r
return false;
}
if (u->was_uectxtrelease_requested()) {
if (u->was_uectxtrelease_requested() or not u->ctxt.mme_ue_s1ap_id.has_value()) {
logger.warning("UE context for RNTI:0x%x is in zombie state. Releasing...", rnti);
users.erase(u);
rrc->release_ue(rnti);
@ -437,10 +437,7 @@ bool s1ap::user_release(uint16_t rnti, asn1::s1ap::cause_radio_network_e cause_r
cause_c cause;
cause.set_radio_network().value = cause_radio.value;
if (u->ctxt.mme_ue_s1ap_id.has_value()) {
return u->send_uectxtreleaserequest(cause);
}
return true;
return u->send_uectxtreleaserequest(cause);
}
bool s1ap::user_exists(uint16_t rnti)
@ -1172,7 +1169,11 @@ bool s1ap::send_ho_req_ack(const asn1::s1ap::ho_request_s& msg,
tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_HO_RES_ALLOC);
ho_request_ack_ies_container& container = tx_pdu.successful_outcome().value.ho_request_ack().protocol_ies;
ue* ue_ptr = users.find_ue_mmeid(msg.protocol_ies.mme_ue_s1ap_id.value.value);
ue* ue_ptr = users.find_ue_mmeid(msg.protocol_ies.mme_ue_s1ap_id.value.value);
if (ue_ptr == nullptr) {
logger.error("The MME-S1AP-UE-ID=%ld is not valid", msg.protocol_ies.mme_ue_s1ap_id.value.value);
return false;
}
ue_ptr->ctxt.rnti = rnti;
ue_ptr->ctxt.enb_cc_idx = enb_cc_idx;
@ -1183,9 +1184,13 @@ bool s1ap::send_ho_req_ack(const asn1::s1ap::ho_request_s& msg,
container.erab_admitted_list.value.resize(admitted_bearers.size());
for (size_t i = 0; i < admitted_bearers.size(); ++i) {
container.erab_admitted_list.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_ADMITTED_ITEM);
auto& c = container.erab_admitted_list.value[i].value.erab_admitted_item();
c = admitted_bearers[i];
c.transport_layer_address = addr_to_asn1(args.gtp_bind_addr.c_str());
auto& c = container.erab_admitted_list.value[i].value.erab_admitted_item();
c = admitted_bearers[i];
if (!args.gtp_advertise_addr.empty()) {
c.transport_layer_address = addr_to_asn1(args.gtp_advertise_addr.c_str());
} else {
c.transport_layer_address = addr_to_asn1(args.gtp_bind_addr.c_str());
}
// If E-RAB is proposed for forward tunneling
if (c.dl_g_tp_teid_present) {
@ -1678,7 +1683,11 @@ void s1ap::ue::get_erab_addr(uint16_t erab_id, transp_addr_t& transp_addr, asn1:
// Note: RRC does not yet update correctly gtpu transp_addr
transp_addr.resize(32);
uint8_t addr[4];
inet_pton(AF_INET, s1ap_ptr->args.gtp_bind_addr.c_str(), addr);
if (!s1ap_ptr->args.gtp_advertise_addr.empty()) {
inet_pton(AF_INET, s1ap_ptr->args.gtp_advertise_addr.c_str(), addr);
} else {
inet_pton(AF_INET, s1ap_ptr->args.gtp_bind_addr.c_str(), addr);
}
for (uint32_t j = 0; j < 4; ++j) {
transp_addr.data()[j] = addr[3 - j];
}

@ -280,7 +280,8 @@ sched_sim_events rand_sim_params(uint32_t nof_ttis)
sched_sim_event_generator generator;
sim_gen.sim_args.cell_cfg = {generate_default_cell_cfg(nof_prb)};
sim_gen.sim_args.cell_cfg[0].target_ul_sinr = pick_random_uniform({10, 15, 20, -1});
sim_gen.sim_args.cell_cfg[0].target_pucch_ul_sinr = pick_random_uniform({10, 15, 20, -1});
sim_gen.sim_args.cell_cfg[0].target_pusch_ul_sinr = pick_random_uniform({10, 15, 20, -1});
sim_gen.sim_args.cell_cfg[0].enable_phr_handling = false;
sim_gen.sim_args.default_ue_sim_cfg.ue_cfg = generate_default_ue_cfg();
sim_gen.sim_args.default_ue_sim_cfg.periodic_cqi = true;

@ -49,21 +49,22 @@ inline srsenb::sched_interface::cell_cfg_t generate_default_cell_cfg(uint32_t no
cell_cfg_phy.phich_length = SRSRAN_PHICH_NORM;
cell_cfg_phy.phich_resources = SRSRAN_PHICH_R_1;
cell_cfg.sibs[0].len = 18;
cell_cfg.sibs[0].period_rf = 8;
cell_cfg.sibs[1].len = 41;
cell_cfg.sibs[1].period_rf = 16;
cell_cfg.si_window_ms = 40;
cell_cfg.nrb_pucch = (cell_cfg_phy.nof_prb == 6) ? 1 : 2;
cell_cfg.prach_freq_offset = (cell_cfg_phy.nof_prb == 6) ? 0 : 4;
cell_cfg.prach_rar_window = 3;
cell_cfg.maxharq_msg3tx = 3;
cell_cfg.initial_dl_cqi = 6;
cell_cfg.target_ul_sinr = -1;
cell_cfg.nrb_cqi = 1;
cell_cfg.n1pucch_an = 12;
cell_cfg.delta_pucch_shift = 1;
cell_cfg.ncs_an = 0;
cell_cfg.sibs[0].len = 18;
cell_cfg.sibs[0].period_rf = 8;
cell_cfg.sibs[1].len = 41;
cell_cfg.sibs[1].period_rf = 16;
cell_cfg.si_window_ms = 40;
cell_cfg.nrb_pucch = (cell_cfg_phy.nof_prb == 6) ? 1 : 2;
cell_cfg.prach_freq_offset = (cell_cfg_phy.nof_prb == 6) ? 0 : 4;
cell_cfg.prach_rar_window = 3;
cell_cfg.maxharq_msg3tx = 3;
cell_cfg.initial_dl_cqi = 6;
cell_cfg.target_pusch_ul_sinr = -1;
cell_cfg.target_pucch_ul_sinr = -1;
cell_cfg.nrb_cqi = 1;
cell_cfg.n1pucch_an = 12;
cell_cfg.delta_pucch_shift = 1;
cell_cfg.ncs_an = 0;
return cell_cfg;
}

@ -35,7 +35,7 @@ int test_finite_target_snr()
const uint32_t nof_prbs = 50;
const int target_snr = 15;
tpc tpcfsm(nof_prbs, 15, true);
tpc tpcfsm(nof_prbs, 15, 15, true);
// TEST: While no SNR info is provided, no TPC commands are sent
for (uint32_t i = 0; i < 100; ++i) {
@ -82,7 +82,7 @@ int test_undefined_target_snr()
{
const uint32_t nof_prbs = 50;
tpc tpcfsm(nof_prbs, -1, true);
tpc tpcfsm(nof_prbs, -1, -1, true);
TESTASSERT(tpcfsm.max_ul_prbs() == 50);
// TEST: While the PHR is not updated, a limited number of TPC commands should be sent

@ -1180,8 +1180,8 @@ public:
private:
// Test constants
static const uint32_t delta_pucch = 2;
static const uint32_t N_pucch_1 = 2;
static const uint32_t delta_pucch = 1;
static const uint32_t N_pucch_1 = 12;
// Private classes
unique_dummy_radio_t radio;

@ -14,9 +14,9 @@
# mme_bind_addr: IP bind addr to listen for eNB S1-MME connnections
# dns_addr: DNS server address for the UEs
# encryption_algo: Preferred encryption algorithm for NAS layer
# (default: EEA0, support: EEA1, EEA2)
# (supported: EEA0 (default), EEA1, EEA2, EEA3)
# integrity_algo: Preferred integrity protection algorithm for NAS
# (default: EIA1, support: EIA1, EIA2 (EIA0 not support)
# (supported: EIA0 (rejected by most UEs), EIA1 (default), EIA2, EIA3
# paging_timer: Value of paging timer in seconds (T3413)
#
#####################################################################

@ -137,6 +137,8 @@ typedef struct {
uint16_t paging_timer;
std::string apn;
std::string dns;
std::string full_net_name;
std::string short_net_name;
srsran::CIPHERING_ALGORITHM_ID_ENUM cipher_algo;
srsran::INTEGRITY_ALGORITHM_ID_ENUM integ_algo;
} nas_init_t;
@ -273,6 +275,8 @@ private:
uint16_t m_tac = 0;
std::string m_apn;
std::string m_dns;
std::string m_full_net_name;
std::string m_short_net_name;
// Timers timeout values
uint16_t m_t3413 = 0;

@ -44,6 +44,8 @@ typedef struct {
std::string mme_bind_addr;
std::string mme_name;
std::string dns_addr;
std::string full_net_name;
std::string short_net_name;
std::string mme_apn;
bool pcap_enable;
std::string pcap_filename;

@ -87,6 +87,8 @@ void parse_args(all_args_t* args, int argc, char* argv[])
string sgi_if_addr;
string sgi_if_name;
string dns_addr;
string full_net_name;
string short_net_name;
string hss_db_file;
string hss_auth_algo;
string log_filename;
@ -110,6 +112,8 @@ void parse_args(all_args_t* args, int argc, char* argv[])
("mme.mnc", bpo::value<string>(&mnc)->default_value("01"), "Mobile Network Code")
("mme.mme_bind_addr", bpo::value<string>(&mme_bind_addr)->default_value("127.0.0.1"), "IP address of MME for S1 connection")
("mme.dns_addr", bpo::value<string>(&dns_addr)->default_value("8.8.8.8"), "IP address of the DNS server for the UEs")
("mme.full_net_name", bpo::value<string>(&full_net_name)->default_value("Software Radio Systems RAN"), "Full name of the network")
("mme.short_net_name", bpo::value<string>(&short_net_name)->default_value("srsRAN"), "Short name of the network")
("mme.apn", bpo::value<string>(&mme_apn)->default_value(""), "Set Access Point Name (APN) for data services")
("mme.encryption_algo", bpo::value<string>(&encryption_algo)->default_value("EEA0"), "Set preferred encryption algorithm for NAS layer ")
("mme.integrity_algo", bpo::value<string>(&integrity_algo)->default_value("EIA1"), "Set preferred integrity protection algorithm for NAS")
@ -269,6 +273,8 @@ void parse_args(all_args_t* args, int argc, char* argv[])
args->mme_args.s1ap_args.mme_bind_addr = mme_bind_addr;
args->mme_args.s1ap_args.mme_name = mme_name;
args->mme_args.s1ap_args.dns_addr = dns_addr;
args->mme_args.s1ap_args.full_net_name = full_net_name;
args->mme_args.s1ap_args.short_net_name = short_net_name;
args->mme_args.s1ap_args.mme_apn = mme_apn;
args->mme_args.s1ap_args.paging_timer = paging_timer;
args->spgw_args.gtpu_bind_addr = spgw_bind_addr;

@ -43,6 +43,8 @@ nas::nas(const nas_init_t& args, const nas_if_t& itf) :
m_tac(args.tac),
m_apn(args.apn),
m_dns(args.dns),
m_full_net_name(args.full_net_name),
m_short_net_name(args.short_net_name),
m_t3413(args.paging_timer)
{
m_sec_ctx.integ_algo = args.integ_algo;
@ -1573,10 +1575,10 @@ bool nas::pack_emm_information(srsran::byte_buffer_t* nas_buffer)
LIBLTE_MME_EMM_INFORMATION_MSG_STRUCT emm_info;
emm_info.full_net_name_present = true;
strncpy(emm_info.full_net_name.name, "Software Radio Systems LTE", LIBLTE_STRING_LEN);
memccpy(emm_info.full_net_name.name, m_full_net_name.c_str(), 0, LIBLTE_STRING_LEN);
emm_info.full_net_name.add_ci = LIBLTE_MME_ADD_CI_DONT_ADD;
emm_info.short_net_name_present = true;
strncpy(emm_info.short_net_name.name, "srsRAN", LIBLTE_STRING_LEN);
memccpy(emm_info.short_net_name.name, m_short_net_name.c_str(), 0, LIBLTE_STRING_LEN);
emm_info.short_net_name.add_ci = LIBLTE_MME_ADD_CI_DONT_ADD;
emm_info.local_time_zone_present = false;

@ -75,6 +75,8 @@ void s1ap_nas_transport::init()
m_nas_init.tac = m_s1ap->m_s1ap_args.tac;
m_nas_init.apn = m_s1ap->m_s1ap_args.mme_apn;
m_nas_init.dns = m_s1ap->m_s1ap_args.dns_addr;
m_nas_init.full_net_name = m_s1ap->m_s1ap_args.full_net_name;
m_nas_init.short_net_name = m_s1ap->m_s1ap_args.short_net_name;
m_nas_init.paging_timer = m_s1ap->m_s1ap_args.paging_timer;
m_nas_init.integ_algo = m_s1ap->m_s1ap_args.integrity_algo;
m_nas_init.cipher_algo = m_s1ap->m_s1ap_args.encryption_algo;

@ -244,7 +244,7 @@ void spgw::gtpu::handle_sgi_pdu(srsran::unique_byte_buffer_t msg)
m_gtpc->send_downlink_data_notification(spgw_teid);
m_gtpc->queue_downlink_packet(spgw_teid, std::move(msg));
return;
} else if (usr_found == false && ctr_found == true) {
} else if (usr_found == true && ctr_found == false) {
m_logger.error("User plane tunnel found without a control plane tunnel present.");
} else {
send_s1u_pdu(enb_fteid, msg.get());

@ -51,13 +51,13 @@ public:
void stop();
private:
void set_metrics_helper(const srsran::rf_metrics_t rf,
const srsran::sys_metrics_t sys,
const phy_metrics_t phy,
const mac_metrics_t mac[SRSRAN_MAX_CARRIERS],
const rrc_metrics_t rrc,
const uint32_t cc,
const uint32_t r);
void set_metrics_helper(const srsran::rf_metrics_t& rf,
const srsran::sys_metrics_t& sys,
const phy_metrics_t& phy,
const mac_metrics_t mac[SRSRAN_MAX_CARRIERS],
const rrc_metrics_t& rrc,
const uint32_t cc,
const uint32_t r);
std::string float_to_string(float f, int digits, bool add_semicolon = true);

@ -48,11 +48,11 @@ public:
private:
static const bool FORCE_NEIGHBOUR_CELL = false; // Set to true for printing always neighbour cells
void set_metrics_helper(const phy_metrics_t phy,
const mac_metrics_t mac[SRSRAN_MAX_CARRIERS],
const rrc_metrics_t rrc,
bool display_neighbours,
const uint32_t r);
void set_metrics_helper(const phy_metrics_t& phy,
const mac_metrics_t mac[SRSRAN_MAX_CARRIERS],
const rrc_metrics_t& rrc,
bool display_neighbours,
const uint32_t r);
std::string float_to_string(float f, int digits);
std::string float_to_eng_string(float f, int digits);
void print_table(const bool display_neighbours);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save