new NAS/RRC structure. Attaching and ping working

This commit is contained in:
Ismael Gomez 2017-06-23 19:15:30 +02:00
parent fa05304632
commit fa9eaee498
13 changed files with 1961 additions and 1925 deletions

View File

@ -30,6 +30,7 @@
#include <ctype.h>
#include <stdint.h>
#include <string>
#include <srslte/asn1/liblte_rrc.h>
namespace srslte {
@ -112,6 +113,12 @@ inline bool mnc_to_string(uint16_t mnc, std::string *str)
*str += (mnc & 0x000F) + '0';
return true;
}
inline std::string plmn_id_to_c_str(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) {
std::string mcc_str, mnc_str;
mnc_to_string(plmn_id.mnc, &mnc_str);
mcc_to_string(plmn_id.mcc, &mcc_str);
return mcc_str + mnc_str;
}
} // namespace srslte

View File

@ -623,7 +623,9 @@ int rf_uhd_recv_with_time_multi(void *h,
log_overflow(handler);
} else if (error_code == UHD_RX_METADATA_ERROR_CODE_LATE_COMMAND) {
log_late(handler);
} else if (error_code != UHD_RX_METADATA_ERROR_CODE_NONE) {
} else if (error_code == UHD_RX_METADATA_ERROR_CODE_TIMEOUT) {
fprintf(stderr, "Error timed out while receiving asynchronoous messages from UHD.\n");
} else if (error_code != UHD_RX_METADATA_ERROR_CODE_NONE ) {
fprintf(stderr, "Error code 0x%x was returned during streaming. Aborting.\n", error_code);
}

View File

@ -47,7 +47,7 @@ bool radio::init(char *args, char *devname)
cur_tx_srate = 0;
is_start_of_burst = true;
// Suppress radio stdout
// Suppress radio stdout
srslte_rf_suppress_stdout(&rf_device);
tx_adv_auto = true;
@ -389,8 +389,6 @@ void radio::set_tx_srate(float srate)
// Calculate TX advance in seconds from samples and sampling rate
tx_adv_sec = nsamples/cur_tx_srate;
printf("Setting TX/RX offset %d samples, %.2f us\n", nsamples, tx_adv_sec*1e6);
}
void radio::start_rx()

View File

@ -74,13 +74,12 @@ private:
void set_ue_sync_opts(srslte_ue_sync_t *q);
void run_thread();
int sync_sfn();
bool running;
srslte::radio_multi *radio_h;
srslte::radio_multi *radio_h;
mac_interface_phy *mac;
rrc_interface_phy *rrc;
rrc_interface_phy *rrc;
srslte::log *log_h;
srslte::thread_pool *workers_pool;
phch_common *worker_com;
@ -91,16 +90,20 @@ private:
uint32_t nof_rx_antennas;
cf_t *sf_buffer_sfn[SRSLTE_MAX_PORTS];
cf_t *sf_buffer[SRSLTE_MAX_PORTS];
// Sync metrics
sync_metrics_t metrics;
enum {
IDLE, CELL_SEARCH, CELL_SELECT, CAMPING
} phy_state;
IDLE, CELL_SEARCH, CELL_MEASURE, CELL_SELECT, CELL_CAMP
} phy_state;
srslte_cell_t cell;
enum {
SRATE_NONE=0, SRATE_FIND, SRATE_CAMP
} srate_mode;
srslte_cell_t cell;
bool cell_is_set;
bool is_sfn_synched;
bool started;
@ -118,10 +121,19 @@ private:
const static uint32_t SYNC_SFN_TIMEOUT = 5000;
float ul_dl_factor;
int cur_earfcn_index;
bool cell_search(int force_N_id_2 = -1);
bool init_cell();
void free_cell();
bool cell_search_in_progress;
uint32_t measure_cnt;
float measure_rsrp;
srslte_ue_dl_t ue_dl_measure;
const static int RSRP_MEASURE_NOF_FRAMES = 20;
int cell_sync_sfn();
int cell_meas_rsrp();
bool cell_search(int force_N_id_2 = -1);
bool init_cell();
void free_cell();
};
} // namespace srsue

View File

@ -61,15 +61,16 @@ namespace srsue {
*******************************************************************************/
typedef struct {
uint32_t dl_earfcn;
float dl_freq;
float ul_freq;
float rx_gain;
float tx_gain;
uint32_t nof_rx_ant;
std::string device_name;
std::string device_args;
std::string time_adv_nsamples;
std::string burst_preamble;
uint32_t nof_rx_ant;
std::string device_name;
std::string device_args;
std::string time_adv_nsamples;
std::string burst_preamble;
}rf_args_t;
typedef struct {
@ -110,16 +111,16 @@ typedef struct {
}gui_args_t;
typedef struct {
phy_args_t phy;
phy_args_t phy;
float metrics_period_secs;
bool pregenerate_signals;
int ue_cateogry;
}expert_args_t;
typedef struct {
rf_args_t rf;
rf_cal_t rf_cal;
rf_cal_t rf_cal;
pcap_args_t pcap;
trace_args_t trace;
log_args_t log;
@ -144,7 +145,7 @@ public:
void stop();
bool is_attached();
void start_plot();
static void rf_msg(srslte_rf_error_t error);
void handle_rf_msg(srslte_rf_error_t error);
@ -152,10 +153,10 @@ public:
bool get_metrics(ue_metrics_t &m);
void pregenerate_signals(bool enable);
// Testing
void test_con_restablishment();
void test_con_restablishment();
private:
static ue *instance;

View File

@ -107,6 +107,9 @@ namespace srsue {
plmn_selection_state_t plmn_selection;
LIBLTE_RRC_PLMN_IDENTITY_STRUCT current_plmn;
LIBLTE_RRC_PLMN_IDENTITY_STRUCT home_plmn;
std::vector<LIBLTE_RRC_PLMN_IDENTITY_STRUCT > known_plmns;
// Save short MAC

View File

@ -61,8 +61,7 @@ namespace srsue {
typedef enum {
SI_ACQUIRE_IDLE = 0,
SI_ACQUIRE_SIB1,
SI_ACQUIRE_SIB2,
SI_ACQUIRE_DONE
SI_ACQUIRE_SIB2
} si_acquire_state_t;

View File

@ -141,7 +141,7 @@ void mac::run_thread() {
while(started) {
while (!phy_h->sync_status()) {
while (!phy_h->sync_status() && started) {
usleep(5000);
if (phy_h->sync_status()) {
Debug("Setting ttysync to %d\n", phy_h->get_current_tti());

View File

@ -61,8 +61,9 @@ void parse_args(all_args_t *args, int argc, char *argv[]) {
// Command line or config file options
bpo::options_description common("Configuration options");
common.add_options()
("rf.dl_freq", bpo::value<float>(&args->rf.dl_freq)->default_value(2680000000), "Downlink centre frequency")
("rf.ul_freq", bpo::value<float>(&args->rf.ul_freq)->default_value(2560000000), "Uplink centre frequency")
("rf.dl_earfcn", bpo::value<uint32_t>(&args->rf.dl_earfcn)->default_value(3400), "Downlink EARFCN")
("rf.dl_freq", bpo::value<float>(&args->rf.dl_freq)->default_value(2680000000), "(optional) Downlink centre frequency")
("rf.ul_freq", bpo::value<float>(&args->rf.ul_freq)->default_value(2560000000), "(optional) Uplink centre frequency")
("rf.rx_gain", bpo::value<float>(&args->rf.rx_gain)->default_value(-1), "Front-end receiver gain")
("rf.tx_gain", bpo::value<float>(&args->rf.tx_gain)->default_value(-1), "Front-end transmitter gain")
("rf.nof_rx_ant", bpo::value<uint32_t>(&args->rf.nof_rx_ant)->default_value(1), "Number of RX antennas")

View File

@ -25,6 +25,7 @@
*/
#include <unistd.h>
#include <srslte/srslte.h>
#include "srslte/srslte.h"
#include "srslte/common/log.h"
#include "phy/phch_worker.h"
@ -62,9 +63,11 @@ namespace srsue {
time_adv_sec = 0;
cell_is_set = false;
sync_sfn_cnt = 0;
srate_mode = SRATE_NONE;
cell_search_in_progress = false;
for (uint32_t i = 0; i < nof_rx_antennas; i++) {
sf_buffer_sfn[i] = (cf_t *) srslte_vec_malloc(sizeof(cf_t) * 3 * SRSLTE_SF_LEN_PRB(100));
sf_buffer[i] = (cf_t *) srslte_vec_malloc(sizeof(cf_t) * 3 * SRSLTE_SF_LEN_PRB(100));
}
nof_tx_mutex = MUTEX_X_WORKER * workers_pool->get_nof_workers();
@ -82,8 +85,8 @@ namespace srsue {
running = false;
wait_thread_finish();
for (uint32_t i = 0; i < nof_rx_antennas; i++) {
if (sf_buffer_sfn[i]) {
free(sf_buffer_sfn[i]);
if (sf_buffer[i]) {
free(sf_buffer[i]);
}
}
}
@ -152,9 +155,14 @@ namespace srsue {
// Set options defined in expert section
set_ue_sync_opts(&ue_sync);
if (srslte_ue_dl_init_multi(&ue_dl_measure, cell, nof_rx_antennas)) {
Error("Setting cell: initiating ue_dl_measure\n");
return false;
}
for (uint32_t i = 0; i < workers_pool->get_nof_workers(); i++) {
if (!((phch_worker *) workers_pool->get_worker(i))->init_cell(cell)) {
Error("Error setting cell: initiating PHCH worker\n");
Error("Setting cell: initiating PHCH worker\n");
return false;
}
}
@ -179,6 +187,10 @@ namespace srsue {
usleep(2000);
}
srslte_ue_sync_free(&ue_sync);
srslte_ue_dl_free(&ue_dl_measure);
if (cell_is_set) {
for (uint32_t i = 0; i < workers_pool->get_nof_workers(); i++) {
((phch_worker *) workers_pool->get_worker(i))->free_cell();
@ -198,7 +210,6 @@ namespace srsue {
bzero(found_cells, 3 * sizeof(srslte_ue_cellsearch_result_t));
log_h->console("Searching for cell...\n");
if (srslte_ue_cellsearch_init_multi(&cs, SRSLTE_DEFAULT_MAX_FRAMES_PSS, radio_recv_wrapper_cs, nof_rx_antennas,
radio_h)) {
Error("Initiating UE cell search\n");
@ -214,7 +225,10 @@ namespace srsue {
srslte_ue_sync_start_agc(&cs.ue_sync, callback_set_rx_gain, last_gain);
}
radio_h->set_rx_srate(1.92e6);
if (srate_mode != SRATE_FIND) {
srate_mode = SRATE_FIND;
radio_h->set_rx_srate(1.92e6);
}
radio_h->start_rx();
/* Find a cell in the given N_id_2 or go through the 3 of them to find the strongest */
@ -246,9 +260,6 @@ namespace srsue {
cell.cp = found_cells[max_peak_cell].cp;
cellsearch_cfo = found_cells[max_peak_cell].cfo;
log_h->console("Found CELL ID: %d CP: %s, CFO: %.1f KHz.\nTrying to decode MIB...\n",
cell.id, srslte_cp_string(cell.cp), cellsearch_cfo / 1000);
srslte_ue_mib_sync_t ue_mib_sync;
if (srslte_ue_mib_sync_init_multi(&ue_mib_sync, cell.id, cell.cp, radio_recv_wrapper_cs, nof_rx_antennas,
@ -281,10 +292,6 @@ namespace srsue {
if (ret == 1) {
srslte_pbch_mib_unpack(bch_payload, &cell, NULL);
worker_com->set_cell(cell);
srslte_cell_fprint(stdout, &cell, 0);
srslte_bit_pack_vector(bch_payload, bch_payload_bits, SRSLTE_BCH_PAYLOAD_LEN);
mac->bch_decoded_ok(bch_payload_bits, SRSLTE_BCH_PAYLOAD_LEN / 8);
return true;
} else {
Warning("Error decoding MIB: Error decoding PBCH\n");
@ -293,13 +300,94 @@ namespace srsue {
}
int phch_recv::sync_sfn(void) {
void phch_recv::resync_sfn() {
sync_sfn_cnt = 0;
phy_state = CELL_SELECT;
}
void phch_recv::set_earfcn(std::vector<uint32_t> earfcn) {
this->earfcn = earfcn;
}
void phch_recv::cell_search_next() {
cell_search_in_progress = true;
cur_earfcn_index++;
if (cur_earfcn_index >= 0) {
if (cur_earfcn_index >= (int) earfcn.size() - 1) {
cur_earfcn_index = 0;
}
// If PHY is running, stop and free resources
free_cell();
float dl_freq = 1e6*srslte_band_fd(earfcn[cur_earfcn_index]);
if (dl_freq >= 0) {
log_h->info("Cell Search: Set DL EARFCN=%d, frequency=%.1f MHz, channel_index=%d\n", earfcn[cur_earfcn_index],
dl_freq / 1e6, cur_earfcn_index);
radio_h->set_rx_freq(dl_freq);
// Start PHY cell search (finds maximum cell in frequency)
phy_state = CELL_SEARCH;
} else {
log_h->error("Cell Search: Invalid EARFCN=%d, channel_index=%d\n", earfcn[cur_earfcn_index], cur_earfcn_index);
}
}
}
void phch_recv::cell_search_start() {
if (earfcn.size() > 0) {
cur_earfcn_index = -1;
log_h->console("Starting Cell Search procedure in %d EARFCNs...\n", earfcn.size());
log_h->info("Cell Search: Starting procedure...\n");
cell_search_next();
} else {
log_h->info("Empty EARFCN list. Stopping cell search...\n");
log_h->console("Empty EARFCN list. Stopping cell search...\n");
}
}
bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) {
free_cell();
int cnt=0;
while(phy_state == CELL_SEARCH && cnt<100) {
usleep(10000);
log_h->info("PHY in CELL_SEARCH. Waiting...\n");
}
if (phy_state==CELL_SEARCH) {
log_h->warning("PHY still in CELL_SEARCH, forcing CELL_SELECT...\n");
}
float dl_freq = 1e6*srslte_band_fd(earfcn);
float ul_freq = 1e6*srslte_band_fu(srslte_band_ul_earfcn(earfcn));
if (dl_freq >= 0 || ul_freq <= 0) {
log_h->info("Cell Select: Set EARFCN=%d, frequency=%.1f MHz, UL frequency=%.1f MHz\n", earfcn, dl_freq / 1e6,
ul_freq / 1e6);
radio_h->set_rx_freq(dl_freq);
radio_h->set_tx_freq(ul_freq);
ul_dl_factor = ul_freq/dl_freq;
cell_search_in_progress = false;
this->cell = cell;
if (init_cell()) {
phy_state = CELL_SELECT;
return true;
} else {
log_h->error("Cell Select: Initializing cell in EARFCN=%d, PCI=%d\n", earfcn, cell.id);
}
} else {
log_h->error("Cell Select: Invalid EARFCN=%d\n", earfcn);
}
return false;
}
int phch_recv::cell_sync_sfn(void) {
int ret = SRSLTE_ERROR;
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN];
srslte_ue_sync_decode_sss_on_track(&ue_sync, true);
ret = srslte_ue_sync_zerocopy_multi(&ue_sync, sf_buffer_sfn);
ret = srslte_ue_sync_zerocopy_multi(&ue_sync, sf_buffer);
if (ret < 0) {
Error("Error calling ue_sync_get_buffer");
return -1;
@ -309,9 +397,9 @@ namespace srsue {
if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) {
int sfn_offset = 0;
Info("SYNC: Decoding MIB...\n");
int n = srslte_ue_mib_decode(&ue_mib, sf_buffer_sfn[0], bch_payload, NULL, &sfn_offset);
int n = srslte_ue_mib_decode(&ue_mib, sf_buffer[0], bch_payload, NULL, &sfn_offset);
if (n < 0) {
Error("Error decoding MIB while synchronising SFN");
Error("SYNC: Error decoding MIB while synchronising SFN");
return -1;
} else if (n == SRSLTE_UE_MIB_FOUND) {
uint32_t sfn;
@ -332,70 +420,35 @@ namespace srsue {
return 0;
}
void phch_recv::resync_sfn() {
sync_sfn_cnt = 0;
phy_state = CELL_SELECT;
}
int phch_recv::cell_meas_rsrp() {
void phch_recv::set_earfcn(std::vector<uint32_t> earfcn) {
this->earfcn = earfcn;
}
uint32_t cfi = 0;
void phch_recv::cell_search_next() {
cur_earfcn_index++;
if (cur_earfcn_index >= 0) {
if ((uint32_t) cur_earfcn_index >= earfcn.size() - 1) {
cur_earfcn_index = 0;
tti = (tti+1) % 10240;
log_h->step(tti);
uint32_t sf_idx = tti%10;
int sync_res = srslte_ue_sync_zerocopy_multi(&ue_sync, sf_buffer);
if (sync_res == 1) {
if (srslte_ue_dl_decode_fft_estimate_multi(&ue_dl_measure, sf_buffer, sf_idx, &cfi)) {
log_h->error("SYNC: Measuring RSRP: Estimating channel\n");
return -1;
}
// If PHY is running, stop and free resources
free_cell();
float dl_freq = srslte_band_fd(earfcn[cur_earfcn_index]);
if (dl_freq >= 0) {
log_h->console("Cell Search: Set DL EARFCN=%d, frequency=%.1f MHz\n", earfcn[cur_earfcn_index], dl_freq / 1e6);
log_h->info("Cell Search: Set DL EARFCN=%d, frequency=%.1f MHz, channel_index=%d\n", earfcn[cur_earfcn_index],
dl_freq / 1e6, cur_earfcn_index);
radio_h->set_rx_freq(dl_freq);
// Start PHY cell search (finds maximum cell in frequency)
phy_state = CELL_SEARCH;
} else {
log_h->error("Cell Search: Invalid EARFCN=%d, channel_index=%d\n", earfcn[cur_earfcn_index], cur_earfcn_index);
}
}
}
void phch_recv::cell_search_start() {
cur_earfcn_index = -1;
log_h->console("Cell Search: Starting procedure...\n");
log_h->info("Cell Search: Starting procedure...\n");
cell_search_next();
}
bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) {
free_cell();
float dl_freq = srslte_band_fd(earfcn);
float ul_freq = srslte_band_ul_earfcn(earfcn);
if (dl_freq >= 0 || ul_freq <= 0) {
log_h->console("Cell Select: Set EARFCN=%d, DL frequency=%.1f MHz, UL frequency=%.1f MHz\n", earfcn,
dl_freq / 1e6, ul_freq / 1e6);
log_h->info("Cell Select: Set EARFCN=%d, frequency=%.1f MHz, UL frequency=%.1f MHz\n", earfcn, dl_freq / 1e6,
ul_freq / 1e6);
radio_h->set_rx_freq(dl_freq);
radio_h->set_tx_freq(ul_freq);
this->cell = cell;
if (init_cell()) {
phy_state = CELL_SELECT;
return true;
} else {
log_h->error("Cell Select: Initializing cell in EARFCN=%d, PCI=%d\n", earfcn, cell.id);
float rsrp = srslte_chest_dl_get_rsrp(&ue_dl_measure.chest);
measure_rsrp = SRSLTE_VEC_CMA(rsrp, measure_rsrp, measure_cnt);
measure_cnt++;
log_h->info("SYNC: Measuring RSRP %d/%d, sf_idx=%d, RSRP=%.1f dBm\n",
measure_cnt, RSRP_MEASURE_NOF_FRAMES, sf_idx, 10 * log10(rsrp / 1000));
if (measure_cnt >= RSRP_MEASURE_NOF_FRAMES) {
return 1;
}
} else {
log_h->error("Cell Select: Invalid EARFCN=%d\n", earfcn);
log_h->error("SYNC: Measuring RSRP: Sync error\n");
return -1;
}
return false;
return 0;
}
void phch_recv::run_thread() {
@ -406,7 +459,6 @@ namespace srsue {
switch (phy_state) {
case CELL_SEARCH:
if (cell_search()) {
log_h->console("Initializating cell configuration...\n");
init_cell();
float srate = (float) srslte_sampling_freq_hz(cell.nof_prb);
@ -416,12 +468,11 @@ namespace srsue {
radio_h->set_master_clock_rate(23.04e6);
}
log_h->console("Setting Sampling frequency %.2f MHz\n", (float) srate / 1000000);
log_h->info("Setting Sampling frequency %.2f MHz\n", (float) srate / 1000000);
srate_mode = SRATE_CAMP;
radio_h->set_rx_srate(srate);
radio_h->set_tx_srate(srate);
ul_dl_factor = radio_h->get_tx_freq() / radio_h->get_rx_freq();
Info("SYNC: Cell found. Synchronizing...\n");
phy_state = CELL_SELECT;
sync_sfn_cnt = 0;
@ -438,14 +489,21 @@ namespace srsue {
radio_is_streaming = true;
}
switch (sync_sfn()) {
switch (cell_sync_sfn()) {
default:
log_h->console("Going IDLE\n");
phy_state = IDLE;
break;
case 1:
srslte_ue_sync_set_agc_period(&ue_sync, 20);
phy_state = CAMPING;
if (!cell_search_in_progress) {
phy_state = CELL_CAMP;
log_h->console("Sync OK. Camping on cell PCI=%d...\n", cell.id);
} else {
measure_cnt = 0;
measure_rsrp = 0;
phy_state = CELL_MEASURE;
}
break;
case 0:
break;
@ -459,10 +517,21 @@ namespace srsue {
log_h->warning("Timeout while synchronizing SFN\n");
}
break;
case CAMPING:
case CELL_MEASURE:
switch(cell_meas_rsrp()) {
case 1:
rrc->cell_found(earfcn[cur_earfcn_index], cell, 10*log10(measure_rsrp/1000));
phy_state = CELL_CAMP;
case 0:
break;
default:
log_h->error("SYNC: Getting RSRP cell measurement.\n");
cell_search_next();
}
break;
case CELL_CAMP:
tti = (tti+1) % 10240;
worker = (phch_worker *) workers_pool->wait_worker(tti);
sync_res = 0;
if (worker) {
for (uint32_t i = 0; i < nof_rx_antennas; i++) {
buffer[i] = worker->get_buffer(i);
@ -535,7 +604,7 @@ namespace srsue {
}
bool phch_recv::status_is_sync() {
return phy_state == CAMPING;
return phy_state == CELL_CAMP;
}
void phch_recv::get_current_cell(srslte_cell_t *cell_) {

View File

@ -33,6 +33,7 @@
#include <string>
#include <algorithm>
#include <iterator>
#include <ue.h>
using namespace srslte;
@ -74,7 +75,7 @@ ue::~ue()
bool ue::init(all_args_t *args_)
{
args = args_;
logger.init(args->log.filename);
rf_log.init("RF ", &logger);
phy_log.init("PHY ", &logger, true);
@ -169,6 +170,7 @@ bool ue::init(all_args_t *args_)
}
if (args->rf.tx_gain > 0) {
radio.set_tx_gain(args->rf.tx_gain);
printf("set tx gain %f\n", args->rf.tx_gain);
} else {
radio.set_tx_gain(args->rf.rx_gain);
std::cout << std::endl <<
@ -189,6 +191,14 @@ bool ue::init(all_args_t *args_)
gw.init(&pdcp, &rrc, this, &gw_log);
usim.init(&args->usim, &usim_log);
// Currently EARFCN list is set to only one frequency as indicated in ue.conf
std::vector<uint32_t> earfcn_list;
earfcn_list.push_back(args->rf.dl_earfcn);
phy.set_earfcn(earfcn_list);
printf("\n\nRequesting NAS Attach...\n");
nas.attach_request();
started = true;
return true;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff