5G-MAG Reference Tools - MBMS Modem
Public Member Functions | Private Attributes | List of all members
CasFrameProcessor Class Reference

Frame processor for CAS subframes. More...

#include <CasFrameProcessor.h>

Collaboration diagram for CasFrameProcessor:
Collaboration graph

Public Member Functions

 CasFrameProcessor (const libconfig::Config &cfg, Phy &phy, srsran::rlc &rlc, RestHandler &rest, unsigned rx_channels)
 Default constructor. More...
 
virtual ~CasFrameProcessor ()
 Default destructor. More...
 
bool init ()
 Initialize signal- and softbuffers, init all underlying components. More...
 
bool process (uint32_t tti)
 Process the sample data in the signal buffer. More...
 
void set_cell (srsran_cell_t cell)
 Set the parameters for the cell (Nof PRB, etc). More...
 
cf_t ** rx_buffer ()
 Get a handle of the signal buffer to store samples for processing in. More...
 
uint32_t rx_buffer_size ()
 Size of the signal buffer. More...
 
void unlock ()
 Unlock the processor. More...
 
std::vector< uint8_t > ce_values ()
 Get the CE values (time domain) for displaying the spectrum of the received signal. More...
 
std::vector< uint8_t > pdsch_data ()
 Get the constellation diagram data (I/Q data of the subcarriers after CE) More...
 
float cinr_db ()
 Get the CINR estimate (in dB) More...
 

Private Attributes

const libconfig::Config & _cfg
 
srsran::rlc & _rlc
 
Phy_phy
 
RestHandler_rest
 
cf_t * _signal_buffer_rx [SRSRAN_MAX_PORTS] = {}
 
uint32_t _signal_buffer_max_samples = 0
 
srsran_softbuffer_rx_t _softbuffer
 
uint8_t * _data [SRSRAN_MAX_CODEWORDS]
 
srsran_ue_dl_t _ue_dl = {}
 
srsran_ue_dl_cfg_t _ue_dl_cfg = {}
 
srsran_dl_sf_cfg_t _sf_cfg = {}
 
srsran_cell_t _cell
 
std::mutex _mutex
 
unsigned _rx_channels
 

Detailed Description

Frame processor for CAS subframes.

Handles the complete processing chain for a CAS subframe: calls FFT and channel estimation, decodes PCFICH and PDCCH and gets DCI(s), decodes PDSCH and passes received PDUs to RLC.

Definition at line 37 of file CasFrameProcessor.h.

Constructor & Destructor Documentation

◆ CasFrameProcessor()

CasFrameProcessor::CasFrameProcessor ( const libconfig::Config &  cfg,
Phy phy,
srsran::rlc &  rlc,
RestHandler rest,
unsigned  rx_channels 
)
inline

Default constructor.

Parameters
cfgConfig singleton reference
phyPHY reference
rlcRLC reference
restRESTful API handler reference

Definition at line 47 of file CasFrameProcessor.h.

48  : _cfg(cfg)
49  , _phy(phy)
50  , _rest(rest)
51  , _rlc(rlc)
52  , _rx_channels(rx_channels)
53  {}
const libconfig::Config & _cfg
static Config cfg
Global configuration object.
Definition: main.cpp:165

◆ ~CasFrameProcessor()

CasFrameProcessor::~CasFrameProcessor ( )
virtual

Default destructor.

Definition at line 73 of file CasFrameProcessor.cpp.

73  {
74  for (auto & i : _data) {
75  if (i) {
76  free(i);
77  }
78  }
79  srsran_softbuffer_rx_free(&_softbuffer);
80  srsran_ue_dl_free(&_ue_dl);
81 }
srsran_softbuffer_rx_t _softbuffer
uint8_t * _data[SRSRAN_MAX_CODEWORDS]
srsran_ue_dl_t _ue_dl

Member Function Documentation

◆ ce_values()

auto CasFrameProcessor::ce_values ( )

Get the CE values (time domain) for displaying the spectrum of the received signal.

Definition at line 165 of file CasFrameProcessor.cpp.

165  {
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));
173 }

◆ cinr_db()

float CasFrameProcessor::cinr_db ( )
inline

Get the CINR estimate (in dB)

Definition at line 112 of file CasFrameProcessor.h.

112 { return _ue_dl.chest_res.snr_db; }

◆ init()

auto CasFrameProcessor::init ( )

Initialize signal- and softbuffers, init all underlying components.

Must be called once before the first call to process().

Definition at line 24 of file CasFrameProcessor.cpp.

24  {
25  _signal_buffer_max_samples = 3 * SRSRAN_SF_LEN_PRB(MAX_PRB);
26 
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");
31  return false;
32  }
33  }
34 
35  if (srsran_ue_dl_init(&_ue_dl, _signal_buffer_rx, MAX_PRB, _rx_channels)) {
36  spdlog::error("Could not init ue_dl\n");
37  return false;;
38  }
39 
40  srsran_softbuffer_rx_init(&_softbuffer, 100);
41 
42  _ue_dl_cfg.snr_to_cqi_offset = 0;
43 
44  for (auto & i : _data) {
45  i = srsran_vec_u8_malloc(2000 * 8);
46  if (!i) {
47  spdlog::error("Allocating data");
48  return false;
49  }
50  }
51 
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;
63 
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;
69 
70  return true;
71 }
constexpr unsigned int MAX_PRB
Definition: Phy.h:35
srsran_ue_dl_cfg_t _ue_dl_cfg
uint32_t _signal_buffer_max_samples
cf_t * _signal_buffer_rx[SRSRAN_MAX_PORTS]

◆ pdsch_data()

auto CasFrameProcessor::pdsch_data ( )

Get the constellation diagram data (I/Q data of the subcarriers after CE)

Definition at line 175 of file CasFrameProcessor.cpp.

175  {
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));
178 }

◆ process()

auto CasFrameProcessor::process ( uint32_t  tti)

Process the sample data in the signal buffer.

Data must already be present in the buffer obtained through the handle returnd by rx_buffer()

Parameters
ttiTTI of the subframe the data belongs to

Definition at line 89 of file CasFrameProcessor.cpp.

89  {
90  _sf_cfg.tti = tti;
91  _sf_cfg.sf_type = SRSRAN_SF_NORM;
92 
93  if ((tti/10)%100 == 0) {
94  _rest._pdsch.total = 0;
95  _rest._pdsch.errors = 0;
96  }
97 
98  _rest._pdsch.total++;
99 
100  // Run the FFT and do channel estimation
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");
104  _mutex.unlock();
105  return false;
106  }
107 
108  // Feedback the CFO from CE to the Phy
110 
111  // Try to decode DCIs from PDCCH
112  srsran_dci_dl_t dci[SRSRAN_MAX_CARRIERS] = {}; // NOLINT
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++) {
115  char str[512]; // NOLINT
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);
119 
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");
122  _mutex.unlock();
123  return false;
124  }
125 
126  // We can construct a DL grant
127  _ue_dl_cfg.cfg.pdsch.rnti = dci[k].rnti;
128  srsran_pdsch_cfg_t* pdsch_cfg = &_ue_dl_cfg.cfg.pdsch;
129 
130  srsran_pdsch_res_t pdsch_res[SRSRAN_MAX_CODEWORDS] = {}; // NOLINT
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;
137  }
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);
141  }
142  }
143 
145 
146  // Decode PDSCH..
147  auto ret = srsran_ue_dl_decode_pdsch(&_ue_dl, &_sf_cfg, &_ue_dl_cfg.cfg.pdsch, pdsch_res);
148  if (ret) {
149  spdlog::error("Error decoding PDSCH\n");
150  _rest._pdsch.errors++;
151  } else {
152  spdlog::debug("Decoded PDSCH");
153  for (int i = 0; i < SRSRAN_MAX_CODEWORDS; i++) {
154  // .. and pass received PDUs to RLC for further processing
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);
157  }
158  }
159  }
160  }
161  _mutex.unlock();
162  return true;
163 }
srsran_dl_sf_cfg_t _sf_cfg
std::vector< uint8_t > pdsch_data()
Get the constellation diagram data (I/Q data of the subcarriers after CE)
void set_cfo_from_channel_estimation(float cfo)
Set the CFO value from channel estimation.
Definition: Phy.h:113
void SetData(std::vector< uint8_t > data)
Definition: RestHandler.h:72
ChannelInfo _pdsch
RX info for PDSCH.
Definition: RestHandler.h:98

◆ rx_buffer()

cf_t** CasFrameProcessor::rx_buffer ( )
inline

Get a handle of the signal buffer to store samples for processing in.

Definition at line 84 of file CasFrameProcessor.h.

84 { _mutex.lock(); return _signal_buffer_rx; }

◆ rx_buffer_size()

uint32_t CasFrameProcessor::rx_buffer_size ( )
inline

Size of the signal buffer.

Definition at line 89 of file CasFrameProcessor.h.

◆ set_cell()

void CasFrameProcessor::set_cell ( srsran_cell_t  cell)

Set the parameters for the cell (Nof PRB, etc).

Parameters
cellThe cell we're camping on

Definition at line 83 of file CasFrameProcessor.cpp.

83  {
84  _cell = cell;
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);
87 }

◆ unlock()

void CasFrameProcessor::unlock ( )
inline

Unlock the processor.

See also
get_rx_buffer_and_lock()

Definition at line 96 of file CasFrameProcessor.h.

96 { _mutex.unlock(); }

Member Data Documentation

◆ _cell

srsran_cell_t CasFrameProcessor::_cell
private

Definition at line 130 of file CasFrameProcessor.h.

◆ _cfg

const libconfig::Config& CasFrameProcessor::_cfg
private

Definition at line 115 of file CasFrameProcessor.h.

◆ _data

uint8_t* CasFrameProcessor::_data[SRSRAN_MAX_CODEWORDS]
private

Definition at line 124 of file CasFrameProcessor.h.

◆ _mutex

std::mutex CasFrameProcessor::_mutex
private

Definition at line 131 of file CasFrameProcessor.h.

◆ _phy

Phy& CasFrameProcessor::_phy
private

Definition at line 117 of file CasFrameProcessor.h.

◆ _rest

RestHandler& CasFrameProcessor::_rest
private

Definition at line 118 of file CasFrameProcessor.h.

◆ _rlc

srsran::rlc& CasFrameProcessor::_rlc
private

Definition at line 116 of file CasFrameProcessor.h.

◆ _rx_channels

unsigned CasFrameProcessor::_rx_channels
private

Definition at line 132 of file CasFrameProcessor.h.

◆ _sf_cfg

srsran_dl_sf_cfg_t CasFrameProcessor::_sf_cfg = {}
private

Definition at line 128 of file CasFrameProcessor.h.

◆ _signal_buffer_max_samples

uint32_t CasFrameProcessor::_signal_buffer_max_samples = 0
private

Definition at line 121 of file CasFrameProcessor.h.

◆ _signal_buffer_rx

cf_t* CasFrameProcessor::_signal_buffer_rx[SRSRAN_MAX_PORTS] = {}
private

Definition at line 120 of file CasFrameProcessor.h.

◆ _softbuffer

srsran_softbuffer_rx_t CasFrameProcessor::_softbuffer
private

Definition at line 123 of file CasFrameProcessor.h.

◆ _ue_dl

srsran_ue_dl_t CasFrameProcessor::_ue_dl = {}
private

Definition at line 126 of file CasFrameProcessor.h.

◆ _ue_dl_cfg

srsran_ue_dl_cfg_t CasFrameProcessor::_ue_dl_cfg = {}
private

Definition at line 127 of file CasFrameProcessor.h.


The documentation for this class was generated from the following files: