26 #include "spdlog/spdlog.h"
28 using web::json::value;
29 using web::http::methods;
31 using web::http::http_request;
32 using web::http::status_codes;
33 using web::http::experimental::listener::http_listener;
34 using web::http::experimental::listener::http_listener_config;
45 http_listener_config server_config;
46 if (url.rfind(
"https", 0) == 0) {
47 server_config.set_ssl_context_callback(
48 [&](boost::asio::ssl::context& ctx) {
49 std::string cert_file =
"/usr/share/5gmag-rt/cert.pem";
50 cfg.lookupValue(
"modem.restful_api.cert", cert_file);
52 std::string key_file =
"/usr/share/5gmag-rt/key.pem";
53 cfg.lookupValue(
"modem.restful_api.key", key_file);
55 ctx.set_options(boost::asio::ssl::context::default_workarounds);
56 ctx.use_certificate_chain_file(cert_file);
57 ctx.use_private_key_file(key_file, boost::asio::ssl::context::pem);
63 _api_key =
"106cd60-76c8-4c37-944c-df21aa690c1e";
64 cfg.lookupValue(
"modem.restful_api.api_key.key",
_api_key);
67 _listener = std::make_unique<http_listener>(
79 spdlog::debug(
"Received GET request {}", message.to_string() );
80 auto paths = uri::split_path(uri::decode(message.relative_uri().path()));
82 (message.headers()[
"Authorization"] !=
"Bearer " +
_api_key)) {
83 message.reply(status_codes::Unauthorized);
88 message.reply(status_codes::NotFound);
90 if (paths[0] ==
"status") {
91 auto state = value::object();
95 state[
"state"] = value::string(
"searching");
98 state[
"state"] = value::string(
"syncing");
101 state[
"state"] = value::string(
"synchronized");
106 state[
"nof_prb"] = value(
_phy.
cell().nof_prb);
108 state[
"nof_prb"] = value(
_phy.
cell().mbsfn_prb);
110 state[
"cell_id"] = value(
_phy.
cell().id);
111 state[
"cfo"] = value(
_phy.
cfo());
112 state[
"cinr_db"] = value(
cinr_db());
140 message.reply(status_codes::OK, state);
141 }
else if (paths[0] ==
"sdr_params") {
142 value sdr = value::object();
151 message.reply(status_codes::OK, sdr);
152 }
else if (paths[0] ==
"ce_values") {
153 auto cestream = Concurrency::streams::bytestream::open_istream(
_ce_values);
154 message.reply(status_codes::OK, cestream);
155 }
else if (paths[0] ==
"cir_values") {
156 auto cestream = Concurrency::streams::bytestream::open_istream(
_cir_values);
157 message.reply(status_codes::OK, cestream);
158 }
else if (paths[0] ==
"cir_values_mbsfn") {
159 auto cestream = Concurrency::streams::bytestream::open_istream(
_cir_values_mbsfn);
160 message.reply(status_codes::OK, cestream);
161 }
else if (paths[0] ==
"corr_values") {
162 auto cestream = Concurrency::streams::bytestream::open_istream(
_corr_values);
163 message.reply(status_codes::OK, cestream);
164 }
else if (paths[0] ==
"corr_values_mbsfn") {
166 message.reply(status_codes::OK, cestream);
167 }
else if (paths[0] ==
"pdsch_status") {
168 value sdr = value::object();
174 message.reply(status_codes::OK, sdr);
175 }
else if (paths[0] ==
"pdsch_data") {
176 auto cestream = Concurrency::streams::bytestream::open_istream(
_pdsch.
GetData());
177 message.reply(status_codes::OK, cestream);
178 }
else if (paths[0] ==
"mcch_status") {
179 value sdr = value::object();
180 sdr[
"bler"] = value(
static_cast<float>(
_mcch.
errors) /
185 message.reply(status_codes::OK, sdr);
186 }
else if (paths[0] ==
"mcch_data") {
187 auto cestream = Concurrency::streams::bytestream::open_istream(
_mcch.
GetData());
188 message.reply(status_codes::OK, cestream);
189 }
else if (paths[0] ==
"mch_info") {
190 std::vector<value> mi;
192 std::for_each(std::begin(mch_info), std::end(mch_info), [&mi](
Phy::mch_info_t const& mch) {
194 m[
"mcs"] = value(mch.
mcs);
195 std::vector<value> mti;
198 mt[
"tmgi"] = value(mtch.tmgi);
199 mt[
"dest"] = value(mtch.dest);
200 mt[
"lcid"] = value(mtch.lcid);
203 m[
"mtchs"] = value::array(mti);
206 message.reply(status_codes::OK, value::array(mi));
207 }
else if (paths[0] ==
"mch_status") {
208 int idx = std::stoi(paths[1]);
209 value sdr = value::object();
210 sdr[
"bler"] = value(
static_cast<float>(
_mch[idx].errors) /
211 static_cast<float>(
_mch[idx].total));
212 sdr[
"ber"] = value(
_mch[idx].ber);
213 sdr[
"mcs"] = value(
_mch[idx].mcs);
214 sdr[
"present"] = value(
_mch[idx].present);
215 message.reply(status_codes::OK, sdr);
216 }
else if (paths[0] ==
"mch_data") {
217 int idx = std::stoi(paths[1]);
218 auto cestream = Concurrency::streams::bytestream::open_istream(
_mch[idx].GetData());
219 message.reply(status_codes::OK, cestream);
220 }
else if (paths[0] ==
"log") {
221 std::string logfile =
"/var/log/syslog";
223 Concurrency::streams::file_stream<uint8_t>::open_istream(logfile).then(
224 [message](
const Concurrency::streams::basic_istream<unsigned char>&
226 message.reply(status_codes::OK, file_stream,
"text/plain");
233 spdlog::debug(
"Received PUT request {}", message.to_string() );
236 (message.headers()[
"Authorization"] !=
"Bearer " +
_api_key)) {
237 message.reply(status_codes::Unauthorized);
241 auto paths = uri::split_path(uri::decode(message.relative_uri().path()));
243 message.reply(status_codes::NotFound);
245 if (paths[0] ==
"sdr_params") {
254 const auto & jval = message.extract_json().get();
255 spdlog::debug(
"Received JSON: {}", jval.serialize());
257 if (jval.has_field(
"antenna")) {
258 a = jval.at(
"antenna").as_string();
260 if (jval.has_field(
"frequency")) {
261 f = jval.at(
"frequency").as_integer();
263 if (jval.has_field(
"gain")) {
264 g = jval.at(
"gain").as_double();
268 message.reply(status_codes::OK, answer);
269 }
else if (paths[0] ==
"chest_cfg_params") {
272 const auto & jval = message.extract_json().get();
273 spdlog::debug(
"Recieved JSON: {}", jval.serialize());
275 if (jval.has_field(
"noise_alg")) {
276 auto alg = jval.at(
"noise_alg").as_string();
277 spdlog::info(
"New alg est {}", alg);
280 if (jval.has_field(
"sync_error")) {
281 spdlog::info(
"New sync error value");
283 bool alg = jval.at(
"sync_error").as_bool();
285 spdlog::info(
"{}", alg);
288 if (jval.has_field(
"estimator_alg")) {
289 auto alg = jval.at(
"estimator_alg").as_string();
290 spdlog::info(
"New alg est {}", alg);
293 if (jval.has_field(
"filter_type")) {
294 auto type = jval.at(
"filter_type").as_string();
295 spdlog::info(
"New filter type {}", type);
298 if (jval.has_field(
"filter_order")) {
299 spdlog::info(
"New filter order");
300 auto order = jval.at(
"filter_order").as_integer();
303 if (jval.has_field(
"filter_coef")) {
304 spdlog::info(
"New filter coef");
305 auto coef = jval.at(
"filter_coef").as_double();
310 if (jval.has_field(
"cfo_est_pss_find")) {
311 spdlog::info(
"New cfo est pss find");
312 auto toggle = jval.at(
"cfo_est_pss_find").as_bool();
315 if (jval.has_field(
"cfo_est_pss_track")) {
316 spdlog::info(
"New cfo est pss track");
317 auto toggle = jval.at(
"cfo_est_pss_track").as_bool();
320 if (jval.has_field(
"cfo_correct_find")) {
321 spdlog::info(
"New cfo correct find");
322 auto toggle = jval.at(
"cfo_correct_find").as_bool();
325 if (jval.has_field(
"cfo_correct_track")) {
326 spdlog::info(
"New cfo correct track");
327 auto toggle = jval.at(
"cfo_correct_track").as_bool();
330 if (jval.has_field(
"cfo_pss_loop_bw")) {
331 spdlog::info(
"New BW pss CFO loop");
332 auto bw = jval.at(
"cfo_pss_loop_bw").as_double();
335 if (jval.has_field(
"cfo_ema_alpha_find")) {
336 spdlog::info(
"New CFO ema alpha for find");
337 auto ema = jval.at(
"cfo_ema_alpha_find").as_double();
340 if (jval.has_field(
"cfo_ema_alpha_track")) {
341 spdlog::info(
"New CFO ema alpha for track");
342 auto ema = jval.at(
"cfo_ema_alpha_track").as_double();
345 if (jval.has_field(
"pss_ema_find")) {
346 spdlog::info(
"New PSS corr ema alpha for find");
347 auto ema = jval.at(
"pss_ema_find").as_double();
350 if (jval.has_field(
"pss_ema_track")) {
351 spdlog::info(
"New PSS corr ema alpha for track");
352 auto ema = jval.at(
"pss_ema_track").as_double();
355 if (jval.has_field(
"threshold_find")) {
356 spdlog::info(
"New threshold for find");
357 auto ema = jval.at(
"threshold_find").as_double();
360 if (jval.has_field(
"threshold_track")) {
361 spdlog::info(
"New threshold for track");
362 auto ema = jval.at(
"threshold_track").as_double();
366 message.reply(status_codes::OK, answer);
uint8_t get_filter_order()
void set_noise_alg(srsran_chest_dl_noise_alg_t noise_alg)
Set the noise estimation algorithm used in the channel estimation stage.
void set_sync_error(bool enable)
Enables the estimation os synchronization error.
uint8_t get_estimator_alg()
void set_estimator_alg(srsran_chest_dl_estimator_alg_t estimator_alg)
Set the method to estimate the channel estimates of the complete resource grid from the reference sym...
void set_filter_coef(float filter_coef)
Set the coef for gauss filtering.
void set_filter_order(uint8_t filter_order)
Set the filter order used to filter the channel estimates.
void set_filter_type(srsran_chest_filter_t filter_type)
Set the filter type for chest.
uint8_t get_filter_type()
float get_ue_sync_threshold_track()
bool get_ue_sync_track_cfo_pss_enable()
void set_ue_sync_track_cfo_ema(float ema)
Sets the ema alpha value used for the tracking of the CFO in the trackin sync object,...
const std::vector< mch_info_t > & mch_info()
void set_ue_sync_threshold_track(float threshold)
Sets the threshold of the peak found while tracking for synchronization.
bool get_ue_sync_find_cfo_pss_enable()
float get_ue_sync_pss_cfo_ema_find()
float get_ue_sync_track_cfo_ema()
void set_ue_sync_find_cfo_ema(float ema)
Sets the ema alpha value used for the tracking of the CFO in the trackin sync object,...
srsran_cell_t cell()
Get the current cell (with params adjusted for MBSFN)
void set_ue_sync_track_cfo_pss_enable(bool enable)
Enables or disables the CFO estimation from the PSS in the tracking stage.
void set_ue_sync_pss_cfo_ema_find(float ema)
Sets the weight factor alpha for the exponential moving average of the PSS correlation output
float get_ue_sync_find_cfo_ema()
void set_ue_sync_pss_cfo_ema_track(float ema)
Sets the weight factor alpha for the exponential moving average of the PSS correlation output
void set_ue_sync_track_cfo_correct_enable(bool enable)
Enables the CFO correction while tracking the synchronization from previous estimations.
float get_ue_sync_cfo_loop_bw_pss()
float mbsfn_subcarrier_spacing_khz()
bool get_ue_sync_find_cfo_correct_enable()
void set_ue_sync_find_cfo_pss_enable(bool enable)
Enables or disables the CFO estimation from the PSS in the finding stage.
void set_ue_sync_find_cfo_correct_enable(bool enable)
Enables the CFO correction while finding the synchronization from previous estimations.
float get_ue_sync_pss_cfo_ema_track()
bool get_ue_sync_track_cfo_correct_enable()
void set_ue_sync_cfo_loop_bw_pss(float bw)
Set the factor for the PSS loopback.
float cfo()
Get the current CFO value.
void set_ue_sync_threshold_find(float threshold)
Sets the threshold of the peak found while searching for synchronization.
float get_ue_sync_threshold_find()
std::vector< uint8_t > GetData()
CasFrameProcessor * _cas_processor
std::vector< uint8_t > _cir_values
Time domain channel impulse response of the CAS.
std::unique_ptr< web::http::experimental::listener::http_listener > _listener
float cinr_db()
Current instantaneous CINR value.
float cinr_db_avg()
Current average CINR value.
std::vector< uint8_t > _ce_values
Time domain subcarrier CE values.
void put(web::http::http_request message)
std::vector< uint8_t > _corr_values
Correlaton samples from the sync functions.
ChannelInfo _mcch
RX info for MCCH.
std::vector< float > _cinr_db
void add_cinr_value(float cinr)
std::map< uint32_t, ChannelInfo > _mch
RX info for MCHs.
std::function< void(const std::string &antenna, unsigned fcen, double gain, unsigned sample_rate, unsigned bandwidth)> set_params_t
Definition of the callback for setting new reception parameters.
RestHandler(const libconfig::Config &cfg, const std::string &url, state_t &state, SdrReader &sdr, Phy &phy, set_params_t set_params)
Default constructor.
void get(web::http::http_request message)
ChannelInfo _pdsch
RX info for PDSCH.
virtual ~RestHandler()
Default destructor.
std::vector< uint8_t > _corr_values_mbsfn
Correlaton samples from the sync functions.
bool _require_bearer_token
std::vector< uint8_t > _cir_values_mbsfn
Time domain channel impulse response of the mbsfn subframes.
Interface to the SDR stick.
double get_frequency()
Get current center frequency.
double get_buffer_level()
Get current ringbuffer level (0 = empty .
unsigned get_filter_bw()
Get current filter bandwidth.
std::string get_antenna()
Get current antenna port.
double get_gain()
Get current gain.
double get_sample_rate()
Get current sample rate.
static Config cfg
Global configuration object.
void set_params(const std::string &ant, unsigned fc, double g, unsigned sr, unsigned bw)
Set new SDR parameters and initialize resynchronisation.
std::vector< mtch_info_t > mtchs