17 #include <uhd/utils/thread.hpp> 18 #include <uhd/utils/safe_main.hpp> 19 #include <uhd/usrp/multi_usrp.hpp> 20 #include <uhd/exception.hpp> 21 #include <uhd/types/tune_request.hpp> 22 #include <boost/program_options.hpp> 23 #include <boost/format.hpp> 24 #include <boost/thread.hpp> 28 #include <libconfig.h++> 29 #include <boost/log/core.hpp> 30 #include <boost/log/trivial.hpp> 31 #include <boost/log/expressions.hpp> 32 #include <boost/log/utility/setup/file.hpp> 33 #include <boost/log/utility/setup/common_attributes.hpp> 36 #include "../lib/variables/common_variables/common_variables.h" 38 #include "../lib/phy/libphy/libphy.h" 39 #include "../lib/asn1c/nr_rrc/SIB1.h" 40 #include "../lib/variables/common_variables/common_variables.h" 57 void scan_bands(vector<free5GRAN::band> BANDS,
double ssb_period,
const string &rf_address,
int input_gain);
61 int main(
int argc,
char *argv[]) {
68 libconfig::Config cfg;
72 cfg.readFile(argv[1]);
73 cout <<
"Using configuration file $PWD/" << argv[1] << endl;
75 catch(
const libconfig::FileIOException &fioex)
79 string path =
"/root/.config/free5GRAN/config/free5GRAN.cfg";
80 cfg.readFile(path.c_str());
81 cout <<
"Using configuration file " << path << endl;
83 catch(
const libconfig::FileIOException &fioex)
85 cerr <<
"Please provide a config file!" << endl;
89 catch(
const libconfig::ParseException &pex)
91 cerr <<
"Parse error at " << pex.getFile() <<
":" << pex.getLine()
92 <<
" - " << pex.getError() << endl;
99 if (!cfg.lookupValue(
"logging", level)){
103 BOOST_LOG_TRIVIAL(info) <<
"Initializing free5GRAN";
104 string func = cfg.lookup(
"function");
105 string rf_address = cfg.lookup(
"rf_address");
106 int gain = cfg.lookup(
"gain");
107 const libconfig::Setting& root = cfg.getRoot();
108 if (func ==
"CELL_SEARCH"){
109 cout <<
"## CELL SEARCH ##" << endl;
110 BOOST_LOG_TRIVIAL(info) <<
"CELL SEARCH";
111 const libconfig::Setting& cell_info = root[
"cell_info"];
115 if (!root.lookupValue(
"ssb_period", ssb_period)){
118 }
if (cell_info.lookupValue(
"band", band) ){
119 bool found_band =
false;
124 BOOST_LOG_TRIVIAL(trace) <<
"Band n" + to_string(band);
131 if (cell_info.lookupValue(
"ssb_frequency", frequency) || cell_info.lookupValue(
"gscn", gscn)){
132 if (!cell_info.lookupValue(
"ssb_frequency", frequency)){
138 cerr <<
"Missing parameters (frequency or GSCN) in config file" << endl;
141 cout <<
"BAND not supported" << endl;
145 cerr <<
"Missing parameters (band) in config file" << endl;
147 }
else if (func ==
"BAND_SCAN"){
148 BOOST_LOG_TRIVIAL(info) <<
"BAND SCANNING";
149 cout <<
"## BAND SCAN ##" << endl;
150 const libconfig::Setting& bands = root[
"bands"];
151 int count = bands.getLength();
152 vector<free5GRAN::band> band_array;
153 BOOST_LOG_TRIVIAL(trace) <<
"Adding bands to scan: ";
154 for (
int i = 0; i < count; i ++){
155 int band_id = bands[i];
159 BOOST_LOG_TRIVIAL(trace) <<
"Band n" + to_string(band_id);
165 if (!root.lookupValue(
"ssb_period", ssb_period)){
169 scan_bands(band_array, ssb_period, rf_address, gain);
172 catch(
const libconfig::SettingNotFoundException &nfex)
174 cerr <<
"Missing function, RF device address of gain in config file" << endl;
181 void scan_bands(vector<free5GRAN::band> BANDS,
double ssb_period,
const string &rf_address,
int input_gain){
185 string device_args(
"serial="+rf_address);
186 string subdev(
"A:A");
188 string ref(
"internal");
194 double gain(input_gain);
201 rf rf_device(rate, freq, gain, bw, subdev, ant, ref, device_args);
202 vector<found_cell> found_cells;
204 auto start = chrono::high_resolution_clock::now();
205 float received_power;
209 for (
int i = 0; i < BANDS.size() ; i ++){
210 current_band = BANDS[i];
211 BOOST_LOG_TRIVIAL(info) <<
"###########################################";
212 BOOST_LOG_TRIVIAL(info) <<
"Scanning band n"+ to_string(current_band.
number);
216 for (
int gscn = current_band.
min_gscn; gscn <= current_band.
max_gscn; gscn ++){
221 BOOST_LOG_TRIVIAL(info) <<
"Scanning gscn= "+ to_string(gscn) +
" and freq= " + to_string(freq/1e6) +
" MHz";
229 BOOST_LOG_TRIVIAL(trace) <<
"Bandwidth informations are: ";
230 BOOST_LOG_TRIVIAL(trace) <<
"SCS: " + to_string(band_info.
scs);
232 int fft_size_pss = 128;
236 phy phy_layer(&rf_device, ssb_period, fft_size_pss, band_info.
scs, current_band);
239 cout <<
"\r## Searching in band n" + to_string(current_band.
number) +
" - " + to_string((((
float) gscn - (
float) current_band.
min_gscn)/((
float) current_band.
max_gscn - (
float) current_band.
min_gscn)) * 100.0) +
"% (found " + to_string(found_cells.size()) +
" cells)";
248 BOOST_LOG_TRIVIAL(trace) <<
"Received power: " + to_string(received_power) +
" dB (Gain= "+ to_string(rf_device.
getGain()) +
" dB)";
249 while (received_power > -2 && rf_device.
getGain() > 0){
252 BOOST_LOG_TRIVIAL(trace) <<
"Received power: " + to_string(received_power) +
" dB (Gain= "+ to_string(rf_device.
getGain()) +
" dB)";
254 BOOST_LOG_TRIVIAL(trace) <<
"Final received power: " + to_string(received_power) +
" dB (Final gain= "+ to_string(rf_device.
getGain()) +
" dB)";
260 new_fft_size = (int) (30.72e6/band_info.
scs);
272 new_cell.
scs = current_band.
scs;
273 new_cell.
gscn = gscn;
277 found_cells.push_back(new_cell);
282 for (
int i = 0; i < found_cells.size(); i ++){
284 cout <<
"#######################################################################" << endl;
285 cout <<
"########################## CELL " + to_string(i) +
" ##########################" << endl;
286 cout <<
"#######################################################################" << endl;
288 cout <<
"# Gain: " + to_string(found_cells[i].gain) +
" dB"<< endl;
289 found_cells[i].phy_obj.print_cell_info();
290 if (found_cells[i].dci_found || found_cells[i].phy_obj.getSIB1RV() == 1 || found_cells[i].phy_obj.getSIB1RV() == 2){
291 found_cells[i].phy_obj.print_dci_info();
293 found_cells[i].phy_obj.print_sib1();
294 }
catch (
const std::exception& e) { cout <<
"NO SIB1" << endl; }
296 cout <<
"###### DCI" << endl;
297 cout <<
"# DCI not found, not CRC validated, or unsupported RV";
300 cout <<
"#######################################################################" << endl;
303 auto stop = chrono::high_resolution_clock::now();
304 auto duration = chrono::duration_cast<chrono::microseconds>(stop - start);
305 cout <<
"Executed in "+ to_string(duration.count()/1e6) +
" seconds" << endl;
314 string device_args(
"serial="+rf_address);
315 string subdev(
"A:A");
317 string ref(
"internal");
321 double gain(input_gain);
323 if (frequency < 3000e6){
328 BOOST_LOG_TRIVIAL(trace) <<
"Bandwidth informations are: ";
329 BOOST_LOG_TRIVIAL(trace) <<
"SCS: " + to_string(band_info.
scs);
333 int fft_size_pss = 128;
334 rf rf_device(fft_size_pss * band_info.
scs, frequency, gain, fft_size_pss * band_info.
scs, subdev, ant, ref, device_args);
338 phy phy_layer(&rf_device, ssb_period, fft_size_pss, band_info.
scs, band);
342 cout <<
"########################## Searching cell ##########################" << endl;
344 cout <<
"###### RADIO" << endl;
345 cout <<
"# Frequency: " + to_string(frequency/1e6) +
" MHz" << endl;
346 cout <<
"# SCS: " + to_string(band_info.
scs/1e3) +
" kHz" << endl;
349 BOOST_LOG_TRIVIAL(info) <<
"Searching cell with frequency = " + to_string(frequency/1e6) +
" MHz and SCS = " + to_string(band_info.
scs/1e3) +
" kHz";
351 float received_power;
356 cout <<
"###### Power ramping" << endl;
357 cout <<
"Received power: "+ to_string(received_power) +
" dB" << endl;
358 BOOST_LOG_TRIVIAL(trace) <<
"Received power: " + to_string(received_power) +
" dB (Gain= "+ to_string(rf_device.
getGain()) +
" dB)";
360 while (received_power > -2 && rf_device.
getGain() > 0){
363 cout <<
"New gain: "+ to_string(rf_device.
getGain()) +
" dB" << endl;
364 cout <<
"Received power: "+ to_string(received_power) +
" dB" << endl;
365 BOOST_LOG_TRIVIAL(trace) <<
"Received power: " + to_string(received_power) +
" dB (Gain= "+ to_string(rf_device.
getGain()) +
" dB)";
368 BOOST_LOG_TRIVIAL(trace) <<
"Final received power: " + to_string(received_power) +
" dB (Final gain= "+ to_string(rf_device.
getGain()) +
" dB)";
371 new_fft_size = (int) (30.72e6/band_info.
scs);
383 cout <<
"####################################################################" << endl;
385 cout <<
"########################## Cell not confirmed ##########################" << endl;
386 cout <<
"####################################################################" << endl;
389 cout <<
"########################## Cell not found ##########################" << endl;
390 cout <<
"####################################################################" << endl;
392 cout <<
"####################################################################" << endl;
398 boost::log::register_simple_formatter_factory<boost::log::trivial::severity_level, char>(
"Severity");
400 boost::log::add_file_log
402 boost::log::keywords::file_name =
"/var/log/free5GRAN/free5GRAN.log",
403 boost::log::keywords::format =
"[%TimeStamp%] [%ThreadID%] [%Severity%] %Message%" 406 if (level ==
"trace"){
407 boost::log::core::get()->set_filter
409 boost::log::trivial::severity >= boost::log::trivial::trace
411 }
else if (level ==
"debug"){
412 boost::log::core::get()->set_filter
414 boost::log::trivial::severity >= boost::log::trivial::debug
416 }
else if (level ==
"info"){
417 boost::log::core::get()->set_filter
419 boost::log::trivial::severity >= boost::log::trivial::info
421 }
else if (level ==
"warning"){
422 boost::log::core::get()->set_filter
424 boost::log::trivial::severity >= boost::log::trivial::warning
426 }
else if (level ==
"error"){
427 boost::log::core::get()->set_filter
429 boost::log::trivial::severity >= boost::log::trivial::error
432 boost::log::core::get()->set_filter
434 boost::log::trivial::severity >= boost::log::trivial::fatal
438 boost::log::add_common_attributes();
void setSampleRate(double rate)
struct free5GRAN::band_ band
void search_pdcch(bool &validated)
void scan_bands(vector< free5GRAN::band > BANDS, double ssb_period, const string &rf_address, int input_gain)
void setCenterFrequency(double freq)
void search_cell_with_defined_params(double frequency, double ssb_period, const string &rf_address, free5GRAN::band band, int input_gain)
void init_logging(const string &level)
bandwidth_info BANDWIDTH_15_KHZ
double compute_freq_from_gscn(int gscn)
int main(int argc, char *argv[])
struct found_cell_ found_cell
bandwidth_info BANDWIDTH_30_KHZ
int cell_synchronization(float &received_power)
void reconfigure(int fft_size)
void setGain(double gain)
free5GRAN::band AVAILABLE_BANDS[7]