21 #include "spdlog/spdlog.h"
25 _signal_buffer_max_samples = 3 * SRSRAN_SF_LEN_PRB(
MAX_PRB);
27 for (
auto ch = 0; ch < _rx_channels; ch++) {
28 _signal_buffer_rx[ch] = srsran_vec_cf_malloc(_signal_buffer_max_samples);
29 if (!_signal_buffer_rx[ch]) {
30 spdlog::error(
"Could not allocate regular DL signal buffer\n");
35 if (srsran_ue_dl_init(&_ue_dl, _signal_buffer_rx,
MAX_PRB, _rx_channels)) {
36 spdlog::error(
"Could not init ue_dl\n");
40 srsran_softbuffer_rx_init(&_softbuffer, 100);
42 _ue_dl_cfg.snr_to_cqi_offset = 0;
44 for (
auto & i : _data) {
45 i = srsran_vec_u8_malloc(2000 * 8);
47 spdlog::error(
"Allocating data");
52 srsran_chest_dl_cfg_t* chest_cfg = &_ue_dl_cfg.chest_cfg;
53 bzero(chest_cfg,
sizeof(srsran_chest_dl_cfg_t));
54 chest_cfg->filter_coef[0] = 4;
55 chest_cfg->filter_coef[1] = 1.0f;
56 chest_cfg->filter_type = SRSRAN_CHEST_FILTER_GAUSS;
57 chest_cfg->noise_alg = SRSRAN_NOISE_ALG_EMPTY;
58 chest_cfg->rsrp_neighbour =
false;
59 chest_cfg->sync_error_enable =
false;
60 chest_cfg->estimator_alg = SRSRAN_ESTIMATOR_ALG_AVERAGE;
61 chest_cfg->cfo_estimate_enable =
true;
62 chest_cfg->cfo_estimate_sf_mask = 1023;
64 _ue_dl_cfg.cfg.pdsch.csi_enable =
true;
65 _ue_dl_cfg.cfg.pdsch.max_nof_iterations = 8;
66 _ue_dl_cfg.cfg.pdsch.meas_evm_en =
false;
67 _ue_dl_cfg.cfg.pdsch.decoder_type = SRSRAN_MIMO_DECODER_MMSE;
68 _ue_dl_cfg.cfg.pdsch.softbuffers.rx[0] = &_softbuffer;
74 for (
auto & i :
_data) {
80 srsran_ue_dl_free(&
_ue_dl);
85 spdlog::debug(
"CAS processor setting cell ({} PRB / {} MBSFN PRB).", cell.nof_prb, cell.mbsfn_prb);
86 srsran_ue_dl_set_cell(&
_ue_dl, cell);
91 _sf_cfg.sf_type = SRSRAN_SF_NORM;
93 if ((tti/10)%100 == 0) {
94 _rest._pdsch.total = 0;
95 _rest._pdsch.errors = 0;
101 if (srsran_ue_dl_decode_fft_estimate(&_ue_dl, &_sf_cfg, &_ue_dl_cfg) < 0) {
102 _rest._pdsch.errors++;
103 spdlog::error(
"Getting PDCCH FFT estimate\n");
109 _phy.set_cfo_from_channel_estimation(_ue_dl.chest_res.cfo);
112 srsran_dci_dl_t dci[SRSRAN_MAX_CARRIERS] = {};
113 int nof_grants = srsran_ue_dl_find_dl_dci(&_ue_dl, &_sf_cfg, &_ue_dl_cfg, _cell.mbms_dedicated ? SRSRAN_SIRNTI_MBMS_DEDICATED : SRSRAN_SIRNTI, dci);
114 for (
int k = 0; k < nof_grants; k++) {
116 srsran_dci_dl_info(&dci[k], str, 512);
117 _rest._pdsch.mcs = dci[k].tb[0].mcs_idx;
118 spdlog::debug(
"Decoded PDCCH: {}, snr={} dB\n", str, _ue_dl.chest_res.snr_db);
120 if (srsran_ue_dl_dci_to_pdsch_grant(&_ue_dl, &_sf_cfg, &_ue_dl_cfg, &dci[k], &_ue_dl_cfg.cfg.pdsch.grant)) {
121 spdlog::error(
"Converting DCI message to DL dci\n");
127 _ue_dl_cfg.cfg.pdsch.rnti = dci[k].rnti;
128 srsran_pdsch_cfg_t* pdsch_cfg = &_ue_dl_cfg.cfg.pdsch;
130 srsran_pdsch_res_t pdsch_res[SRSRAN_MAX_CODEWORDS] = {};
131 for (
int i = 0; i < SRSRAN_MAX_CODEWORDS; i++) {
132 if (pdsch_cfg->grant.tb[i].enabled) {
133 if (pdsch_cfg->grant.tb[i].rv < 0) {
134 uint32_t sfn = tti / 10;
135 uint32_t k = (sfn / 2) % 4;
136 pdsch_cfg->grant.tb[i].rv = ((int32_t)ceilf(
static_cast<float>(1.5) * k)) % 4;
138 pdsch_res[i].payload = _data[i];
139 pdsch_res[i].crc =
false;
140 srsran_softbuffer_rx_reset_tbs(pdsch_cfg->softbuffers.rx[i], (uint32_t)pdsch_cfg->grant.tb[i].tbs);
144 _rest._pdsch.SetData(pdsch_data());
147 auto ret = srsran_ue_dl_decode_pdsch(&_ue_dl, &_sf_cfg, &_ue_dl_cfg.cfg.pdsch, pdsch_res);
149 spdlog::error(
"Error decoding PDSCH\n");
150 _rest._pdsch.errors++;
152 spdlog::debug(
"Decoded PDSCH");
153 for (
int i = 0; i < SRSRAN_MAX_CODEWORDS; i++) {
155 if (pdsch_cfg->grant.tb[i].enabled && pdsch_res[i].crc) {
156 _rlc.write_pdu_bcch_dlsch(_data[i], (uint32_t)pdsch_cfg->grant.tb[i].tbs);
166 auto sz = (uint32_t)srsran_symbol_sz(_cell.nof_prb);
167 std::vector<float> ce_abs;
168 ce_abs.resize(sz, 0);
169 uint32_t g = (sz - 12 * _cell.nof_prb) / 2;
170 srsran_vec_abs_dB_cf(_ue_dl.chest_res.ce[0][0], -80, &ce_abs[g], SRSRAN_NRE * _cell.nof_prb);
171 const uint8_t* data =
reinterpret_cast<uint8_t*
>(ce_abs.data());
172 return std::vector<uint8_t>( data, data + sz *
sizeof(
float));
176 const uint8_t* data =
reinterpret_cast<uint8_t*
>(_ue_dl.pdsch.d[0]);
177 return std::vector<uint8_t>( data, data + _ue_dl_cfg.cfg.pdsch.grant.nof_re *
sizeof(cf_t));
constexpr unsigned int MAX_PRB
srsran_softbuffer_rx_t _softbuffer
std::vector< uint8_t > ce_values()
Get the CE values (time domain) for displaying the spectrum of the received signal.
uint8_t * _data[SRSRAN_MAX_CODEWORDS]
virtual ~CasFrameProcessor()
Default destructor.
bool init()
Initialize signal- and softbuffers, init all underlying components.
void set_cell(srsran_cell_t cell)
Set the parameters for the cell (Nof PRB, etc).
std::vector< uint8_t > pdsch_data()
Get the constellation diagram data (I/Q data of the subcarriers after CE)
bool process(uint32_t tti)
Process the sample data in the signal buffer.