25 #include "spdlog/spdlog.h"
27 using web::json::value;
28 using web::http::methods;
30 using web::http::http_request;
31 using web::http::status_codes;
32 using web::http::experimental::listener::http_listener;
33 using web::http::experimental::listener::http_listener_config;
44 http_listener_config server_config;
45 if (url.rfind(
"https", 0) == 0) {
46 server_config.set_ssl_context_callback(
47 [&](boost::asio::ssl::context& ctx) {
48 std::string cert_file =
"/usr/share/5gmag-rt/cert.pem";
49 cfg.lookupValue(
"modem.restful_api.cert", cert_file);
51 std::string key_file =
"/usr/share/5gmag-rt/key.pem";
52 cfg.lookupValue(
"modem.restful_api.key", key_file);
54 ctx.set_options(boost::asio::ssl::context::default_workarounds);
55 ctx.use_certificate_chain_file(cert_file);
56 ctx.use_private_key_file(key_file, boost::asio::ssl::context::pem);
62 _api_key =
"106cd60-76c8-4c37-944c-df21aa690c1e";
63 cfg.lookupValue(
"modem.restful_api.api_key.key",
_api_key);
66 _listener = std::make_unique<http_listener>(
78 spdlog::debug(
"Received GET request {}", message.to_string() );
79 auto paths = uri::split_path(uri::decode(message.relative_uri().path()));
81 (message.headers()[
"Authorization"] !=
"Bearer " +
_api_key)) {
82 message.reply(status_codes::Unauthorized);
87 message.reply(status_codes::NotFound);
89 if (paths[0] ==
"status") {
90 auto state = value::object();
94 state[
"state"] = value::string(
"searching");
97 state[
"state"] = value::string(
"syncing");
100 state[
"state"] = value::string(
"synchronized");
105 state[
"nof_prb"] = value(
_phy.
cell().nof_prb);
107 state[
"nof_prb"] = value(
_phy.
cell().mbsfn_prb);
109 state[
"cell_id"] = value(
_phy.
cell().id);
110 state[
"cfo"] = value(
_phy.
cfo());
111 state[
"cinr_db"] = value(
cinr_db());
113 message.reply(status_codes::OK, state);
114 }
else if (paths[0] ==
"sdr_params") {
115 value sdr = value::object();
124 message.reply(status_codes::OK, sdr);
125 }
else if (paths[0] ==
"ce_values") {
126 auto cestream = Concurrency::streams::bytestream::open_istream(
_ce_values);
127 message.reply(status_codes::OK, cestream);
128 }
else if (paths[0] ==
"pdsch_status") {
129 value sdr = value::object();
135 message.reply(status_codes::OK, sdr);
136 }
else if (paths[0] ==
"pdsch_data") {
137 auto cestream = Concurrency::streams::bytestream::open_istream(
_pdsch.
GetData());
138 message.reply(status_codes::OK, cestream);
139 }
else if (paths[0] ==
"mcch_status") {
140 value sdr = value::object();
141 sdr[
"bler"] = value(
static_cast<float>(
_mcch.
errors) /
146 message.reply(status_codes::OK, sdr);
147 }
else if (paths[0] ==
"mcch_data") {
148 auto cestream = Concurrency::streams::bytestream::open_istream(
_mcch.
GetData());
149 message.reply(status_codes::OK, cestream);
150 }
else if (paths[0] ==
"mch_info") {
151 std::vector<value> mi;
153 std::for_each(std::begin(mch_info), std::end(mch_info), [&mi](
Phy::mch_info_t const& mch) {
155 m[
"mcs"] = value(mch.
mcs);
156 std::vector<value> mti;
159 mt[
"tmgi"] = value(mtch.tmgi);
160 mt[
"dest"] = value(mtch.dest);
161 mt[
"lcid"] = value(mtch.lcid);
164 m[
"mtchs"] = value::array(mti);
167 message.reply(status_codes::OK, value::array(mi));
168 }
else if (paths[0] ==
"mch_status") {
169 int idx = std::stoi(paths[1]);
170 value sdr = value::object();
171 sdr[
"bler"] = value(
static_cast<float>(
_mch[idx].errors) /
172 static_cast<float>(
_mch[idx].total));
173 sdr[
"ber"] = value(
_mch[idx].ber);
174 sdr[
"mcs"] = value(
_mch[idx].mcs);
175 sdr[
"present"] = value(
_mch[idx].present);
176 message.reply(status_codes::OK, sdr);
177 }
else if (paths[0] ==
"mch_data") {
178 int idx = std::stoi(paths[1]);
179 auto cestream = Concurrency::streams::bytestream::open_istream(
_mch[idx].GetData());
180 message.reply(status_codes::OK, cestream);
181 }
else if (paths[0] ==
"log") {
182 std::string logfile =
"/var/log/syslog";
184 Concurrency::streams::file_stream<uint8_t>::open_istream(logfile).then(
185 [message](
const Concurrency::streams::basic_istream<unsigned char>&
187 message.reply(status_codes::OK, file_stream,
"text/plain");
194 spdlog::debug(
"Received PUT request {}", message.to_string() );
197 (message.headers()[
"Authorization"] !=
"Bearer " +
_api_key)) {
198 message.reply(status_codes::Unauthorized);
202 auto paths = uri::split_path(uri::decode(message.relative_uri().path()));
204 message.reply(status_codes::NotFound);
206 if (paths[0] ==
"sdr_params") {
215 const auto & jval = message.extract_json().get();
216 spdlog::debug(
"Received JSON: {}", jval.serialize());
218 if (jval.has_field(
"antenna")) {
219 a = jval.at(
"antenna").as_string();
221 if (jval.has_field(
"frequency")) {
222 f = jval.at(
"frequency").as_integer();
224 if (jval.has_field(
"gain")) {
225 g = jval.at(
"gain").as_double();
229 message.reply(status_codes::OK, answer);
const std::vector< mch_info_t > & mch_info()
srsran_cell_t cell()
Get the current cell (with params adjusted for MBSFN)
float mbsfn_subcarrier_spacing_khz()
float cfo()
Get the current CFO value.
std::vector< uint8_t > GetData()
std::unique_ptr< web::http::experimental::listener::http_listener > _listener
float cinr_db()
Current CINR value.
std::vector< uint8_t > _ce_values
Time domain subcarrier CE values.
void put(web::http::http_request message)
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.
bool _require_bearer_token
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